1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0+ 3# 4# Rerun a series of tests under KVM. 5# 6# Usage: kvm-again.sh /path/to/old/run [ options ] 7# 8# Copyright (C) 2021 Facebook, Inc. 9# 10# Authors: Paul E. McKenney <paulmck@kernel.org> 11 12scriptname=$0 13args="$*" 14 15T="`mktemp -d ${TMPDIR-/tmp}/kvm-again.sh.XXXXXX`" 16trap 'rm -rf $T' 0 17 18if ! test -d tools/testing/selftests/rcutorture/bin 19then 20 echo $scriptname must be run from top-level directory of kernel source tree. 21 exit 1 22fi 23 24oldrun=$1 25shift 26if ! test -d "$oldrun" 27then 28 echo "Usage: $scriptname /path/to/old/run [ options ]" 29 exit 1 30fi 31if ! cp "$oldrun/scenarios" $T/scenarios.oldrun 32then 33 # Later on, can reconstitute this from console.log files. 34 echo Prior run batches file does not exist: $oldrun/batches 35 exit 1 36fi 37 38if test -f "$oldrun/torture_suite" 39then 40 torture_suite="`cat $oldrun/torture_suite`" 41elif test -f "$oldrun/TORTURE_SUITE" 42then 43 torture_suite="`cat $oldrun/TORTURE_SUITE`" 44else 45 echo "Prior run torture_suite file does not exist: $oldrun/{torture_suite,TORTURE_SUITE}" 46 exit 1 47fi 48 49RCUTORTURE="`pwd`/tools/testing/selftests/rcutorture"; export RCUTORTURE 50PATH=${RCUTORTURE}/bin:$PATH; export PATH 51. functions.sh 52 53bootargs= 54dryrun= 55dur= 56default_link="cp -R" 57resdir="`pwd`/tools/testing/selftests/rcutorture/res" 58rundir="$resdir/`date +%Y.%m.%d-%H.%M.%S-again`" 59got_datestamp= 60got_rundir= 61 62startdate="`date`" 63starttime="`get_starttime`" 64 65usage () { 66 echo "Usage: $scriptname $oldrun [ arguments ]:" 67 echo " --bootargs kernel-boot-arguments" 68 echo " --datestamp string" 69 echo " --dryrun" 70 echo " --duration minutes | <seconds>s | <hours>h | <days>d" 71 echo " --link hard|soft|copy" 72 echo " --remote" 73 echo " --rundir /new/res/path" 74 echo "Command line: $scriptname $args" 75 exit 1 76} 77 78while test $# -gt 0 79do 80 case "$1" in 81 --bootargs|--bootarg) 82 checkarg --bootargs "(list of kernel boot arguments)" "$#" "$2" '.*' '^--' 83 bootargs="$bootargs $2" 84 shift 85 ;; 86 --datestamp) 87 checkarg --datestamp "(relative pathname)" "$#" "$2" '^[a-zA-Z0-9._/-]*$' '^--' 88 if test -n "$got_rundir" || test -n "$got_datestamp" 89 then 90 echo Only one of --datestamp or --rundir may be specified 91 usage 92 fi 93 got_datestamp=y 94 ds=$2 95 rundir="$resdir/$ds" 96 if test -e "$rundir" 97 then 98 echo "--datestamp $2: Already exists." 99 usage 100 fi 101 shift 102 ;; 103 --dryrun) 104 dryrun=1 105 ;; 106 --duration) 107 checkarg --duration "(minutes)" $# "$2" '^[0-9][0-9]*\(s\|m\|h\|d\|\)$' '^error' 108 mult=60 109 if echo "$2" | grep -q 's$' 110 then 111 mult=1 112 elif echo "$2" | grep -q 'h$' 113 then 114 mult=3600 115 elif echo "$2" | grep -q 'd$' 116 then 117 mult=86400 118 fi 119 ts=`echo $2 | sed -e 's/[smhd]$//'` 120 dur=$(($ts*mult)) 121 shift 122 ;; 123 --link) 124 checkarg --link "hard|soft|copy" "$#" "$2" 'hard\|soft\|copy' '^--' 125 case "$2" in 126 copy) 127 arg_link="cp -R" 128 ;; 129 hard) 130 arg_link="cp -Rl" 131 ;; 132 soft) 133 arg_link="cp -Rs" 134 ;; 135 esac 136 shift 137 ;; 138 --remote) 139 arg_remote=1 140 default_link="cp -as" 141 ;; 142 --rundir) 143 checkarg --rundir "(absolute pathname)" "$#" "$2" '^/' '^error' 144 if test -n "$got_rundir" || test -n "$got_datestamp" 145 then 146 echo Only one of --datestamp or --rundir may be specified 147 usage 148 fi 149 got_rundir=y 150 rundir=$2 151 if test -e "$rundir" 152 then 153 echo "--rundir $2: Already exists." 154 usage 155 fi 156 shift 157 ;; 158 *) 159 if test -n "$1" 160 then 161 echo Unknown argument $1 162 usage 163 fi 164 ;; 165 esac 166 shift 167done 168if test -z "$arg_link" 169then 170 arg_link="$default_link" 171fi 172 173echo ---- Re-run results directory: $rundir 174 175# Copy old run directory tree over and adjust. 176mkdir -p "`dirname "$rundir"`" 177if ! $arg_link "$oldrun" "$rundir" 178then 179 echo "Cannot copy from $oldrun to $rundir." 180 usage 181fi 182rm -f "$rundir"/*/{console.log,console.log.diags,qemu_pid,qemu-pid,qemu-retval,Warnings,kvm-test-1-run.sh.out,kvm-test-1-run-qemu.sh.out,vmlinux} "$rundir"/log 183touch "$rundir/log" 184echo $scriptname $args | tee -a "$rundir/log" 185echo $oldrun > "$rundir/re-run" 186if ! test -d "$rundir/../../bin" 187then 188 $arg_link "$oldrun/../../bin" "$rundir/../.." 189fi 190for i in $rundir/*/qemu-cmd 191do 192 cp "$i" $T 193 qemu_cmd_dir="`dirname "$i"`" 194 kernel_dir="`echo $qemu_cmd_dir | sed -e 's/\.[0-9]\+$//'`" 195 jitter_dir="`dirname "$kernel_dir"`" 196 kvm-transform.sh "$kernel_dir/bzImage" "$qemu_cmd_dir/console.log" "$jitter_dir" $dur "$bootargs" < $T/qemu-cmd > $i 197 if test -n "$arg_remote" 198 then 199 echo "# TORTURE_KCONFIG_GDB_ARG=''" >> $i 200 fi 201done 202 203# Extract settings from the last qemu-cmd file transformed above. 204grep '^#' $i | sed -e 's/^# //' > $T/qemu-cmd-settings 205. $T/qemu-cmd-settings 206 207grep -v '^#' $T/scenarios.oldrun | awk ' 208{ 209 curbatch = ""; 210 for (i = 2; i <= NF; i++) 211 curbatch = curbatch " " $i; 212 print "kvm-test-1-run-batch.sh" curbatch; 213}' > $T/runbatches.sh 214 215if test -n "$dryrun" 216then 217 echo ---- Dryrun complete, directory: $rundir | tee -a "$rundir/log" 218else 219 ( cd "$rundir"; sh $T/runbatches.sh ) | tee -a "$rundir/log" 220 kvm-end-run-stats.sh "$rundir" "$starttime" 221fi 222