aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/libxl/libxl.c93
-rw-r--r--tools/libxl/libxl.h3
-rw-r--r--tools/libxl/libxl_internal.h5
-rw-r--r--tools/libxl/libxl_xshelp.c25
-rw-r--r--tools/libxl/xl_cmdimpl.c4
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);