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

[Xen-devel] [PATCH 2/2] libxl: Properly parse vbd names



# HG changeset patch
# User Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
# Date 1265298284 0
# Node ID 126cd870c07057abfcf40bf1e049c574e40d1d5f
# Parent  5d65c6b5a32e712dea1eea182acb2ddc1e0c7a43
libxl: Properly parse vbd names

Implement proper parsing of vbd names, as documented here:
  From: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>
  Subject: Xen vbd numbering
  Date: Wed, 03 Feb 2010 16:51:47 GMT
  Message-ID: <19305.43376.600816.817077@xxxxxxxxxxxxxxxxxxxxxxxx>
  http://lists.xensource.com/archives/html/xen-devel/2010-02/msg00183.html

Previously, xvd and numerical specification were broken in libxl.

Signed-off-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>

diff -r 5d65c6b5a32e -r 126cd870c070 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Thu Feb 04 14:40:51 2010 +0000
+++ b/tools/libxl/libxl_device.c        Thu Feb 04 15:44:44 2010 +0000
@@ -139,40 +139,88 @@
     return 0;
 }
 
-int device_virtdisk_major_minor(char *virtpath, int *major, int *minor)
-{
-    if (strstr(virtpath, "sd") == virtpath) {
-        return -1;
-    } else if (strstr(virtpath, "xvd") == virtpath) {
-        return -1;
-    } else if (strstr(virtpath, "hd") == virtpath) {
-        char letter, letter2;
+static int device_virtdisk_matches(const char *virtpath, const char *devtype,
+                                   int *index_r, int max_index,
+                                   int *partition_r, int max_partition) {
+    const char *p;
+    char *ep;
+    int tl, c;
+    long pl;
 
-        *major = 0; *minor = 0;
-        letter = virtpath[2];
-        if (letter < 'a' || letter > 't')
-            return -1;
-        letter2 = virtpath[3];
+    tl = strlen(devtype);
+    if (memcmp(virtpath, devtype, tl))
+        return 0;
 
-        *major = letter - 'a';
-        *minor = atoi(virtpath + 3);
+    /* We decode the drive letter as if it were in base 52
+     * with digits a-zA-Z, more or less */
+    *index_r = -1;
+    p = virtpath + tl;
+    for (;;) {
+        c = *p++;
+        if (c >= 'a' && c <= 'z') {
+            c -= 'a';
+        } else {
+            --p;
+            break;
+        }
+        (*index_r)++;
+        (*index_r) *= 26;
+        (*index_r) += c;
+
+        if (*index_r > max_index)
+            return 0;
+    }
+
+    if (!*p) {
+        *partition_r = 0;
+        return 1;
+    }
+
+    if (*p=='0')
+        return 0; /* leading zeroes not permitted in partition number */
+
+    pl = strtoul(p, &ep, 10);
+    if (pl > max_partition || *ep)
         return 0;
-    } else {
-        return -1;
-    }
+
+    *partition_r = pl;
+    return 1;
 }
 
 int device_disk_dev_number(char *virtpath)
 {
-    int majors_table[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 };
-    int major, minor;
+    int disk, partition;
+    char *ep;
+    unsigned long ul;
+    int chrused;
 
-    if (strstr(virtpath, "hd") == virtpath) {
-        if (device_virtdisk_major_minor(virtpath, &major, &minor))
-            return -1;
-        return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor;
-    } else if (strstr(virtpath, "xvd") == virtpath) {
-        return (202 << 8) + ((virtpath[3] - 'a') << 4) + (virtpath[4] ? 
(virtpath[4] - '0') : 0);
+    chrused = -1;
+    if ((sscanf(virtpath, "d%ip%i%n", &disk, &partition, &chrused)  >= 2
+         && chrused == strlen(virtpath) && disk < (1<<20) && partition < 256)
+        ||
+        device_virtdisk_matches(virtpath, "xvd",
+                                &disk, (1<<20)-1,
+                                &partition, 255)) {
+        if (disk <= 15 && partition <= 15)
+            return (202 << 8) | (disk << 4) | partition;
+        else
+            return (1 << 28) | (disk << 8) | partition;
+    }
+
+    errno = 0;
+    ul = strtoul(virtpath, &ep, 0);
+    if (!errno && !*ep && ul <= INT_MAX)
+        return ul;
+
+    if (device_virtdisk_matches(virtpath, "hd",
+                                &disk, 3,
+                                &partition, 63)) {
+        return ((disk<2 ? 3 : 22) << 8) | ((disk & 1) << 6) | partition;
+    }
+    if (device_virtdisk_matches(virtpath, "sd",
+                                &disk, 15,
+                                &partition, 15)) {
+        return (8 << 8) | (disk << 4) | partition;
     }
     return -1;
 }
diff -r 5d65c6b5a32e -r 126cd870c070 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Thu Feb 04 14:40:51 2010 +0000
+++ b/tools/libxl/libxl_internal.h      Thu Feb 04 15:44:44 2010 +0000
@@ -139,7 +139,6 @@
 char *device_disk_string_of_phystype(libxl_disk_phystype phystype);
 
 int device_physdisk_major_minor(char *physpath, int *major, int *minor);
-int device_virtdisk_major_minor(char *virtpath, int *major, int *minor);
 int device_disk_dev_number(char *virtpath);
 
 int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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