4 # Copyright (c) International Business Machines Corp., 2005
5 # Authors: Avantika Mathur (mathurav@us.ibm.com)
6 # Matt Helsley (matthltc@us.ibm.com)
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2.1 of the License, or (at your option) any later version.
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # Lesser General Public License for more details.
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this library; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 if tst_kvercmp
2 6 15 ; then
24 tst_resm TCONF
"System kernel version is less than 2.6.15"
25 tst_resm TCONF
"Cannot execute test"
32 #######################################################################
34 #######################################################################
37 ## Remove logged test state depending on results. 0 means do not remove,
38 ## 1 means OK to remove.
39 # rm saved state from tests that appear to have cleaned up properly?
41 # rm saved state from tests that don't appear to have fully cleaned up?
44 #######################################################################
45 ## Initialize some variables
46 #######################################################################
50 test_dirs
=( move
bind rbind regression
) #cloneNS
54 # set the LTPROOT directory
57 echo "${LTPROOT}" |
grep testscripts
> /dev
/null
2>&1
63 FS_BIND_ROOT
="${LTPROOT}/testcases/kernel/fs/fs_bind"
65 total
=0 # total number of tests
66 for dir
in "${test_dirs[@]}" ; do
67 ((total
+= `ls "${FS_BIND_ROOT}/${dir}/test"* | wc -l`))
71 # set the PATH to include testcases/bin
72 LTPBIN
="${LTPROOT}/testcases/bin"
73 PATH
="${PATH}:/usr/sbin:${LTPBIN}:${FS_BIND_ROOT}/bin"
76 resdir
="${LTPROOT}/results/fs_bind"
77 if [ ! -d "${resdir}" ]; then
78 mkdir
-p "${resdir}" 2> /dev
/null
81 TMPDIR
="${TMPDIR:-/tmp}"
82 # A temporary directory where we can do stuff and that is
84 sandbox
="${TMPDIR}/sandbox"
88 export LTPBIN PATH FS_BIND_ROOT ERR_MSG TCID TST_COUNT TST_TOTAL
90 if [ ! -d "${resdir}" ]; then
91 tst_brkm TBROK true
"$0: failed to make results directory"
98 # Must be root to run the containers testsuite
99 if [ $UID != 0 ]; then
100 tst_brkm TBROK true
"FAILED: Must be root to execute this script"
104 mkdir
"${sandbox}" >& /dev
/null
105 if [ ! -d "${sandbox}" -o ! -x "${sandbox}" ]; then
106 tst_brkm TBROK true
"$0: failed to make directory \"${sandbox}\""
113 pushd "${sandbox}" > /dev
/null
&& {
114 mkdir bind_test move_test
&& {
115 mount
--bind bind_test bind_test
&& {
117 mount
--move bind_test move_test
&& {
121 # bind mount succeeded but move mount
126 # mount failed -- check if it's because we
127 # don't have privileges we need
128 if [ $?
-eq 32 ]; then
129 tst_brkm TBROK true
"$0 requires the privilege to use the mount command"
133 rmdir bind_test move_test
138 if [ ${mnt_bind} -eq 1 -o ${mnt_move} -eq 1 ]; then
139 tst_brkm TBROK true
"$0: requires that mount support the --bind and --move options"
145 if [ $X -lt 0 ]; then
146 tst_brkm TBROK
"$0: failed to get the running kernel version"
148 elif [ $X -lt 1 ]; then
149 tst_resm TWARN
"$0: the remaining tests require 2.6.15 or later"
153 tst_resm TINFO
"$0: kernel >= 2.6.15 detected -- continuing"
156 mount
--bind "${sandbox}" "${sandbox}" && {
157 mount
--make-shared "${sandbox}" > /dev/null 2>&1 || "${FS_BIND_ROOT}/bin/smount" "${sandbox}" shared
158 umount
"${sandbox}" ||
{
159 tst_resm TFAIL
"$0: failed to umount simplest shared subtree"
163 tst_brkm TBROK true
"$0: failed to perform bind mount"
167 tst_resm TPASS
"$0: umounted simplest shared subtree"
171 # mounts we are concerned with in a well-defined order (helps diff)
172 # returns grep return codes
177 # Save the pipefail shell option
182 # Grep /proc/mounts which is often more up-to-date than mounts
183 # We use pipefail because if the grep fails we want to pass that along
184 grep -F "${sandbox}" /proc
/mounts |
sort -b
187 # Restore the pipefail shell options
188 [ $save -eq 0 ] && shopt -o -s pipefail ||
shopt -o -u pipefail
193 # Record the mount state
196 touch "$2/proc_mounts.before" >& /dev
/null
197 if [ $?
-ne 0 ]; then
198 tst_brkm TBROK true
"$1: failed to record proc mounts"
202 grep_proc_mounts
2> /dev
/null
> "$2/proc_mounts.before"
206 # Compare mount list after the test with the list from before.
207 # If there are no differences then remove the before list and silently
208 # return 0. Else print the differences to stderr and return 1.
213 if [ ! -r "$2/proc_mounts.before" ]; then
214 tst_brkm TBROK true
"${tname}: Could not find pre-test proc mount list"
218 grep_proc_mounts
2> /dev
/null
> "$2/proc_mounts.after"
219 # If the mounts are the same then just return
220 diff ${dopts} -q "$2/proc_mounts.before" "$2/proc_mounts.after" >& /dev
/null
221 if [ $?
-eq 0 ]; then
222 [ $rm_ok -eq 1 ] && rm -f "$2/proc_mounts."{before
,after
}
226 tst_resm TWARN
"${tname}: did not properly clean up its proc mounts"
227 diff ${dopts} -U 0 "$2/proc_mounts.before" "$2/proc_mounts.after" |
grep -vE '^\@\@' 1>&2
228 [ $rm_err -eq 1 ] && rm -f "$2/proc_mounts."{before
,after
}
232 # Undo leftover mounts
233 restore_proc_mounts
()
237 # do lazy umounts -- we're assuming that tests will only leave
238 # new mounts around and will never remove mounts outside the test
240 ( while grep_proc_mounts
; do
241 grep_proc_mounts |
awk '{print $2}' |
xargs -r --max-args=1 umount
-l
244 # mount list and exit with 0
245 [ $rm_err -eq 1 ] && rm -f "$2/proc_mounts."{before
,after
} 1>&2 # >& /dev/null
247 # if returning error do this:
248 # tst_brkm TBROK true "${tname}: failed to restore mounts"
251 # mounts we are concerned with in a well-defined order (helps diff)
252 # returns grep return codes
257 # Save the pipefail shell option
262 # Grep mount command output (which tends to come from /etc/mtab)
263 # We use pipefail because if the grep fails we want to pass that along
264 mount |
grep -F "${sandbox}" |
sort -b
267 # Restore the pipefail shell options
268 [ $save -eq 0 ] && shopt -o -s pipefail ||
shopt -o -u pipefail
273 # Record the mount state
276 touch "$2/mtab.before" >& /dev
/null
277 if [ $?
-ne 0 ]; then
278 tst_brkm TBROK true
"$1: failed to record mtab mounts"
282 grep_mounts
2> /dev
/null
> "$2/mtab.before"
286 # Compare mount list after the test with the list from before.
287 # If there are no differences then remove the before list and silently
288 # return 0. Else print the differences to stderr and return 1.
293 if [ ! -r "$2/mtab.before" ]; then
294 tst_brkm TBROK true
"${tname}: Could not find pre-test mtab mount list"
298 grep_mounts
2> /dev
/null
> "$2/mtab.after"
299 # If the mounts are the same then just return
300 diff ${dopts} -q "$2/mtab.before" "$2/mtab.after" >& /dev
/null
301 if [ $?
-eq 0 ]; then
302 [ $rm_ok -eq 1 ] && rm -f "$2/mtab."{before
,after
}
306 tst_resm TWARN
"${tname}: did not properly clean up its mtab mounts"
307 diff ${dopts} -U 0 "$2/mtab.before" "$2/mtab.after" |
grep -vE '^\@\@' 1>&2
308 [ $rm_err -eq 1 ] && rm -f "$2/mtab."{before
,after
}
312 # Undo leftover mounts
317 # do lazy umounts -- we're assuming that tests will only leave
318 # new mounts around and will never remove mounts outside the test
320 ( while grep_mounts
; do
321 grep_mounts |
awk '{print $3}' |
xargs -r --max-args=1 umount
-l
324 # mount list and exit with 0
325 [ $rm_err -eq 1 ] && rm -f "$2/mtab."{before
,after
} 1>&2 # >& /dev/null
327 # if returning error do this:
328 # tst_brkm TBROK true "${tname}: failed to restore mounts"
331 # Record the sandbox state
332 # We don't save full sandbox state -- just the names of files and dirs present
338 if [ -e "$2/files.before" ]; then
339 if [ -e "$2/files.after" ]; then
340 tst_brkm TBROK true
"${tname}: stale catalog of \"${sandbox}\""
346 ( find "${sandbox}" -type d
-print |
sort > "$2/dirs.$when"
347 find "${sandbox}" -type f
-print |
sort | \
348 grep -vE '^'"$2"'/(dirs|files)\.(before|after)$' > "$2/files.$when" ) >& /dev
/null
352 # Save sandbox after test and then compare. If the sandbox state is not
353 # clean then print the differences to stderr and return 1. Else remove all
354 # saved sandbox state and silently return 0
359 if [ ! -r "$2/files.before" -o ! -r "$2/dirs.before" ]; then
360 tst_brkm TBROK true
"${tname} missing saved catalog of \"${sandbox}\""
364 save_sandbox
"${tname} (check)" "$2"
366 ( diff ${dopts} -q "$2/dirs.before" "$2/dirs.after" && \
367 diff ${dopts} -q "$2/files.before" "$2/files.after" ) >& /dev
/null \
369 [ $rm_ok -eq 1 ] && rm -f "$2/"{files
,dirs}.
{before
,after
}
373 tst_resm TWARN
"${tname} did not properly clean up \"${sandbox}\""
374 diff ${dopts} -U 0 "$2/dirs.before" "$2/dirs.after" 1>&2
375 diff ${dopts} -U 0 "$2/files.before" "$2/files.after" 1>&2
376 [ $rm_err -eq 1 ] && rm -f "$2/"{files
,dirs}.
{before
,after
} 1>&2
380 # Robust sandbox cleanup
385 { rm -rf "${sandbox}" ; mkdir "${sandbox}" ; } >& /dev/null
386 if [ ! -d "${sandbox}" -o ! -x "${sandbox}" ]; then
387 tst_brkm TBROK true "$tname: failed to
make directory
\"${sandbox}\""
393 # Check file for non-whitespace chars
396 awk '/^[[:space:]]*$/ { next }
401 # Run the specified test script.
403 # Return 1 if the test was broken but should not stop the remaining test
404 # categories from being run.
405 # Return 2 if the test was broken and no further tests should be run.
406 # Return 0 otherwise (if the test was broken but it shouldn't affect other
408 # Note that this means the return status is not the success or failure of the
414 local tname="$
(basename "$(dirname "$t")")/$
(basename "$t")"
415 local log="$resdir/$tname/log
"
416 local errlog="$resdir/$tname/err
"
422 mkdir -p "$resdir/$tname"
423 if [ ! -d "$resdir/$tname" -o ! -x "$resdir/$tname" ]; then
424 tst_brkm TBROK true "$0: can
't make or use \"$resdir/$tname\" as a log directory"
428 save_sandbox "$tname" "$resdir/$tname" || do_break=1
429 save_mounts "$tname" "$resdir/$tname" || do_break=1
430 save_proc_mounts "$tname" "$resdir/$tname" || do_break=1
431 if [ $do_break -eq 1 ]; then
432 tst_brkm TBROK true "$tname: failed to save pre-test state of \"${sandbox}\""
435 pushd "${sandbox}" > /dev/null
441 export LTPBIN PATH FS_BIND_ROOT ERR_MSG TCID TST_COUNT TST_TOTAL
442 "$t" #> "$log" 2> "$errlog"
449 if [ $rc -ne 0 ]; then
456 check_proc_mounts "$tname" "$resdir/$tname" || \
457 restore_proc_mounts "$tname" "$resdir/$tname" || do_break=1
458 check_mounts "$tname" "$resdir/$tname" || \
459 restore_mounts "$tname" "$resdir/$tname" || do_break=1
460 check_sandbox "$tname" "$resdir/$tname"
461 clean_sandbox "$tname" || do_break=1
462 if [ $do_break -eq 1 ]; then
463 tst_brkm TBROK true "$tname: failed to restore pre-test state of \"${sandbox}\""
467 # If we succeeded and the error log is empty remove it
468 if [ $rc -eq 0 -a -w "$errlog" ] && is_file_empty "$errlog" ; then
477 for dir in "${test_dirs[@]}" ; do
478 tests=( $(find "${FS_BIND_ROOT}/${dir}" -type f -name 'test*') )
479 clean_sandbox "$0" || break
480 for t in "${tests[@]}" ; do
484 if [ $rc -ne 0 ]; then
494 skipped=$((total - nsucceeded - nfailed))
495 if [ $nfailed -eq 0 -a $skipped -eq 0 ]; then
496 # Use PASSED for the summary rather than SUCCEEDED to make it
497 # easy to determine 100% success from a calling script
500 # Use FAILED to make it easy to find > 0% failure from a
505 *********************************
508 passed: $nsucceeded/$total
509 failed: $nfailed/$total
510 skipped: $skipped/$total
513 *********************************
518 test_prereqs || exit 1
519 declare -r FS_BIND_ROOT
521 main #2> "$resdir/errors" 1> "$resdir/summary"