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

[Xen-devel] [PATCH v2 4/5] libxl: call hotplug scripts from libxl for vif



As the previous change already introduces most of needed machinery to call
hotplug scripts from libxl, this only adds the necessary bits to call this
scripts for vif interfaces also.

libxl_device_nic_add has been changed to make use of the new event
functionality, and the necessary vif hotplug code has been added. No changes
where needed in the teardown part, since it uses exactly the same code
introduced for vbd.

An exception has been introduced for tap devices, since hotplug scripts
should be called after the device model has been created, so the hotplug
call for those is done in do_domain_create after confirmation of the device
model startup. On the other hand, tap devices don't use teardown scripts,
so add another exception for that.

libxl__device_from_nic was moved to libxl_device.c, so it can be used
in libxl_create.c, and libxl__device_from_disk was also moved to mantain
the simmetry.

libxl__initiate_device_remove has been changed a little, to nuke the frontend
xenstore path before trying to perform device teardown, this allows for
unitialized devices to be closed gracefully, specially vif interfaces added to
HVM machines and not used.

PV nic devices are set to LIBXL_NIC_TYPE_VIF, since the default value is
LIBXL_NIC_TYPE_IOEMU regardless of the guest type.

A new gobal option, called disable_vif_scripts has been added to allow the user
decide if he wants to execute the hotplug scripts from xl or from udev. This has
been documented in the xl.conf man page.

Changes since v1:

 * Propagated changes from previous patch (disable_udev and libxl_device_nic_add
   switch).

 * Modified udev rules to add the new env variable.

 * Added support for named interfaces.

Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxx>
---
 docs/man/xl.conf.pod.5                |    7 ++
 tools/hotplug/Linux/xen-backend.rules |    6 +-
 tools/libxl/libxl.c                   |   90 +++++++-------------
 tools/libxl/libxl.h                   |    3 +-
 tools/libxl/libxl_create.c            |   22 +++++-
 tools/libxl/libxl_device.c            |   77 +++++++++++++++--
 tools/libxl/libxl_dm.c                |    2 +-
 tools/libxl/libxl_internal.h          |    6 ++
 tools/libxl/libxl_linux.c             |  150 ++++++++++++++++++++++++++++++++-
 tools/libxl/libxl_types.idl           |    1 +
 tools/libxl/xl.c                      |    4 +
 tools/libxl/xl.h                      |    1 +
 tools/libxl/xl_cmdimpl.c              |   15 +++-
 13 files changed, 308 insertions(+), 76 deletions(-)

diff --git a/docs/man/xl.conf.pod.5 b/docs/man/xl.conf.pod.5
index 8bd45ea..cf2c477 100644
--- a/docs/man/xl.conf.pod.5
+++ b/docs/man/xl.conf.pod.5
@@ -55,6 +55,13 @@ default.
 
 Default: C<1>
 
+=item B<disable_vif_scripts=BOOLEAN>
+
+If enabled xl will not execute nic hotplug scripts itself, and instead
+relegate this task to udev.
+
+Default: C<0>
+
 =item B<lockfile="PATH">
 
 Sets the path to the lock file used by xl to serialise certain
diff --git a/tools/hotplug/Linux/xen-backend.rules 
b/tools/hotplug/Linux/xen-backend.rules
index ef8ef8e..35c4e13 100644
--- a/tools/hotplug/Linux/xen-backend.rules
+++ b/tools/hotplug/Linux/xen-backend.rules
@@ -2,8 +2,8 @@ SUBSYSTEM=="xen-backend", KERNEL=="tap*", 
ENV{HOTPLUG_GATE}="$XENBUS_PATH/disabl
 SUBSYSTEM=="xen-backend", KERNEL=="vbd*", 
ENV{HOTPLUG_GATE}="$XENBUS_PATH/disable_udev", RUN+="/etc/xen/scripts/block 
$env{ACTION}"
 SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm 
$env{ACTION}"
 SUBSYSTEM=="xen-backend", KERNEL=="vif2-*", RUN+="/etc/xen/scripts/vif2 
