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>
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,