#!/bin/bash # # Shell functions for the rest of the scripts. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, you can access it online at # http://www.gnu.org/licenses/gpl-2.0.html. # # Copyright (C) IBM Corporation, 2013 # # Authors: Paul E. McKenney # bootparam_hotplug_cpu bootparam-string # # Returns 1 if the specified boot-parameter string tells rcutorture to # test CPU-hotplug operations. proc bootparam_hotplug_cpu { echo $1 | grep -q "rcutorture\.onoff_" } # checkarg --argname argtype $# arg mustmatch cannotmatch # # Checks the specified argument "arg" against the mustmatch and cannotmatch # patterns. proc checkarg { if test $3 -le 1 { echo $1 needs argument $2 matching '"'$5'"' usage } if echo $4 | grep -q -e $5 { : } else { echo $1 $2 '"'$4'"' must match '"'$5'"' usage } if echo $4 | grep -q -e $6 { echo $1 $2 '"'$4'"' must not match '"'$6'"' usage } } # configfrag_boot_params bootparam-string config-fragment-file # # Adds boot parameters from the .boot file, if any. proc configfrag_boot_params { if test -r "$2.boot" { echo $1 $[grep -v '^#' "$2.boot" | tr '\012' ' ] } else { echo $1 } } # configfrag_boot_cpus bootparam-string config-fragment-file config-cpus # # Decreases number of CPUs based on any maxcpus= boot parameters specified. proc configfrag_boot_cpus { var bootargs = $[configfrag_boot_params $1 $2] var maxcpus = '' if echo $(bootargs) | grep -q 'maxcpus=[0-9]' { maxcpus := $[echo $(bootargs) | sed -e 's/^.*maxcpus=\([0-9]*\).*$/\1/] if test $3 -gt $maxcpus { echo $maxcpus } else { echo $3 } } else { echo $3 } } # configfrag_hotplug_cpu config-fragment-file # # Returns 1 if the config fragment specifies hotplug CPU. proc configfrag_hotplug_cpu { if test ! -r $1 { echo Unreadable config fragment $1 !1 > !2 exit -1 } grep -q '^CONFIG_HOTPLUG_CPU=y$' $1 } # identify_boot_image qemu-cmd # # Returns the relative path to the kernel build image. This will be # arch//boot/bzImage or vmlinux if bzImage is not a target for the # architecture, unless overridden with the TORTURE_BOOT_IMAGE environment # variable. proc identify_boot_image { if test -n $TORTURE_BOOT_IMAGE { echo $TORTURE_BOOT_IMAGE } else { matchstr $1 { qemu-system-x86_64|qemu-system-i386 { echo arch/x86/boot/bzImage } * { echo vmlinux } } } } # identify_qemu builddir # # Returns our best guess as to which qemu command is appropriate for # the kernel at hand. Override with the TORTURE_QEMU_CMD environment variable. proc identify_qemu { var u = $[file $1] if test -n $TORTURE_QEMU_CMD { echo $TORTURE_QEMU_CMD } elif echo $u | grep -q x86-64 { echo qemu-system-x86_64 } elif echo $u | grep -q "Intel 80386" { echo qemu-system-i386 } elif uname -a | grep -q ppc64 { echo qemu-system-ppc64 } else { echo Cannot figure out what qemu command to use! !1 > !2 echo file $1 output: $u # Usually this will be one of /usr/bin/qemu-system-* # Use TORTURE_QEMU_CMD environment variable or appropriate # argument to top-level script. exit 1 } } # identify_qemu_append qemu-cmd # # Output arguments for the qemu "-append" string based on CPU type # and the TORTURE_QEMU_INTERACTIVE environment variable. proc identify_qemu_append { matchstr $1 { qemu-system-x86_64|qemu-system-i386 { echo noapic selinux=0 initcall_debug debug } } if test -n $TORTURE_QEMU_INTERACTIVE { echo root=/dev/sda } else { echo console=ttyS0 } } # identify_qemu_args qemu-cmd serial-file # # Output arguments for qemu arguments based on the TORTURE_QEMU_MAC # and TORTURE_QEMU_INTERACTIVE environment variables. proc identify_qemu_args { matchstr $1 { qemu-system-x86_64|qemu-system-i386 { } qemu-system-ppc64 { echo -enable-kvm -M pseries -nodefaults echo -device spapr-vscsi if test -n $TORTURE_QEMU_INTERACTIVE -a -n $TORTURE_QEMU_MAC { echo -device spapr-vlan,netdev=net0,mac=$TORTURE_QEMU_MAC echo -netdev bridge,br=br0,id=net0 } elif test -n $TORTURE_QEMU_INTERACTIVE { echo -net nic -net user } } } if test -n $TORTURE_QEMU_INTERACTIVE { echo -monitor stdio -serial pty -S } else { echo -serial file:$2 } } # identify_qemu_vcpus # # Returns the number of virtual CPUs available to the aggregate of the # guest OSes. proc identify_qemu_vcpus { lscpu | grep '^CPU(s):' | sed -e 's/CPU(s)://' } # print_bug # # Prints "BUG: " in red followed by remaining arguments proc print_bug { printf '\033[031mBUG: \033[m' echo $ifsjoin(Argv) } # print_warning # # Prints "WARNING: " in yellow followed by remaining arguments proc print_warning { printf '\033[033mWARNING: \033[m' echo $ifsjoin(Argv) } # specify_qemu_cpus qemu-cmd qemu-args #cpus # # Appends a string containing "-smp XXX" to qemu-args, unless the incoming # qemu-args already contains "-smp". proc specify_qemu_cpus { var nt = ''; if echo $2 | grep -q -e -smp { echo $2 } else { matchstr $1 { qemu-system-x86_64|qemu-system-i386 { echo $2 -smp $3 } qemu-system-ppc64 { nt := $[lscpu | grep '^NUMA node0' | sed -e 's/^[^,]*,\([0-9]*\),.*$/\1/] echo $2 -smp cores=$[expr '(' $3 + $nt - 1 ')' / $nt],threads=$nt } } } } (CommandList children: [ (FuncDef name: bootparam_hotplug_cpu body: (BraceGroup children: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Number "$1"))}) (C {(grep)} {(-q)} {(DQ (rcutorture) (EscapedLiteralPart token:) (onoff_))} ) ] negated: False ) ] spids: [81] ) spids: [76 80] ) (FuncDef name: checkarg body: (BraceGroup children: [ (If arms: [ (if_arm cond: [(C {(test)} {($ VSub_Number "$3")} {(-le)} {(1)})] action: [ (C {(echo)} {($ VSub_Number "$1")} {(needs)} {(argument)} {($ VSub_Number "$2")} {(matching)} {(EscapedLiteralPart token:) ($ VSub_Number "$5") (EscapedLiteralPart token:) } ) (C {(usage)}) ] spids: [-1 136] ) ] spids: [-1 159] ) (If arms: [ (if_arm cond: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Number "$4"))}) (C {(grep)} {(-q)} {(-e)} {(DQ ($ VSub_Number "$5"))}) ] negated: False ) ] action: [(C {(Lit_Other ":")})] spids: [-1 183] ) ] else_action: [ (C {(echo)} {($ VSub_Number "$1")} {($ VSub_Number "$2")} {(EscapedLiteralPart token:) ($ VSub_Number "$4") (EscapedLiteralPart token:) } {(must)} {(match)} {(EscapedLiteralPart token:) ($ VSub_Number "$5") (EscapedLiteralPart token:) } ) (C {(usage)}) ] spids: [189 214] ) (If arms: [ (if_arm cond: [ (Pipeline children: [ (C {(echo)} {(DQ ($ VSub_Number "$4"))}) (C {(grep)} {(-q)} {(-e)} {(DQ ($ VSub_Number "$6"))}) ] negated: False ) ] action: [ (C {(echo)} {($ VSub_Number "$1")} {($ VSub_Number "$2")} {(EscapedLiteralPart token:) ($ VSub_Number "$4") (EscapedLiteralPart token:) } {(must)} {(not)} {(match)} {(EscapedLiteralPart token:) ($ VSub_Number "$6") (EscapedLiteralPart token:) } ) (C {(usage)}) ] spids: [-1 238] ) ] spids: [-1 265] ) ] spids: [122] ) spids: [117 121] ) (FuncDef name: configfrag_boot_params body: (BraceGroup children: [ (If arms: [ (if_arm cond: [(C {(test)} {(-r)} {(DQ ($ VSub_Number "$2") (.boot))})] action: [ (C {(echo)} {($ VSub_Number "$1")} { (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(grep)} {(-v)} {(SQ <"^#">)} {(DQ ($ VSub_Number "$2") (.boot))}) (C {(tr)} {(SQ <"\\012">)} {(SQ <" ">)}) ] negated: False ) ] ) left_token: spids: [306 331] ) } ) ] spids: [-1 299] ) ] else_action: [(C {(echo)} {($ VSub_Number "$1")})] spids: [334 342] ) ] spids: [284] ) spids: [279 283] ) (FuncDef name: configfrag_boot_cpus body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:bootargs) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (C {(configfrag_boot_params)} {(DQ ($ VSub_Number "$1"))} {(DQ ($ VSub_Number "$2"))} ) ] ) left_token: spids: [368 378] ) ) } spids: [366] ) ] spids: [364] ) (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:maxcpus) op:Equal spids:[384])] spids: [382] ) (If arms: [ (if_arm cond: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name bootargs))}) (C {(grep)} {(-q)} {(SQ <"maxcpus=[0-9]">)}) ] negated: False ) ] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:maxcpus) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(echo)} {(DQ (${ VSub_Name bootargs))}) (C {(sed)} {(-e)} {(SQ <"s/^.*maxcpus=\\([0-9]*\\).*$/\\1/">)} ) ] negated: False ) ] ) left_token: spids: [413 431] ) ) } spids: [411] ) ] spids: [411] ) (If arms: [ (if_arm cond: [ (C {(test)} {(DQ ($ VSub_Number "$3"))} {(-gt)} {(DQ ($ VSub_Name "$maxcpus"))} ) ] action: [(C {(echo)} {($ VSub_Name "$maxcpus")})] spids: [-1 450] ) ] else_action: [(C {(echo)} {($ VSub_Number "$3")})] spids: [458 466] ) ] spids: [-1 408] ) ] else_action: [(C {(echo)} {($ VSub_Number "$3")})] spids: [469 477] ) ] spids: [361] ) spids: [356 360] ) (FuncDef name: configfrag_hotplug_cpu body: (BraceGroup children: [ (If arms: [ (if_arm cond: [(C {(test)} {(KW_Bang "!")} {(-r)} {(DQ ($ VSub_Number "$1"))})] action: [ (SimpleCommand words: [{(echo)} {(Unreadable)} {(config)} {(fragment)} {(DQ ($ VSub_Number "$1"))}] redirects: [(Redir op_id:Redir_GreatAnd fd:1 arg_word:{(2)} spids:[527])] ) (C {(exit)} {(-1)}) ] spids: [-1 512] ) ] spids: [-1 536] ) (C {(grep)} {(-q)} {(SQ <"^CONFIG_HOTPLUG_CPU=y$">)} {(DQ ($ VSub_Number "$1"))}) ] spids: [496] ) spids: [491 495] ) (FuncDef name: identify_boot_image body: (BraceGroup children: [ (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_BOOT_IMAGE"))})] action: [(C {(echo)} {($ VSub_Name "$TORTURE_BOOT_IMAGE")})] spids: [-1 591] ) ] else_action: [ (Case to_match: {(DQ ($ VSub_Number "$1"))} arms: [ (case_arm pat_list: [{(qemu-system-x86_64)} {(qemu-system-i386)}] action: [(C {(echo)} {(arch/x86/boot/bzImage)})] spids: [611 614 622 -1] ) (case_arm pat_list: [{(Lit_Other "*")}] action: [(C {(echo)} {(vmlinux)})] spids: [625 626 634 -1] ) ] spids: [602 608 637] ) ] spids: [599 640] ) ] spids: [577] ) spids: [572 576] ) (FuncDef name: identify_qemu body: (BraceGroup children: [ (Assignment keyword: Assign_Local pairs: [ (assign_pair lhs: (LhsName name:u) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [(C {(file)} {(DQ ($ VSub_Number "$1"))})] ) left_token: spids: [669 675] ) ) } spids: [667] ) ] spids: [665] ) (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_QEMU_CMD"))})] action: [(C {(echo)} {($ VSub_Name "$TORTURE_QEMU_CMD")})] spids: [-1 690] ) (if_arm cond: [ (Pipeline children: [(C {(echo)} {($ VSub_Name "$u")}) (C {(grep)} {(-q)} {(x86-64)})] negated: False ) ] action: [(C {(echo)} {(qemu-system-x86_64)})] spids: [698 713] ) (if_arm cond: [ (Pipeline children: [ (C {(echo)} {($ VSub_Name "$u")}) (C {(grep)} {(-q)} {(DQ ("Intel 80386"))}) ] negated: False ) ] action: [(C {(echo)} {(qemu-system-i386)})] spids: [721 738] ) (if_arm cond: [ (Pipeline children: [(C {(uname)} {(-a)}) (C {(grep)} {(-q)} {(ppc64)})] negated: False ) ] action: [(C {(echo)} {(qemu-system-ppc64)})] spids: [746 761] ) ] else_action: [ (SimpleCommand words: [ {(echo)} {(Cannot)} {(figure)} {(out)} {(what)} {(qemu)} {(command)} {(to)} {(use) (KW_Bang "!")} ] redirects: [(Redir op_id:Redir_GreatAnd fd:1 arg_word:{(2)} spids:[791])] ) (C {(echo)} {(file)} {($ VSub_Number "$1")} {(output) (Lit_Other ":")} {($ VSub_Name "$u")} ) (C {(exit)} {(1)}) ] spids: [769 824] ) ] spids: [662] ) spids: [657 661] ) (FuncDef name: identify_qemu_append body: (BraceGroup children: [ (Case to_match: {(DQ ($ VSub_Number "$1"))} arms: [ (case_arm pat_list: [{(qemu-system-x86_64)} {(qemu-system-i386)}] action: [ (C {(echo)} {(noapic)} {(Lit_VarLike "selinux=") (0)} {(initcall_debug)} {(debug)}) ] spids: [858 861 876 -1] ) ] spids: [849 855 879] ) (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_QEMU_INTERACTIVE"))})] action: [(C {(echo)} {(Lit_VarLike "root=") (/dev/sda)})] spids: [-1 893] ) ] else_action: [(C {(echo)} {(Lit_VarLike "console=") (ttyS0)})] spids: [902 911] ) ] spids: [846] ) spids: [841 845] ) (FuncDef name: identify_qemu_args body: (BraceGroup children: [ (Case to_match: {(DQ ($ VSub_Number "$1"))} arms: [ (case_arm pat_list: [{(qemu-system-x86_64)} {(qemu-system-i386)}] spids: [945 948 951 -1] ) (case_arm pat_list: [{(qemu-system-ppc64)}] action: [ (C {(echo)} {(-enable-kvm)} {(-M)} {(pseries)} {(-nodefaults)}) (C {(echo)} {(-device)} {(spapr-vscsi)}) (If arms: [ (if_arm cond: [ (C {(test)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_QEMU_INTERACTIVE"))} {(-a)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_QEMU_MAC"))} ) ] action: [ (C {(echo)} {(-device)} {(spapr-vlan) (Lit_Comma ",") (Lit_VarLike "netdev=") (net0) (Lit_Comma ",") (Lit_VarLike "mac=") ($ VSub_Name "$TORTURE_QEMU_MAC") } ) (C {(echo)} {(-netdev)} {(bridge) (Lit_Comma ",") (Lit_VarLike "br=") (br0) (Lit_Comma ",") (Lit_VarLike "id=") (net0) } ) ] spids: [-1 995] ) (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_QEMU_INTERACTIVE"))})] action: [(C {(echo)} {(-net)} {(nic)} {(-net)} {(user)})] spids: [1024 1035] ) ] spids: [-1 1049] ) ] spids: [954 955 1052 -1] ) ] spids: [936 942 1055] ) (If arms: [ (if_arm cond: [(C {(test)} {(-n)} {(DQ ($ VSub_Name "$TORTURE_QEMU_INTERACTIVE"))})] action: [(C {(echo)} {(-monitor)} {(stdio)} {(-serial)} {(pty)} {(-S)})] spids: [-1 1069] ) ] else_action: [(C {(echo)} {(-serial)} {(file) (Lit_Other ":") ($ VSub_Number "$2")})] spids: [1085 1097] ) ] spids: [933] ) spids: [928 932] ) (FuncDef name: identify_qemu_vcpus body: (BraceGroup children: [ (Pipeline children: [ (C {(lscpu)}) (C {(grep)} {(SQ <"^CPU(s):">)}) (C {(sed)} {(-e)} {(SQ <"s/CPU(s)://">)}) ] negated: False ) ] spids: [1119] ) spids: [1114 1118] ) (FuncDef name: print_bug body: (BraceGroup children: [(C {(printf)} {(SQ <"\\033[031mBUG: \\033[m">)}) (C {(echo)} {($ VSub_Star "$*")})] spids: [1159] ) spids: [1154 1158] ) (FuncDef name: print_warning body: (BraceGroup children: [ (C {(printf)} {(SQ <"\\033[033mWARNING: \\033[m">)}) (C {(echo)} {($ VSub_Star "$*")}) ] spids: [1190] ) spids: [1185 1189] ) (FuncDef name: specify_qemu_cpus body: (BraceGroup children: [ (Sentence child: (Assignment keyword: Assign_Local pairs: [(assign_pair lhs:(LhsName name:nt) op:Equal spids:[1229])] spids: [1227] ) terminator: ) (If arms: [ (if_arm cond: [ (Pipeline children: [(C {(echo)} {($ VSub_Number "$2")}) (C {(grep)} {(-q)} {(-e)} {(-smp)})] negated: False ) ] action: [(C {(echo)} {($ VSub_Number "$2")})] spids: [-1 1251] ) ] else_action: [ (Case to_match: {(DQ ($ VSub_Number "$1"))} arms: [ (case_arm pat_list: [{(qemu-system-x86_64)} {(qemu-system-i386)}] action: [(C {(echo)} {($ VSub_Number "$2")} {(-smp)} {($ VSub_Number "$3")})] spids: [1271 1274 1286 -1] ) (case_arm pat_list: [{(qemu-system-ppc64)}] action: [ (Assignment keyword: Assign_None pairs: [ (assign_pair lhs: (LhsName name:nt) op: Equal rhs: { (DQ (CommandSubPart command_list: (CommandList children: [ (Pipeline children: [ (C {(lscpu)}) (C {(grep)} {(SQ <"^NUMA node0">)}) (C {(sed)} {(-e)} {(SQ <"s/^[^,]*,\\([0-9]*\\),.*$/\\1/">)} ) ] negated: False ) ] ) left_token: spids: [1295 1315] ) ) } spids: [1293] ) ] spids: [1293] ) (C {(echo)} {($ VSub_Number "$2")} {(-smp)} {(Lit_VarLike "cores=") (CommandSubPart command_list: (CommandList children: [ (C {(expr)} {(EscapedLiteralPart token:)} {($ VSub_Number "$3")} {(Lit_Other "+")} {($ VSub_Name "$nt")} {(-)} {(1)} {(EscapedLiteralPart token:)} {(/)} {($ VSub_Name "$nt")} ) ] ) left_token: spids: [1326 1346] ) (Lit_Comma ",") (Lit_VarLike "threads=") ($ VSub_Name "$nt") } ) ] spids: [1289 1290 1352 -1] ) ] spids: [1262 1268 1355] ) ] spids: [1259 1358] ) ] spids: [1224] ) spids: [1219 1223] ) ] )