$env{ACTION}"
-SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="online", 
RUN+="/etc/xen/scripts/vif-setup online type_if=vif"
-SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ACTION=="offline", 
RUN+="/etc/xen/scripts/vif-setup offline type_if=vif"
+SUBSYSTEM=="xen-backend", KERNEL=="vif-*", 
ENV{HOTPLUG_GATE}="$XENBUS_PATH/disable_udev", ACTION=="online", 
RUN+="/etc/xen/scripts/vif-setup online type_if=vif"
+SUBSYSTEM=="xen-backend", KERNEL=="vif-*", 
ENV{HOTPLUG_GATE}="$XENBUS_PATH/disable_udev", ACTION=="offline", 
RUN+="/etc/xen/scripts/vif-setup offline type_if=vif"
 SUBSYSTEM=="xen-backend", KERNEL=="vscsi*", RUN+="/etc/xen/scripts/vscsi 
$env{ACTION}"
 SUBSYSTEM=="xen-backend", ACTION=="remove", 
ENV{HOTPLUG_GATE}="$XENBUS_PATH/disable_udev", 
RUN+="/etc/xen/scripts/xen-hotplug-cleanup"
 KERNEL=="evtchn", NAME="xen/%k"
@@ -13,4 +13,4 @@ KERNEL=="blktap-control", NAME="xen/blktap-2/control", 
MODE="0600"
 KERNEL=="gntdev", NAME="xen/%k", MODE="0600"
 KERNEL=="pci_iomul", NAME="xen/%k", MODE="0600"
 KERNEL=="tapdev[a-z]*", NAME="xen/blktap-2/tapdev%m", MODE="0600"
-SUBSYSTEM=="net", KERNEL=="xentap*", ACTION=="add", 
RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
+SUBSYSTEM=="net", KERNEL=="xentap*", ACTION=="add", 
ENV{HOTPLUG_GATE}="$XENBUS_PATH/disable_udev", RUN+="/etc/xen/scripts/vif-setup 
$env{ACTION} type_if=tap"
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 06438ea..d0d6968 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -1277,46 +1277,6 @@ int libxl__device_disk_setdefault(libxl__gc *gc, 
libxl_device_disk *disk)
     return rc;
 }
 
-static int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
-                                   libxl_device_disk *disk,
-                                   libxl__device *device)
-{
-    libxl_ctx *ctx = libxl__gc_owner(gc);
-    int devid;
-
-    devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL);
-    if (devid==-1) {
-        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid or unsupported"
-               " virtual disk identifier %s", disk->vdev);
-        return ERROR_INVAL;
-    }
-
-    device->backend_domid = disk->backend_domid;
-    device->backend_devid = devid;
-
-    switch (disk->backend) {
-        case LIBXL_DISK_BACKEND_PHY:
-            device->backend_kind = LIBXL__DEVICE_KIND_VBD;
-            break;
-        case LIBXL_DISK_BACKEND_TAP:
-            device->backend_kind = LIBXL__DEVICE_KIND_VBD;
-            break;
-        case LIBXL_DISK_BACKEND_QDISK:
-            device->backend_kind = LIBXL__DEVICE_KIND_QDISK;
-            break;
-        default:
-            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unrecognized disk backend type: 
%d\n",
-                       disk->backend);
-            return ERROR_INVAL;
-    }
-
-    device->domid = domid;
-    device->devid = devid;
-    device->kind  = LIBXL__DEVICE_KIND_VBD;
-
-    return 0;
-}
-
 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid,
                           libxl_device_disk *disk,
                           const libxl_asyncop_how *ao_how)
@@ -1831,23 +1791,10 @@ int libxl__device_nic_setdefault(libxl__gc *gc, 
libxl_device_nic *nic)
     return 0;
 }
 
-static int libxl__device_from_nic(libxl__gc *gc, uint32_t domid,
-                                  libxl_device_nic *nic,
-                                  libxl__device *device)
-{
-    device->backend_devid    = nic->devid;
-    device->backend_domid    = nic->backend_domid;
-    device->backend_kind     = LIBXL__DEVICE_KIND_VIF;
-    device->devid            = nic->devid;
-    device->domid            = domid;
-    device->kind             = LIBXL__DEVICE_KIND_VIF;
-
-    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);
     flexarray_t *front;
     flexarray_t *back;
     libxl__device device;
@@ -1862,7 +1809,7 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, 
libxl_device_nic *nic)
         rc = ERROR_NOMEM;
         goto out;
     }
-    back = flexarray_make(16, 1);
+    back = flexarray_make(18, 1);
     if (!back) {
         rc = ERROR_NOMEM;
         goto out_free;
@@ -1915,6 +1862,13 @@ 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__sprintf(gc, "%d", nic->nictype));
+    /* compatibility addon to keep udev rules */
+    if (!nic->disable_vif_script) {
+        flexarray_append(back, "disable_udev");
+        flexarray_append(back, "y");
+    }
 
     flexarray_append(front, "backend-id");
     flexarray_append(front, libxl__sprintf(gc, "%d", nic->backend_domid));
@@ -1929,14 +1883,30 @@ int libxl_device_nic_add(libxl_ctx *ctx, uint32_t 
domid, libxl_device_nic *nic)
                              libxl__xs_kvs_of_flexarray(gc, back, back->count),
                              libxl__xs_kvs_of_flexarray(gc, front, 
front->count));
 
-    /* FIXME: wait for plug */
+    switch(nic->nictype) {
+    case LIBXL_NIC_TYPE_VIF:
+        if (!nic->disable_vif_script) {
+            rc = libxl__initiate_device_add(egc, ao, &device);
+            if (rc) goto out_free;
+        }
+        break;
+    case LIBXL_NIC_TYPE_IOEMU:
+        /*
+         * Don't execute hotplug scripts for IOEMU interfaces yet,
+         * we need to launch the device model first.
+        */
+    default:
+        libxl__ao_complete(egc, ao, 0);
+        break;
+    }
+
     rc = 0;
 out_free:
     flexarray_free(back);
     flexarray_free(front);
 out:
-    GC_FREE;
-    return rc;
+    if (rc) return AO_ABORT(rc);
+    return AO_INPROGRESS;
 }
 
 int libxl_device_nic_remove(libxl_ctx *ctx, uint32_t domid,
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index b7347be..6da6107 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -551,7 +551,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 de598ad..a1f5731 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -607,7 +607,7 @@ static int do_domain_create(libxl__gc *gc, 
libxl_domain_config *d_config,
         }
     }
     for (i = 0; i < d_config->num_vifs; i++) {
-        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i]);
+        ret = libxl_device_nic_add(ctx, domid, &d_config->vifs[i], 0);
         if (ret) {
             LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
                        "cannot add nic %d to domain: %d", i, ret);
@@ -685,6 +685,26 @@ static int do_domain_create(libxl__gc *gc, 
libxl_domain_config *d_config,
                        "device model did not start: %d", ret);
             goto error_out;
         }
+        /* 
+         * Execute hotplug scripts for tap devices, this has to be done
+         * after the domain model has been started.
+        */
+        for (i = 0; i < d_config->num_vifs; i++) {
+            if (d_config->vifs[i].nictype == LIBXL_NIC_TYPE_IOEMU &&
+                !d_config->vifs[i].disable_vif_script) {
+                libxl__device device;
+                ret = libxl__device_from_nic(gc, domid, &d_config->vifs[i],
+                                             &device);
+                if (ret < 0) goto error_out;
+                ret = libxl__device_hotplug(gc, &device, CONNECT);
+                if (ret < 0) {
+                    LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                               "unable to launch hotplug script for device: "
+                               "%"PRIu32, device.devid);
+                    goto error_out;
+                }
+            }
+        }
     }
 
     for (i = 0; i < d_config->num_pcidevs; i++)
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index f352beb..033f23c 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -249,6 +249,60 @@ char 
*libxl__device_disk_string_of_backend(libxl_disk_backend backend)
     }
 }
 
