Various patches before this one plugged fd leaks of files opened within nbdkit that the shell script need not see. It's time to add testsuite coverage to ensure we don't regress.
However, a user may intentionally want to expose an open fd to nbdkit, which in turn remains available all the way through to the shell script, so nbdkit does not close unrecognized inherited fds at startup. This makes the test more interesting - if you run 'exec 17>/dev/null && make check', then there will be one more inherited fd in the environment of both nbdkit and the shell script, but this is not an nbdkit leak. Furthermore, checking how many fds are open in a shell is tricky: many actions in the shell (such as a glob or pipeline) increase the number of temporarily-open file descriptors; I settled on creating a subshell, then using ls to check the files still open in $$ (the subshell prevents the parent from using any more fds, all without changing $$). This addition is rather fragile - if it causes testsuite failures in some environments, we may end up reverting it. Signed-off-by: Eric Blake <[email protected]> --- tests/test-parallel-sh.sh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test-parallel-sh.sh b/tests/test-parallel-sh.sh index 21bc010a..ddbdf90c 100755 --- a/tests/test-parallel-sh.sh +++ b/tests/test-parallel-sh.sh @@ -53,12 +53,35 @@ qemu-io -f raw -c "aio_write -P 1 0 512" -c "aio_write -P 2 512 512" \ # happens). This test may have spurious failures under heavy loads on # the test machine, where tuning the delays may help. +# Also test for leaked fds when possible: nbdkit does not close fds it +# inherited, but other than 0, 1, 2, and the fd associated with the +# script, the child shell should not see any new fds not also present +# in nbdkit's parent environment. When testing for the count of open +# fds, use ls in a subshell (rather than a glob directly within the +# shell under test), to avoid yet another fd open on the /proc/self/fd +# directory. + +curr_fds= +if test -d /proc/$$/fd; then + curr_fds=$(/usr/bin/env bash -c '(ls /proc/$$/fd)' | wc -w) +fi +echo "using curr_fds=$curr_fds" + cat > test-parallel-sh.script <<EOF #!/usr/bin/env bash f=test-parallel-sh.data if ! test -f \$f; then echo "can't locate test-parallel-sh.data" >&2; exit 5 fi +if test -d /proc/\$\$/fd; then + ( + if test \$( ls /proc/\$\$/fd | wc -w ) -ne \$(($curr_fds + 1)); then + echo "there seem to be leaked fds, curr_fds=$curr_fds" >&2 + ls -l /proc/\$\$/fd >&2 + exit 1 + fi + ) || exit 5 +fi case \$1 in get_size) stat -L -c %s \$f || exit 1 ;; pread) dd iflag=skip_bytes,count_bytes skip=\$4 count=\$3 if=\$f || exit 1 ;; -- 2.20.1 _______________________________________________ Libguestfs mailing list [email protected] https://www.redhat.com/mailman/listinfo/libguestfs
