PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/testing/selftests/rcutorture/bin/kvm-remote.sh

https://gitlab.com/dieselnutjob/linux-next
Shell | 269 lines | 211 code | 18 blank | 40 comment | 24 complexity | 64f51bec973708090f679a6247363dc6 MD5 | raw file
  1. #!/bin/bash
  2. # SPDX-License-Identifier: GPL-2.0+
  3. #
  4. # Run a series of tests on remote systems under KVM.
  5. #
  6. # Usage: kvm-remote.sh "systems" [ <kvm.sh args> ]
  7. # kvm-remote.sh "systems" /path/to/old/run [ <kvm-again.sh args> ]
  8. #
  9. # Copyright (C) 2021 Facebook, Inc.
  10. #
  11. # Authors: Paul E. McKenney <paulmck@kernel.org>
  12. scriptname=$0
  13. args="$*"
  14. if ! test -d tools/testing/selftests/rcutorture/bin
  15. then
  16. echo $scriptname must be run from top-level directory of kernel source tree.
  17. exit 1
  18. fi
  19. KVM="`pwd`/tools/testing/selftests/rcutorture"; export KVM
  20. PATH=${KVM}/bin:$PATH; export PATH
  21. . functions.sh
  22. starttime="`get_starttime`"
  23. systems="$1"
  24. if test -z "$systems"
  25. then
  26. echo $scriptname: Empty list of systems will go nowhere good, giving up.
  27. exit 1
  28. fi
  29. shift
  30. # Pathnames:
  31. # T: /tmp/kvm-remote.sh.$$
  32. # resdir: /tmp/kvm-remote.sh.$$/res
  33. # rundir: /tmp/kvm-remote.sh.$$/res/$ds ("-remote" suffix)
  34. # oldrun: `pwd`/tools/testing/.../res/$otherds
  35. #
  36. # Pathname segments:
  37. # TD: kvm-remote.sh.$$
  38. # ds: yyyy.mm.dd-hh.mm.ss-remote
  39. TD=kvm-remote.sh.$$
  40. T=${TMPDIR-/tmp}/$TD
  41. trap 'rm -rf $T' 0
  42. mkdir $T
  43. resdir="$T/res"
  44. ds=`date +%Y.%m.%d-%H.%M.%S`-remote
  45. rundir=$resdir/$ds
  46. echo Results directory: $rundir
  47. echo $scriptname $args
  48. if echo $1 | grep -q '^--'
  49. then
  50. # Fresh build. Create a datestamp unless the caller supplied one.
  51. datestamp="`echo "$@" | awk -v ds="$ds" '{
  52. for (i = 1; i < NF; i++) {
  53. if ($i == "--datestamp") {
  54. ds = "";
  55. break;
  56. }
  57. }
  58. if (ds != "")
  59. print "--datestamp " ds;
  60. }'`"
  61. kvm.sh --remote "$@" $datestamp --buildonly > $T/kvm.sh.out 2>&1
  62. ret=$?
  63. if test "$ret" -ne 0
  64. then
  65. echo $scriptname: kvm.sh failed exit code $?
  66. cat $T/kvm.sh.out
  67. exit 2
  68. fi
  69. oldrun="`grep -m 1 "^Results directory: " $T/kvm.sh.out | awk '{ print $3 }'`"
  70. touch "$oldrun/remote-log"
  71. echo $scriptname $args >> "$oldrun/remote-log"
  72. echo | tee -a "$oldrun/remote-log"
  73. echo " ----" kvm.sh output: "(`date`)" | tee -a "$oldrun/remote-log"
  74. cat $T/kvm.sh.out | tee -a "$oldrun/remote-log"
  75. # We are going to run this, so remove the buildonly files.
  76. rm -f "$oldrun"/*/buildonly
  77. kvm-again.sh $oldrun --dryrun --remote --rundir "$rundir" > $T/kvm-again.sh.out 2>&1
  78. ret=$?
  79. if test "$ret" -ne 0
  80. then
  81. echo $scriptname: kvm-again.sh failed exit code $? | tee -a "$oldrun/remote-log"
  82. cat $T/kvm-again.sh.out | tee -a "$oldrun/remote-log"
  83. exit 2
  84. fi
  85. else
  86. # Re-use old run.
  87. oldrun="$1"
  88. if ! echo $oldrun | grep -q '^/'
  89. then
  90. oldrun="`pwd`/$oldrun"
  91. fi
  92. shift
  93. touch "$oldrun/remote-log"
  94. echo $scriptname $args >> "$oldrun/remote-log"
  95. kvm-again.sh "$oldrun" "$@" --dryrun --remote --rundir "$rundir" > $T/kvm-again.sh.out 2>&1
  96. ret=$?
  97. if test "$ret" -ne 0
  98. then
  99. echo $scriptname: kvm-again.sh failed exit code $? | tee -a "$oldrun/remote-log"
  100. cat $T/kvm-again.sh.out | tee -a "$oldrun/remote-log"
  101. exit 2
  102. fi
  103. cp -a "$rundir" "$KVM/res/"
  104. oldrun="$KVM/res/$ds"
  105. fi
  106. echo | tee -a "$oldrun/remote-log"
  107. echo " ----" kvm-again.sh output: "(`date`)" | tee -a "$oldrun/remote-log"
  108. cat $T/kvm-again.sh.out
  109. echo | tee -a "$oldrun/remote-log"
  110. echo Remote run directory: $rundir | tee -a "$oldrun/remote-log"
  111. echo Local build-side run directory: $oldrun | tee -a "$oldrun/remote-log"
  112. # Create the kvm-remote-N.sh scripts in the bin directory.
  113. awk < "$rundir"/scenarios -v dest="$T/bin" -v rundir="$rundir" '
  114. {
  115. n = $1;
  116. sub(/\./, "", n);
  117. fn = dest "/kvm-remote-" n ".sh"
  118. print "kvm-remote-noreap.sh " rundir " &" > fn;
  119. scenarios = "";
  120. for (i = 2; i <= NF; i++)
  121. scenarios = scenarios " " $i;
  122. print "kvm-test-1-run-batch.sh" scenarios >> fn;
  123. print "sync" >> fn;
  124. print "rm " rundir "/remote.run" >> fn;
  125. }'
  126. chmod +x $T/bin/kvm-remote-*.sh
  127. ( cd "`dirname $T`"; tar -chzf $T/binres.tgz "$TD/bin" "$TD/res" )
  128. # Check first to avoid the need for cleanup for system-name typos
  129. for i in $systems
  130. do
  131. ncpus="`ssh $i getconf _NPROCESSORS_ONLN 2> /dev/null`"
  132. echo $i: $ncpus CPUs " " `date` | tee -a "$oldrun/remote-log"
  133. ret=$?
  134. if test "$ret" -ne 0
  135. then
  136. echo System $i unreachable, giving up. | tee -a "$oldrun/remote-log"
  137. exit 4
  138. fi
  139. done
  140. # Download and expand the tarball on all systems.
  141. echo Build-products tarball: `du -h $T/binres.tgz` | tee -a "$oldrun/remote-log"
  142. for i in $systems
  143. do
  144. echo Downloading tarball to $i `date` | tee -a "$oldrun/remote-log"
  145. cat $T/binres.tgz | ssh $i "cd /tmp; tar -xzf -"
  146. ret=$?
  147. if test "$ret" -ne 0
  148. then
  149. echo Unable to download $T/binres.tgz to system $i, waiting and then retrying. | tee -a "$oldrun/remote-log"
  150. sleep 60
  151. cat $T/binres.tgz | ssh $i "cd /tmp; tar -xzf -"
  152. ret=$?
  153. if test "$ret" -ne 0
  154. then
  155. echo Unable to download $T/binres.tgz to system $i, giving up. | tee -a "$oldrun/remote-log"
  156. exit 10
  157. fi
  158. fi
  159. done
  160. # Function to check for presence of a file on the specified system.
  161. # Complain if the system cannot be reached, and retry after a wait.
  162. # Currently just waits forever if a machine disappears.
  163. #
  164. # Usage: checkremotefile system pathname
  165. checkremotefile () {
  166. local ret
  167. local sleeptime=60
  168. while :
  169. do
  170. ssh $1 "test -f \"$2\""
  171. ret=$?
  172. if test "$ret" -eq 255
  173. then
  174. echo " ---" ssh failure to $1 checking for file $2, retry after $sleeptime seconds. `date` | tee -a "$oldrun/remote-log"
  175. elif test "$ret" -eq 0
  176. then
  177. return 0
  178. elif test "$ret" -eq 1
  179. then
  180. echo " ---" File \"$2\" not found: ssh $1 test -f \"$2\" | tee -a "$oldrun/remote-log"
  181. return 1
  182. else
  183. echo " ---" Exit code $ret: ssh $1 test -f \"$2\", retry after $sleeptime seconds. `date` | tee -a "$oldrun/remote-log"
  184. return $ret
  185. fi
  186. sleep $sleeptime
  187. done
  188. }
  189. # Function to start batches on idle remote $systems
  190. #
  191. # Usage: startbatches curbatch nbatches
  192. #
  193. # Batches are numbered starting at 1. Returns the next batch to start.
  194. # Be careful to redirect all debug output to FD 2 (stderr).
  195. startbatches () {
  196. local curbatch="$1"
  197. local nbatches="$2"
  198. local ret
  199. # Each pass through the following loop examines one system.
  200. for i in $systems
  201. do
  202. if test "$curbatch" -gt "$nbatches"
  203. then
  204. echo $((nbatches + 1))
  205. return 0
  206. fi
  207. if checkremotefile "$i" "$resdir/$ds/remote.run" 1>&2
  208. then
  209. continue # System still running last test, skip.
  210. fi
  211. ssh "$i" "cd \"$resdir/$ds\"; touch remote.run; PATH=\"$T/bin:$PATH\" nohup kvm-remote-$curbatch.sh > kvm-remote-$curbatch.sh.out 2>&1 &" 1>&2
  212. ret=$?
  213. if test "$ret" -ne 0
  214. then
  215. echo ssh $i failed: exitcode $ret 1>&2
  216. exit 11
  217. fi
  218. echo " ----" System $i Batch `head -n $curbatch < "$rundir"/scenarios | tail -1` `date` 1>&2
  219. curbatch=$((curbatch + 1))
  220. done
  221. echo $curbatch
  222. }
  223. # Launch all the scenarios.
  224. nbatches="`wc -l "$rundir"/scenarios | awk '{ print $1 }'`"
  225. curbatch=1
  226. while test "$curbatch" -le "$nbatches"
  227. do
  228. startbatches $curbatch $nbatches > $T/curbatch 2> $T/startbatches.stderr
  229. curbatch="`cat $T/curbatch`"
  230. if test -s "$T/startbatches.stderr"
  231. then
  232. cat "$T/startbatches.stderr" | tee -a "$oldrun/remote-log"
  233. fi
  234. if test "$curbatch" -le "$nbatches"
  235. then
  236. sleep 30
  237. fi
  238. done
  239. echo All batches started. `date` | tee -a "$oldrun/remote-log"
  240. # Wait for all remaining scenarios to complete and collect results.
  241. for i in $systems
  242. do
  243. while checkremotefile "$i" "$resdir/$ds/remote.run"
  244. do
  245. sleep 30
  246. done
  247. echo " ---" Collecting results from $i `date` | tee -a "$oldrun/remote-log"
  248. ( cd "$oldrun"; ssh $i "cd $rundir; tar -czf - kvm-remote-*.sh.out */console.log */kvm-test-1-run*.sh.out */qemu[_-]pid */qemu-retval */qemu-affinity; rm -rf $T > /dev/null 2>&1" | tar -xzf - )
  249. done
  250. ( kvm-end-run-stats.sh "$oldrun" "$starttime"; echo $? > $T/exitcode ) | tee -a "$oldrun/remote-log"
  251. exit "`cat $T/exitcode`"