xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Roger Pau Monne <roger.pau@citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>,
	Roger Pau Monne <roger.pau@citrix.com>
Subject: [PATCH v2 09/15] libxl: convert libxl_device_nic_add to an async operation
Date: Tue, 22 May 2012 15:02:39 +0100	[thread overview]
Message-ID: <1337695365-5142-10-git-send-email-roger.pau@citrix.com> (raw)
In-Reply-To: <1337695365-5142-1-git-send-email-roger.pau@citrix.com>

This patch converts libxl_device_nic_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 latter patches that will launch hotplug scripts after
we reached the desired xenbus state.

Calls to libxl_device_nic_add have also been moved to occur after the
device model has been launched, so when hotplug scripts are called
from this functions the interfaces already exists.

As usual, libxl_device_nic_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.

Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Signed-off-by: Roger Pau Monne <roger.pau@citrix.com>
---
 tools/libxl/libxl.c          |   39 ++++++++++++++++++-----
 tools/libxl/libxl.h          |    3 +-
 tools/libxl/libxl_create.c   |   70 +++++++++++++++++++++++++++++++++++++-----
 tools/libxl/libxl_device.c   |   18 +++++++++++
 tools/libxl/libxl_dm.c       |   54 ++++++++++++++++++++++++++++++--
 tools/libxl/libxl_internal.h |   11 ++++++
 tools/libxl/xl_cmdimpl.c     |    2 +-
 7 files changed, 176 insertions(+), 21 deletions(-)

diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 46d13a7..1a04f7a 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -2017,12 +2017,27 @@ static int libxl__device_from_nic(libxl__gc *gc, uint32_t domid,
     return 0;
 }
 
-int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
+int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic,
+                         const libxl_asyncop_how *ao_how)
 {
-    GC_INIT(ctx);
+    AO_CREATE(ctx, domid, ao_how);
+    libxl__ao_device *device;
+
+    GCNEW(device);
+    libxl__init_ao_device(device, ao, NULL);
+    device->callback = libxl__device_cb;
+    libxl__device_nic_add(egc, domid, nic, device);
+
+    return AO_INPROGRESS;
+}
+
+void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
+                           libxl_device_nic *nic, libxl__ao_device *aoadd)
+{
+    STATE_AO_GC(aoadd->ao);
     flexarray_t *front;
     flexarray_t *back;
-    libxl__device device;
+    libxl__device *device;
     char *dompath, **l;
     unsigned int nb, rc;
 
@@ -2053,7 +2068,8 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
         }
     }
 
-    rc = libxl__device_from_nic(gc, domid, nic, &device);
+    GCNEW(device);
+    rc = libxl__device_from_nic(gc, domid, nic, device);
     if ( rc != 0 ) goto out_free;
 
     flexarray_append(back, "frontend-id");
@@ -2094,6 +2110,9 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
     flexarray_append(back, libxl__strdup(gc, nic->bridge));
     flexarray_append(back, "handle");
     flexarray_append(back, libxl__sprintf(gc, "%d", nic->devid));
+    flexarray_append(back, "type");
+    flexarray_append(back, libxl__strdup(gc,
+                                     libxl_nic_type_to_string(nic->nictype)));
 
     flexarray_append(front, "backend-id");
     flexarray_append(front, libxl__sprintf(gc, "%d", nic->backend_domid));
@@ -2104,18 +2123,22 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
     flexarray_append(front, "mac");
     flexarray_append(front, libxl__sprintf(gc,
                                     LIBXL_MAC_FMT, LIBXL_MAC_BYTES(nic->mac)));
-    libxl__device_generic_add(gc, &device,
+    libxl__device_generic_add(gc, device,
                              libxl__xs_kvs_of_flexarray(gc, back, back->count),
                              libxl__xs_kvs_of_flexarray(gc, front, front->count));
 
-    /* FIXME: wait for plug */
+    aoadd->dev = device;
+    aoadd->action = DEVICE_CONNECT;
+    libxl__initiate_device_add(egc, aoadd);
+
     rc = 0;
 out_free:
     flexarray_free(back);
     flexarray_free(front);
 out:
-    GC_FREE;
-    return rc;
+    aoadd->rc = rc;
+    if (rc) aoadd->callback(egc, aoadd);
+    return;
 }
 
 int libxl_device_nic_remove(libxl_ctx *ctx, uint32_t domid,
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index c14e832..0b15586 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -691,7 +691,8 @@ char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk *disk);
 int libxl_device_disk_local_detach(libxl_ctx *ctx, libxl_device_disk *disk);
 
 /* Network Interfaces */
