.. | .. |
---|
1 | 1 | #!/bin/bash |
---|
| 2 | +# SPDX-License-Identifier: GPL-2.0+ |
---|
2 | 3 | # |
---|
3 | 4 | # Run a kvm-based test of the specified tree on the specified configs. |
---|
4 | 5 | # Fully automated run and error checking, no graphics console. |
---|
.. | .. |
---|
20 | 21 | # |
---|
21 | 22 | # More sophisticated argument parsing is clearly needed. |
---|
22 | 23 | # |
---|
23 | | -# This program is free software; you can redistribute it and/or modify |
---|
24 | | -# it under the terms of the GNU General Public License as published by |
---|
25 | | -# the Free Software Foundation; either version 2 of the License, or |
---|
26 | | -# (at your option) any later version. |
---|
27 | | -# |
---|
28 | | -# This program is distributed in the hope that it will be useful, |
---|
29 | | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
30 | | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
31 | | -# GNU General Public License for more details. |
---|
32 | | -# |
---|
33 | | -# You should have received a copy of the GNU General Public License |
---|
34 | | -# along with this program; if not, you can access it online at |
---|
35 | | -# http://www.gnu.org/licenses/gpl-2.0.html. |
---|
36 | | -# |
---|
37 | 24 | # Copyright (C) IBM Corporation, 2011 |
---|
38 | 25 | # |
---|
39 | | -# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com> |
---|
| 26 | +# Authors: Paul E. McKenney <paulmck@linux.ibm.com> |
---|
40 | 27 | |
---|
41 | 28 | T=${TMPDIR-/tmp}/kvm-test-1-run.sh.$$ |
---|
42 | 29 | trap 'rm -rf $T' 0 |
---|
.. | .. |
---|
49 | 36 | config_dir=`echo $config_template | sed -e 's,/[^/]*$,,'` |
---|
50 | 37 | title=`echo $config_template | sed -e 's/^.*\///'` |
---|
51 | 38 | builddir=${2} |
---|
52 | | -if test -z "$builddir" -o ! -d "$builddir" -o ! -w "$builddir" |
---|
53 | | -then |
---|
54 | | - echo "kvm-test-1-run.sh :$builddir: Not a writable directory, cannot build into it" |
---|
55 | | - exit 1 |
---|
56 | | -fi |
---|
57 | 39 | resdir=${3} |
---|
58 | 40 | if test -z "$resdir" -o ! -d "$resdir" -o ! -w "$resdir" |
---|
59 | 41 | then |
---|
.. | .. |
---|
62 | 44 | fi |
---|
63 | 45 | echo ' ---' `date`: Starting build |
---|
64 | 46 | echo ' ---' Kconfig fragment at: $config_template >> $resdir/log |
---|
65 | | -touch $resdir/ConfigFragment.input $resdir/ConfigFragment |
---|
66 | | -if test -r "$config_dir/CFcommon" |
---|
67 | | -then |
---|
68 | | - echo " --- $config_dir/CFcommon" >> $resdir/ConfigFragment.input |
---|
69 | | - cat < $config_dir/CFcommon >> $resdir/ConfigFragment.input |
---|
70 | | - config_override.sh $config_dir/CFcommon $config_template > $T/Kc1 |
---|
71 | | - grep '#CHECK#' $config_dir/CFcommon >> $resdir/ConfigFragment |
---|
72 | | -else |
---|
73 | | - cp $config_template $T/Kc1 |
---|
74 | | -fi |
---|
75 | | -echo " --- $config_template" >> $resdir/ConfigFragment.input |
---|
76 | | -cat $config_template >> $resdir/ConfigFragment.input |
---|
77 | | -grep '#CHECK#' $config_template >> $resdir/ConfigFragment |
---|
78 | | -if test -n "$TORTURE_KCONFIG_ARG" |
---|
79 | | -then |
---|
80 | | - echo $TORTURE_KCONFIG_ARG | tr -s " " "\012" > $T/cmdline |
---|
81 | | - echo " --- --kconfig argument" >> $resdir/ConfigFragment.input |
---|
82 | | - cat $T/cmdline >> $resdir/ConfigFragment.input |
---|
83 | | - config_override.sh $T/Kc1 $T/cmdline > $T/Kc2 |
---|
84 | | - # Note that "#CHECK#" is not permitted on commandline. |
---|
85 | | -else |
---|
86 | | - cp $T/Kc1 $T/Kc2 |
---|
87 | | -fi |
---|
88 | | -cat $T/Kc2 >> $resdir/ConfigFragment |
---|
| 47 | +touch $resdir/ConfigFragment.input |
---|
| 48 | + |
---|
| 49 | +# Combine additional Kconfig options into an existing set such that |
---|
| 50 | +# newer options win. The first argument is the Kconfig source ID, the |
---|
| 51 | +# second the to-be-updated file within $T, and the third and final the |
---|
| 52 | +# list of additional Kconfig options. Note that a $2.tmp file is |
---|
| 53 | +# created when doing the update. |
---|
| 54 | +config_override_param () { |
---|
| 55 | + if test -n "$3" |
---|
| 56 | + then |
---|
| 57 | + echo $3 | sed -e 's/^ *//' -e 's/ *$//' | tr -s " " "\012" > $T/Kconfig_args |
---|
| 58 | + echo " --- $1" >> $resdir/ConfigFragment.input |
---|
| 59 | + cat $T/Kconfig_args >> $resdir/ConfigFragment.input |
---|
| 60 | + config_override.sh $T/$2 $T/Kconfig_args > $T/$2.tmp |
---|
| 61 | + mv $T/$2.tmp $T/$2 |
---|
| 62 | + # Note that "#CHECK#" is not permitted on commandline. |
---|
| 63 | + fi |
---|
| 64 | +} |
---|
| 65 | + |
---|
| 66 | +echo > $T/KcList |
---|
| 67 | +config_override_param "$config_dir/CFcommon" KcList "`cat $config_dir/CFcommon 2> /dev/null`" |
---|
| 68 | +config_override_param "$config_template" KcList "`cat $config_template 2> /dev/null`" |
---|
| 69 | +config_override_param "--gdb options" KcList "$TORTURE_KCONFIG_GDB_ARG" |
---|
| 70 | +config_override_param "--kasan options" KcList "$TORTURE_KCONFIG_KASAN_ARG" |
---|
| 71 | +config_override_param "--kcsan options" KcList "$TORTURE_KCONFIG_KCSAN_ARG" |
---|
| 72 | +config_override_param "--kconfig argument" KcList "$TORTURE_KCONFIG_ARG" |
---|
| 73 | +cp $T/KcList $resdir/ConfigFragment |
---|
89 | 74 | |
---|
90 | 75 | base_resdir=`echo $resdir | sed -e 's/\.[0-9]\+$//'` |
---|
91 | 76 | if test "$base_resdir" != "$resdir" -a -f $base_resdir/bzImage -a -f $base_resdir/vmlinux |
---|
.. | .. |
---|
98 | 83 | ln -s $base_resdir/.config $resdir # for kvm-recheck.sh |
---|
99 | 84 | # Arch-independent indicator |
---|
100 | 85 | touch $resdir/builtkernel |
---|
101 | | -elif kvm-build.sh $T/Kc2 $builddir $resdir |
---|
| 86 | +elif kvm-build.sh $T/KcList $resdir |
---|
102 | 87 | then |
---|
103 | 88 | # Had to build a kernel for this test. |
---|
104 | | - QEMU="`identify_qemu $builddir/vmlinux`" |
---|
| 89 | + QEMU="`identify_qemu vmlinux`" |
---|
105 | 90 | BOOT_IMAGE="`identify_boot_image $QEMU`" |
---|
106 | | - cp $builddir/vmlinux $resdir |
---|
107 | | - cp $builddir/.config $resdir |
---|
108 | | - cp $builddir/Module.symvers $resdir > /dev/null || : |
---|
109 | | - cp $builddir/System.map $resdir > /dev/null || : |
---|
| 91 | + cp vmlinux $resdir |
---|
| 92 | + cp .config $resdir |
---|
| 93 | + cp Module.symvers $resdir > /dev/null || : |
---|
| 94 | + cp System.map $resdir > /dev/null || : |
---|
110 | 95 | if test -n "$BOOT_IMAGE" |
---|
111 | 96 | then |
---|
112 | | - cp $builddir/$BOOT_IMAGE $resdir |
---|
| 97 | + cp $BOOT_IMAGE $resdir |
---|
113 | 98 | KERNEL=$resdir/${BOOT_IMAGE##*/} |
---|
114 | 99 | # Arch-independent indicator |
---|
115 | 100 | touch $resdir/builtkernel |
---|
.. | .. |
---|
120 | 105 | parse-build.sh $resdir/Make.out $title |
---|
121 | 106 | else |
---|
122 | 107 | # Build failed. |
---|
123 | | - cp $builddir/Make*.out $resdir |
---|
124 | | - cp $builddir/.config $resdir || : |
---|
| 108 | + cp .config $resdir || : |
---|
125 | 109 | echo Build failed, not running KVM, see $resdir. |
---|
126 | 110 | if test -f $builddir.wait |
---|
127 | 111 | then |
---|
.. | .. |
---|
141 | 125 | qemu_args=$5 |
---|
142 | 126 | boot_args=$6 |
---|
143 | 127 | |
---|
144 | | -cd $KVM |
---|
145 | | -kstarttime=`awk 'BEGIN { print systime() }' < /dev/null` |
---|
| 128 | +kstarttime=`gawk 'BEGIN { print systime() }' < /dev/null` |
---|
146 | 129 | if test -z "$TORTURE_BUILDONLY" |
---|
147 | 130 | then |
---|
148 | 131 | echo ' ---' `date`: Starting kernel |
---|
.. | .. |
---|
152 | 135 | qemu_args="-enable-kvm -nographic $qemu_args" |
---|
153 | 136 | cpu_count=`configNR_CPUS.sh $resdir/ConfigFragment` |
---|
154 | 137 | cpu_count=`configfrag_boot_cpus "$boot_args" "$config_template" "$cpu_count"` |
---|
155 | | -vcpus=`identify_qemu_vcpus` |
---|
156 | | -if test $cpu_count -gt $vcpus |
---|
| 138 | +if test "$cpu_count" -gt "$TORTURE_ALLOTED_CPUS" |
---|
157 | 139 | then |
---|
158 | | - echo CPU count limited from $cpu_count to $vcpus | tee -a $resdir/Warnings |
---|
159 | | - cpu_count=$vcpus |
---|
| 140 | + echo CPU count limited from $cpu_count to $TORTURE_ALLOTED_CPUS | tee -a $resdir/Warnings |
---|
| 141 | + cpu_count=$TORTURE_ALLOTED_CPUS |
---|
160 | 142 | fi |
---|
161 | 143 | qemu_args="`specify_qemu_cpus "$QEMU" "$qemu_args" "$cpu_count"`" |
---|
| 144 | +qemu_args="`specify_qemu_net "$qemu_args"`" |
---|
162 | 145 | |
---|
163 | 146 | # Generate architecture-specific and interaction-specific qemu arguments |
---|
164 | 147 | qemu_args="$qemu_args `identify_qemu_args "$QEMU" "$resdir/console.log"`" |
---|
.. | .. |
---|
170 | 153 | boot_args="`configfrag_boot_params "$boot_args" "$config_template"`" |
---|
171 | 154 | # Generate kernel-version-specific boot parameters |
---|
172 | 155 | boot_args="`per_version_boot_params "$boot_args" $resdir/.config $seconds`" |
---|
| 156 | +if test -n "$TORTURE_BOOT_GDB_ARG" |
---|
| 157 | +then |
---|
| 158 | + boot_args="$boot_args $TORTURE_BOOT_GDB_ARG" |
---|
| 159 | +fi |
---|
| 160 | +echo $QEMU $qemu_args -m $TORTURE_QEMU_MEM -kernel $KERNEL -append \"$qemu_append $boot_args\" $TORTURE_QEMU_GDB_ARG > $resdir/qemu-cmd |
---|
173 | 161 | |
---|
174 | 162 | if test -n "$TORTURE_BUILDONLY" |
---|
175 | 163 | then |
---|
.. | .. |
---|
177 | 165 | touch $resdir/buildonly |
---|
178 | 166 | exit 0 |
---|
179 | 167 | fi |
---|
| 168 | + |
---|
| 169 | +# Decorate qemu-cmd with redirection, backgrounding, and PID capture |
---|
| 170 | +sed -e 's/$/ 2>\&1 \&/' < $resdir/qemu-cmd > $T/qemu-cmd |
---|
| 171 | +echo 'echo $! > $resdir/qemu_pid' >> $T/qemu-cmd |
---|
| 172 | + |
---|
| 173 | +# In case qemu refuses to run... |
---|
180 | 174 | echo "NOTE: $QEMU either did not run or was interactive" > $resdir/console.log |
---|
181 | | -echo $QEMU $qemu_args -m $TORTURE_QEMU_MEM -kernel $KERNEL -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd |
---|
182 | | -( $QEMU $qemu_args -m $TORTURE_QEMU_MEM -kernel $KERNEL -append "$qemu_append $boot_args"& echo $! > $resdir/qemu_pid; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) & |
---|
| 175 | + |
---|
| 176 | +# Attempt to run qemu |
---|
| 177 | +( . $T/qemu-cmd; wait `cat $resdir/qemu_pid`; echo $? > $resdir/qemu-retval ) & |
---|
183 | 178 | commandcompleted=0 |
---|
184 | | -sleep 10 # Give qemu's pid a chance to reach the file |
---|
185 | | -if test -s "$resdir/qemu_pid" |
---|
| 179 | +if test -z "$TORTURE_KCONFIG_GDB_ARG" |
---|
186 | 180 | then |
---|
187 | | - qemu_pid=`cat "$resdir/qemu_pid"` |
---|
188 | | - echo Monitoring qemu job at pid $qemu_pid |
---|
189 | | -else |
---|
190 | | - qemu_pid="" |
---|
191 | | - echo Monitoring qemu job at yet-as-unknown pid |
---|
| 181 | + sleep 10 # Give qemu's pid a chance to reach the file |
---|
| 182 | + if test -s "$resdir/qemu_pid" |
---|
| 183 | + then |
---|
| 184 | + qemu_pid=`cat "$resdir/qemu_pid"` |
---|
| 185 | + echo Monitoring qemu job at pid $qemu_pid |
---|
| 186 | + else |
---|
| 187 | + qemu_pid="" |
---|
| 188 | + echo Monitoring qemu job at yet-as-unknown pid |
---|
| 189 | + fi |
---|
| 190 | +fi |
---|
| 191 | +if test -n "$TORTURE_KCONFIG_GDB_ARG" |
---|
| 192 | +then |
---|
| 193 | + echo Waiting for you to attach a debug session, for example: > /dev/tty |
---|
| 194 | + echo " gdb $base_resdir/vmlinux" > /dev/tty |
---|
| 195 | + echo 'After symbols load and the "(gdb)" prompt appears:' > /dev/tty |
---|
| 196 | + echo " target remote :1234" > /dev/tty |
---|
| 197 | + echo " continue" > /dev/tty |
---|
| 198 | + kstarttime=`gawk 'BEGIN { print systime() }' < /dev/null` |
---|
192 | 199 | fi |
---|
193 | 200 | while : |
---|
194 | 201 | do |
---|
.. | .. |
---|
196 | 203 | then |
---|
197 | 204 | qemu_pid=`cat "$resdir/qemu_pid"` |
---|
198 | 205 | fi |
---|
199 | | - kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null` |
---|
| 206 | + kruntime=`gawk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null` |
---|
200 | 207 | if test -z "$qemu_pid" || kill -0 "$qemu_pid" > /dev/null 2>&1 |
---|
201 | 208 | then |
---|
202 | | - if test $kruntime -ge $seconds |
---|
| 209 | + if test $kruntime -ge $seconds -o -f "$TORTURE_STOPFILE" |
---|
203 | 210 | then |
---|
204 | 211 | break; |
---|
205 | 212 | fi |
---|
.. | .. |
---|
228 | 235 | fi |
---|
229 | 236 | if test $commandcompleted -eq 0 -a -n "$qemu_pid" |
---|
230 | 237 | then |
---|
231 | | - echo Grace period for qemu job at pid $qemu_pid |
---|
| 238 | + if ! test -f "$TORTURE_STOPFILE" |
---|
| 239 | + then |
---|
| 240 | + echo Grace period for qemu job at pid $qemu_pid |
---|
| 241 | + fi |
---|
232 | 242 | oldline="`tail $resdir/console.log`" |
---|
233 | 243 | while : |
---|
234 | 244 | do |
---|
235 | | - kruntime=`awk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null` |
---|
| 245 | + if test -f "$TORTURE_STOPFILE" |
---|
| 246 | + then |
---|
| 247 | + echo "PID $qemu_pid killed due to run STOP request" >> $resdir/Warnings 2>&1 |
---|
| 248 | + kill -KILL $qemu_pid |
---|
| 249 | + break |
---|
| 250 | + fi |
---|
| 251 | + kruntime=`gawk 'BEGIN { print systime() - '"$kstarttime"' }' < /dev/null` |
---|
236 | 252 | if kill -0 $qemu_pid > /dev/null 2>&1 |
---|
237 | 253 | then |
---|
238 | 254 | : |
---|
.. | .. |
---|
246 | 262 | must_continue=yes |
---|
247 | 263 | fi |
---|
248 | 264 | last_ts="`tail $resdir/console.log | grep '^\[ *[0-9]\+\.[0-9]\+]' | tail -1 | sed -e 's/^\[ *//' -e 's/\..*$//'`" |
---|
249 | | - if test -z "last_ts" |
---|
| 265 | + if test -z "$last_ts" |
---|
250 | 266 | then |
---|
251 | 267 | last_ts=0 |
---|
252 | 268 | fi |
---|