[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v3 5/8] libxl: properly use vdev vs local device



The current code in libxl assumed that vdev is equal to local device, but
this is only true for Linux systems. In other OSes the local device can use
a nomenclature completely different from the virtual device one.

Move the current libxl__devid_to_localdev Linux implementation out of the
OS-specific file and rename it to libxl__devid_to_vdev, and then make sure
local_device_attach_cb return the local device in the diskpath field.

Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Acked-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
---
 tools/libxl/libxl.c          | 12 ++++------
 tools/libxl/libxl_device.c   | 57 ++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h |  1 +
 tools/libxl/libxl_linux.c    | 49 +------------------------------------
 4 files changed, 64 insertions(+), 55 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 944f4d1..a2767fa 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2989,7 +2989,7 @@ static char * libxl__alloc_vdev(libxl__gc *gc, void 
*get_vdev_user,
                     GCSPRINTF("%s/device/vbd/%d/backend",
                         dompath, devid)) == NULL) {
             if (errno == ENOENT)
-                return libxl__devid_to_localdev(gc, devid);
+                return libxl__devid_to_vdev(gc, devid);
             else
                 return NULL;
         }
@@ -3126,7 +3126,7 @@ static void local_device_attach_cb(libxl__egc *egc, 
libxl__ao_device *aodev)
 {
     STATE_AO_GC(aodev->ao);
     libxl__disk_local_state *dls = CONTAINER_OF(aodev, *dls, aodev);
-    char *dev = NULL, *be_path = NULL;
+    char *be_path = NULL;
     int rc;
     libxl__device device;
     libxl_device_disk *disk = &dls->disk;
@@ -3140,9 +3140,6 @@ static void local_device_attach_cb(libxl__egc *egc, 
libxl__ao_device *aodev)
         goto out;
     }
 
-    dev = GCSPRINTF("/dev/%s", disk->vdev);
-    LOG(DEBUG, "locally attaching disk %s", dev);
-
     rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &device);
     if (rc < 0)
         goto out;
@@ -3151,8 +3148,9 @@ static void local_device_attach_cb(libxl__egc *egc, 
libxl__ao_device *aodev)
     if (rc < 0)
         goto out;
 
-    if (dev != NULL)
-        dls->diskpath = libxl__strdup(gc, dev);
+    dls->diskpath = GCSPRINTF("/dev/%s",
+                              libxl__devid_to_localdev(gc, device.devid));
+    LOG(DEBUG, "locally attached disk %s", dls->diskpath);
 
     dls->callback(egc, dls, 0);
     return;
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 4ced9b6..9410563 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -436,6 +436,63 @@ int libxl__device_disk_dev_number(const char *virtpath, 
int *pdisk,
     return -1;
 }
 
+static char *encode_disk_name(char *ptr, unsigned int n)
+{
+    if (n >= 26)
+        ptr = encode_disk_name(ptr, n / 26 - 1);
+    *ptr = 'a' + n % 26;
+    return ptr + 1;
+}
+
+char *libxl__devid_to_vdev(libxl__gc *gc, int devid)
+{
+    unsigned int minor;
+    int offset;
+    int nr_parts;
+    char *ptr = NULL;
+/* Same as in Linux.
+ * encode_disk_name might end up using up to 29 bytes (BUFFER_SIZE - 3)
+ * including the trailing \0.
+ *
+ * The code is safe because 26 raised to the power of 28 (that is the
+ * maximum offset that can be stored in the allocated buffer as a
+ * string) is far greater than UINT_MAX on 64 bits so offset cannot be
+ * big enough to exhaust the available bytes in ret. */
+#define BUFFER_SIZE 32
+    char *ret = libxl__zalloc(gc, BUFFER_SIZE);
+
+#define EXT_SHIFT 28
+#define EXTENDED (1<<EXT_SHIFT)
+#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
+#define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
+/* the size of the buffer to store the device name is 32 bytes to match the
+ * equivalent buffer in the Linux kernel code */
+
+    if (!VDEV_IS_EXTENDED(devid)) {
+        minor = devid & 0xff;
+        nr_parts = 16;
+    } else {
+        minor = BLKIF_MINOR_EXT(devid);
+        nr_parts = 256;
+    }
+    offset = minor / nr_parts;
+
+    strcpy(ret, "xvd");
+    ptr = encode_disk_name(ret + 3, offset);
+    if (minor % nr_parts == 0)
+        *ptr = 0;
+    else
+        /* overflow cannot happen, thanks to the upper bound */
+        snprintf(ptr, ret + 32 - ptr,
+                "%d", minor & (nr_parts - 1));
+    return ret;
+#undef BUFFER_SIZE
+#undef EXT_SHIFT
+#undef EXTENDED
+#undef VDEV_IS_EXTENDED
+#undef BLKIF_MINOR_EXT
+}
+
 /* Device AO operations */
 
 void libxl__prepare_ao_device(libxl__ao *ao, libxl__ao_device *aodev)
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 9fde212..6f80917 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1156,6 +1156,7 @@ _hidden int libxl__device_disk_set_backend(libxl__gc*, 
libxl_device_disk*);
 _hidden int libxl__device_physdisk_major_minor(const char *physpath, int 
*major, int *minor);
 _hidden int libxl__device_disk_dev_number(const char *virtpath,
                                           int *pdisk, int *ppartition);
+_hidden char *libxl__devid_to_vdev(libxl__gc *gc, int devid);
 
 _hidden int libxl__device_console_add(libxl__gc *gc, uint32_t domid,
                                       libxl__device_console *console,
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index be4afc6..624f028 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -26,56 +26,9 @@ int libxl__try_phy_backend(mode_t st_mode)
     return 0;
 }
 
-#define EXT_SHIFT 28
-#define EXTENDED (1<<EXT_SHIFT)
-#define VDEV_IS_EXTENDED(dev) ((dev)&(EXTENDED))
-#define BLKIF_MINOR_EXT(dev) ((dev)&(~EXTENDED))
-/* the size of the buffer to store the device name is 32 bytes to match the
- * equivalent buffer in the Linux kernel code */
-#define BUFFER_SIZE 32
-
-/* Same as in Linux.
- * encode_disk_name might end up using up to 29 bytes (BUFFER_SIZE - 3)
- * including the trailing \0.
- *
- * The code is safe because 26 raised to the power of 28 (that is the
- * maximum offset that can be stored in the allocated buffer as a
- * string) is far greater than UINT_MAX on 64 bits so offset cannot be
- * big enough to exhaust the available bytes in ret. */
-static char *encode_disk_name(char *ptr, unsigned int n)
-{
-    if (n >= 26)
-        ptr = encode_disk_name(ptr, n / 26 - 1);
-    *ptr = 'a' + n % 26;
-    return ptr + 1;
-}
-
 char *libxl__devid_to_localdev(libxl__gc *gc, int devid)
 {
-    unsigned int minor;
-    int offset;
-    int nr_parts;
-    char *ptr = NULL;
-    char *ret = libxl__zalloc(gc, BUFFER_SIZE);
-
-    if (!VDEV_IS_EXTENDED(devid)) {
-        minor = devid & 0xff;
-        nr_parts = 16;
-    } else {
-        minor = BLKIF_MINOR_EXT(devid);
-        nr_parts = 256;
-    }
-    offset = minor / nr_parts;
-
-    strcpy(ret, "xvd");
-    ptr = encode_disk_name(ret + 3, offset);
-    if (minor % nr_parts == 0)
-        *ptr = 0;
-    else
-        /* overflow cannot happen, thanks to the upper bound */
-        snprintf(ptr, ret + 32 - ptr,
-                "%d", minor & (nr_parts - 1));
-    return ret;
+    return libxl__devid_to_vdev(gc, devid);
 }
 
 /* Hotplug scripts helpers */
-- 
2.6.4 (Apple Git-63)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.