]> xenbits.xensource.com Git - xen.git/commitdiff
libxl: make libxl_cdrom_insert async.
authorIan Campbell <ian.campbell@citrix.com>
Thu, 26 Jul 2012 14:58:18 +0000 (15:58 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Thu, 26 Jul 2012 14:58:18 +0000 (15:58 +0100)
This functionality is a bit of a mess and several configurations are
not properly supported.

The protocol for changing is basically to change the params node in
the disk xenstore backend. There is no interlock or error reporting in
this protocol. Completely removing the device and recreating it is not
necessary nor expected. For reference the equivalent xend code is
tools/python/xen/xend/server/blkif.py::BlkifController::reconfigureDevice().

Device model stub domains are not supported. There appears to be no
way correctly to do a media change on the emulated device while also
changing the stub domains PV backend to point to the new
backend. Reworking this is a significant task deferred until 4.3. xend
(via the equivalent "xm block-configure" functionality) also does not
support media change for stub domains (confirmed by code inspection
and experiment). Unlike xend this version errors out instead of
silently not achieving anything in this case.

There is no support for qemu-xen (upstream) media change. I expect
this is supported on the qemu side and required QMP plumbing on the
libxl side. Again this is deferred until 4.3.

On the plus side the current implementation is trivially "asynchronous".

Adds a libxl__xs_writev_atonce helper to write a key-value list to
xenstore in one go.

Tested with Windows 7.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Campbell <ian.campbell@citrix.com>
tools/libxl/libxl.c
tools/libxl/libxl.h
tools/libxl/libxl_internal.h
tools/libxl/libxl_xshelp.c
tools/libxl/xl_cmdimpl.c

index 559b45e586ab6ef1457cdc6e047a4df7e71c21b2..092a87d2a0cf94c22adae44efb03939a499e5617 100644 (file)
@@ -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
index c730ac522c6fdf009b7893fafb60c429bd83af34..6f659386eed0065374091c1a955eea8aaf38f055 100644 (file)
@@ -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);
index 4938510ec02b619db8c5d9e7e63bea35dd623331..fc71eb4ec8c48ff3b3366eb3df6cfbea7d8ebed2 100644 (file)
@@ -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.
index 855ac8561185968e86cde9e45bef8ebc3ed27825..0fedf8fac09bcd0c835b8e764e15bf737ec82365 100644 (file)
@@ -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, ...)
 {
index 9912200def9d14c39e4ed665d2cf4bc5bc5a408f..e7e4016e371b984dfcd2f547a8854e7645425137 100644 (file)
@@ -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);