+int libxl__device_from_nic(libxl__gc *gc, uint32_t domid,
+                           libxl_device_nic *nic,
+                           libxl__device *device)
+{
+    device->backend_devid    = nic->devid;
+    device->backend_domid    = nic->backend_domid;
+    device->backend_kind     = LIBXL__DEVICE_KIND_VIF;
+    device->devid            = nic->devid;
+    device->domid            = domid;
+    device->kind             = LIBXL__DEVICE_KIND_VIF;
+
+    return 0;
+}
+
+int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
+                            libxl_device_disk *disk,
+                            libxl__device *device)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    int devid;
+
+    devid = libxl__device_disk_dev_number(disk->vdev, NULL, NULL);
+    if (devid==-1) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid or unsupported"
+               " virtual disk identifier %s", disk->vdev);
+        return ERROR_INVAL;
+    }
+
+    device->backend_domid = disk->backend_domid;
+    device->backend_devid = devid;
+
+    switch (disk->backend) {
+        case LIBXL_DISK_BACKEND_PHY:
+            device->backend_kind = LIBXL__DEVICE_KIND_VBD;
+            break;
+        case LIBXL_DISK_BACKEND_TAP:
+            device->backend_kind = LIBXL__DEVICE_KIND_VBD;
+            break;
+        case LIBXL_DISK_BACKEND_QDISK:
+            device->backend_kind = LIBXL__DEVICE_KIND_QDISK;
+            break;
+        default:
+            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unrecognized disk backend type: 
%d\n",
+                       disk->backend);
+            return ERROR_INVAL;
+    }
+
+    device->domid = domid;
+    device->devid = devid;
+    device->kind  = LIBXL__DEVICE_KIND_VBD;
+
+    return 0;
+}
+
 int libxl__device_physdisk_major_minor(const char *physpath, int *major, int 
*minor)
 {
     struct stat buf;
@@ -450,22 +504,29 @@ int libxl__initiate_device_remove(libxl__egc *egc, 
libxl__ao *ao,
 {
     AO_GC;
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    xs_transaction_t t;
+    xs_transaction_t t = 0;
     char *be_path = libxl__device_backend_path(gc, dev);
     char *state_path = libxl__sprintf(gc, "%s/state", be_path);
-    char *state = libxl__xs_read(gc, XBT_NULL, state_path);
+    char *state;
     int rc = 0;
     libxl__ao_device_remove *aorm = 0;
 
+    /*
+     * Nuke frontend to force backend teardown
+     * It's not pretty, but it's the only way that seems to work for all
+     * types of backends
+     */
+    libxl__xs_path_cleanup(gc, libxl__device_frontend_path(gc, dev));
+
+retry_transaction:
+    t = xs_transaction_start(ctx->xsh);
+    state = libxl__xs_read(gc, t, state_path);
     if (!state)
         goto out_ok;
-    if (atoi(state) != 4) {
+    if (atoi(state) == XenbusStateClosed)
         libxl__device_destroy_tapdisk(gc, be_path);
         goto out_ok;
-    }
 
-retry_transaction:
-    t = xs_transaction_start(ctx->xsh);
     xs_write(ctx->xsh, t, libxl__sprintf(gc, "%s/online", be_path), "0", 
strlen("0"));
     xs_write(ctx->xsh, t, state_path, "5", strlen("5"));
     if (!xs_transaction_end(ctx->xsh, t, 0)) {
@@ -476,6 +537,8 @@ retry_transaction:
             goto out_fail;
         }
     }
+    /* mark transaction as ended, to prevent double closing it on out_ok */
+    t = 0;
 
     libxl__device_destroy_tapdisk(gc, be_path);
 
@@ -497,8 +560,8 @@ retry_transaction:
     return rc;
 
  out_ok:
+    if (t) xs_transaction_end(ctx->xsh, t, 0);
     rc = libxl__device_hotplug(gc, dev, DISCONNECT);
-    libxl__xs_path_cleanup(gc, libxl__device_frontend_path(gc, dev));
     libxl__xs_path_cleanup(gc, be_path);
     return 0;
 }
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 4779a78..04f76c2 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -795,7 +795,7 @@ retry_transaction:
             goto out_free;
     }
     for (i = 0; i < dm_config.num_vifs; i++) {
-        ret = libxl_device_nic_add(ctx, dm_domid, &dm_config.vifs[i]);
+        ret = libxl_device_nic_add(ctx, dm_domid, &dm_config.vifs[i], 0);
         if (ret)
             goto out_free;
     }
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a39346c..3787217 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -756,6 +756,12 @@ _hidden int libxl__domain_pvcontrol_write(libxl__gc *gc, 
xs_transaction_t t,
 _hidden char *libxl__device_disk_string_of_backend(libxl_disk_backend backend);
 _hidden char *libxl__device_disk_string_of_format(libxl_disk_format format);
 _hidden int libxl__device_disk_set_backend(libxl__gc*, libxl_device_disk*);
+_hidden int libxl__device_from_nic(libxl__gc *gc, uint32_t domid,
+                                   libxl_device_nic *nic,
+                                   libxl__device *device);
+_hidden int libxl__device_from_disk(libxl__gc *gc, uint32_t domid,
+                                    libxl_device_disk *disk,
+                                    libxl__device *device);
 
 _hidden int libxl__device_physdisk_major_minor(const char *physpath, int 
*major, int *minor);
 _hidden int libxl__device_disk_dev_number(const char *virtpath,
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index c5583af..1ef282f 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -27,11 +27,30 @@ int libxl__try_phy_backend(mode_t st_mode)
 }
 
 /* Hotplug scripts helpers */
+
+static libxl_nic_type get_nic_type(libxl__gc *gc, libxl__device *dev)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *snictype, *be_path;
+
+    be_path = libxl__device_backend_path(gc, dev);
+
+    snictype = libxl__xs_read(gc, XBT_NULL,
+                            libxl__sprintf(gc, "%s/%s", be_path, "type"));
+    if (!snictype) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to read nictype from %s",
+                                          be_path);
+        return -1;
+    }
+
+    return atoi(snictype);
+}
+
 static char **get_hotplug_env(libxl__gc *gc, libxl__device *dev)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *be_path = libxl__device_backend_path(gc, dev);
