[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Added device-sharing checks for loopback-mounted files. The existing
# HG changeset patch # User emellor@xxxxxxxxxxxxxxxxxxxxxx # Node ID c08cfaf353c60781f9b7baa5a8d91dfda6eca880 # Parent cfcf9212a90bb01e5f343a3407b0d32d07ab45a3 Added device-sharing checks for loopback-mounted files. The existing check_sharing functions have been rejigged slightly so that the file-specific stuff can share the code therein. This separates the actual test from the generation of the error message, and introduces the canonicalise_mode function. This also restores the broken teardown functionality for file: devices -- the writing of XENBUS_PATH/node had been removed, but this is required for file device teardown. Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx> diff -r cfcf9212a90b -r c08cfaf353c6 tools/examples/block --- a/tools/examples/block Sun Nov 27 00:10:14 2005 +++ b/tools/examples/block Sun Nov 27 00:56:34 2005 @@ -1,4 +1,6 @@ #!/bin/sh + +set -x dir=$(dirname "$0") . "$dir/block-common.sh" @@ -17,8 +19,24 @@ } +canonicalise_mode() +{ + local mode="$1" + + if ! expr index "$mode" 'w' >/dev/null + then + echo 'ro' + elif ! expr index "$mode" '!' >/dev/null + then + echo 'rw' + else + echo 'no' + fi +} + + ## -# check_sharing device device_major_minor writable +# check_sharing device device_major_minor mode # # Check whether the device requested is already in use. To use the device in # read-only mode, it may be in use in read-only mode, but may not be in use in @@ -27,13 +45,13 @@ # check_sharing() { - local dev="$1" - local devmm="$2" - local writable="$3" + local mode="$2" + + local devmm=$(device_major_minor "$dev") local file - if [ "$writable" ] + if [ "$mode" == 'rw' ] then toskip="^$" else @@ -48,18 +66,8 @@ if [ "$d" == "$devmm" ] then - if [ "$writable" ] - then - m1="" - m2="" - else - m1="read-write " - m2="read-only " - fi - - ebusy \ -"Device $dev is mounted ${m1}in the privileged domain, -and so cannot be mounted ${m2}by a guest." + echo 'local' + return fi fi done @@ -71,73 +79,182 @@ local d=$(cat "$file") if [ "$d" == "$devmm" ] then - if [ "$writable" ] - then - ebusy \ -"Device $dev is already mounted in a guest domain, and so -cannot be mounted read-write now." + if [ "$mode" == 'rw' ] + then + echo 'guest' + return else local m=$(cat "${file/physical_device/mode}") if expr index "$m" 'w' >/dev/null then - ebusy \ -"Device $dev is already mounted read-write in a guest domain, -and so cannot be mounted read-only again." + echo 'guest' + return fi fi fi fi done + + echo 'ok' } check_device_sharing() { local dev="$1" - local devmm=$(device_major_minor "$dev") - local mode=$(xenstore_read "$XENBUS_PATH/mode") - - if ! expr index "$mode" 'w' >/dev/null - then - # No w implies read-only use; sharing with writers must be prevented. - check_sharing "$dev" "$devmm" "" - elif ! expr index "$mode" '!' >/dev/null - then - # No exclamation mark implies all sharing must be prevented. - check_sharing "$dev" "$devmm" 1 - fi -} - - -t=$(xenstore_read_default "$XENBUS_PATH/type" "MISSING") - -case "$command" in + local mode=$(canonicalise_mode "$2") + local result + + if [ "$mode" == 'no' ] + then + return 0 + fi + + result=$(check_sharing "$dev" "$mode") + + if [ "$result" != 'ok' ] + then + do_ebusy "Device $dev is mounted " "$mode" "$result" + fi +} + + +check_file_sharing() +{ + local file="$1" + local dev="$2" + local mode="$3" + + result=$(check_sharing "$dev" "$mode") + + if [ "$result" != 'ok' ] + then + do_ebusy "File $file is loopback-mounted through $dev, +which is mounted " "$mode" "$result" + fi +} + + +do_ebusy() +{ + local prefix="$1" + local mode="$2" + local result="$3" + + if [ "$result" == 'guest' ] + then + dom='a guest ' + when='now' + else + dom='the privileged ' + when='by a guest' + fi + + if [ "$mode" == 'rw' ] + then + m1='' + m2='' + else + m1='read-write ' + m2='read-only ' + fi + + ebusy \ +"${prefix}${m1}in ${dom}domain, +and so cannot be mounted ${m2}${when}." +} + + +t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING') + +case "$command" in add) - phys=$(xenstore_read_default "$XENBUS_PATH/physical-device" "MISSING") - if [ "$phys" != "MISSING" ] + phys=$(xenstore_read_default "$XENBUS_PATH/physical-device" 'MISSING') + if [ "$phys" != 'MISSING' ] then # Depending upon the hotplug configuration, it is possible for this # script to be called twice, so just bail. exit 0 fi + p=$(xenstore_read "$XENBUS_PATH/params") + mode=$(xenstore_read "$XENBUS_PATH/mode") + case $t in phy) dev=$(expand_dev $p) - check_device_sharing "$dev" + check_device_sharing "$dev" "$mode" write_dev "$dev" exit 0 ;; file) - for dev in /dev/loop* ; do - if losetup $dev $p; then - write_dev "$dev" - exit 0 - fi - done - exit 1 + # Canonicalise the file, for sharing check comparison, and the mode + # for ease of use here. + file=$(readlink -f "$p") + mode=$(canonicalise_mode "$mode") + + if [ "$mode" == 'rw' ] && ! stat "$file" -c %A | grep w >&/dev/null + then + ebusy \ +"File $file is read-only, and so I will not +mount it read-write in a guest domain." + fi + + loopdev='' + + for dev in /dev/loop* + do + if [ ! -b "$dev" ] + then + continue + fi + + f=$(losetup "$dev" 2>/dev/null) || f='()' + f=$(echo "$f" | sed -e 's/.*(\(.*\)).*/\1/g') + + log err "$file $f $dev" + + if [ "$f" ] + then + # $dev is in use. Check sharing. + + if [ "$mode" == 'no' ] + then + continue + fi + + f=$(readlink -f "$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 [ "$loopdev" == '' ] + then + loopdev="$dev" + fi + fi + done + + if [ "$loopdev" == '' ] + then + fatal 'Failed to find an unused loop device' + fi + + if losetup "$loopdev" "$file" + then + xenstore_write "$XENBUS_PATH/node" "$loopdev" + write_dev "$loopdev" + exit 0 + else + fatal "losetup $loopdev $file failed" + fi ;; esac ;; @@ -150,7 +267,7 @@ file) node=$(xenstore_read "$XENBUS_PATH/node") - losetup -d $node + losetup -d "$node" exit 0 ;; esac _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |