From 80bad981f884d1b08b8ec038511ddffdb060d60c Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Fri, 26 Feb 2016 10:53:21 +0100 Subject: [PATCH 5/8] libxl: properly use vdev vs local device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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é --- Cc: Ian Jackson Cc: Stefano Stabellini Cc: Ian Campbell Cc: Wei Liu --- 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 069d5bd..cbe1608 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3024,7 +3024,7 @@ static char * libxl__alloc_vdev(libxl__gc *gc, void *get_vdev_user, libxl__sprintf(gc, "%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; } @@ -3125,7 +3125,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; @@ -3139,9 +3139,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 qdisk %s", dev); - rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &device); if (rc < 0) goto out; @@ -3150,8 +3147,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 4b51ded..82e86c0 100644 --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -434,6 +434,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<= 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.5.4 (Apple Git-61)