diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/libxl/libxl.c | 93 | ||||
-rw-r--r-- | tools/libxl/libxl.h | 3 | ||||
-rw-r--r-- | tools/libxl/libxl_internal.h | 5 | ||||
-rw-r--r-- | tools/libxl/libxl_xshelp.c | 25 | ||||
-rw-r--r-- | tools/libxl/xl_cmdimpl.c | 4 |
5 files changed, 111 insertions, 19 deletions
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 559b45e586..092a87d2a0 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2076,17 +2076,49 @@ int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, return 0; } -int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) +int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, + const libxl_asyncop_how *ao_how) { - int num, i; - uint32_t stubdomid; - libxl_device_disk *disks; - int ret = ERROR_FAIL; + AO_CREATE(ctx, domid, ao_how); + int num = 0, i; + libxl_device_disk *disks = NULL; + int rc, dm_ver; - if (!disk->pdev_path) { - disk->pdev_path = strdup(""); - disk->format = LIBXL_DISK_FORMAT_EMPTY; + libxl__device device; + const char * path; + + flexarray_t *insert = NULL; + + libxl_domain_type type = libxl__domain_type(gc, domid); + if (type == LIBXL_DOMAIN_TYPE_INVALID) { + rc = ERROR_FAIL; + goto out; + } + if (type != LIBXL_DOMAIN_TYPE_HVM) { + LOG(ERROR, "cdrom-insert requires an HVM domain"); + rc = ERROR_INVAL; + goto out; + } + + if (libxl_get_stubdom_id(ctx, domid) != 0) { + LOG(ERROR, "cdrom-insert doesn't work for stub domains"); + rc = ERROR_INVAL; + goto out; + } + + dm_ver = libxl__device_model_version_running(gc, domid); + if (dm_ver == -1) { + LOG(ERROR, "cannot determine device model version"); + rc = ERROR_FAIL; + goto out; + } + if (dm_ver != LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL) { + LOG(ERROR, "cdrom-insert does not work with %s", + libxl_device_model_version_to_string(dm_ver)); + rc = ERROR_INVAL; + goto out; } + disks = libxl_device_disk_list(ctx, domid, &num); for (i = 0; i < num; i++) { if (disks[i].is_cdrom && !strcmp(disk->vdev, disks[i].vdev)) @@ -2095,23 +2127,52 @@ int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk) } if (i == num) { LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Virtual device not found"); + rc = ERROR_FAIL; goto out; } - ret = 0; + rc = libxl__device_disk_setdefault(gc, disk); + if (rc) goto out; - libxl_device_disk_remove(ctx, domid, disks + i, 0); - libxl_device_disk_add(ctx, domid, disk); - stubdomid = libxl_get_stubdom_id(ctx, domid); - if (stubdomid) { - libxl_device_disk_remove(ctx, stubdomid, disks + i, 0); - libxl_device_disk_add(ctx, stubdomid, disk); + if (!disk->pdev_path) { + disk->pdev_path = libxl__strdup(NOGC, ""); + disk->format = LIBXL_DISK_FORMAT_EMPTY; } + + rc = libxl__device_from_disk(gc, domid, disk, &device); + if (rc) goto out; + path = libxl__device_backend_path(gc, &device); + + insert = flexarray_make(4, 1); + + flexarray_append_pair(insert, "type", + libxl__device_disk_string_of_backend(disk->backend)); + if (disk->format != LIBXL_DISK_FORMAT_EMPTY) + flexarray_append_pair(insert, "params", + GCSPRINTF("%s:%s", + libxl__device_disk_string_of_format(disk->format), + disk->pdev_path)); + else + flexarray_append_pair(insert, "params", ""); + + rc = libxl__xs_writev_atonce(gc, path, + libxl__xs_kvs_of_flexarray(gc, insert, insert->count)); + if (rc) goto out; + + /* success, no actual async */ + libxl__ao_complete(egc, ao, 0); + + rc = 0; + out: for (i = 0; i < num; i++) libxl_device_disk_dispose(&disks[i]); free(disks); - return ret; + + if (insert) flexarray_free(insert); + + if (rc) return AO_ABORT(rc); + return AO_INPROGRESS; } /* libxl__alloc_vdev only works on the local domain, that is the domain diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index c730ac522c..6f659386ee 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -691,7 +691,8 @@ int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid, * Insert a CD-ROM device. A device corresponding to disk must already * be attached to the guest. */ -int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk); +int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk, + const libxl_asyncop_how *ao_how); /* Network Interfaces */ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic); diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index 4938510ec0..fc71eb4ec8 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -498,8 +498,13 @@ _hidden int libxl__remove_file_or_directory(libxl__gc *gc, const char *path); _hidden char **libxl__xs_kvs_of_flexarray(libxl__gc *gc, flexarray_t *array, int length); +/* treats kvs as pairs of keys and values and writes each to dir. */ _hidden int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t, const char *dir, char **kvs); +/* _atonce creates a transaction and writes all keys at once */ +_hidden int libxl__xs_writev_atonce(libxl__gc *gc, + const char *dir, char **kvs); + _hidden int libxl__xs_write(libxl__gc *gc, xs_transaction_t t, const char *path, const char *fmt, ...) PRINTF_ATTRIBUTE(4, 5); /* Each fn returns 0 on success. diff --git a/tools/libxl/libxl_xshelp.c b/tools/libxl/libxl_xshelp.c index 855ac85611..0fedf8fac0 100644 --- a/tools/libxl/libxl_xshelp.c +++ b/tools/libxl/libxl_xshelp.c @@ -61,6 +61,31 @@ int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t, return 0; } +int libxl__xs_writev_atonce(libxl__gc *gc, + const char *dir, char *kvs[]) +{ + int rc; + xs_transaction_t t = XBT_NULL; + + for (;;) { + rc = libxl__xs_transaction_start(gc, &t); + if (rc) goto out; + + rc = libxl__xs_writev(gc, t, dir, kvs); + if (rc) goto out; + + rc = libxl__xs_transaction_commit(gc, &t); + if (!rc) break; + if (rc<0) goto out; + } + +out: + libxl__xs_transaction_abort(gc, &t); + + return rc; + +} + int libxl__xs_write(libxl__gc *gc, xs_transaction_t t, const char *path, const char *fmt, ...) { diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 9912200def..e7e4016e37 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -2004,7 +2004,7 @@ start: case LIBXL_EVENT_TYPE_DISK_EJECT: /* XXX what is this for? */ - libxl_cdrom_insert(ctx, domid, &event->u.disk_eject.disk); + libxl_cdrom_insert(ctx, domid, &event->u.disk_eject.disk, NULL); break; default:; @@ -2225,7 +2225,7 @@ static void cd_insert(const char *dom, const char *virtdev, char *phys) disk.backend_domid = 0; - libxl_cdrom_insert(ctx, domid, &disk); + libxl_cdrom_insert(ctx, domid, &disk, NULL); libxl_device_disk_dispose(&disk); free(buf); |