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=${TMPDIR-/tmp}/kvm-again.sh.$$
16trap 'rm -rf $T' 0
17mkdir $T
18
19if ! test -d tools/testing/selftests/rcutorture/bin
20then
21	echo $scriptname must be run from top-level directory of kernel source tree.
22	exit 1
23fi
24
25oldrun=$1
26shift
27if ! test -d "$oldrun"
28then
29	echo "Usage: $scriptname /path/to/old/run [ options ]"
30	exit 1
31fi
32if ! cp "$oldrun/batches" $T/batches.oldrun
33then
34	# Later on, can reconstitute this from console.log files.
35	echo Prior run batches file does not exist: $oldrun/batches
36	exit 1
37fi
38
39if test -f "$oldrun/torture_suite"
40then
41	torture_suite="`cat $oldrun/torture_suite`"
42elif test -f "$oldrun/TORTURE_SUITE"
43then
44	torture_suite="`cat $oldrun/TORTURE_SUITE`"
45else
46	echo "Prior run torture_suite file does not exist: $oldrun/{torture_suite,TORTURE_SUITE}"
47	exit 1
48fi
49
50KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM
51PATH=${KVM}/bin:$PATH; export PATH
52. functions.sh
53
54dryrun=
55dur=
56default_link="cp -R"
57rundir="`pwd`/tools/testing/selftests/rcutorture/res/`date +%Y.%m.%d-%H.%M.%S-again`"
58
59startdate="`date`"
60starttime="`get_starttime`"
61
62usage () {
63	echo "Usage: $scriptname $oldrun [ arguments ]:"
64	echo "       --dryrun"
65	echo "       --duration minutes | <seconds>s | <hours>h | <days>d"
66	echo "       --link hard|soft|copy"
67	echo "       --remote"
68	echo "       --rundir /new/res/path"
69	exit 1
70}
71
72while test $# -gt 0
73do
74	case "$1" in
75	--dryrun)
76		dryrun=1
77		;;
78	--duration)
79		checkarg --duration "(minutes)" $# "$2" '^[0-9][0-9]*\(s\|m\|h\|d\|\)$' '^error'
80		mult=60
81		if echo "$2" | grep -q 's$'
82		then
83			mult=1
84		elif echo "$2" | grep -q 'h$'
85		then
86			mult=3600
87		elif echo "$2" | grep -q 'd$'
88		then
89			mult=86400
90		fi
91		ts=`echo $2 | sed -e 's/[smhd]$//'`
92		dur=$(($ts*mult))
93		shift
94		;;
95	--link)
96		checkarg --link "hard|soft|copy" "$#" "$2" 'hard\|soft\|copy' '^--'
97		case "$2" in
98		copy)
99			arg_link="cp -R"
100			;;
101		hard)
102			arg_link="cp -Rl"
103			;;
104		soft)
105			arg_link="cp -Rs"
106			;;
107		esac
108		shift
109		;;
110	--remote)
111		arg_remote=1
112		default_link="cp -as"
113		;;
114	--rundir)
115		checkarg --rundir "(absolute pathname)" "$#" "$2" '^/' '^error'
116		rundir=$2
117		if test -e "$rundir"
118		then
119			echo "--rundir $2: Already exists."
120			usage
121		fi
122		shift
123		;;
124	*)
125		echo Unknown argument $1
126		usage
127		;;
128	esac
129	shift
130done
131if test -z "$arg_link"
132then
133	arg_link="$default_link"
134fi
135
136echo ---- Re-run results directory: $rundir
137
138# Copy old run directory tree over and adjust.
139mkdir -p "`dirname "$rundir"`"
140if ! $arg_link "$oldrun" "$rundir"
141then
142	echo "Cannot copy from $oldrun to $rundir."
143	usage
144fi
145rm -f "$rundir"/*/{console.log,console.log.diags,qemu_pid,qemu-retval,Warnings,kvm-test-1-run.sh.out,kvm-test-1-run-qemu.sh.out,vmlinux} "$rundir"/log
146echo $oldrun > "$rundir/re-run"
147if ! test -d "$rundir/../../bin"
148then
149	$arg_link "$oldrun/../../bin" "$rundir/../.."
150fi
151for i in $rundir/*/qemu-cmd
152do
153	cp "$i" $T
154	qemu_cmd_dir="`dirname "$i"`"
155	kernel_dir="`echo $qemu_cmd_dir | sed -e 's/\.[0-9]\+$//'`"
156	jitter_dir="`dirname "$kernel_dir"`"
157	kvm-transform.sh "$kernel_dir/bzImage" "$qemu_cmd_dir/console.log" "$jitter_dir" $dur < $T/qemu-cmd > $i
158	if test -n "$arg_remote"
159	then
160		echo "# TORTURE_KCONFIG_GDB_ARG=''" >> $i
161	fi
162done
163
164# Extract settings from the last qemu-cmd file transformed above.
165grep '^#' $i | sed -e 's/^# //' > $T/qemu-cmd-settings
166. $T/qemu-cmd-settings
167
168grep -v '^#' $T/batches.oldrun | awk '
169BEGIN {
170	oldbatch = 1;
171}
172
173{
174	if (oldbatch != $1) {
175		print "kvm-test-1-run-batch.sh" curbatch;
176		curbatch = "";
177		oldbatch = $1;
178	}
179	curbatch = curbatch " " $2;
180}
181
182END {
183	print "kvm-test-1-run-batch.sh" curbatch
184}' > $T/runbatches.sh
185
186if test -n "$dryrun"
187then
188	echo ---- Dryrun complete, directory: $rundir | tee -a "$rundir/log"
189else
190	( cd "$rundir"; sh $T/runbatches.sh )
191	kcsan-collapse.sh "$rundir" | tee -a "$rundir/log"
192	echo | tee -a "$rundir/log"
193	echo ---- Results directory: $rundir | tee -a "$rundir/log"
194	kvm-recheck.sh "$rundir" > $T/kvm-recheck.sh.out 2>&1
195	ret=$?
196	cat $T/kvm-recheck.sh.out | tee -a "$rundir/log"
197	echo " --- Done at `date` (`get_starttime_duration $starttime`) exitcode $ret" | tee -a "$rundir/log"
198	exit $ret
199fi
200