Added debug2perf and disable_proc configurations to the regression tests.
[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, runs
30 #   'make debug2release' 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-$1.txt"
225   local workingdirectory="${outputdir}/scst-$1"
226
227   echo "Testing whether the $1 SCST tree compiles fine ..."
228   (
229     if mkdir -p "${workingdirectory}"  \
230        && cd "${workingdirectory}"     \
231        && duplicate_scst_source_tree "${scst}"  \
232        && make -s "$1"                 \
233        && (make -s clean               \
234            && make -s scst iscsi-scst  \
235            && if "${scst_local}" = "true" ; then make -C scst_local clean; fi \
236            && if "${scst_local}" = "true" ; then make -C scst_local -s   ; fi \
237            && if "${mpt_scst}"   = "true" ; then make -C mpt clean; fi \
238            && if "${mpt_scst}"   = "true" ; then make -C mpt -s   ; fi \
239            && make -C srpt -s clean     \
240            && make -C srpt -s )         \
241           &> "${outputfile}"
242     then
243       echo "OK"
244     else
245       echo "FAILED"
246     fi
247   )
248 }
249
250 # Download the file from URL $1 and save it in the current directory.
251 function download_file {
252   if [ ! -e "$(basename "$1")" ]; then
253     if [ "${quiet_download}" = "false" ]; then
254       echo "Downloading $1 ..."
255     fi
256     if ! wget -q -nc "$1"; then
257       echo "Downloading $1 failed."
258       return 1
259     fi
260   fi
261 }
262
263 # Make sure the kernel tarball and patch file are present in directory
264 # ${kernel_sources}. Download any missing files from ${kernel_mirror}.
265 function download_kernel {
266   local kver="$(kernel_version $1)"
267   local plevel="$(patchlevel $1)"
268
269   mkdir -p "${kernel_sources}" || return $?
270   test -w "${kernel_sources}" || return $?
271   (
272     cd "${kernel_sources}" || return $?
273     download_file "${kernel_mirror}/linux-$(kernel_version $1).tar.bz2" \
274       || return $?
275     if [ "${plevel}" != "" ]; then
276       download_file "${kernel_mirror}/patch-$1.bz2" || return $?
277     fi
278   )
279 }
280
281 # Generate a kernel patch from the SCST source tree for kernel version $1.
282 function generate_kernel_patch {
283   local scst_dir="${PWD}"
284   local kver="$(kernel_version $1)"
285   local patchfile="${outputdir}/scst-$1-kernel.patch"
286   local patchfile_m="${outputdir}/scst-$1-kernel-matching-line-numbers.patch"
287
288   SIGNED_OFF_BY="..." \
289   scripts/generate-kernel-patch \
290     $([ "${scst_local}" = "true" ] && echo -- "-l") \
291     $([ "${mpt_scst}"   = "true" ] && echo -- "-m") \
292     $([ "${qla2x00t}"   = "true" ] && echo -- "-q") \
293     ${1} > "${patchfile}"
294
295   SIGNED_OFF_BY="..." \
296   scripts/generate-kernel-patch \
297     -n                                              \
298     $([ "${scst_local}" = "true" ] && echo -- "-l") \
299     $([ "${mpt_scst}"   = "true" ] && echo -- "-m") \
300     $([ "${qla2x00t}"   = "true" ] && echo -- "-q") \
301     ${1} > "${patchfile_m}"
302 }
303
304 # Generate a kernel patch through scripts/generate-kernel-patch and test
305 # whether it applies cleanly to kernel version $1. Leaves a vanilla kernel
306 # in directory "${outputdir}/linux-$1" at exit.
307 function test_if_patch_applies_cleanly {
308   local kver="$(kernel_version $1)"
309   local plevel="$(patchlevel $1)"
310   local outputfile="${outputdir}/kernel-$1-patch-output.txt"
311   local patchfile="${outputdir}/scst-$1-kernel.patch"
312   local rc=0
313
314   echo "Testing whether the generated kernel patch applies cleanly ..."
315   ( cd "${outputdir}" && extract_kernel_tree "$1" )
316   ( cd "${outputdir}/linux-$1" \
317     && patch -p1 --dry-run -f < "${patchfile}" &> "${outputfile}" )
318   if [ $? != 0 ]; then
319     echo "FAILED"
320     rc=1
321   fi
322   return $rc
323 }
324
325 # Run checkpatch on the generated kernel patch. Assumes that there is a
326 # vanilla kernel tree present in directory "${outputdir}/linux-$1", and leaves
327 # this kernel tree clean.
328 function run_checkpatch  {
329   local kver="$(kernel_version $1)"
330   local plevel="$(patchlevel $1)"
331   local outputfile="${outputdir}/checkpatch-$1-output.txt"
332   local patchfile="${outputdir}/scst-$1-kernel.patch"
333
334   if [ -e "${outputdir}/linux-$1/scripts/checkpatch.pl" ]
335   then
336     echo "Running checkpatch on the SCST kernel patch ..."
337     ( cd "${outputdir}/linux-$1" \
338       && scripts/checkpatch.pl - < "${patchfile}" &> "${outputfile}")
339     local errors=$(grep -c '^ERROR' "${outputfile}")
340     local warnings=$(grep -c '^WARNING' "${outputfile}")
341     echo "${errors} errors / ${warnings} warnings."
342     grep -E '^WARNING|^ERROR' "${outputfile}" | sort | uniq -c
343   else
344     echo "Skipping checkpatch step for kernel $1."
345   fi
346   return 0
347 }
348
349 function patch_and_configure_kernel {
350   local patchfile="${outputdir}/scst-$1-kernel-matching-line-numbers.patch"
351
352   echo "Patching and configuring kernel ..."
353   (
354     cd "${outputdir}/linux-$1"                                     \
355     && patch -p1 -f -s <"${patchfile}"                             \
356                        >"${outputdir}/patch-command-output-$1.txt" \
357     && make -s allmodconfig &>/dev/null
358   )
359 }
360
361 # Patches and compiles a kernel tree. Assumes that there is a vanilla kernel
362 # tree present in directory "${outputdir}/linux-$1".
363 function compile_patched_kernel {
364   local kver="$(kernel_version $1)"
365   local plevel="$(patchlevel $1)"
366   local outputfile="${outputdir}/kernel-$1-compilation-output.txt"
367
368   echo "Compiling kernel $1 ..."
369   (
370     (
371       cd "${outputdir}/linux-$1" \
372       && LC_ALL=C make -s -k bzImage modules
373     )
374   ) &> "${outputfile}"
375   echo "See also ${outputfile}."
376   return 0
377 }
378
379 # Compile subdirectory $2 of the patched kernel tree linux-$1.
380 function compile_kernel {
381   local kver="$(kernel_version $1)"
382   local plevel="$(patchlevel $1)"
383   local outputfile="${outputdir}/compilation-$1-output.txt"
384   local subdir="$2"
385
386   echo "Compiling the patched kernel ..."
387   (
388     cd "${outputdir}/linux-$1" \
389     && make -s prepare \
390     && make -s scripts \
391     && LC_ALL=C make -k M="${subdir}"
392   ) &> "${outputfile}"
393   local errors=$(grep -c ' error:' "${outputfile}")
394   local warnings=$(grep -c ' warning:' "${outputfile}")
395   echo "${errors} errors / ${warnings} warnings."
396   cat "${outputfile}" | grep -E 'warning:|error:' | sort | uniq -c
397   return 0
398 }
399
400 # Run the source code verification tool 'sparse' on the SCST code. Assumes that
401 # there is a patched kernel tree present in directory "${outputdir}/linux-$1".
402 # For more information about endianness annotations, see also
403 # http://lwn.net/Articles/205624/.
404 function run_sparse {
405   local kver="$(kernel_version $1)"
406   local plevel="$(patchlevel $1)"
407   local outputfile="${outputdir}/sparse-$1-output.txt"
408   local subdir="$2"
409
410   echo "Running sparse on the patched kernel ..."
411   (
412     cd "${outputdir}/linux-$1" \
413     && make -s prepare \
414     && make -s scripts \
415     && LC_ALL=C make -k C=2 M="${subdir}" # CF=-D__CHECK_ENDIAN__
416   ) &> "${outputfile}"
417   local errors=$(grep -c ' error:' "${outputfile}")
418   local warnings=$(grep -c ' warning:' "${outputfile}")
419   echo "${errors} errors / ${warnings} warnings."
420   cat "${outputfile}" \
421     | grep -E 'warning:|error:' \
422     | sed -e 's/^[^ ]*:[^ ]*:[^ ]*: //' \
423           -e "s/context imbalance in '[^']*':/context imbalance in <function>:/g" \
424           -e "s/context problem in '[^']*': '[^']*'/context problem in <function>: <function>/g" \
425           -e "s/function '[^']*'/function/g" \
426           -e "s/symbol '[^']*'/symbol/g" \
427     | sort \
428     | uniq -c
429   return 0
430 }
431
432 function run_checkstack {
433   local kver="$(kernel_version $1)"
434   local plevel="$(patchlevel $1)"
435   local outputfile="${outputdir}/checkstack-$1-output.txt"
436
437   echo "Running checkstack on the patched $1 kernel ..."
438   (
439     cd "${outputdir}/linux-$1" \
440     && make -s prepare \
441     && make -s scripts \
442     && LC_ALL=C make -k checkstack
443   ) &> "${outputfile}"
444   echo "See also ${outputfile}."
445   return 0
446 }
447
448 function run_namespacecheck {
449   local kver="$(kernel_version $1)"
450   local plevel="$(patchlevel $1)"
451   local outputfile="${outputdir}/namespacecheck-$1-output.txt"
452
453   echo "Running namespacecheck on the patched $1 kernel ..."
454   (
455     cd "${outputdir}/linux-$1" \
456     && make -s prepare \
457     && make -s scripts \
458     && LC_ALL=C make -k namespacecheck
459   ) &> "${outputfile}"
460   echo "See also ${outputfile}."
461   return 0
462 }
463
464 function run_headers_check {
465   local kver="$(kernel_version $1)"
466   local plevel="$(patchlevel $1)"
467   local outputfile="${outputdir}/headers_check-$1-output.txt"
468
469   echo "Running headers check on the patched $1 kernel ..."
470   (
471     cd "${outputdir}/linux-$1" \
472     && make -s prepare \
473     && make -s scripts \
474     && LC_ALL=C make -k headers_check
475   ) &> "${outputfile}"
476   local errors=$(grep -c '^[^ ]' "${outputfile}")
477   echo "${errors} errors."
478   grep '^[^ ]' "${outputfile}" | sed 's/.*: //' | sort | uniq -c
479   return 0
480 }
481
482 function run_make_htmldocs {
483   local kver="$(kernel_version $1)"
484   local plevel="$(patchlevel $1)"
485   local outputfile="${outputdir}/htmldocs-$1-output.txt"
486
487   echo "Generating HTML documentation for the patched $1 kernel ..."
488   (
489     cd "${outputdir}/linux-$1" \
490     && make -s prepare \
491     && make -s scripts \
492     && LC_ALL=C make -k htmldocs
493   ) &> "${outputfile}"
494   echo "See also ${outputfile}."
495   return 0
496 }
497
498
499 #########################
500 # Argument verification #
501 #########################
502
503 export LC_ALL=C
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 debug2release || exit $?
578 compile_scst_patched debug2perf    || exit $?
579 compile_scst_patched disable_proc  || exit $?
580
581 first_iteration="true"
582 for k in ${kernel_versions}
583 do
584   echo "===================="
585   printf "= kernel %-9s =\n" "${k}"
586   echo "===================="
587
588   download_kernel $k || continue
589   generate_kernel_patch $k || continue
590   test_if_patch_applies_cleanly $k || continue
591   if [ "${first_iteration}" = "true" -o "${k#2.6.26}" != "$k" ]; 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