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....@citrix.com> --- Cc: Ian Jackson <ian.jack...@eu.citrix.com> Cc: Stefano Stabellini <stefano.stabell...@eu.citrix.com> Cc: Ian Campbell <ian.campb...@citrix.com> Cc: Wei Liu <wei.l...@citrix.com> --- 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 6d719d7..d55c699 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3071,7 +3071,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; } @@ -3137,7 +3137,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; @@ -3151,9 +3151,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; @@ -3162,8 +3159,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 8bb5e93..f5b8bf6 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 1a3fa35..4d1c51f 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 7e6d7b9..8073aec 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.5.4 (Apple Git-61) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel