diff options
author | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-05-29 16:36:50 +0100 |
---|---|---|
committer | Stefano Stabellini <stefano.stabellini@eu.citrix.com> | 2012-05-29 16:36:50 +0100 |
commit | 38c65b140ef885c9868a5ff8f5963f7aa4b5e997 (patch) | |
tree | c6d4ec274d1b6c1d6a5f8f66de1130b148233c5e /tools/libxl/libxl_linux.c | |
parent | da84f22a257fe46b60c5a9986255bf176bb4695b (diff) | |
download | xen-38c65b140ef885c9868a5ff8f5963f7aa4b5e997.tar.gz xen-38c65b140ef885c9868a5ff8f5963f7aa4b5e997.tar.bz2 xen-38c65b140ef885c9868a5ff8f5963f7aa4b5e997.zip |
libxl: introduce libxl__alloc_vdev
Introduce libxl__alloc_vdev: find a spare virtual block device in the
domain passed as argument.
Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/libxl/libxl_linux.c')
-rw-r--r-- | tools/libxl/libxl_linux.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c index 925248b8ff..0169b2ff0b 100644 --- a/tools/libxl/libxl_linux.c +++ b/tools/libxl/libxl_linux.c @@ -25,3 +25,55 @@ int libxl__try_phy_backend(mode_t st_mode) return 1; } + +#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; +} |