-int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic);
+int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic,
+                         const libxl_asyncop_how *ao_how);
 int libxl_device_nic_remove(libxl_ctx *ctx, uint32_t domid,
                             libxl_device_nic *nic,
                             const libxl_asyncop_how *ao_how);
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 4378f48..076f755 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -577,6 +577,11 @@ static void domcreate_bootloader_done(libxl__egc *egc,
 
 static void domcreate_disk_connected(libxl__egc *egc, libxl__ao_device *aorm);
 
+static void domcreate_nic_connected(libxl__egc *egc, libxl__ao_device *aorm);
+
+static void domcreate_attach_pci(libxl__egc *egc,
+                                 libxl__domain_create_state *dcs);
+
 static void domcreate_console_available(libxl__egc *egc,
                                         libxl__domain_create_state *dcs);
 
@@ -737,13 +742,11 @@ static void domcreate_disk_connected(libxl__egc *egc, libxl__ao_device *aorm)
     }
 
     for (i = 0; i < d_config->num_vifs; i++) {
-        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]);
-        if (ret) {
-            LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
-                       "cannot add nic %d to domain: %d", i, ret);
-            ret = ERROR_FAIL;
-            goto error_out;
-        }
+        /* We have to init the nic here, because we still haven't
+         * called libxl_device_nic_add at this point, but qemu needs
+         * the nic information to be complete.
+         */
+        libxl__device_nic_setdefault(gc, &d_config->vifs[i]);
     }
     switch (d_config->c_info.type) {
     case LIBXL_DOMAIN_TYPE_HVM:
@@ -816,7 +819,6 @@ static void domcreate_devmodel_started(libxl__egc *egc,
 {
     libxl__domain_create_state *dcs = CONTAINER_OF(dmss, *dcs, dmss.dm);
     STATE_AO_GC(dmss->spawn.ao);
-    int i;
     libxl_ctx *ctx = CTX;
     int domid = dcs->guest_domid;
 
@@ -836,6 +838,58 @@ static void domcreate_devmodel_started(libxl__egc *egc,
         }
     }
 
+    /* Plug nic interfaces */
+    if (!ret && d_config->num_vifs > 0) {
+        /* Attach nics */
+        dcs->num_devices = d_config->num_vifs;
+        libxl__add_nics(egc, ao, domid, d_config, &dcs->devices,
+                        domcreate_nic_connected);
+        return;
+    }
+
+    domcreate_attach_pci(egc, dcs);
+    return;
+
+error_out:
+    assert(ret);
+    domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_nic_connected(libxl__egc *egc, libxl__ao_device *aorm)
+{
+    STATE_AO_GC(aorm->ao);
+    libxl__domain_create_state *dcs = CONTAINER_OF(aorm->base, *dcs, devices);
+    int last, ret = 0;
+
+    ret = libxl__ao_device_check_last(gc, aorm, dcs->devices,
+                                      dcs->num_devices, &last);
+
+    if (!last) return;
+    if (ret) {
+        LOGE(ERROR, "error connecting nics devices");
+        goto error_out;
+    }
+
+    domcreate_attach_pci(egc, dcs);
+    return;
+
+error_out:
+    assert(ret);
+    domcreate_complete(egc, dcs, ret);
+}
+
+static void domcreate_attach_pci(libxl__egc *egc,
+                                 libxl__domain_create_state *dcs)
+{
+    STATE_AO_GC(dcs->ao);
+    int i, ret = 0;
+    libxl_ctx *ctx = CTX;
+    int domid = dcs->guest_domid;
+
+    /* convenience aliases */
+    libxl_domain_config *const d_config = dcs->guest_config;
+
+
     for (i = 0; i < d_config->num_pcidevs; i++)
         libxl__device_pci_add(gc, domid, &d_config->pcidevs[i], 1);
 
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 8058afa..91ec69f 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -444,6 +444,24 @@ void libxl__add_disks(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
     }
 }
 
+void libxl__add_nics(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                     libxl_domain_config *d_config,
+                     libxl__ao_device **devices,
+                     libxl__device_callback callback)
+{
+    AO_GC;
+    GCNEW_ARRAY(*devices, d_config->num_vifs);
+    libxl__ao_device *aodev = *devices;
+    int i;
+
+    for (i = 0; i < d_config->num_vifs; i++) {
+        libxl__init_ao_device(&aodev[i], ao, devices);
+        aodev[i].callback = callback;
+        libxl__device_nic_add(egc, domid, &d_config->vifs[i],
+                               &aodev[i]);
+    }
+}
+
 int libxl__device_destroy(libxl__gc *gc, libxl__device *dev)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 670d1dd..034ca8e 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -675,6 +675,12 @@ static void spawn_stubdom_pvqemu_cb(libxl__egc *egc,
 
 static void spawn_stub_disk_connected(libxl__egc *egc, libxl__ao_device *aorm);
 
+static void stubdom_nics_connected(libxl__egc *egc, libxl__ao_device *aorm);
+
+static void stubdom_pvqemu_cb(libxl__egc *egc,
+                              libxl__dm_spawn_state *stubdom_dmss,
+                              int rc);
+
 static void spaw_stubdom_pvqemu_destroy_cb(libxl__egc *egc,
                                            libxl__destroy_domid_state *dis,
                                            int rc);
@@ -840,9 +846,11 @@ static void spawn_stub_disk_connected(libxl__egc *egc, libxl__ao_device *aorm)
      }
 
     for (i = 0; i < dm_config->num_vifs; i++) {
-        ret = libxl_device_nic_add(ctx, dm_domid, &dm_config->vifs[i]);
-        if (ret)
-            goto out;
+         /* We have to init the nic here, because we still haven't
+         * called libxl_device_nic_add at this point, but qemu needs
+         * the nic information to be complete.
+         */
+        libxl__device_nic_setdefault(gc, &dm_config->vifs[i]);
     }
     ret = libxl_device_vfb_add(ctx, dm_domid, &dm_config->vfbs[0]);
     if (ret)
@@ -918,9 +926,49 @@ static void spawn_stubdom_pvqemu_cb(libxl__egc *egc,
         CONTAINER_OF(stubdom_dmss, *sdss, pvqemu);
     STATE_AO_GC(sdss->dm.spawn.ao);
     uint32_t dm_domid = sdss->pvqemu.guest_domid;
+    libxl_domain_config *d_config = stubdom_dmss->guest_config;
 
     if (rc) goto out;
 
+    if (!rc && d_config->num_vifs > 0) {
+        sdss->num_devices = d_config->num_vifs;
+        libxl__add_nics(egc, ao, dm_domid, d_config, &sdss->devices,
+                        stubdom_nics_connected);
+        return;
+    }
+
+out:
+    stubdom_pvqemu_cb(egc, stubdom_dmss, rc);
+}
+
+static void stubdom_nics_connected(libxl__egc *egc, libxl__ao_device *aoadd)
+{
+    STATE_AO_GC(aoadd->ao);
+    libxl__stub_dm_spawn_state *sdss =
+        CONTAINER_OF(aoadd->base, *sdss, devices);
+    int last, ret = 0;
+
+    ret = libxl__ao_device_check_last(gc, aoadd, sdss->devices,
+                                      sdss->num_devices, &last);
+
+    if (!last) return;
+    if (ret)
+        LOGE(ERROR, "error connecting nics devices");
+
+    stubdom_pvqemu_cb(egc, &sdss->pvqemu, ret);
+    return;
+}
+
+static void stubdom_pvqemu_cb(libxl__egc *egc,
+                              libxl__dm_spawn_state *stubdom_dmss,
+                              int rc)
+{
+    libxl__stub_dm_spawn_state *sdss =
+        CONTAINER_OF(stubdom_dmss, *sdss, pvqemu);
+    STATE_AO_GC(sdss->dm.spawn.ao);
+    uint32_t dm_domid = sdss->pvqemu.guest_domid;
+
+
     rc = libxl_domain_unpause(CTX, dm_domid);
     if (rc) goto out;
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a5fc092..d303123 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1796,6 +1796,11 @@ _hidden void libxl__device_disk_add(libxl__egc *egc, uint32_t domid,
                                     libxl_device_disk *disk,
                                     libxl__ao_device *aorm);
 
+/* Internal AO operation to connect a nic device */
+_hidden void libxl__device_nic_add(libxl__egc *egc, uint32_t domid,
+                                   libxl_device_nic *nic,
+                                   libxl__ao_device *aorm);
+
 /* Arranges that dev will be added to the guest, and the
  * hotplug scripts will be executed (if necessary). When
  * this is done (or an error happens), the callback in
@@ -1900,6 +1905,12 @@ void libxl__add_disks(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
                       libxl__ao_device **devices,
                       libxl__device_callback callback);
 
+/* Helper function to add a bunch of disks */
+void libxl__add_nics(libxl__egc *egc, libxl__ao *ao, uint32_t domid,
+                     libxl_domain_config *d_config,
+                     libxl__ao_device **devices,
+                     libxl__device_callback callback);
+
 /*----- device model creation -----*/
 
 /* First layer; wraps libxl__spawn_spawn. */
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 69ce45a..46af9fb 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -4970,7 +4970,7 @@ int main_networkattach(int argc, char **argv)
         return 0;
     }
 
-    if (libxl_device_nic_add(ctx, domid, &nic)) {
+    if (libxl_device_nic_add(ctx, domid, &nic, 0)) {
         fprintf(stderr, "libxl_device_nic_add failed.\n");
         return 1;
     }
-- 
1.7.7.5 (Apple Git-26)

  parent reply	other threads:[~2012-05-22 14:02 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-22 14:02 [PATCH v2 0/15] execute hotplug scripts from libxl Roger Pau Monne
2012-05-22 14:02 ` [PATCH v2 01/15] libxl: pass env vars to libxl__exec Roger Pau Monne
2012-05-22 14:02 ` [PATCH v2 02/15] libxl: fix libxl__xs_directory usage of transaction Roger Pau Monne
2012-05-22 14:02 ` [PATCH v2 03/15] libxl: add libxl__xs_path_cleanup Roger Pau Monne
2012-05-22 14:19   ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 04/15] libxl: reoder libxl_device unplug functions Roger Pau Monne
2012-05-22 14:21   ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 05/15] libxl: change libxl__ao_device_remove to libxl__ao_device Roger Pau Monne
2012-05-22 15:10   ` Ian Jackson
2012-05-22 15:27     ` Ian Campbell
2012-05-22 16:23       ` Ian Jackson
2012-05-22 15:34     ` Roger Pau Monne
2012-05-22 15:55     ` Roger Pau Monne
2012-05-22 16:32       ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 06/15] libxl: move device model creation prototypes Roger Pau Monne
2012-05-22 15:10   ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 07/15] libxl: convert libxl_domain_destroy to an async op Roger Pau Monne
2012-05-22 14:11   ` Roger Pau Monne
2012-05-22 17:01   ` Ian Jackson
2012-05-22 17:30     ` Roger Pau Monne
2012-05-22 17:48       ` Ian Jackson
2012-05-23  9:47     ` Roger Pau Monne
2012-05-23 10:45       ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 08/15] libxl: convert libxl_device_disk_add to an asyn op Roger Pau Monne
2012-05-22 17:04   ` Ian Jackson
2012-05-22 14:02 ` Roger Pau Monne [this message]
2012-05-22 17:06   ` [PATCH v2 09/15] libxl: convert libxl_device_nic_add to an async operation Ian Jackson
2012-05-23 10:24     ` Roger Pau Monne
2012-05-22 14:02 ` [PATCH v2 10/15] libxl: add option to choose who executes hotplug scripts Roger Pau Monne
2012-05-22 17:13   ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 11/15] libxl: set nic type to VIF by default Roger Pau Monne
2012-05-22 14:02 ` [PATCH v2 12/15] libxl: call hotplug scripts for disk devices from libxl Roger Pau Monne
2012-05-22 17:40   ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 13/15] libxl: call hotplug scripts for nic " Roger Pau Monne
2012-05-22 17:45   ` Ian Jackson
2012-05-23 15:14     ` Roger Pau Monne
2012-05-22 14:02 ` [PATCH v2 14/15] libxl: use libxl__xs_path_cleanup on device_destroy Roger Pau Monne
2012-05-22 17:46   ` Ian Jackson
2012-05-22 14:02 ` [PATCH v2 15/15] libxl: add dummy netbsd functions Roger Pau Monne
2012-05-22 17:47   ` Ian Jackson
2012-05-22 17:47   ` Ian Jackson
2012-05-23 15:05     ` Roger Pau Monne
2012-05-23 10:07 ` [PATCH v2 0/15] execute hotplug scripts from libxl Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1337695365-5142-10-git-send-email-roger.pau@citrix.com \
    --to=roger.pau@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).