diff options
author | Brian Behlendorf <[email protected]> | 2014-04-08 16:46:13 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2014-04-09 13:29:32 -0700 |
commit | cc9ee13e1a36511decb526bf84146e20a846b3d6 (patch) | |
tree | 662b68c1a76104b2a3f22bbd034ce5ad5b21d06c /scripts/common.sh.in | |
parent | 787c455ed7a519bbf2e56140621259eb7b23b6fb (diff) |
Dynamically create loop devices
Several of the in-tree regression tests depend on the availability
of loop devices. If for some reason no loop devices are available
the tests will fail.
Normally this isn't an issue because most Linux distributions create
8 loop devices by default. This is enough for our purposes. However,
recent Fedora releases have only been creating a single loop device
and this leads to failures. Alternately, if something else of the
system is using the loop devices we may see failures.
The fix for this is to update the support scripts to dynamically
create loop devices as needed. The scripts need only create a node
under /dev/ and the loop driver with create the minor. This behavior
has been supported by the loop driver for ages.
Additionally this patch updates cleanup_loop_devices() to cleanup
loop devices which have already had their file store deleted. This
helps prevent stale loop devices from accumulating on the system due
to test failures.
Signed-off-by: Brian Behlendorf <[email protected]>
Signed-off-by: Prakash Surya <[email protected]>
Closes #2249
Diffstat (limited to 'scripts/common.sh.in')
-rw-r--r-- | scripts/common.sh.in | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/scripts/common.sh.in b/scripts/common.sh.in index ae1c5cf09..a6586f4aa 100644 --- a/scripts/common.sh.in +++ b/scripts/common.sh.in @@ -288,34 +288,61 @@ check_loop_utils() { # -# Find and return an unused loopback device. +# Find and return an unused loop device. A new /dev/loopN node will be +# created if required. The kernel loop driver will automatically register +# the minor as long as it's less than /sys/module/loop/parameters/max_loop. # unused_loop_device() { - for DEVICE in `ls -1 /dev/loop[0-9]* 2>/dev/null`; do - ${LOSETUP} ${DEVICE} &>/dev/null - if [ $? -ne 0 ]; then - echo ${DEVICE} - return + local DEVICE=`${LOSETUP} -f` + local MAX_LOOP_PATH="/sys/module/loop/parameters/max_loop" + local MAX_LOOP; + + # An existing /dev/loopN device was available. + if [ -n "${DEVICE}" ]; then + echo "${DEVICE}" + return 0 + fi + + # Create a new /dev/loopN provided we are not at MAX_LOOP. + if [ -f "${MAX_LOOP_PATH}" ]; then + MAX_LOOP=`cat /sys/module/loop/parameters/max_loop` + if [ ${MAX_LOOP} -eq 0 ]; then + MAX_LOOP=255 fi - done - die "Error: Unable to find unused loopback device" + for (( i=0; i<=${MAX_LOOP}; i++ )); do + DEVICE="/dev/loop$i" + + if [ -b "${DEVICE}" ]; then + continue + else + mknod -m660 "${DEVICE}" b 7 $i + chown root.disk "${DEVICE}" + chmod 666 "${DEVICE}" + + echo "${DEVICE}" + return 0 + fi + done + fi + + die "Error: Unable to create new loopback device" } # # This can be slightly dangerous because the loop devices we are # cleaning up may not be ours. However, if the devices are currently # in use we will not be able to remove them, and we only remove -# devices which include 'zpool' in the name. So any damage we might -# do should be limited to other zfs related testing. +# devices which include 'zpool' or 'deleted' in the name. So any +# damage we might do should be limited to other zfs related testing. # cleanup_loop_devices() { local TMP_FILE=`mktemp` ${LOSETUP} -a | tr -d '()' >${TMP_FILE} ${AWK} -F":" -v losetup="$LOSETUP" \ - '/zpool/ { system("losetup -d "$1) }' ${TMP_FILE} - ${AWK} -F" " '/zpool/ { system("rm -f "$3) }' ${TMP_FILE} + '/zpool/ || /deleted/ { system("losetup -d "$1) }' ${TMP_FILE} + ${AWK} -F" " '/zpool/ || /deleted/ { system("rm -f "$3) }' ${TMP_FILE} rm -f ${TMP_FILE} } |