debuggers.hg

changeset 20948:bdce1894c6a7

libxl: Properly parse vbd names

Implement proper parsing of vbd names, as documented here:
From: Ian Jackson <Ian.Jackson@eu.citrix.com>
Subject: Xen vbd numbering
Date: Wed, 03 Feb 2010 16:51:47 GMT
Message-ID: <19305.43376.600816.817077@mariner.uk.xensource.com>
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@eu.citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Feb 05 10:36:17 2010 +0000 (2010-02-05)
parents 503b47f53b53
children a6fac2ba6785
files tools/libxl/libxl_device.c tools/libxl/libxl_internal.h
line diff
     1.1 --- a/tools/libxl/libxl_device.c	Fri Feb 05 10:35:57 2010 +0000
     1.2 +++ b/tools/libxl/libxl_device.c	Fri Feb 05 10:36:17 2010 +0000
     1.3 @@ -139,40 +139,88 @@ int device_physdisk_major_minor(char *ph
     1.4      return 0;
     1.5  }
     1.6  
     1.7 -int device_virtdisk_major_minor(char *virtpath, int *major, int *minor)
     1.8 -{
     1.9 -    if (strstr(virtpath, "sd") == virtpath) {
    1.10 -        return -1;
    1.11 -    } else if (strstr(virtpath, "xvd") == virtpath) {
    1.12 -        return -1;
    1.13 -    } else if (strstr(virtpath, "hd") == virtpath) {
    1.14 -        char letter, letter2;
    1.15 +static int device_virtdisk_matches(const char *virtpath, const char *devtype,
    1.16 +                                   int *index_r, int max_index,
    1.17 +                                   int *partition_r, int max_partition) {
    1.18 +    const char *p;
    1.19 +    char *ep;
    1.20 +    int tl, c;
    1.21 +    long pl;
    1.22 +
    1.23 +    tl = strlen(devtype);
    1.24 +    if (memcmp(virtpath, devtype, tl))
    1.25 +        return 0;
    1.26  
    1.27 -        *major = 0; *minor = 0;
    1.28 -        letter = virtpath[2];
    1.29 -        if (letter < 'a' || letter > 't')
    1.30 -            return -1;
    1.31 -        letter2 = virtpath[3];
    1.32 +    /* We decode the drive letter as if it were in base 52
    1.33 +     * with digits a-zA-Z, more or less */
    1.34 +    *index_r = -1;
    1.35 +    p = virtpath + tl;
    1.36 +    for (;;) {
    1.37 +        c = *p++;
    1.38 +        if (c >= 'a' && c <= 'z') {
    1.39 +            c -= 'a';
    1.40 +        } else {
    1.41 +            --p;
    1.42 +            break;
    1.43 +        }
    1.44 +        (*index_r)++;
    1.45 +        (*index_r) *= 26;
    1.46 +        (*index_r) += c;
    1.47  
    1.48 -        *major = letter - 'a';
    1.49 -        *minor = atoi(virtpath + 3);
    1.50 +        if (*index_r > max_index)
    1.51 +            return 0;
    1.52 +    }
    1.53 +
    1.54 +    if (!*p) {
    1.55 +        *partition_r = 0;
    1.56 +        return 1;
    1.57 +    }
    1.58 +
    1.59 +    if (*p=='0')
    1.60 +        return 0; /* leading zeroes not permitted in partition number */
    1.61 +
    1.62 +    pl = strtoul(p, &ep, 10);
    1.63 +    if (pl > max_partition || *ep)
    1.64          return 0;
    1.65 -    } else {
    1.66 -        return -1;
    1.67 -    }
    1.68 +
    1.69 +    *partition_r = pl;
    1.70 +    return 1;
    1.71  }
    1.72  
    1.73  int device_disk_dev_number(char *virtpath)
    1.74  {
    1.75 -    int majors_table[] = { 3, 22, 33, 34, 56, 57, 88, 89, 90, 91 };
    1.76 -    int major, minor;
    1.77 +    int disk, partition;
    1.78 +    char *ep;
    1.79 +    unsigned long ul;
    1.80 +    int chrused;
    1.81  
    1.82 -    if (strstr(virtpath, "hd") == virtpath) {
    1.83 -        if (device_virtdisk_major_minor(virtpath, &major, &minor))
    1.84 -            return -1;
    1.85 -        return majors_table[major / 2] * 256 + (64 * (major % 2)) + minor;
    1.86 -    } else if (strstr(virtpath, "xvd") == virtpath) {
    1.87 -        return (202 << 8) + ((virtpath[3] - 'a') << 4) + (virtpath[4] ? (virtpath[4] - '0') : 0);
    1.88 +    chrused = -1;
    1.89 +    if ((sscanf(virtpath, "d%ip%i%n", &disk, &partition, &chrused)  >= 2
    1.90 +         && chrused == strlen(virtpath) && disk < (1<<20) && partition < 256)
    1.91 +        ||
    1.92 +        device_virtdisk_matches(virtpath, "xvd",
    1.93 +                                &disk, (1<<20)-1,
    1.94 +                                &partition, 255)) {
    1.95 +        if (disk <= 15 && partition <= 15)
    1.96 +            return (202 << 8) | (disk << 4) | partition;
    1.97 +        else
    1.98 +            return (1 << 28) | (disk << 8) | partition;
    1.99 +    }
   1.100 +
   1.101 +    errno = 0;
   1.102 +    ul = strtoul(virtpath, &ep, 0);
   1.103 +    if (!errno && !*ep && ul <= INT_MAX)
   1.104 +        return ul;
   1.105 +
   1.106 +    if (device_virtdisk_matches(virtpath, "hd",
   1.107 +                                &disk, 3,
   1.108 +                                &partition, 63)) {
   1.109 +        return ((disk<2 ? 3 : 22) << 8) | ((disk & 1) << 6) | partition;
   1.110 +    }
   1.111 +    if (device_virtdisk_matches(virtpath, "sd",
   1.112 +                                &disk, 15,
   1.113 +                                &partition, 15)) {
   1.114 +        return (8 << 8) | (disk << 4) | partition;
   1.115      }
   1.116      return -1;
   1.117  }
     2.1 --- a/tools/libxl/libxl_internal.h	Fri Feb 05 10:35:57 2010 +0000
     2.2 +++ b/tools/libxl/libxl_internal.h	Fri Feb 05 10:36:17 2010 +0000
     2.3 @@ -139,7 +139,6 @@ char *device_disk_backend_type_of_physty
     2.4  char *device_disk_string_of_phystype(libxl_disk_phystype phystype);
     2.5  
     2.6  int device_physdisk_major_minor(char *physpath, int *major, int *minor);
     2.7 -int device_virtdisk_major_minor(char *virtpath, int *major, int *minor);
     2.8  int device_disk_dev_number(char *virtpath);
     2.9  
    2.10  int libxl_device_generic_add(struct libxl_ctx *ctx, libxl_device *device,