212 lines
7.9 KiB
Diff
212 lines
7.9 KiB
Diff
Index: xen-3.4.1-testing/tools/hotplug/Linux/block
|
|
===================================================================
|
|
--- xen-3.4.1-testing.orig/tools/hotplug/Linux/block
|
|
+++ xen-3.4.1-testing/tools/hotplug/Linux/block
|
|
@@ -241,107 +241,111 @@ case "$command" in
|
|
mount it read-write in a guest domain."
|
|
fi
|
|
|
|
- loopdev=''
|
|
- for dev in /dev/loop*
|
|
+ losetup_failure=1
|
|
+ for do_losetup in 1 2 3
|
|
do
|
|
- if [ ! -b "$dev" ]
|
|
- then
|
|
- continue
|
|
- fi
|
|
-
|
|
- f=$(losetup "$dev" 2>/dev/null) || f=''
|
|
-
|
|
- if [ "$f" ]
|
|
- then
|
|
- # $dev is in use. Check sharing.
|
|
- if [ "x$mode" = 'x!' ]
|
|
+ loopdev=''
|
|
+ for dev in /dev/loop*
|
|
+ do
|
|
+ if [ ! -b "$dev" ]
|
|
then
|
|
continue
|
|
fi
|
|
|
|
- f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
|
|
+ f=$(losetup "$dev" 2>/dev/null) || f=''
|
|
|
|
- # $f is the filename, as read from losetup, but the loopback
|
|
- # driver truncates filenames at 64 characters, so we need to go
|
|
- # trawling through the store if it's longer than that. Truncation
|
|
- # is indicated by an asterisk at the end of the filename.
|
|
- if expr index "$f" '*' >/dev/null
|
|
+ if [ "$f" ]
|
|
then
|
|
- found=""
|
|
- for dom in $(xenstore-list "$XENBUS_BASE_PATH")
|
|
- do
|
|
- for domdev in $(xenstore-list "$XENBUS_BASE_PATH/$dom")
|
|
+ # $dev is in use. Check sharing.
|
|
+ if [ "x$mode" = 'x!' ]
|
|
+ then
|
|
+ continue
|
|
+ fi
|
|
+
|
|
+ f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g')
|
|
+
|
|
+ # $f is the filename, as read from losetup, but the loopback
|
|
+ # driver truncates filenames at 64 characters, so we need to go
|
|
+ # trawling through the store if it's longer than that. Truncation
|
|
+ # is indicated by an asterisk at the end of the filename.
|
|
+ if expr index "$f" '*' >/dev/null
|
|
+ then
|
|
+ found=""
|
|
+ for dom in $(xenstore-list "$XENBUS_BASE_PATH")
|
|
do
|
|
- d=$(xenstore_read_default \
|
|
- "$XENBUS_BASE_PATH/$dom/$domdev/node" "")
|
|
- if [ "$d" = "$dev" ]
|
|
- then
|
|
- f=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$domdev/params")
|
|
- found=1
|
|
- break 2
|
|
- fi
|
|
+ for domdev in $(xenstore-list "$XENBUS_BASE_PATH/$dom")
|
|
+ do
|
|
+ d=$(xenstore_read_default \
|
|
+ "$XENBUS_BASE_PATH/$dom/$domdev/node" "")
|
|
+ if [ "$d" = "$dev" ]
|
|
+ then
|
|
+ f=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$domdev/params")
|
|
+ found=1
|
|
+ break 2
|
|
+ fi
|
|
+ done
|
|
done
|
|
- done
|
|
|
|
- if [ ! "$found" ]
|
|
- then
|
|
- # This loopback device is in use by someone else, so skip it.
|
|
- log debug "Loopback sharing check skips device $dev."
|
|
- continue
|
|
+ if [ ! "$found" ]
|
|
+ then
|
|
+ # This loopback device is in use by someone else, so skip it.
|
|
+ log debug "Loopback sharing check skips device $dev."
|
|
+ continue
|
|
+ fi
|
|
fi
|
|
- fi
|
|
|
|
- # Canonicalise the filename for the comparison.
|
|
+ # Canonicalise the filename for the comparison.
|
|
|
|
- # I have seen this readlink fails because the filename given by
|
|
- # losetup is only the basename. This cannot happen when the loop
|
|
- # device is set up through this script, because file is
|
|
- # canonicalised above, but it may happen when loop devices are set
|
|
- # up some other way. This readlink may also conceivably fail if
|
|
- # the file backing this loop device has been removed.
|
|
+ # I have seen this readlink fails because the filename given by
|
|
+ # losetup is only the basename. This cannot happen when the loop
|
|
+ # device is set up through this script, because file is
|
|
+ # canonicalised above, but it may happen when loop devices are set
|
|
+ # up some other way. This readlink may also conceivably fail if
|
|
+ # the file backing this loop device has been removed.
|
|
|
|
- # For maximum safety, in the case that $f does not resolve, we
|
|
- # assume that $file and $f are in the same directory.
|
|
+ # For maximum safety, in the case that $f does not resolve, we
|
|
+ # assume that $file and $f are in the same directory.
|
|
|
|
- # If you create a loopback filesystem, remove it and continue to
|
|
- # run on it, and then create another file with the same name, then
|
|
- # this check will block that -- don't do that.
|
|
+ # If you create a loopback filesystem, remove it and continue to
|
|
+ # run on it, and then create another file with the same name, then
|
|
+ # this check will block that -- don't do that.
|
|
|
|
- # If you create loop devices through some other mechanism, use
|
|
- # relative filenames, and then use the same filename through this
|
|
- # script, then this check will block that -- don't do that either.
|
|
+ # If you create loop devices through some other mechanism, use
|
|
+ # relative filenames, and then use the same filename through this
|
|
+ # script, then this check will block that -- don't do that either.
|
|
|
|
- f=$(readlink -f "$f" || echo $(dirname "$file")/$(basename "$f"))
|
|
+ f=$(readlink -f "$f" || echo $(dirname "$file")/$(basename "$f"))
|
|
|
|
|
|
- if [ "$f" = "$file" ]
|
|
- then
|
|
- check_file_sharing "$file" "$dev" "$mode"
|
|
- fi
|
|
- else
|
|
- # $dev is not in use, so we'll remember it for use later; we want
|
|
- # to finish the sharing check first.
|
|
+ if [ "$f" = "$file" ]
|
|
+ then
|
|
+ check_file_sharing "$file" "$dev" "$mode"
|
|
+ fi
|
|
+ else
|
|
+ # $dev is not in use, so we'll remember it for use later; we want
|
|
+ # to finish the sharing check first.
|
|
|
|
- if [ "$loopdev" = '' ]
|
|
- then
|
|
- loopdev="$dev"
|
|
+ if [ "$loopdev" = '' ]
|
|
+ then
|
|
+ loopdev="$dev"
|
|
+ fi
|
|
fi
|
|
+ done
|
|
+
|
|
+ if [ "$loopdev" = '' ]
|
|
+ then
|
|
+ release_lock "block"
|
|
+ fatal 'Failed to find an unused loop device'
|
|
fi
|
|
+
|
|
+ losetup "$loopdev" "$file" && losetup_failure="" && break
|
|
done
|
|
|
|
- if [ "$loopdev" = '' ]
|
|
+ if [ "$losetup_failure" ]
|
|
then
|
|
- release_lock "block"
|
|
- fatal 'Failed to find an unused loop device'
|
|
+ fatal 'losetup $loopdev $file'
|
|
fi
|
|
|
|
- if LANG=C losetup -h 2>&1 | grep read-only >/dev/null
|
|
- then
|
|
- roflag="-$mode"; roflag="${roflag#-w}"; roflag="${roflag#-!}"
|
|
- else
|
|
- roflag=''
|
|
- fi
|
|
- do_or_die losetup $roflag "$loopdev" "$file"
|
|
xenstore_write "$XENBUS_PATH/node" "$loopdev"
|
|
write_dev "$loopdev"
|
|
release_lock "block"
|
|
@@ -364,8 +368,18 @@ mount it read-write in a guest domain."
|
|
|
|
file)
|
|
node=$(xenstore_read "$XENBUS_PATH/node")
|
|
- losetup -d "$node"
|
|
- exit 0
|
|
+
|
|
+ #In case the loopback is temporarily blocked, retry the losetup -d.
|
|
+ for i in 1 2 3 4 5
|
|
+ do
|
|
+ if losetup -d "$node"
|
|
+ then
|
|
+ exit 0
|
|
+ fi
|
|
+ sleep 1
|
|
+ done
|
|
+ log err "losetup -d $node failed."
|
|
+ exit 1
|
|
;;
|
|
|
|
"")
|