[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] libxl: convert libxl_device_disk_add to an async op


  • To: xen-changelog@xxxxxxxxxxxxxxxxxxx
  • From: Xen patchbot-unstable <patchbot@xxxxxxx>
  • Date: Sat, 28 Jul 2012 03:00:18 +0000
  • Delivery-date: Sat, 28 Jul 2012 03:00:29 +0000
  • List-id: "Change log for Mercurial \(receive only\)" <xen-changelog.lists.xen.org>

# HG changeset patch
# User Roger Pau Monne <roger.pau@xxxxxxxxxx>
# Date 1343317650 -3600
# Node ID fe34db0860d312ca1000192aede47c8cf563c16f
# Parent  34b942aae898e0e26b3576d4c63bc16d5e7aeed5
libxl: convert libxl_device_disk_add to an async op

This patch converts libxl_device_disk_add to an ao operation that
waits for device backend to reach state XenbusStateInitWait and then
marks the operation as completed. This is not really useful now, but
will be used by later patches that will launch hotplug scripts after
we reached the desired xenbus state.

As usual, libxl_device_disk_add callers have been modified, and the
internal function libxl__device_disk_add has been used if the call was
inside an already running ao.

Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxx>
Acked-by: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
[ ijc -- drop hunk modifying libxl_cdrom_insert which is not needed after
         25670:3666e9712eaf "libxl: make libxl_cdrom_insert async" ]
Committed-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---


diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/libxl.c       Thu Jul 26 16:47:30 2012 +0100
@@ -1785,16 +1785,18 @@ int libxl__device_from_disk(libxl__gc *g
  * The passed get_vdev function is also in charge of printing
  * the corresponding error message when appropiate.
  */
-static int device_disk_add(libxl__gc *gc, uint32_t domid,
+static void device_disk_add(libxl__egc *egc, uint32_t domid,
                            libxl_device_disk *disk,
+                           libxl__ao_device *aodev,
                            char *get_vdev(libxl__gc *, void *,
                                           xs_transaction_t),
                            void *get_vdev_user)
 {
+    STATE_AO_GC(aodev->ao);
     flexarray_t *front = NULL;
     flexarray_t *back = NULL;
     char *dev;
-    libxl__device device;
+    libxl__device *device;
     int major, minor, rc;
     libxl_ctx *ctx = gc->owner;
     xs_transaction_t t = XBT_NULL;
@@ -1837,7 +1839,8 @@ static int device_disk_add(libxl__gc *gc
             goto out_free;
         }
 
-        rc = libxl__device_from_disk(gc, domid, disk, &device);
+        GCNEW(device);
+        rc = libxl__device_from_disk(gc, domid, disk, device);
         if (rc != 0) {
             LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid or unsupported"
                    " virtual disk identifier %s", disk->vdev);
@@ -1855,7 +1858,7 @@ static int device_disk_add(libxl__gc *gc
                 flexarray_append(back, "params");
                 flexarray_append(back, dev);
 
-                assert(device.backend_kind == LIBXL__DEVICE_KIND_VBD);
+                assert(device->backend_kind == LIBXL__DEVICE_KIND_VBD);
                 break;
             case LIBXL_DISK_BACKEND_TAP:
                 dev = libxl__blktap_devpath(gc, disk->pdev_path, disk->format);
@@ -1876,7 +1879,7 @@ static int device_disk_add(libxl__gc *gc
                 flexarray_append(back, "params");
                 flexarray_append(back, libxl__sprintf(gc, "%s:%s",
                               
libxl__device_disk_string_of_format(disk->format), disk->pdev_path));
-                assert(device.backend_kind == LIBXL__DEVICE_KIND_QDISK);
+                assert(device->backend_kind == LIBXL__DEVICE_KIND_QDISK);
                 break;
             default:
                 LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unrecognized disk backend 
type: %d\n", disk->backend);
@@ -1908,11 +1911,11 @@ static int device_disk_add(libxl__gc *gc
         flexarray_append(front, "state");
         flexarray_append(front, libxl__sprintf(gc, "%d", 1));
         flexarray_append(front, "virtual-device");
-        flexarray_append(front, libxl__sprintf(gc, "%d", device.devid));
+        flexarray_append(front, libxl__sprintf(gc, "%d", device->devid));
         flexarray_append(front, "device-type");
         flexarray_append(front, disk->is_cdrom ? "cdrom" : "disk");
 
-        libxl__device_generic_add(gc, t, &device,
+        libxl__device_generic_add(gc, t, device,
                             libxl__xs_kvs_of_flexarray(gc, back, back->count),
                             libxl__xs_kvs_of_flexarray(gc, front, 
front->count));
 
@@ -1921,6 +1924,10 @@ static int device_disk_add(libxl__gc *gc
         if (rc < 0) goto out_free;
     }
 
+    aodev->dev = device;
+    aodev->action = DEVICE_CONNECT;
+    libxl__wait_device_connection(egc, aodev);
+
     rc = 0;
 
 out_free:
@@ -1928,21 +1935,15 @@ out_free:
     flexarray_free(front);
 out:
     libxl__xs_transaction_abort(gc, &t);
-    return rc;
+    aodev->rc = rc;
+    if (rc) aodev->callback(egc, aodev);
+    return;
 }
 
-int libxl__device_disk_add(libxl__gc *gc, uint32_t domid,
-                           libxl_device_disk *disk)
+void libxl__device_disk_add(libxl__egc *egc, uint32_t domid,
+                           libxl_device_disk *disk, libxl__ao_device *aodev)
 {
-    return device_disk_add(gc, domid, disk, NULL, NULL);
-}
-
-int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk 
*disk)
-{
-    GC_INIT(ctx);
-    int rc = libxl__device_disk_add(gc, domid, disk);
-    GC_FREE;
-    return rc;
+    device_disk_add(egc, domid, disk, aodev, NULL, NULL);
 }
 
 static void libxl__device_disk_from_xs_be(libxl__gc *gc,
@@ -2252,14 +2253,17 @@ static char * libxl__alloc_vdev(libxl__g
     return NULL;
 }
 
+/* Callbacks */
+
+static void local_device_attach_cb(libxl__egc *egc, libxl__ao_device *aodev);
+
 void libxl__device_disk_local_initiate_attach(libxl__egc *egc,
                                      libxl__disk_local_state *dls)
 {
     STATE_AO_GC(dls->ao);
     libxl_ctx *ctx = CTX;
-    char *dev = NULL, *be_path = NULL;
+    char *dev = NULL;
     int rc;
-    libxl__device device;
     const libxl_device_disk *in_disk = dls->in_disk;
     libxl_device_disk *disk = &dls->disk;
     const char *blkdev_start = dls->blkdev_start;
@@ -2306,14 +2310,12 @@ void libxl__device_disk_local_initiate_a
             break;
         case LIBXL_DISK_BACKEND_QDISK:
             if (disk->format != LIBXL_DISK_FORMAT_RAW) {
-                if (device_disk_add(gc, LIBXL_TOOLSTACK_DOMID, disk,
-                                    libxl__alloc_vdev,
-                                    (void *) blkdev_start)) {
-                    LOG(ERROR, "libxl_device_disk_add failed");
-                    rc = ERROR_FAIL;
-                    goto out;
-                }
-                dev = GCSPRINTF("/dev/%s", disk->vdev);
+                libxl__prepare_ao_device(ao, &dls->aodev);
+                dls->aodev.callback = local_device_attach_cb;
+                device_disk_add(egc, LIBXL_TOOLSTACK_DOMID, disk,
+                                &dls->aodev, libxl__alloc_vdev,
+                                (void *) blkdev_start);
+                return;
             } else {
                 dev = disk->pdev_path;
             }
@@ -2326,15 +2328,48 @@ void libxl__device_disk_local_initiate_a
             goto out;
     }
 
-    if (disk->vdev != NULL) {
-        rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &device);
-        if (rc < 0)
-            goto out;
-        be_path = libxl__device_backend_path(gc, &device);
-        rc = libxl__wait_for_backend(gc, be_path, "4");
-        if (rc < 0)
-            goto out;
+    if (dev != NULL)
+        dls->diskpath = strdup(dev);
+
+    dls->callback(egc, dls, 0);
+    return;
+
+ out:
+    assert(rc);
+    dls->rc = rc;
+    libxl__device_disk_local_initiate_detach(egc, dls);
+    dls->callback(egc, dls, rc);
+}
+
+static void local_device_attach_cb(libxl__egc *egc, libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    libxl__disk_local_state *dls = CONTAINER_OF(aodev, *dls, aodev);
+    char *dev = NULL, *be_path = NULL;
+    int rc;
+    libxl__device device;
+    libxl_device_disk *disk = &dls->disk;
+
+    rc = aodev->rc;
+    if (rc) {
+        LOGE(ERROR, "unable to %s %s with id %u",
+                    aodev->action == DEVICE_CONNECT ? "add" : "remove",
+                    libxl__device_kind_to_string(aodev->dev->kind),
+                    aodev->dev->devid);
+        goto out;
     }
+
+    dev = GCSPRINTF("/dev/%s", disk->vdev);
+    LOG(DEBUG, "locally attaching qdisk %s", dev);
+
+    rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID, disk, &device);
+    if (rc < 0)
+        goto out;
+    be_path = libxl__device_backend_path(gc, &device);
+    rc = libxl__wait_for_backend(gc, be_path, "4");
+    if (rc < 0)
+        goto out;
+
     if (dev != NULL)
         dls->diskpath = libxl__strdup(gc, dev);
 
@@ -3058,6 +3093,36 @@ DEFINE_DEVICE_REMOVE(vfb, destroy, 1)
 
 
/******************************************************************************/
 
+/* Macro for defining device addition functions in a compact way */
+/* The following functions are defined:
+ * libxl_device_disk_add
+ */
+
+#define DEFINE_DEVICE_ADD(type)                                         \
+    int libxl_device_##type##_add(libxl_ctx *ctx,                       \
+        uint32_t domid, libxl_device_##type *type,                      \
+        const libxl_asyncop_how *ao_how)                                \
+    {                                                                   \
+        AO_CREATE(ctx, domid, ao_how);                                  \
+        libxl__ao_device *aodev;                                        \
+                                                                        \
+        GCNEW(aodev);                                                   \
+        libxl__prepare_ao_device(ao, aodev);                            \
+        aodev->callback = device_addrm_aocomplete;                      \
+        libxl__device_##type##_add(egc, domid, type, aodev);            \
+                                                                        \
+        return AO_INPROGRESS;                                           \
+    }
+
+/* Define alladd functions and undef the macro */
+
+/* disk */
+DEFINE_DEVICE_ADD(disk)
+
+#undef DEFINE_DEVICE_ADD
+
+/******************************************************************************/
+
 int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
 {
     GC_INIT(ctx);
diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/libxl.h       Thu Jul 26 16:47:30 2012 +0100
@@ -675,7 +675,9 @@ void libxl_vcpuinfo_list_free(libxl_vcpu
  */
 
 /* Disks */
-int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk 
*disk);
+int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid,
+                          libxl_device_disk *disk,
+                          const libxl_asyncop_how *ao_how);
 int libxl_device_disk_remove(libxl_ctx *ctx, uint32_t domid,
                              libxl_device_disk *disk,
                              const libxl_asyncop_how *ao_how);
diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c        Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/libxl_create.c        Thu Jul 26 16:47:30 2012 +0100
@@ -560,6 +560,10 @@ static void domcreate_bootloader_console
 static void domcreate_bootloader_done(libxl__egc *egc,
                                       libxl__bootloader_state *bl,
                                       int rc);
+
+static void domcreate_launch_dm(libxl__egc *egc, libxl__ao_devices *aodevs,
+                                int ret);
+
 static void domcreate_console_available(libxl__egc *egc,
                                         libxl__domain_create_state *dcs);
 
@@ -850,12 +854,10 @@ static void domcreate_rebuild_done(libxl
                                    int ret)
 {
     STATE_AO_GC(dcs->ao);
-    int i;
 
     /* convenience aliases */
     const uint32_t domid = dcs->guest_domid;
     libxl_domain_config *const d_config = dcs->guest_config;
-    libxl__domain_build_state *const state = &dcs->build_state;
     libxl_ctx *const ctx = CTX;
 
     if (ret) {
@@ -866,14 +868,34 @@ static void domcreate_rebuild_done(libxl
 
     store_libxl_entry(gc, domid, &d_config->b_info);
 
-    for (i = 0; i < d_config->num_disks; i++) {
-        ret = libxl_device_disk_add(ctx, domid, &d_config->disks[i]);
-        if (ret) {
-            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
-                       "cannot add disk %d to domain: %d", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
+    dcs->aodevs.size = d_config->num_disks;
+    dcs->aodevs.callback = domcreate_launch_dm;
+    libxl__prepare_ao_devices(ao, &dcs->aodevs);
+    libxl__add_disks(egc, ao, domid, 0, d_config, &dcs->aodevs);
+
+    return;
+
+ error_out:
+    assert(ret);
+    domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_launch_dm(libxl__egc *egc, libxl__ao_devices *aodevs,
+                                int ret)
+{
+    libxl__domain_create_state *dcs = CONTAINER_OF(aodevs, *dcs, aodevs);
+    STATE_AO_GC(dcs->ao);
+    int i;
+
+    /* convenience aliases */
+    const uint32_t domid = dcs->guest_domid;
+    libxl_domain_config *const d_config = dcs->guest_config;
+    libxl__domain_build_state *const state = &dcs->build_state;
+    libxl_ctx *const ctx = CTX;
+
+    if (ret) {
+        LOG(ERROR, "unable to add disk devices");
+        goto error_out;
     }
     for (i = 0; i < d_config->num_nics; i++) {
         ret = libxl_device_nic_add(ctx, domid, &d_config->nics[i]);
diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/libxl_device.c        Thu Jul 26 16:47:30 2012 +0100
@@ -447,6 +447,37 @@ void libxl__ao_devices_callback(libxl__e
     return;
 }
 
+/******************************************************************************/
+
+/* Macro for defining the functions that will add a bunch of disks when
+ * inside an async op.
+ * This macro is added to prevent repetition of code.
+ *
+ * The following functions are defined:
+ * libxl__add_disks
+ */
+
+#define DEFINE_DEVICES_ADD(type)                                               
\
+    void libxl__add_##type##s(libxl__egc *egc, libxl__ao *ao, uint32_t domid,  
\
+                              int start, libxl_domain_config *d_config,        
\
+                              libxl__ao_devices *aodevs)                       
\
+    {                                                                          
\
+        AO_GC;                                                                 
\
+        int i;                                                                 
\
+        int end = start + d_config->num_##type##s;                             
\
+        for (i = start; i < end; i++) {                                        
\
+            aodevs->array[i].callback = libxl__ao_devices_callback;            
\
+            libxl__device_##type##_add(egc, domid, 
&d_config->type##s[i-start],\
+                                       &aodevs->array[i]);                     
\
+        }                                                                      
\
+    }
+
+DEFINE_DEVICES_ADD(disk)
+
+#undef DEFINE_DEVICES_ADD
+
+/******************************************************************************/
+
 int libxl__device_destroy(libxl__gc *gc, libxl__device *dev)
 {
     char *be_path = libxl__device_backend_path(gc, dev);
@@ -593,6 +624,52 @@ static void device_backend_cleanup(libxl
 
 static void device_hotplug_done(libxl__egc *egc, libxl__ao_device *aodev);
 
+void libxl__wait_device_connection(libxl__egc *egc, libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    char *be_path = libxl__device_backend_path(gc, aodev->dev);
+    char *state_path = libxl__sprintf(gc, "%s/state", be_path);
+    libxl_dominfo info;
+    uint32_t domid = aodev->dev->domid;
+    int rc = 0;
+
+    libxl_dominfo_init(&info);
+    rc = libxl_domain_info(CTX, &info, domid);
+    if (rc) {
+        LOG(ERROR, "unable to get info for domain %d", domid);
+        goto out;
+    }
+    if (QEMU_BACKEND(aodev->dev)) {
+        /*
+         * If Qemu is not running, there's no point in waiting for
+         * it to change the state of the device.
+         *
+         * If Qemu is running, it will set the state of the device to
+         * 4 directly, without waiting in state 2 for any hotplug execution.
+         */
+        device_hotplug_done(egc, aodev);
+        return;
+    }
+
+    rc = libxl__ev_devstate_wait(gc, &aodev->backend_ds,
+                                 device_backend_callback,
+                                 state_path, XenbusStateInitWait,
+                                 LIBXL_INIT_TIMEOUT * 1000);
+    if (rc) {
+        LOG(ERROR, "unable to initialize device %s", be_path);
+        goto out;
+    }
+
+    libxl_dominfo_dispose(&info);
+    return;
+
+out:
+    aodev->rc = rc;
+    libxl_dominfo_dispose(&info);
+    device_hotplug_done(egc, aodev);
+    return;
+}
+
 void libxl__initiate_device_remove(libxl__egc *egc,
                                    libxl__ao_device *aodev)
 {
diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c    Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/libxl_dm.c    Thu Jul 26 16:47:30 2012 +0100
@@ -713,6 +713,9 @@ static void spawn_stubdom_pvqemu_cb(libx
                                 libxl__dm_spawn_state *stubdom_dmss,
                                 int rc);
 
+static void spawn_stub_launch_dm(libxl__egc *egc,
+                                 libxl__ao_devices *aodevs, int ret);
+
 static void spaw_stubdom_pvqemu_destroy_cb(libxl__egc *egc,
                                            libxl__destroy_domid_state *dis,
                                            int rc);
@@ -726,10 +729,9 @@ void libxl__spawn_stub_dm(libxl__egc *eg
 {
     STATE_AO_GC(sdss->dm.spawn.ao);
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    int i, num_console = STUBDOM_SPECIAL_CONSOLES, ret;
-    libxl__device_console *console;
-    libxl_device_vfb vfb;
-    libxl_device_vkb vkb;
+    int ret;
+    libxl_device_vfb *vfb;
+    libxl_device_vkb *vkb;
     char **args;
     struct xs_permissions perm[2];
     xs_transaction_t t;
@@ -784,10 +786,12 @@ void libxl__spawn_stub_dm(libxl__egc *eg
     ret = libxl__domain_build_info_setdefault(gc, &dm_config->b_info);
     if (ret) goto out;
 
-    libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, &vfb, &vkb);
-    dm_config->vfbs = &vfb;
+    GCNEW(vfb);
+    GCNEW(vkb);
+    libxl__vfb_and_vkb_from_hvm_guest_config(gc, guest_config, vfb, vkb);
+    dm_config->vfbs = vfb;
     dm_config->num_vfbs = 1;
-    dm_config->vkbs = &vkb;
+    dm_config->vkbs = vkb;
     dm_config->num_vkbs = 1;
 
     stubdom_state->pv_kernel.path
@@ -845,22 +849,54 @@ retry_transaction:
         if (errno == EAGAIN)
             goto retry_transaction;
 
-    for (i = 0; i < dm_config->num_disks; i++) {
-        ret = libxl_device_disk_add(ctx, dm_domid, &dm_config->disks[i]);
-        if (ret)
-            goto out_free;
-    }
+    sdss->aodevs.size = dm_config->num_disks;
+    sdss->aodevs.callback = spawn_stub_launch_dm;
+    libxl__prepare_ao_devices(ao, &sdss->aodevs);
+    libxl__add_disks(egc, ao, dm_domid, 0, dm_config, &sdss->aodevs);
+
+    free(args);
+    return;
+
+out_free:
+    free(args);
+out:
+    assert(ret);
+    spawn_stubdom_pvqemu_cb(egc, &sdss->pvqemu, ret);
+}
+
+static void spawn_stub_launch_dm(libxl__egc *egc,
+                                 libxl__ao_devices *aodevs, int ret)
+{
+    libxl__stub_dm_spawn_state *sdss = CONTAINER_OF(aodevs, *sdss, aodevs);
+    STATE_AO_GC(sdss->dm.spawn.ao);
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    int i, num_console = STUBDOM_SPECIAL_CONSOLES;
+    libxl__device_console *console;
+
+    /* convenience aliases */
+    libxl_domain_config *const dm_config = &sdss->dm_config;
+    libxl_domain_config *const guest_config = sdss->dm.guest_config;
+    const int guest_domid = sdss->dm.guest_domid;
+    libxl__domain_build_state *const d_state = sdss->dm.build_state;
+    libxl__domain_build_state *const stubdom_state = &sdss->dm_state;
+    uint32_t dm_domid = sdss->pvqemu.guest_domid;
+
+    if (ret) {
+        LOG(ERROR, "error connecting disk devices");
+        goto out;
+     }
+
     for (i = 0; i < dm_config->num_nics; i++) {
         ret = libxl_device_nic_add(ctx, dm_domid, &dm_config->nics[i]);
         if (ret)
-            goto out_free;
+            goto out;
     }
     ret = libxl_device_vfb_add(ctx, dm_domid, &dm_config->vfbs[0]);
     if (ret)
-        goto out_free;
+        goto out;
     ret = libxl_device_vkb_add(ctx, dm_domid, &dm_config->vkbs[0]);
     if (ret)
-        goto out_free;
+        goto out;
 
     if (guest_config->b_info.u.hvm.serial)
         num_console++;
@@ -868,7 +904,7 @@ retry_transaction:
     console = libxl__calloc(gc, num_console, sizeof(libxl__device_console));
     if (!console) {
         ret = ERROR_NOMEM;
-        goto out_free;
+        goto out;
     }
 
     for (i = 0; i < num_console; i++) {
@@ -904,7 +940,7 @@ retry_transaction:
         ret = libxl__device_console_add(gc, dm_domid, &console[i],
                         i == STUBDOM_CONSOLE_LOGGING ? stubdom_state : NULL);
         if (ret)
-            goto out_free;
+            goto out;
     }
 
     sdss->pvqemu.spawn.ao = ao;
@@ -915,11 +951,8 @@ retry_transaction:
 
     libxl__spawn_local_dm(egc, &sdss->pvqemu);
 
-    free(args);
     return;
 
-out_free:
-    free(args);
 out:
     assert(ret);
     spawn_stubdom_pvqemu_cb(egc, &sdss->pvqemu, ret);
diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/libxl_internal.h      Thu Jul 26 16:47:30 2012 +0100
@@ -72,6 +72,7 @@
 #include "_libxl_types_internal.h"
 #include "_libxl_types_internal_json.h"
 
+#define LIBXL_INIT_TIMEOUT 10
 #define LIBXL_DESTROY_TIMEOUT 10
 #define LIBXL_DEVICE_MODEL_START_TIMEOUT 10
 #define LIBXL_QEMU_BODGE_TIMEOUT 2
@@ -1338,8 +1339,6 @@ _hidden void libxl__device_destroy_tapdi
 _hidden int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
                                    libxl_device_disk *disk,
                                    libxl__device *device);
-_hidden int libxl__device_disk_add(libxl__gc *gc, uint32_t domid,
-                                   libxl_device_disk *disk);
 
 _hidden char *libxl__uuid2string(libxl__gc *gc, const libxl_uuid uuid);
 
@@ -1923,6 +1922,27 @@ struct libxl__ao_devices {
  *                   DONE.
  */
 
+/* AO operation to connect a disk device, called by
+ * libxl_device_disk_add and libxl__add_disks. This function calls
+ * libxl__wait_device_connection to wait for the device to
+ * finish the connection (might involve executing hotplug scripts).
+ *
+ * Once finished, aodev->callback will be executed.
+ */
+_hidden void libxl__device_disk_add(libxl__egc *egc, uint32_t domid,
+                                    libxl_device_disk *disk,
+                                    libxl__ao_device *aodev);
+
+/* Waits for the passed device to reach state XenbusStateInitWait.
+ * This is not really useful by itself, but is important when executing
+ * hotplug scripts, since we need to be sure the device is in the correct
+ * state before executing them.
+ *
+ * Once finished, aodev->callback will be executed.
+ */
+_hidden void libxl__wait_device_connection(libxl__egc*,
+                                           libxl__ao_device *aodev);
+
 /* Arranges that dev will be removed to the guest, and the
  * hotplug scripts will be executed (if necessary). When
  * this is done (or an error happens), the callback in
@@ -2295,6 +2315,19 @@ _hidden void libxl__destroy_domid(libxl_
 _hidden void libxl__devices_destroy(libxl__egc *egc,
                                     libxl__devices_remove_state *drs);
 
+/* Helper function to add a bunch of disks. This should be used when
+ * the caller is inside an async op. "devices" will NOT be prepared by this
+ * function, so the caller must make sure to call _prepare before calling this
+ * function. The start parameter contains the position inside the aodevs array
+ * that should be used to store the state of this devices.
+ *
+ * The "callback" will be called for each device, and the user is responsible
+ * for calling libxl__ao_device_check_last on the callback.
+ */
+_hidden void libxl__add_disks(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                              int start, libxl_domain_config *d_config,
+                              libxl__ao_devices *aodevs);
+
 /*----- device model creation -----*/
 
 /* First layer; wraps libxl__spawn_spawn. */
@@ -2329,6 +2362,7 @@ typedef struct {
     libxl__domain_build_state dm_state;
     libxl__dm_spawn_state pvqemu;
     libxl__destroy_domid_state dis;
+    libxl__ao_devices aodevs;
 } libxl__stub_dm_spawn_state;
 
 _hidden void libxl__spawn_stub_dm(libxl__egc *egc, 
libxl__stub_dm_spawn_state*);
@@ -2360,6 +2394,7 @@ struct libxl__domain_create_state {
     libxl__save_helper_state shs;
     /* necessary if the domain creation failed and we have to destroy it */
     libxl__domain_destroy_state dds;
+    libxl__ao_devices aodevs;
 };
 
 /*----- Domain suspend (save) functions -----*/
diff -r 34b942aae898 -r fe34db0860d3 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Thu Jul 26 16:47:30 2012 +0100
@@ -5360,7 +5360,7 @@ int main_blockattach(int argc, char **ar
         return 0;
     }
 
-    if (libxl_device_disk_add(ctx, fe_domid, &disk)) {
+    if (libxl_device_disk_add(ctx, fe_domid, &disk, 0)) {
         fprintf(stderr, "libxl_device_disk_add failed.\n");
     }
     return 0;
diff -r 34b942aae898 -r fe34db0860d3 tools/ocaml/libs/xl/xenlight_stubs.c
--- a/tools/ocaml/libs/xl/xenlight_stubs.c      Thu Jul 26 16:47:29 2012 +0100
+++ b/tools/ocaml/libs/xl/xenlight_stubs.c      Thu Jul 26 16:47:30 2012 +0100
@@ -247,7 +247,7 @@ value stub_xl_device_disk_add(value info
        device_disk_val(&gc, &lg, &c_info, info);
 
        INIT_CTX();
-       ret = libxl_device_disk_add(ctx, Int_val(domid), &c_info);
+       ret = libxl_device_disk_add(ctx, Int_val(domid), &c_info, 0);
        if (ret != 0)
                failwith_xl("disk_add", &lg);
        FREE_CTX();

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.