Run a full check not only on the first specified kernel version but also on kernel...
[mirror/scst/.git] / scripts / run-regression-tests
1 #!/bin/bash
2
3 ############################################################################
4 #
5 # Script for running those SCST regression tests that can be run automatically.
6 #
7 # Copyright (C) 2008 Bart Van Assche <bart.vanassche@gmail.com>
8 #
9 # This program is free software; you can redistribute it and/or
10 # modify it under the terms of the GNU General Public License
11 # as published by the Free Software Foundation, version 2
12 # of the License.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 ############################################################################
20
21 ############################################################################
22 # This script performs the following actions:
23 # - Creates a temporary directory for storing the output of the regression
24 #   tests. No existing files are modified by this script.
25 # - Verifies whether the top-level *.patch files apply cleanly to the SCST
26 #   tree.
27 # - Duplicates the entire source tree to the temporary directory and
28 #   compiles the SCST source code.
29 # - Duplicates the entire source tree to the temporary directory, applies
30 #   the full-perf patches and again compiles the SCST source code.
31 # - Checks whether the specified kernel version is present
32 #   in the directory specified through option -c.
33 # - If the source code of the specified kernel version is not present,
34 #   download it.
35 # - Convert the SCST source code into a kernel patch.
36 # - Extract the kernel sources.
37 # - Run checkpatch on the SCST kernel patch.
38 # - Apply the SCST kernel patch to the kernel tree.
39 # - Run 'make allmodconfig'.
40 # - Run the sparse source code checker on the SCST directory.
41 # - Run 'make headers_check'.
42 # - Compile the kernel tree.
43 # - Run 'make checkstack'.
44 # - Run 'make namespacecheck'.
45 # - Run 'make htmldocs'.
46 #
47 # Note: the results of the individual steps are not verified by this script
48 # -- the output generated by the individual steps has to be verified by
49 # reviewing the output files written into the temporary directory.
50 ############################################################################
51
52
53 ########################
54 # Function definitions #
55 ########################
56
57 function usage {
58   echo "Usage: $0 [-c <dir>] [-d <dir>] [-f] [-h] [-j <jobs>] [-q] <kver1> <kver2> ..."
59   echo "        -c - cache directory for Linux kernel tarballs."
60   echo "        -d - directory for temporary regression test files."
61   echo "        -f - full check -- do not only compile SCST but the whole" \
62        "kernel tree."
63   echo "        -h - display this help information."
64   echo "        -j - number of jobs that 'make' should run simultaneously."
65   echo "        -k - remove temporary files before exiting."
66   echo "        -q - download kernel sources silently."
67   echo "        <kver1> <kver2> ... - kernel versions to test."
68 }
69
70 # First three components of the kernel version number.
71 function kernel_version {
72   echo "$1" | sed -n 's/^\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/p'
73 }
74
75 # Last component of the kernel version, or the empty string if $1 has only
76 # three components.
77 function patchlevel {
78   echo "$1" | sed -n 's/^\([0-9]*\.[0-9]*\.[0-9]*\)[.-]\(.*\)$/\2/p'
79 }
80
81 # Create a linux-$1 tree in the current directory, where $1 is a kernel
82 # version number with either three or four components.
83 function extract_kernel_tree {
84   local kver="$(kernel_version $1)"
85   local plevel="$(patchlevel $1)"
86   local tmpdir=kernel-tree-tmp-$$
87
88   rm -rf "linux-$1" "${tmpdir}"
89   mkdir "${tmpdir}" || return $?
90   (
91     cd "${tmpdir}" || return $?
92     tar xjf "${kernel_sources}/linux-${kver}.tar.bz2" || return $?
93     cd "linux-${kver}" || return $?
94     if [ "${plevel}" != "" ]; then
95       bzip2 -cd "${kernel_sources}/patch-$1.bz2" \
96         | patch -p1 -f -s || return $?
97     fi
98     cd ..
99     mv "linux-${kver}" "../linux-$1" || return $?
100     if [ "$1" = "2.6.29" -o "$1" = "2.6.29.1" -o "$1" = "2.6.29.2" -o "$1" = "2.6.29.3" ]
101     then
102       cd "../linux-$1" || return $?
103       patch -f -s -p1 <<'EOF'
104 Make sure that branch profiling does not trigger sparse warnings.
105 See also http://bugzilla.kernel.org/show_bug.cgi?id=12925
106 ---
107 See also http://lkml.org/lkml/2009/4/5/120
108 --- orig/linux-2.6.29/include/linux/compiler.h  2009-03-23 19:12:14.000000000 -0400
109 +++ linux-2.6.29/include/linux/compiler.h       2009-03-24 08:46:46.000000000 -0400
110 @@ -75,7 +75,8 @@ struct ftrace_branch_data {
111   * Note: DISABLE_BRANCH_PROFILING can be used by special lowlevel code
112   * to disable branch tracing on a per file basis.
113   */
114 -#if defined(CONFIG_TRACE_BRANCH_PROFILING) && !defined(DISABLE_BRANCH_PROFILING)
115 +#if defined(CONFIG_TRACE_BRANCH_PROFILING) \
116 +    && !defined(DISABLE_BRANCH_PROFILING) && !defined(__CHECKER__)
117  void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
118  
119  #define likely_notrace(x)      __builtin_expect(!!(x), 1)
120 EOF
121     fi
122     if [ "$1" = "2.6.31" -o "${1#2.6.31.}" != "$1" ]
123     then
124       cd "../linux-$1" || return $?
125       patch -f -s -p1 <<'EOF'
126 Checking a 2.6.31.1 kernel configured with allyesconfig/allmodconfig
127 with sparse (make C=2) triggers a sparse warning on code that uses the
128 kmemcheck_annotate_bitfield() macro. An example of such a warning:
129
130 include/net/inet_sock.h:208:17: warning: do-while statement is not a compound statement
131
132 Signed-off-by: Bart Van Assche <bart.vanassche@gmail.com>
133 Cc: Vegard Nossum <vegardno@ifi.uio.no>
134 Cc: Andrew Morton <akpm@linux-foundation.org>
135
136 ---
137 See also http://lkml.org/lkml/2009/9/26/51
138
139 --- linux-2.6.31.1/include/linux/kmemcheck-orig.h       2009-09-26 13:53:44.000000000 +0200
140 +++ linux-2.6.31.1/include/linux/kmemcheck.h    2009-09-26 13:53:56.000000000 +0200
141 @@ -137,13 +137,13 @@ static inline void kmemcheck_mark_initia
142         int name##_end[0];
143  
144  #define kmemcheck_annotate_bitfield(ptr, name)                         \
145 -       do if (ptr) {                                                   \
146 +       do { if (ptr) {                                                 \
147                 int _n = (long) &((ptr)->name##_end)                    \
148                         - (long) &((ptr)->name##_begin);                \
149                 BUILD_BUG_ON(_n < 0);                                   \
150                                                                         \
151                 kmemcheck_mark_initialized(&((ptr)->name##_begin), _n); \
152 -       } while (0)
153 +       } } while (0)
154  
155  #define kmemcheck_annotate_variable(var)                               \
156         do {                                                            \
157 EOF
158     fi
159   )
160   rmdir "${tmpdir}"
161 }
162
163 # Test whether the *.patch files in the SCST top-level directory apply cleanly
164 # to the SCST tree. Does not modify any files nor produce any output files.
165 function test_scst_tree_patches {
166   local rc=0
167   echo "Testing whether the SCST patches apply cleanly to the SCST tree ..."
168   for p in *.patch srpt/patches/scst_increase_max_tgt_cmds.patch
169   do
170     if ! patch -p0 -f --dry-run -s <$p &>/dev/null; then
171       echo "ERROR: patch $p does not apply cleanly."
172       rc=1
173     fi
174   done
175   if [ "${rc}" = 0 ]; then
176     echo "OK"
177   fi
178 }
179
180 # Copy the entire SCST source code tree from "$1" into the current directory.
181 # Only copy those files which are administered by Subversion.
182 function duplicate_scst_source_tree {
183   if [ -e "$1/AskingQuestions" ]; then
184     ( cd "$1" && svn status -v | cut -c41- \
185       | while read f; do [ ! -d "$f" ] && echo "$f"; done ) \
186     | tar -C "$1" --files-from=- -c -f - | tar -x -f -
187   else
188     return 1
189   fi
190 }
191
192 # Compile the unpatched SCST source code.
193 function compile_scst_unpatched {
194   local scst="$PWD"
195   local outputfile="${outputdir}/compilation-output-unpatched.txt"
196   local workingdirectory="${outputdir}/scst-unpatched"
197
198   echo "Testing whether the SCST tree compiles fine ..."
199   (
200     if mkdir -p "${workingdirectory}"  \
201        && cd "${workingdirectory}"     \
202        && duplicate_scst_source_tree "${scst}"  \
203        && (make -s clean \
204            && make -s scst iscsi-scst  \
205            && if "${scst_local}" = "true" ; then make -C scst_local clean; fi \
206            && if "${scst_local}" = "true" ; then make -C scst_local -s   ; fi \
207            && if "${mpt_scst}"   = "true" ; then make -C mpt clean; fi \
208            && if "${mpt_scst}"   = "true" ; then make -C mpt -s   ; fi \
209            && make -C srpt -s clean     \
210            && make -C srpt -s )         \
211            &> "${outputfile}"
212     then
213       echo "OK"
214     else
215       echo "FAILED"
216     fi
217   )
218 }
219
220 # Test out-of-tree compilation agains the kernel header files in
221 # /lib/modules/$(uname -r)/build.
222 function compile_scst_patched {
223   local scst="$PWD"
224   local outputfile="${outputdir}/compilation-output-patched.txt"
225   local workingdirectory="${outputdir}/scst-patched"
226
227   echo "Testing whether the full-perf SCST tree compiles fine ..."
228   (
229     if mkdir -p "${workingdirectory}"  \
230        && cd "${workingdirectory}"     \
231        && duplicate_scst_source_tree "${scst}"  \
232        && patch -p0 -f -s <"${scst}/iscsi-full_perf.patch"    \
233        && patch -p0 -f -s <"${scst}/qla2x00t-full_perf.patch" \
234        && patch -p0 -f -s <"${scst}/scst-full_perf.patch"     \
235        && (make -s clean               \
236            && make -s scst iscsi-scst  \
237            && if "${scst_local}" = "true" ; then make -C scst_local clean; fi \
238            && if "${scst_local}" = "true" ; then make -C scst_local -s   ; fi \
239            && if "${mpt_scst}"   = "true" ; then make -C mpt clean; fi \
240            && if "${mpt_scst}"   = "true" ; then make -C mpt -s   ; fi \
241            && make -C srpt -s clean     \
242            && make -C srpt -s )         \
243           &> "${outputfile}"
244     then
245       echo "OK"
246     else
247       echo "FAILED"
248     fi
249   )
250 }
251
252 # Download the file from URL $1 and save it in the current directory.
253 function download_file {
254   if [ ! -e "$(basename "$1")" ]; then
255     if [ "${quiet_download}" = "false" ]; then
256       echo "Downloading $1 ..."
257     fi
258     if ! wget -q -nc "$1"; then
259       echo "Downloading $1 failed."
260       return 1
261     fi
262   fi
263 }
264
265 # Make sure the kernel tarball and patch file are present in directory
266 # ${kernel_sources}. Download any missing files from ${kernel_mirror}.
267 function download_kernel {
268   local kver="$(kernel_version $1)"
269   local plevel="$(patchlevel $1)"
270
271   mkdir -p "${kernel_sources}" || return $?
272   test -w "${kernel_sources}" || return $?
273   (
274     cd "${kernel_sources}" || return $?
275     download_file "${kernel_mirror}/linux-$(kernel_version $1).tar.bz2" \
276       || return $?
277     if [ "${plevel}" != "" ]; then
278       download_file "${kernel_mirror}/patch-$1.bz2" || return $?
279     fi
280   )
281 }
282
283 # Generate a kernel patch from the SCST source tree for kernel version $1.
284 function generate_kernel_patch {
285   local scst_dir="${PWD}"
286   local kver="$(kernel_version $1)"
287   local patchfile="${outputdir}/scst-$1-kernel.patch"
288   local patchfile_m="${outputdir}/scst-$1-kernel-matching-line-numbers.patch"
289
290   SIGNED_OFF_BY="..." \
291   scripts/generate-kernel-patch \
292     $([ "${scst_local}" = "true" ] && echo -- "-l") \
293     $([ "${mpt_scst}"   = "true" ] && echo -- "-m") \
294     $([ "${qla2x00t}"   = "true" ] && echo -- "-q") \
295     ${1} > "${patchfile}"
296
297   SIGNED_OFF_BY="..." \
298   scripts/generate-kernel-patch \
299     -n                                              \
300     $([ "${scst_local}" = "true" ] && echo -- "-l") \
301     $([ "${mpt_scst}"   = "true" ] && echo -- "-m") \
302     $([ "${qla2x00t}"   = "true" ] && echo -- "-q") \
303     ${1} > "${patchfile_m}"
304 }
305
306 # Generate a kernel patch through scripts/generate-kernel-patch and test
307 # whether it applies cleanly to kernel version $1. Leaves a vanilla kernel
308 # in directory "${outputdir}/linux-$1" at exit.
309 function test_if_patch_applies_cleanly {
310   local kver="$(kernel_version $1)"
311   local plevel="$(patchlevel $1)"
312   local outputfile="${outputdir}/kernel-$1-patch-output.txt"
313   local patchfile="${outputdir}/scst-$1-kernel.patch"
314   local rc=0
315
316   echo "Testing whether the generated kernel patch applies cleanly ..."
317   ( cd "${outputdir}" && extract_kernel_tree "$1" )
318   ( cd "${outputdir}/linux-$1" \
319     && patch -p1 --dry-run -f < "${patchfile}" &> "${outputfile}" )
320   if [ $? != 0 ]; then
321     echo "FAILED"
322     rc=1
323   fi
324   return $rc
325 }
326
327 # Run checkpatch on the generated kernel patch. Assumes that there is a
328 # vanilla kernel tree present in directory "${outputdir}/linux-$1", and leaves
329 # this kernel tree clean.
330 function run_checkpatch  {
331   local kver="$(kernel_version $1)"
332   local plevel="$(patchlevel $1)"
333   local outputfile="${outputdir}/checkpatch-$1-output.txt"
334   local patchfile="${outputdir}/scst-$1-kernel.patch"
335
336   if [ -e "${outputdir}/linux-$1/scripts/checkpatch.pl" ]
337   then
338     echo "Running checkpatch on the SCST kernel patch ..."
339     ( cd "${outputdir}/linux-$1" \
340       && scripts/checkpatch.pl - < "${patchfile}" &> "${outputfile}")
341     local errors=$(grep -c '^ERROR' "${outputfile}")
342     local warnings=$(grep -c '^WARNING' "${outputfile}")
343     echo "${errors} errors / ${warnings} warnings."
344     grep -E '^WARNING|^ERROR' "${outputfile}" | sort | uniq -c
345   else
346     echo "Skipping checkpatch step for kernel $1."
347   fi
348   return 0
349 }
350
351 function patch_and_configure_kernel {
352   local patchfile="${outputdir}/scst-$1-kernel-matching-line-numbers.patch"
353
354   echo "Patching and configuring kernel ..."
355   (
356     cd "${outputdir}/linux-$1"                                     \
357     && patch -p1 -f -s <"${patchfile}"                             \
358                        >"${outputdir}/patch-command-output-$1.txt" \
359     && make -s allmodconfig &>/dev/null
360   )
361 }
362
363 # Patches and compiles a kernel tree. Assumes that there is a vanilla kernel
364 # tree present in directory "${outputdir}/linux-$1".
365 function compile_patched_kernel {
366   local kver="$(kernel_version $1)"
367   local plevel="$(patchlevel $1)"
368   local outputfile="${outputdir}/kernel-$1-compilation-output.txt"
369
370   echo "Compiling kernel $1 ..."
371   (
372     (
373       cd "${outputdir}/linux-$1" \
374       && LC_ALL=C make -s -k bzImage modules
375     )
376   ) &> "${outputfile}"
377   echo "See also ${outputfile}."
378   return 0
379 }
380
381 # Compile subdirectory $2 of the patched kernel tree linux-$1.
382 function compile_kernel {
383   local kver="$(kernel_version $1)"
384   local plevel="$(patchlevel $1)"
385   local outputfile="${outputdir}/compilation-$1-output.txt"
386   local subdir="$2"
387
388   echo "Compiling the patched kernel ..."
389   (
390     cd "${outputdir}/linux-$1" \
391     && make -s prepare \
392     && make -s scripts \
393     && LC_ALL=C make -k M="${subdir}"
394   ) &> "${outputfile}"
395   local errors=$(grep -c ' error:' "${outputfile}")
396   local warnings=$(grep -c ' warning:' "${outputfile}")
397   echo "${errors} errors / ${warnings} warnings."
398   cat "${outputfile}" | grep -E 'warning:|error:' | sort | uniq -c
399   return 0
400 }
401
402 # Run the source code verification tool 'sparse' on the SCST code. Assumes that
403 # there is a patched kernel tree present in directory "${outputdir}/linux-$1".
404 # For more information about endianness annotations, see also
405 # http://lwn.net/Articles/205624/.
406 function run_sparse {
407   local kver="$(kernel_version $1)"
408   local plevel="$(patchlevel $1)"
409   local outputfile="${outputdir}/sparse-$1-output.txt"
410   local subdir="$2"
411
412   echo "Running sparse on the patched kernel ..."
413   (
414     cd "${outputdir}/linux-$1" \
415     && make -s prepare \
416     && make -s scripts \
417     && LC_ALL=C make -k C=2 M="${subdir}" # CF=-D__CHECK_ENDIAN__
418   ) &> "${outputfile}"
419   local errors=$(grep -c ' error:' "${outputfile}")
420   local warnings=$(grep -c ' warning:' "${outputfile}")
421   echo "${errors} errors / ${warnings} warnings."
422   cat "${outputfile}" \
423     | grep -E 'warning:|error:' \
424     | sed -e 's/^[^ ]*:[^ ]*:[^ ]*: //' \
425           -e "s/context imbalance in '[^']*':/context imbalance in <function>:/g" \
426           -e "s/context problem in '[^']*': '[^']*'/context problem in <function>: <function>/g" \
427           -e "s/function '[^']*'/function/g" \
428           -e "s/symbol '[^']*'/symbol/g" \
429     | sort \
430     | uniq -c
431   return 0
432 }
433
434 function run_checkstack {
435   local kver="$(kernel_version $1)"
436   local plevel="$(patchlevel $1)"
437   local outputfile="${outputdir}/checkstack-$1-output.txt"
438
439   echo "Running checkstack on the patched $1 kernel ..."
440   (
441     cd "${outputdir}/linux-$1" \
442     && make -s prepare \
443     && make -s scripts \
444     && LC_ALL=C make -k checkstack
445   ) &> "${outputfile}"
446   echo "See also ${outputfile}."
447   return 0
448 }
449
450 function run_namespacecheck {
451   local kver="$(kernel_version $1)"
452   local plevel="$(patchlevel $1)"
453   local outputfile="${outputdir}/namespacecheck-$1-output.txt"
454
455   echo "Running namespacecheck on the patched $1 kernel ..."
456   (
457     cd "${outputdir}/linux-$1" \
458     && make -s prepare \
459     && make -s scripts \
460     && LC_ALL=C make -k namespacecheck
461   ) &> "${outputfile}"
462   echo "See also ${outputfile}."
463   return 0
464 }
465
466 function run_headers_check {
467   local kver="$(kernel_version $1)"
468   local plevel="$(patchlevel $1)"
469   local outputfile="${outputdir}/headers_check-$1-output.txt"
470
471   echo "Running headers check on the patched $1 kernel ..."
472   (
473     cd "${outputdir}/linux-$1" \
474     && make -s prepare \
475     && make -s scripts \
476     && LC_ALL=C make -k headers_check
477   ) &> "${outputfile}"
478   local errors=$(grep -c '^[^ ]' "${outputfile}")
479   echo "${errors} errors."
480   grep '^[^ ]' "${outputfile}" | sed 's/.*: //' | sort | uniq -c
481   return 0
482 }
483
484 function run_make_htmldocs {
485   local kver="$(kernel_version $1)"
486   local plevel="$(patchlevel $1)"
487   local outputfile="${outputdir}/htmldocs-$1-output.txt"
488
489   echo "Generating HTML documentation for the patched $1 kernel ..."
490   (
491     cd "${outputdir}/linux-$1" \
492     && make -s prepare \
493     && make -s scripts \
494     && LC_ALL=C make -k htmldocs
495   ) &> "${outputfile}"
496   echo "See also ${outputfile}."
497   return 0
498 }
499
500
501 #########################
502 # Argument verification #
503 #########################
504
505 if [ ! -e scst -o ! -e iscsi-scst -o ! -e srpt ]; then
506   echo "Please run this script from inside the SCST subversion source tree."
507   exit 1
508 fi
509
510 full_check="false"
511 # Where to store persistenly downloaded kernel tarballs and kernel patches.
512 kernel_sources="$HOME/software/downloads"
513 # URL for downloading kernel tarballs and kernel patches.
514 kernel_mirror="ftp://ftp.eu.kernel.org/pub/linux/kernel/v2.6"
515 kernel_versions=""
516 # Directory in which the regression test output files will be stored. Must be
517 # an absolute path.
518 outputdir="${PWD}/regression-test-output-$(date +%Y-%m-%d_%Hh%Mm%Ss)"
519 # Driver configuration.
520 mpt_scst="false"
521 qla2x00t="false"
522 remove_temporary_files_at_end="false"
523 scst_local="true"
524 quiet_download="false"
525
526 set -- $(/usr/bin/getopt "c:d:fj:hkq" "$@")
527 while [ "$1" != "${1#-}" ]
528 do
529   case "$1" in
530     '-c') kernel_sources="$2"; shift; shift;;
531     '-d') outputdir="$2"; shift; shift;;
532     '-f') full_check="true"; shift;;
533     '-h') usage; exit 1;;
534     '-j') export MAKEFLAGS="-j$2"; shift; shift;;
535     '-k') remove_temporary_files_at_end="true"; shift;;
536     '-q') quiet_download="true"; shift;;
537     '--') shift;;
538     *)    usage; exit 1;;
539   esac
540 done
541
542 kernel_versions="$*"
543
544 # RHEL 4.x / CentOS 4.x has a kernel based on version 2.6.9.
545 # RHEL 5.x / CentOS 5.x has a kernel based on version 2.6.18.
546 # Ubuntu 8.04 (Hardy Heron) has a kernel based on version 2.6.24.
547 # Ubuntu 8.10 (Intrepid Ibex) has a kernel based on version 2.6.27.
548 # openSUSE 11.0 has a kernel based on version 2.6.25.
549 # openSUSE 11.1 has a kernel based on version 2.6.27.
550 #kernel_versions="2.6.23.17 2.6.24.7 2.6.25.20 2.6.26.8 2.6.27.21 2.6.28.9 2.6.29.1"
551
552 if [ "${kernel_versions}" = "" ]; then
553   usage
554   exit 1
555 fi
556
557
558 ####################
559 # Regression tests #
560 ####################
561
562 if [ "$(type -p sparse)" = "" ]; then
563   echo "Error: sparse has not yet been installed."
564   echo "See also http://www.kernel.org/pub/software/devel/sparse/."
565 fi
566
567 if ! mkdir -p "${outputdir}"; then
568   if [ -e "${outputdir}" ]; then
569     echo "Error: directory ${outputdir} already exists."
570   else
571     echo "Error: could not create directory ${outputdir}."
572   fi
573 fi
574
575 test_scst_tree_patches || exit $?
576 compile_scst_unpatched || exit $?
577 compile_scst_patched || exit $?
578
579 first_iteration="true"
580 for k in ${kernel_versions}
581 do
582   echo "===================="
583   printf "= kernel %-9s =\n" "${k}"
584   echo "===================="
585
586   download_kernel $k || continue
587   generate_kernel_patch $k || continue
588   test_if_patch_applies_cleanly $k || continue
589   if [ "${first_iteration}" = "true" \
590        -o "${kernel_version#2.6.26}" != "${kernel_version}" ]
591   then
592     first_iteration="false"
593     run_checkpatch $k
594     patch_and_configure_kernel $k
595     run_sparse $k drivers/scst
596   else
597     patch_and_configure_kernel $k
598     compile_kernel $k drivers/scst
599   fi
600   # run_headers_check $k
601   if [ "${full_check}" = "true" ]; then
602     compile_patched_kernel $k
603     run_checkstack $k
604     run_namespacecheck $k
605     run_make_htmldocs $k
606   fi
607   if [ "${remove_temporary_files_at_end}" = "true" ]; then
608     rm -rf "${outputdir}"
609     mkdir -p "${outputdir}"
610   fi
611 done