WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Added device-sharing checks for loopback-mounted files.

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Added device-sharing checks for loopback-mounted files. The existing
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sun, 27 Nov 2005 02:24:08 +0000
Delivery-date: Sun, 27 Nov 2005 02:24:20 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] Added device-sharing checks for loopback-mounted files. The existing, Xen patchbot -unstable <=