363 lines · bash
1#!/bin/bash2# SPDX-License-Identifier: GPL-2.0+3#4# Shell functions for the rest of the scripts.5#6# Copyright (C) IBM Corporation, 20137#8# Authors: Paul E. McKenney <paulmck@linux.ibm.com>9 10# bootparam_hotplug_cpu bootparam-string11#12# Returns 1 if the specified boot-parameter string tells rcutorture to13# test CPU-hotplug operations.14bootparam_hotplug_cpu () {15 echo "$1" | grep -q "torture\.onoff_"16}17 18# checkarg --argname argtype $# arg mustmatch cannotmatch19#20# Checks the specified argument "arg" against the mustmatch and cannotmatch21# patterns.22checkarg () {23 if test $3 -le 124 then25 echo $1 needs argument $2 matching \"$5\"26 usage27 fi28 if echo "$4" | grep -q -e "$5"29 then30 :31 else32 echo $1 $2 \"$4\" must match \"$5\"33 usage34 fi35 if echo "$4" | grep -q -e "$6"36 then37 echo $1 $2 \"$4\" must not match \"$6\"38 usage39 fi40}41 42# configfrag_boot_params bootparam-string config-fragment-file43#44# Adds boot parameters from the .boot file, if any.45configfrag_boot_params () {46 if test -r "$2.boot"47 then48 echo `grep -v '^#' "$2.boot" | tr '\012' ' '` $149 else50 echo $151 fi52}53 54# configfrag_boot_cpus bootparam-string config-fragment-file config-cpus55#56# Decreases number of CPUs based on any nr_cpus= boot parameters specified.57configfrag_boot_cpus () {58 local bootargs="`configfrag_boot_params "$1" "$2"`"59 local nr_cpus60 if echo "${bootargs}" | grep -q 'nr_cpus=[0-9]'61 then62 nr_cpus="`echo "${bootargs}" | sed -e 's/^.*nr_cpus=\([0-9]*\).*$/\1/'`"63 if test "$3" -gt "$nr_cpus"64 then65 echo $nr_cpus66 else67 echo $368 fi69 else70 echo $371 fi72}73 74# configfrag_boot_maxcpus bootparam-string config-fragment-file config-cpus75#76# Decreases number of CPUs based on any maxcpus= boot parameters specified.77# This allows tests where additional CPUs come online later during the78# test run. However, the torture parameters will be set based on the79# number of CPUs initially present, so the scripting should schedule80# test runs based on the maxcpus= boot parameter controlling the initial81# number of CPUs instead of on the ultimate number of CPUs.82configfrag_boot_maxcpus () {83 local bootargs="`configfrag_boot_params "$1" "$2"`"84 local maxcpus85 if echo "${bootargs}" | grep -q 'maxcpus=[0-9]'86 then87 maxcpus="`echo "${bootargs}" | sed -e 's/^.*maxcpus=\([0-9]*\).*$/\1/'`"88 if test "$3" -gt "$maxcpus"89 then90 echo $maxcpus91 else92 echo $393 fi94 else95 echo $396 fi97}98 99# configfrag_hotplug_cpu config-fragment-file100#101# Returns 1 if the config fragment specifies hotplug CPU.102configfrag_hotplug_cpu () {103 if test ! -r "$1"104 then105 echo Unreadable config fragment "$1" 1>&2106 exit -1107 fi108 grep -q '^CONFIG_HOTPLUG_CPU=y$' "$1"109}110 111# get_starttime112#113# Returns a cookie identifying the current time.114get_starttime () {115 awk 'BEGIN { print systime() }' < /dev/null116}117 118# get_starttime_duration starttime119#120# Given the return value from get_starttime, compute a human-readable121# string denoting the time since get_starttime.122get_starttime_duration () {123 awk -v starttime=$1 '124 BEGIN {125 ts = systime() - starttime; 126 tm = int(ts / 60);127 th = int(ts / 3600);128 td = int(ts / 86400);129 d = td;130 h = th - td * 24;131 m = tm - th * 60;132 s = ts - tm * 60;133 if (d >= 1)134 printf "%dd %d:%02d:%02d\n", d, h, m, s135 else if (h >= 1)136 printf "%d:%02d:%02d\n", h, m, s137 else if (m >= 1)138 printf "%d:%02d.0\n", m, s139 else140 print s " seconds"141 }' < /dev/null142}143 144# identify_boot_image qemu-cmd145#146# Returns the relative path to the kernel build image. This will be147# arch/<arch>/boot/bzImage or vmlinux if bzImage is not a target for the148# architecture, unless overridden with the TORTURE_BOOT_IMAGE environment149# variable.150identify_boot_image () {151 if test -n "$TORTURE_BOOT_IMAGE"152 then153 echo $TORTURE_BOOT_IMAGE154 else155 case "$1" in156 qemu-system-x86_64|qemu-system-i386)157 echo arch/x86/boot/bzImage158 ;;159 qemu-system-aarch64)160 echo arch/arm64/boot/Image161 ;;162 qemu-system-s390x)163 echo arch/s390/boot/bzImage164 ;;165 *)166 echo vmlinux167 ;;168 esac169 fi170}171 172# identify_qemu builddir173#174# Returns our best guess as to which qemu command is appropriate for175# the kernel at hand. Override with the TORTURE_QEMU_CMD environment variable.176identify_qemu () {177 local u="`file "$1"`"178 if test -n "$TORTURE_QEMU_CMD"179 then180 echo $TORTURE_QEMU_CMD181 elif echo $u | grep -q x86-64182 then183 echo qemu-system-x86_64184 elif echo $u | grep -q "Intel 80386"185 then186 echo qemu-system-i386187 elif echo $u | grep -q aarch64188 then189 echo qemu-system-aarch64190 elif echo $u | grep -q 'IBM S/390'191 then192 echo qemu-system-s390x193 elif uname -a | grep -q ppc64194 then195 echo qemu-system-ppc64196 else197 echo Cannot figure out what qemu command to use! 1>&2198 echo file $1 output: $u199 # Usually this will be one of /usr/bin/qemu-system-*200 # Use TORTURE_QEMU_CMD environment variable or appropriate201 # argument to top-level script.202 exit 1203 fi204}205 206# identify_qemu_append qemu-cmd207#208# Output arguments for the qemu "-append" string based on CPU type209# and the TORTURE_QEMU_INTERACTIVE environment variable.210identify_qemu_append () {211 echo debug_boot_weak_hash212 echo panic=-1213 local console=ttyS0214 case "$1" in215 qemu-system-x86_64|qemu-system-i386)216 echo selinux=0 initcall_debug debug217 ;;218 qemu-system-aarch64)219 console=ttyAMA0220 ;;221 esac222 if test -n "$TORTURE_QEMU_INTERACTIVE"223 then224 echo root=/dev/sda225 else226 echo console=$console227 fi228}229 230# identify_qemu_args qemu-cmd serial-file231#232# Output arguments for qemu arguments based on the TORTURE_QEMU_MAC233# and TORTURE_QEMU_INTERACTIVE environment variables.234identify_qemu_args () {235 local KVM_CPU=""236 case "$1" in237 qemu-system-x86_64)238 KVM_CPU=kvm64239 ;;240 qemu-system-i386)241 KVM_CPU=kvm32242 ;;243 esac244 case "$1" in245 qemu-system-x86_64|qemu-system-i386)246 echo -machine q35,accel=kvm247 echo -cpu ${KVM_CPU}248 ;;249 qemu-system-aarch64)250 echo -machine virt,gic-version=host -cpu host251 ;;252 qemu-system-ppc64)253 echo -M pseries -nodefaults254 echo -device spapr-vscsi255 if test -n "$TORTURE_QEMU_INTERACTIVE" -a -n "$TORTURE_QEMU_MAC"256 then257 echo -device spapr-vlan,netdev=net0,mac=$TORTURE_QEMU_MAC258 echo -netdev bridge,br=br0,id=net0259 fi260 ;;261 esac262 if test -n "$TORTURE_QEMU_INTERACTIVE"263 then264 echo -monitor stdio -serial pty -S265 else266 echo -serial file:$2267 fi268}269 270# identify_qemu_vcpus271#272# Returns the number of virtual CPUs available to the aggregate of the273# guest OSes.274identify_qemu_vcpus () {275 getconf _NPROCESSORS_ONLN276}277 278# print_bug279#280# Prints "BUG: " in red followed by remaining arguments281print_bug () {282 printf '\033[031mBUG: \033[m'283 echo $*284}285 286# print_warning287#288# Prints "WARNING: " in yellow followed by remaining arguments289print_warning () {290 printf '\033[033mWARNING: \033[m'291 echo $*292}293 294# specify_qemu_cpus qemu-cmd qemu-args #cpus295#296# Appends a string containing "-smp XXX" to qemu-args, unless the incoming297# qemu-args already contains "-smp".298specify_qemu_cpus () {299 local nt;300 301 if echo $2 | grep -q -e -smp302 then303 echo $2304 else305 case "$1" in306 qemu-system-x86_64|qemu-system-i386|qemu-system-aarch64)307 echo $2 -smp $3308 ;;309 qemu-system-ppc64)310 nt="`lscpu | sed -n 's/^Thread(s) per core:\s*//p'`"311 echo $2 -smp cores=`expr \( $3 + $nt - 1 \) / $nt`,threads=$nt312 ;;313 esac314 fi315}316 317# specify_qemu_net qemu-args318#319# Appends a string containing "-net none" to qemu-args, unless the incoming320# qemu-args already contains "-smp" or unless the TORTURE_QEMU_INTERACTIVE321# environment variable is set, in which case the string that is be added is322# instead "-net nic -net user".323specify_qemu_net () {324 if echo $1 | grep -q -e -net325 then326 echo $1327 elif test -n "$TORTURE_QEMU_INTERACTIVE"328 then329 echo $1 -net nic -net user330 else331 echo $1 -net none332 fi333}334 335# Extract the ftrace output from the console log output336# The ftrace output in the original logs look like:337# Dumping ftrace buffer:338# ---------------------------------339# [...]340# ---------------------------------341extract_ftrace_from_console() {342 awk < "$1" '343 344 /Dumping ftrace buffer:/ {345 buffer_count++346 print "Ftrace dump " buffer_count ":"347 capture = 1348 next349 }350 351 /---------------------------------/ {352 if(capture == 1) {353 capture = 2354 next355 } else if(capture == 2) {356 capture = 0357 print ""358 }359 }360 361 capture == 2'362}363