Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:12.2:ARM
xen
xl-create-pv-with-qcow2-img.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xl-create-pv-with-qcow2-img.patch of Package xen
Fix problem that xl cannot create PV guest with qcow/qcow2 disk image by using pygrub. Have discussed with upstream, but the work is something related to both qemu and xen upstream, making it accepted may take a long time. Submit first and will be replaced with upstream patches if it is accepted. http://xen.1045712.n5.nabble.com/xl-create-PV-guest-with-qcow-qcow2-disk-images-fail-td4909399.html Signed-off-by: Chunyan Liu <cyliu@suse.com> Index: xen-4.1.2-testing/tools/libxl/libxl.c =================================================================== --- xen-4.1.2-testing.orig/tools/libxl/libxl.c +++ xen-4.1.2-testing/tools/libxl/libxl.c @@ -1071,11 +1071,131 @@ int libxl_device_disk_del(libxl_ctx *ctx return rc; } +static int libxl_forkexec(libxl_ctx *ctx, char *arg0, char **args) +{ + pid_t pid; + int status; + + pid = libxl_fork(ctx); + if (pid < 0) + return -1; + else if (pid == 0){ + libxl__exec(-1, -1, -1, arg0, args); + exit(127); + } + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) { + status = -1; + break; + } + } + + return status; +} + +#ifdef __linux__ +static int is_nbd_used(int minor) +{ + FILE *proc; + int NBDMAJOR = 43; + char buf[BUFSIZ]; + int find = 0; + + proc = fopen("/proc/partitions", "r"); + if (proc != NULL) { + while (fgets(buf, sizeof(buf), proc)) { + int m, n; + unsigned long long sz; + char name[16]; + char *pname = name; + char *end; + + if (sscanf(buf, " %d %d %llu %128[^\n ]", + &m, &n, &sz, name) != 4) + continue; + if (m != NBDMAJOR) + continue; + if (strncmp(name, "nbd", 3)) + continue; + pname += 3; + n = strtol(pname, &end, 10); + if (end && end != pname && *end == '\0' && n == minor) { + find = 1; + break; + } + } + fclose(proc); + } + + return find; +} + +static int find_free_nbd_minor(void) +{ + int i; + int nbds_max = 16; + int minor = -1; + + for (i = 0; i < nbds_max; i++) { + if (!is_nbd_used(i)) { + minor = i; + break; + } + } + + return minor; +} + +static char * nbd_mount_disk(libxl__gc *gc, libxl_device_disk *disk) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + int n = -1; + char *nbd_dev = NULL; + char *args[] = {"qemu-nbd","-c",NULL,NULL,NULL}; + char *ret = NULL; + + n = find_free_nbd_minor(); + if (n >= 0) { + int i = 0; + int retry = 3; + + nbd_dev = libxl__sprintf(gc, "/dev/nbd%d", n); + args[2] = libxl__sprintf(gc, "%s", nbd_dev); + args[3] = libxl__sprintf(gc, "%s", disk->pdev_path); + libxl_forkexec(ctx, args[0], args); + + /*check connection*/ + while (i < retry) { + if (is_nbd_used(n)) { + ret = strdup(nbd_dev); + break; + } + i++; + sleep(1); + } + } + + return ret; +} + +static int nbd_unmount_disk(libxl__gc *gc, char *diskpath) { + libxl_ctx *ctx = libxl__gc_owner(gc); + char *args[] = {"qemu-nbd","-d",NULL,NULL}; + + args[2] = libxl__sprintf(gc, "%s", diskpath); + if (libxl_forkexec(ctx, args[0], args)) + return 0; + else + return ERROR_FAIL; +} +#endif + char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk) { libxl__gc gc = LIBXL_INIT_GC(ctx); const char *dev = NULL; char *ret = NULL; + char *mdev = NULL; switch (disk->backend) { case DISK_BACKEND_PHY: @@ -1117,8 +1237,17 @@ char * libxl_device_disk_local_attach(li } case DISK_BACKEND_QDISK: if (disk->format != DISK_FORMAT_RAW) { - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot locally attach a qdisk " - "image if the format is not raw"); +#ifdef __linux__ + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "attaching a non-raw qdisk image to domain 0\n"); + mdev = nbd_mount_disk(&gc, disk); + if (mdev) + dev = mdev; + else + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "fail to mount image with qemu-nbd"); +#else + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot locally" + " attach a qdisk image if the format is not raw"); +#endif break; } LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "attaching qdisk %s to domain 0\n", @@ -1134,18 +1263,37 @@ char * libxl_device_disk_local_attach(li if (dev != NULL) ret = strdup(dev); + free(mdev); libxl__free_all(&gc); return ret; } -int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk) +int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk, char *diskpath) { - /* Nothing to do for PHYSTYPE_PHY. */ +#ifdef __linux__ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int ret; + + switch (disk->backend) { + case DISK_BACKEND_QDISK: + if (disk->format != DISK_FORMAT_RAW) { + LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Locally detach a non-raw " + "qdisk image"); + ret = nbd_unmount_disk(&gc, diskpath); + return ret; + } + default: + /* Nothing to do for PHYSTYPE_PHY. */ - /* - * For other device types assume that the blktap2 process is - * needed by the soon to be started domain and do nothing. - */ + /* + * For other device types assume that the blktap2 process is + * needed by the soon to be started domain and do nothing. + */ + break; + } + + libxl__free_all(&gc); +#endif return 0; } Index: xen-4.1.2-testing/tools/libxl/libxl.h =================================================================== --- xen-4.1.2-testing.orig/tools/libxl/libxl.h +++ xen-4.1.2-testing/tools/libxl/libxl.h @@ -429,7 +429,7 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u * Make a disk available in this domain. Returns path to a device. */ char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk); -int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk); +int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk, char *diskpath); int libxl_device_nic_init(libxl_device_nic *nic, int dev_num); int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic); Index: xen-4.1.2-testing/tools/libxl/libxl_bootloader.c =================================================================== --- xen-4.1.2-testing.orig/tools/libxl/libxl_bootloader.c +++ xen-4.1.2-testing/tools/libxl/libxl_bootloader.c @@ -419,7 +419,7 @@ int libxl_run_bootloader(libxl_ctx *ctx, rc = 0; out_close: if (diskpath) { - libxl_device_disk_local_detach(ctx, disk); + libxl_device_disk_local_detach(ctx, disk, diskpath); free(diskpath); } if (fifo_fd > -1)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor