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] Fix the block-sharing check for physical devices by usin

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix the block-sharing check for physical devices by using a lock to serialise
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Sat, 03 Dec 2005 12:04:10 +0000
Delivery-date: Sat, 03 Dec 2005 12:04:56 +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 485871ff1d393fd2ef0281d97032a2af056fb885
# Parent  df011cae33e988efc3b6d784ce33b4521553edbe
Fix the block-sharing check for physical devices by using a lock to serialise
the check, reading from the store rather than /sys, and checking whether the
VM for apparently-conflicting uses is actually the same (i.e. this is a
migration or a reboot in progress).

This fixes recent failures in 12_block_attach_shared_domU and recloses bug #331.

This fix includes particularly skanky path slicing inside xenbus_probe, which
it would be nice to remove very soon.

The loopback device check still suffers from the problem that filenames over
64 characters long are truncated.

Signed-off-by: Ewan Mellor <ewan@xxxxxxxxxxxxx>

diff -r df011cae33e9 -r 485871ff1d39 
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Dec  2 
15:39:13 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c    Fri Dec  2 
15:48:44 2005
@@ -59,6 +59,8 @@
 
 #define streq(a, b) (strcmp((a), (b)) == 0)
 
+static char *kasprintf(const char *fmt, ...);
+
 static struct notifier_block *xenstore_chain;
 
 /* If something in array of ids matches this device, return it. */
@@ -226,8 +228,11 @@
                                  int num_envp, char *buffer, int buffer_size)
 {
        struct xenbus_device *xdev;
+       struct xenbus_driver *drv = NULL;
        int i = 0;
        int length = 0;
+       char *basepath_end;
+       char *frontend_id;
 
        DPRINTK("");
 
@@ -237,6 +242,9 @@
        xdev = to_xenbus_device(dev);
        if (xdev == NULL)
                return -ENODEV;
+
+       if (dev->driver)
+               drv = to_xenbus_driver(dev->driver);
 
        /* stuff we want to pass to /sbin/hotplug */
        add_hotplug_env_var(envp, num_envp, &i,
@@ -246,6 +254,25 @@
        add_hotplug_env_var(envp, num_envp, &i,
                            buffer, buffer_size, &length,
                            "XENBUS_PATH=%s", xdev->nodename);
+
+       add_hotplug_env_var(envp, num_envp, &i,
+                           buffer, buffer_size, &length,
+                           "XENBUS_BASE_PATH=%s", xdev->nodename);
+
+       basepath_end = strrchr(envp[i - 1], '/');
+       length -= strlen(basepath_end);
+       *basepath_end = '\0';
+       basepath_end = strrchr(envp[i - 1], '/');
+       length -= strlen(basepath_end);
+       *basepath_end = '\0';
+
+       basepath_end++;
+       frontend_id = kmalloc(strlen(basepath_end) + 1, GFP_KERNEL);
+       strcpy(frontend_id, basepath_end);
+       add_hotplug_env_var(envp, num_envp, &i,
+                           buffer, buffer_size, &length,
+                           "XENBUS_FRONTEND_ID=%s", frontend_id);
+       kfree(frontend_id);
 
        /* terminate, set to next free slot, shrink available space */
        envp[i] = NULL;
@@ -254,9 +281,9 @@
        buffer = &buffer[length];
        buffer_size -= length;
 
-       if (dev->driver && to_xenbus_driver(dev->driver)->hotplug)
-               return to_xenbus_driver(dev->driver)->hotplug
-                       (xdev, envp, num_envp, buffer, buffer_size);
+       if (drv && drv->hotplug)
+               return drv->hotplug(xdev, envp, num_envp, buffer,
+                                   buffer_size);
 
        return 0;
 }
diff -r df011cae33e9 -r 485871ff1d39 tools/examples/block
--- a/tools/examples/block      Fri Dec  2 15:39:13 2005
+++ b/tools/examples/block      Fri Dec  2 15:48:44 2005
@@ -89,36 +89,51 @@
     fi
   done
 
-##
-## XXX SMH: the below causes live migration on localhost to fail sometimes
-## since the source domain may still appear to be using a local device. 
-## For now simply comment it out - a proper fix will come in due course. 
-
-#   for file in /sys/devices/xen-backend/*/physical_device
-#   do
-#     if [ -e "$file" ] # Cope with no devices, i.e. the * above did not 
expand.
-#     then
-#       local d=$(cat "$file")
-#       if [ "$d" == "$devmm" ]
-#       then
-#         if [ "$mode" == 'w' ]
-#         then
-#           echo 'guest'
-#           return
-#         else
-#           local m=$(cat "${file/physical_device/mode}")
-
-#           if expr index "$m" 'w' >/dev/null
-#           then
-#             echo 'guest'
-#             return
-#           fi
-#         fi
-#       fi
-#     fi
-#   done
+  for dom in $(xenstore-list "$XENBUS_BASE_PATH")
+  do
+    for dev in $(xenstore-list "$XENBUS_BASE_PATH/$dom")
+    do
+      d=$(xenstore_read_default \
+            "$XENBUS_BASE_PATH/$dom/$dev/physical-device" "")
+
+      if [ "$d" == "$devmm" ]
+      then
+        if [ "$mode" == 'w' ]
+        then
+          if ! same_vm $dom
+          then
+            echo 'guest'
+            return
+          fi
+        else
+          local m=$(xenstore_read "$XENBUS_BASE_PATH/$dom/$dev/mode")
+          m=$(canonicalise_mode "$m")
+
+          if [ "$m" == 'w' ]
+          then
+            if ! same_vm $dom
+            then
+              echo 'guest'
+              return
+            fi
+          fi
+        fi
+      fi
+    done
+  done
 
   echo 'ok'
+}
+
+
+same_vm()
+{
+  local thisdom="$XENBUS_FRONTEND_ID"
+  local otherdom="$1"
+  local thisvm=$(xenstore-read "/local/domain/$thisdom/vm")
+  local othervm=$(xenstore-read "/local/domain/otherdom/vm")
+
+  return [ "$thisvm" == "$othervm" ]
 }
 
 
