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

[Xen-devel] [PATCH v6 05/13] libxl: convert libxl__device_disk_local_attach to an async op



This will be needed in future patches, when libxl__device_disk_add
becomes async also. Create a new status structure that defines the
local attach of a disk device and use it in
libxl__device_disk_local_attach.

This is done in this patch to split the changes introduced when
libxl__device_disk_add becomes async.

Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxx>
---
 tools/libxl/libxl.c            |   91 +++++++++++++++++++++++++++----------
 tools/libxl/libxl_bootloader.c |   97 ++++++++++++++++++++++++++++++++++-----
 tools/libxl/libxl_internal.h   |   42 ++++++++++++-----
 3 files changed, 181 insertions(+), 49 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 3ad1931..43affd1 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2027,20 +2027,20 @@ static char * libxl__alloc_vdev(libxl__gc *gc, const 
char *blkdev_start,
     return NULL;
 }
 
-char * libxl__device_disk_local_attach(libxl__gc *gc,
-        const libxl_device_disk *in_disk,
-        libxl_device_disk *disk,
-        const char *blkdev_start)
+void libxl__device_disk_local_attach(libxl__egc *egc,
+                                     libxl__disk_local_state *dls)
 {
-    libxl_ctx *ctx = gc->owner;
+    STATE_AO_GC(dls->ao);
+    libxl_ctx *ctx = CTX;
     char *dev = NULL, *be_path = NULL;
-    char *ret = NULL;
     int rc, xs_ret;
     libxl__device device;
     xs_transaction_t t = XBT_NULL;
+    const libxl_device_disk *in_disk = dls->in_disk;
+    libxl_device_disk *disk = &dls->disk;
+    const char *blkdev_start = dls->blkdev_start;
 
-    if (in_disk->pdev_path == NULL)
-        return NULL;
+    assert(in_disk->pdev_path);
 
     memcpy(disk, in_disk, sizeof(libxl_device_disk));
     disk->pdev_path = libxl__strdup(gc, in_disk->pdev_path);
@@ -2076,6 +2076,7 @@ char * libxl__device_disk_local_attach(libxl__gc *gc,
             default:
                 LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
                            "unrecognized disk format: %d", disk->format);
+                rc = ERROR_FAIL;
                 break;
             }
             break;
@@ -2085,15 +2086,18 @@ char * libxl__device_disk_local_attach(libxl__gc *gc,
                     t = xs_transaction_start(ctx->xsh);
                     if (t == XBT_NULL) {
                         LOG(ERROR, "failed to start a xenstore transaction");
+                        rc = ERROR_FAIL;
                         goto out;
                     }
                     disk->vdev = libxl__alloc_vdev(gc, blkdev_start, t);
                     if (disk->vdev == NULL) {
                         LOG(ERROR, "libxl__alloc_vdev failed");
+                        rc = ERROR_FAIL;
                         goto out;
                     }
-                    if (libxl__device_disk_add(gc, LIBXL_TOOLSTACK_DOMID,
-                                t, disk)) {
+                    rc = libxl__device_disk_add(gc, LIBXL_TOOLSTACK_DOMID,
+                                                t, disk);
+                    if (rc) {
                         LOG(ERROR, "libxl_device_disk_add failed");
                         goto out;
                     }
@@ -2102,6 +2106,7 @@ char * libxl__device_disk_local_attach(libxl__gc *gc,
                 t = XBT_NULL;
                 if (xs_ret == 0) {
                     LOGE(ERROR, "xenstore transaction failed");
+                    rc = ERROR_FAIL;
                     goto out;
                 }
                 dev = GCSPRINTF("/dev/%s", disk->vdev);
@@ -2113,6 +2118,7 @@ char * libxl__device_disk_local_attach(libxl__gc *gc,
         default:
             LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unrecognized disk backend "
                 "type: %d", disk->backend);
+            rc = ERROR_FAIL;
             break;
     }
 
@@ -2126,42 +2132,79 @@ char * libxl__device_disk_local_attach(libxl__gc *gc,
             goto out;
     }
     if (dev != NULL)
-        ret = strdup(dev);
-    return ret;
+        dls->diskpath = strdup(dev);
+
+    dls->callback(egc, dls, 0);
+    return;
 
  out:
+    assert(rc);
     if (t != XBT_NULL)
         xs_transaction_end(ctx->xsh, t, 1);
-    else
-        libxl__device_disk_local_detach(gc, disk);
-    return NULL;
+    dls->callback(egc, dls, rc);
 }
 
-int libxl__device_disk_local_detach(libxl__gc *gc, libxl_device_disk *disk)
+/* Callbacks for local detach */
+
+static void local_device_detach_cb(libxl__egc *egc, libxl__ao_device *aodev);
+
+void libxl__device_disk_local_detach(libxl__egc *egc,
+                                     libxl__disk_local_state *dls)
 {
+    STATE_AO_GC(dls->ao);
     int rc = 0;
+    libxl_device_disk *disk = &dls->disk;
+    libxl__device *device;
+    libxl__ao_device *aodev = &dls->aodev;
 
     switch (disk->backend) {
         case LIBXL_DISK_BACKEND_QDISK:
             if (disk->vdev != NULL) {
-                libxl_device_disk_remove(gc->owner, LIBXL_TOOLSTACK_DOMID,
-                        disk, 0);
-                /* fixme-ao */
-                rc = libxl_device_disk_destroy(gc->owner,
-                        LIBXL_TOOLSTACK_DOMID, disk, 0);
+                GCNEW(device);
+                rc = libxl__device_from_disk(gc, LIBXL_TOOLSTACK_DOMID,
+                                             disk, device);
+                if (rc != 0) goto out;
+
+                libxl__prepare_ao_device(ao, aodev);
+                aodev->action = DEVICE_DISCONNECT;
+                aodev->dev = device;
+                aodev->callback = local_device_detach_cb;
+                aodev->force = 0;
+                libxl__initiate_device_remove(egc, aodev);
             }
-            break;
+            return;
         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.
              */
-            break;
+            dls->callback(egc, dls, rc);
+            return;
     }
 
+out:
+    assert(rc);
+    dls->callback(egc, dls, rc);
+    return;
+}
 
-    return rc;
+static void local_device_detach_cb(libxl__egc *egc, libxl__ao_device *aodev)
+{
+    STATE_AO_GC(aodev->ao);
+    libxl__disk_local_state *dls = CONTAINER_OF(aodev, *dls, aodev);
+
+    if (aodev->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;
+    }
+
+out:
+    dls->callback(egc, dls, aodev->rc);
+    return;
 }
 
 
/******************************************************************************/
diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c
index 7ebc0df..182a975 100644
--- a/tools/libxl/libxl_bootloader.c
+++ b/tools/libxl/libxl_bootloader.c
@@ -224,11 +224,6 @@ static void bootloader_cleanup(libxl__egc *egc, 
libxl__bootloader_state *bl)
     if (bl->outputpath) libxl__remove_file(gc, bl->outputpath);
     if (bl->outputdir) libxl__remove_directory(gc, bl->outputdir);
 
-    if (bl->diskpath) {
-        libxl__device_disk_local_detach(gc, &bl->localdisk);
-        free(bl->diskpath);
-        bl->diskpath = 0;
-    }
     libxl__domaindeathcheck_stop(gc,&bl->deathcheck);
     libxl__datacopier_kill(&bl->keystrokes);
     libxl__datacopier_kill(&bl->display);
@@ -249,10 +244,40 @@ static void bootloader_setpaths(libxl__gc *gc, 
libxl__bootloader_state *bl)
     bl->outputpath = GCSPRINTF(XEN_RUN_DIR "/bootloader.%"PRIu32".out", domid);
 }
 