-    char *script;
+    char *script, *ifname;
     flexarray_t *f_env;
     int nr = 0;
 
@@ -43,7 +62,7 @@ static char **get_hotplug_env(libxl__gc *gc, libxl__device 
*dev)
         return NULL;
     }
 
-    f_env = flexarray_make(9, 1);
+    f_env = flexarray_make(13, 1);
     if (!f_env) {
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
                    "unable to create environment array");
@@ -62,6 +81,35 @@ static char **get_hotplug_env(libxl__gc *gc, libxl__device 
*dev)
                   dev->domid, dev->devid));
     flexarray_set(f_env, nr++, "XENBUS_BASE_PATH");
     flexarray_set(f_env, nr++, "backend");
+    if (dev->backend_kind == LIBXL__DEVICE_KIND_VIF) {
+        ifname = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/%s",
+                                                                 be_path,
+                                                                 "vifname"));
+        switch (get_nic_type(gc, dev)) {
+        case LIBXL_NIC_TYPE_IOEMU:
+            flexarray_set(f_env, nr++, "INTERFACE");
+            if (ifname) {
+                flexarray_set(f_env, nr++, libxl__sprintf(gc, "xentap-%s",
+                                                              ifname));
+            } else {
+                flexarray_set(f_env, nr++,
+                              libxl__sprintf(gc, "xentap%u.%d",
+                              dev->domid, dev->devid));
+            }
+        case LIBXL_NIC_TYPE_VIF:
+            flexarray_set(f_env, nr++, "vif");
+            if (ifname) {
+                flexarray_set(f_env, nr++, ifname);
+            } else {
+                flexarray_set(f_env, nr++,
+                              libxl__sprintf(gc, "vif%u.%d",
+                              dev->domid, dev->devid));
+            }
+            break;
+        default:
+            return NULL;
+        }
+    }
 
     flexarray_set(f_env, nr++, NULL);
 
@@ -123,6 +171,101 @@ out_free:
     return rc;
 }
 