@@ -200,6 +215,7 @@
     m2='read-only '
   fi
 
+  release_lock "block"
   ebusy \
 "${prefix}${m1}in ${dom}domain,
 and so cannot be mounted ${m2}${when}."
@@ -224,8 +240,10 @@
     case $t in 
       phy)
         dev=$(expand_dev $p)
+        claim_lock "block"
         check_device_sharing "$dev" "$mode"
        write_dev "$dev"
+        release_lock "block"
        exit 0
        ;;
 
@@ -235,68 +253,62 @@
         file=$(readlink -f "$p")
         mode=$(canonicalise_mode "$mode")
 
+        claim_lock "block"
+
         if [ "$mode" == 'w' ] && ! stat "$file" -c %A | grep -q w
         then
+          release_lock "block"
           ebusy \
 "File $file is read-only, and so I will not
 mount it read-write in a guest domain."
         fi
 
-
-       while true
-        do 
-          loopdev=''
-          for dev in /dev/loop*
-          do
-            if [ ! -b "$dev" ]
+        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')
+
+          if [ "$f" ]
+          then
+            # $dev is in use.  Check sharing.
+            if [ "$mode" == '!' ]
             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" ]
+            f=$(readlink -f "$f")
+
+            if [ "$f" == "$file" ]
             then
-              # $dev is in use.  Check sharing.
-              if [ "$mode" == '!' ]
-              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
+              check_file_sharing "$file" "$dev" "$mode"
             fi
-          done
-
-          if [ "$loopdev" == '' ]
-          then
-            fatal 'Failed to find an unused loop device'
+          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
-          if losetup "$loopdev" "$file"
-          then
-           log err "mapped $file using $loopdev"
-            xenstore_write "$XENBUS_PATH/node" "$loopdev"
-            write_dev "$loopdev"
-            exit 0
-          else
-            log err "losetup $loopdev $file failed, retry"
-          fi
-       done
+        done
+
+        if [ "$loopdev" == '' ]
+        then
+          fatal 'Failed to find an unused loop device'
+        fi
+
+        do_or_die losetup "$loopdev" "$file"
+        xenstore_write "$XENBUS_PATH/node" "$loopdev"
+        write_dev "$loopdev"
+        release_lock "block"
+        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] Fix the block-sharing check for physical devices by using a lock to serialise, Xen patchbot -unstable <=