+/* Callbacks */
+
+static void bootloader_fisnihed_cb(libxl__egc *egc,
+                                   libxl__disk_local_state *dls,
+                                   int rc);
+
 static void bootloader_callback(libxl__egc *egc, libxl__bootloader_state *bl,
                                 int rc)
 {
     bootloader_cleanup(egc, bl);
+
+    if (bl->diskpath) {
+        bl->dls.callback = bootloader_fisnihed_cb;
+        libxl__device_disk_local_detach(egc, &bl->dls);
+        return;
+    }
+
+    bl->callback(egc, bl, rc);
+}
+
+static void bootloader_fisnihed_cb(libxl__egc *egc,
+                                   libxl__disk_local_state *dls,
+                                   int rc)
+{
+    STATE_AO_GC(dls->ao);
+    libxl__bootloader_state *bl = CONTAINER_OF(dls, *bl, dls);
+
+    free(bl->diskpath);
+    bl->diskpath = 0;
+
+    if (rc) {
+        LOG(ERROR, "unable to detach locally attached disk");
+    }
+
     bl->callback(egc, bl, rc);
 }
 
@@ -275,6 +300,16 @@ static void bootloader_abort(libxl__egc *egc,
 
 /*----- main flow of control -----*/
 
+/* Callbacks */
+
+static void bootloader_disk_attached_cb(libxl__egc *egc,
+                                        libxl__disk_local_state *dls,
+                                        int rc);
+
+static void bootloader_disk_failed_cb(libxl__egc *egc,
+                                      libxl__disk_local_state *dls,
+                                      int rc);
+
 void libxl__bootloader_run(libxl__egc *egc, libxl__bootloader_state *bl)
 {
     STATE_AO_GC(bl->ao);
@@ -282,7 +317,6 @@ void libxl__bootloader_run(libxl__egc *egc, 
libxl__bootloader_state *bl)
     uint32_t domid = bl->domid;
     char *logfile_tmp = NULL;
     int rc, r;
-    const char *bootloader;
 
     libxl__bootloader_init(bl);
 
@@ -344,13 +378,38 @@ void libxl__bootloader_run(libxl__egc *egc, 
libxl__bootloader_state *bl)
         goto out;
     }
 
-    bl->diskpath = libxl__device_disk_local_attach(gc, bl->disk, 
&bl->localdisk,
-            info->blkdev_start);
-    if (!bl->diskpath) {
-        rc = ERROR_FAIL;
-        goto out;
+    bl->dls.ao = ao;
+    bl->dls.in_disk = bl->disk;
+    bl->dls.blkdev_start = info->blkdev_start;
+    bl->dls.callback = bootloader_disk_attached_cb;
+    libxl__device_disk_local_attach(egc, &bl->dls);
+    return;
+
+ out:
+    assert(rc);
+ out_ok:
+    free(logfile_tmp);
+    bootloader_callback(egc, bl, rc);
+}
+
+static void bootloader_disk_attached_cb(libxl__egc *egc,
+                                        libxl__disk_local_state *dls,
+                                        int rc)
+{
+    STATE_AO_GC(dls->ao);
+    libxl__bootloader_state *bl = CONTAINER_OF(dls, *bl, dls);
+    const libxl_domain_build_info *info = bl->info;
+    const char *bootloader;
+
+    if (rc) {
+        LOG(ERROR, "failed to attach local disk for bootloader execution");
+        dls->callback = bootloader_disk_failed_cb;
+        libxl__device_disk_local_detach(egc, dls);
+        return;
     }
 
+    bl->diskpath = bl->dls.diskpath;
+
     LOG(DEBUG, "Config bootloader value: %s", info->u.pv.bootloader);
 
     if ( !strcmp(info->u.pv.bootloader, "/usr/bin/pygrub") )
@@ -389,11 +448,23 @@ void libxl__bootloader_run(libxl__egc *egc, 
libxl__bootloader_state *bl)
 
  out:
     assert(rc);
- out_ok:
-    free(logfile_tmp);
     bootloader_callback(egc, bl, rc);
 }
 
+static void bootloader_disk_failed_cb(libxl__egc *egc,
+                                      libxl__disk_local_state *dls,
+                                      int rc)
+{
+    STATE_AO_GC(dls->ao);
+    libxl__bootloader_state *bl = CONTAINER_OF(dls, *bl, dls);
+
+    if (rc) {
+        LOG(ERROR, "failed to detach locally attached disk");
+    }
+
+    bootloader_callback(egc, bl, ERROR_FAIL);
+}
+
 static void bootloader_gotptys(libxl__egc *egc, libxl__openpty_state *op)
 {
     libxl__bootloader_state *bl = CONTAINER_OF(op, *bl, openpty);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 0000d6b..85c21b4 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1245,17 +1245,6 @@ _hidden int libxl__device_from_disk(libxl__gc *gc, 
uint32_t domid,
 _hidden int libxl__device_disk_add(libxl__gc *gc, uint32_t domid,
         xs_transaction_t t, libxl_device_disk *disk);
 
-/*
- * Make a disk available in this (the control) domain. Returns path to
- * a device.
- */
-_hidden char * libxl__device_disk_local_attach(libxl__gc *gc,
-        const libxl_device_disk *in_disk,
-        libxl_device_disk *new_disk,
-        const char *blkdev_start);
-_hidden int libxl__device_disk_local_detach(libxl__gc *gc,
-        libxl_device_disk *disk);
-
 _hidden char *libxl__uuid2string(libxl__gc *gc, const libxl_uuid uuid);
 
 struct libxl__xen_console_reader {
@@ -1775,6 +1764,35 @@ struct libxl__ao_devices {
 _hidden void libxl__initiate_device_remove(libxl__egc *egc,
                                            libxl__ao_device *aodev);
 
+/*----- local disk attach: attach a disk locally to run the bootloader -----*/
+
+typedef struct libxl__disk_local_state libxl__disk_local_state;
+typedef void libxl__disk_local_state_callback(libxl__egc*,
+                                              libxl__disk_local_state*,
+                                              int rc);
+
+struct libxl__disk_local_state {
+    /* filled by the user */
+    libxl__ao *ao;
+    const libxl_device_disk *in_disk;
+    libxl_device_disk disk;
+    const char *blkdev_start;
+    libxl__disk_local_state_callback *callback;
+    /* filled by libxl__device_disk_local_attach */
+    char *diskpath;
+    /* private for implementation of local detach */
+    libxl__ao_device aodev;
+};
+
+/*
+ * Make a disk available in this (the control) domain. Calls dls->callback
+ * when finished.
+ */
+_hidden void libxl__device_disk_local_attach(libxl__egc *egc,
+                                             libxl__disk_local_state *dls);
+_hidden void libxl__device_disk_local_detach(libxl__egc *egc,
+                                             libxl__disk_local_state *dls);
+
 /*----- datacopier: copies data from one fd to another -----*/
 
 typedef struct libxl__datacopier_state libxl__datacopier_state;
@@ -1872,7 +1890,7 @@ struct libxl__bootloader_state {
      * the caller using libxl__device_disk_local_detach, but only
      * after the domain's kernel and initramfs have been loaded into
      * memory and the file references disposed of. */
-    libxl_device_disk localdisk;
+    libxl__disk_local_state dls;
     uint32_t domid;
     /* outputs:
      *  - caller must initialise kernel and ramdisk to point to file
-- 
1.7.7.5 (Apple Git-26)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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