+static int libxl__hotplug_nic(libxl__gc *gc, libxl__device *dev,
+                              libxl__hotplug_action action)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *be_path = libxl__device_backend_path(gc, dev);
+    char *what, *script;
+    char **args, **env;
+    int nr = 0, rc = 0;
+    libxl_nic_type nictype;
+    flexarray_t *vif_args, *tap_args;
+
+    script = libxl__xs_read(gc, XBT_NULL,
+                            libxl__sprintf(gc, "%s/%s", be_path, "script"));
+    if (!script) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to read script from %s",
+                                          be_path);
+        return -1;
+    }
+
+    nictype = get_nic_type(gc, dev);
+    if (nictype < 0) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "error when fetching nic type");
+        return -1;
+    }
+
+    env = get_hotplug_env(gc, dev);
+    if (!env)
+        return -1;
+
+    vif_args = flexarray_make(4, 1);
+    if (!vif_args) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to create arguments array");
+        return -1;
+    }
+    tap_args = flexarray_make(4, 1);
+    if (!tap_args) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable to create arguments array");
+        return -1;
+    }
+
+    switch(nictype) {
+    case LIBXL_NIC_TYPE_IOEMU:
+        flexarray_set(tap_args, nr++, script);
+        flexarray_set(tap_args, nr++, action == CONNECT ? "add" : "remove");
+        flexarray_set(tap_args, nr++, libxl__sprintf(gc, "type_if=tap"));
+        flexarray_set(tap_args, nr++, NULL);
+        args = (char **) flexarray_contents(tap_args);
+        what = libxl__sprintf(gc, "%s %s", args[0],
+                              action == CONNECT ? "connect" : "disconnect");
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+                   "Calling hotplug script: %s %s %s",
+                   args[0], args[1], args[2]);
+        rc = libxl__hotplug_exec(gc, args[0], args, env);
+        if (rc) {
+            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable execute hotplug scripts "
+                                              "for vif device %"PRIu32,
+                                              dev->devid);
+            goto out;
+        }
+        free(args);
+        nr = 0;
+    case LIBXL_NIC_TYPE_VIF:
+        flexarray_set(vif_args, nr++, script);
+        flexarray_set(vif_args, nr++, action == CONNECT ? "online" : 
"offline");
+        flexarray_set(vif_args, nr++, libxl__sprintf(gc, "type_if=vif"));
+        flexarray_set(vif_args, nr++, NULL);
+        args = (char **) flexarray_contents(vif_args);
+        what = libxl__sprintf(gc, "%s %s", args[0],
+                              action == CONNECT ? "connect" : "disconnect");
+        LIBXL__LOG(ctx, LIBXL__LOG_DEBUG,
+                   "Calling hotplug script: %s %s %s",
+                   args[0], args[1], args[2]);
+        rc = libxl__hotplug_exec(gc, args[0], args, env);
+        if (rc) {
+            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "unable execute hotplug scripts "
+                                              "for vif device %"PRIu32,
+                                              dev->devid);
+            goto out;
+        }
+        break;
+    default:
+        /* Unknown network type */
+        LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "unknown network card type with "
+                                            "id %"PRIu32, dev->devid);
+        return 0;
+    }
+
+    rc = 0;
+
+out:
+    free(env);
+    free(args);
+    return rc;
+}
+
 int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev,
                           libxl__hotplug_action action)
 {
@@ -132,6 +275,9 @@ int libxl__device_hotplug(libxl__gc *gc, libxl__device *dev,
     case LIBXL__DEVICE_KIND_VBD:
         rc = libxl__hotplug_disk(gc, dev, action);
         break;
+    case LIBXL__DEVICE_KIND_VIF:
+        rc = libxl__hotplug_nic(gc, dev, action);
+        break;
     default:
         rc = 0;
         break;
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 09089b2..ac3e79f 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -343,6 +343,7 @@ libxl_device_nic = Struct("device_nic", [
     ("ifname", string),
     ("script", string),
     ("nictype", libxl_nic_type),
+    ("disable_vif_script", integer),
     ])
 
 libxl_device_pci = Struct("device_pci", [
diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c
index a6ffd25..2a705b8 100644
--- a/tools/libxl/xl.c
+++ b/tools/libxl/xl.c
@@ -35,6 +35,7 @@
 xentoollog_logger_stdiostream *logger;
 int dryrun_only;
 int autoballoon = 1;
+int disable_vif_scripts = 0;
 char *lockfile;
 char *default_vifscript = NULL;
 char *default_bridge = NULL;
@@ -66,6 +67,9 @@ static void parse_global_config(const char *configfile,
     if (!xlu_cfg_get_long (config, "autoballoon", &l, 0))
         autoballoon = l;
 
+    if (!xlu_cfg_get_long (config, "disable_vif_scripts", &l, 0))
+        disable_vif_scripts = l;
+
     if (!xlu_cfg_get_string (config, "lockfile", &buf, 0))
         lockfile = strdup(buf);
     else {
diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h
index 7e258d5..13619e7 100644
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -109,6 +109,7 @@ void postfork(void);
 
 /* global options */
 extern int autoballoon;
+extern int disable_vif_scripts;
 extern int dryrun_only;
 extern char *lockfile;
 extern char *default_vifscript;
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 01ff363..41230a6 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -846,6 +846,19 @@ static void parse_config_data(const char 
*configfile_filename_report,
                 nic->script = strdup(default_vifscript);
             }
 
+            /* Set default nic type for PV guests correctly */
+            if (b_info->type == LIBXL_DOMAIN_TYPE_PV) {
+                nic->nictype = LIBXL_NIC_TYPE_VIF;
+            }
+
+            /*
+             * Disable nic network script calling, to allow the user
+             * to attach the nic backend from a different domain.
+             */
+            if (disable_vif_scripts) {
+                nic->disable_vif_script = 1;
+            }
+
            if (default_bridge) {
                free(nic->bridge);
                nic->bridge = strdup(default_bridge);
@@ -4901,7 +4914,7 @@ int main_networkattach(int argc, char **argv)
             return 1;
         }
     }
-    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)


_______________________________________________
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®.