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

[Xen-devel] [PATCH 13/13] libxl: call hotplug scripts for nic devices from libxl



Since most of the needed work is already done in previous patches,
this patch only contains the necessary code to call hotplug scripts
for nic devices, that should be called when the device is added or
removed from a guest.

Since the call to libxl__device_hotplug is already there, this patch
only adds the necessary code to this function to handle the vif case,
and the necessary modification in the udev rules.

Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
Signed-off-by: Roger Pau Monne <roger.pau@xxxxxxxxxx>
---
 tools/hotplug/Linux/xen-backend.rules |    6 +-
 tools/libxl/libxl_internal.h          |    1 +
 tools/libxl/libxl_linux.c             |  130 ++++++++++++++++++++++++++++++++-
 3 files changed, 133 insertions(+), 4 deletions(-)

diff --git a/tools/hotplug/Linux/xen-backend.rules 
b/tools/hotplug/Linux/xen-backend.rules
index d55ff11..c591a3f 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{UDEV_CALL}="1", 
RUN+="/etc/xen/scr
 SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ENV{UDEV_CALL}="1", 
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{UDEV_CALL}="1", 
ACTION=="online", RUN+="/etc/xen/scripts/vif-setup online type_if=vif"
+SUBSYSTEM=="xen-backend", KERNEL=="vif-*", ENV{UDEV_CALL}="1", 
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{UDEV_CALL}="1", 
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=="vif*-emu", ACTION=="add", 
RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
+SUBSYSTEM=="net", KERNEL=="vif*-emu", ACTION=="add", ENV{UDEV_CALL}="1", 
RUN+="/etc/xen/scripts/vif-setup $env{ACTION} type_if=tap"
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 5e2bac5..b5002db 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1817,6 +1817,7 @@ struct libxl__ao_device {
     /* device hotplug execution */
     pid_t pid;
     char *what;
+    int vif_executed;
     libxl__ev_time ev;
     libxl__ev_child child;
 };
diff --git a/tools/libxl/libxl_linux.c b/tools/libxl/libxl_linux.c
index 315ce15..6e752bd 100644
--- a/tools/libxl/libxl_linux.c
+++ b/tools/libxl/libxl_linux.c
@@ -28,6 +28,26 @@ 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)
+{
+    char *snictype, *be_path;
+    libxl_nic_type nictype;
+
+    be_path = libxl__device_backend_path(gc, dev);
+    snictype = libxl__xs_read(gc, XBT_NULL,
+                              GCSPRINTF("%s/%s", be_path, "type"));
+    if (!snictype) {
+        LOGE(ERROR, "unable to read nictype from %s", be_path);
+        return -1;
+    }
+    if (libxl_nic_type_from_string(snictype, &nictype) < 0) {
+        LOGE(ERROR, "unable to parse nictype from %s", be_path);
+        return -1;
+    }
+
+    return nictype;
+}
+
 static void cleanup(libxl__gc *gc, libxl__ao_device *aorm)
 {
     if (!aorm) return;
@@ -47,7 +67,18 @@ static void callback(libxl__egc *egc, libxl__ev_child *child,
                                                     : LIBXL__LOG_WARNING,
                                       aorm->what, pid, status);
         aorm->rc = ERROR_FAIL;
+        goto out;
+    }
+
+    if (aorm->dev->backend_kind == LIBXL__DEVICE_KIND_VIF &&
+        get_nic_type(gc, aorm->dev) == LIBXL_NIC_TYPE_IOEMU &&
+        !aorm->vif_executed) {
+        aorm->vif_executed = 1;
+        libxl__device_hotplug(egc, aorm);
+        return;
     }
+
+out:
     aorm->callback(egc, aorm);
 }
 
@@ -66,7 +97,7 @@ static char **get_hotplug_env(libxl__gc *gc, libxl__device 
*dev)
         return NULL;
     }
 
-    GCNEW_ARRAY(env, 9);
+    GCNEW_ARRAY(env, 13);
     env[nr++] = "script";
     env[nr++] = script;
     env[nr++] = "XENBUS_TYPE";
@@ -75,6 +106,24 @@ static char **get_hotplug_env(libxl__gc *gc, libxl__device 
*dev)
     env[nr++] = GCSPRINTF("backend/%s/%u/%d", type, dev->domid, dev->devid);
     env[nr++] = "XENBUS_BASE_PATH";
     env[nr++] = "backend";
+    if (dev->backend_kind == LIBXL__DEVICE_KIND_VIF) {
+        switch (get_nic_type(gc, dev)) {
+        case LIBXL_NIC_TYPE_IOEMU:
+            env[nr++] = "INTERFACE";
+            env[nr++] = libxl__strdup(gc, libxl__device_nic_devname(gc,
+                                                      dev->domid, dev->devid,
+                                                      LIBXL_NIC_TYPE_IOEMU));
+        case LIBXL_NIC_TYPE_VIF:
+            env[nr++] = "vif";
+            env[nr++] = libxl__strdup(gc, libxl__device_nic_devname(gc,
+                                                      dev->domid, dev->devid,
+                                                      LIBXL_NIC_TYPE_VIF));
+            break;
+        default:
+            return NULL;
+        }
+    }
+
     env[nr++] = NULL;
 
     return env;
@@ -119,6 +168,81 @@ out_free:
     return rc;
 }
 
+static int libxl__hotplug_nic(libxl__gc *gc, libxl__ao_device *aorm)
+{
+    char *be_path = libxl__device_backend_path(gc, aorm->dev);
+    char *what, *script;
+    char **args, **env;
+    int nr = 0, rc = 0;
+    libxl_nic_type nictype;
+
+    script = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/%s", be_path,
+                                                             "script"));
+    if (!script) {
+        LOGE(ERROR, "unable to read script from %s", be_path);
+        return -1;
+    }
+
+    nictype = get_nic_type(gc, aorm->dev);
+    if (nictype < 0) {
+        LOGE(ERROR, "error when fetching nic type");
+        return -1;
+    }
+
+    env = get_hotplug_env(gc, aorm->dev);
+    if (!env)
+        return -1;
+
+    GCNEW_ARRAY(args, 4);
+
+    switch (nictype) {
+    case LIBXL_NIC_TYPE_IOEMU:
+        if (!aorm->vif_executed) goto execute_vif;
+        args[nr++] = script;
+        args[nr++] = aorm->action == DEVICE_CONNECT ? "add" : "remove";
+        args[nr++] = libxl__strdup(gc, "type_if=tap");
+        args[nr++] = NULL;
+        what = GCSPRINTF("%s %s", args[0], aorm->action == DEVICE_CONNECT ?
+                                           "connect" : "disconnect");
+        LOG(DEBUG, "Calling hotplug script: %s %s %s",
+                   args[0], args[1], args[2]);
+        rc = libxl__hotplug_launch(gc, aorm, args[0], args, env, callback);
+        if (rc) {
+            LOGE(ERROR, "unable execute hotplug scripts for vif device 
%"PRIu32,
+                        aorm->dev->devid);
+            goto out;
+        }
+        break;
+    case LIBXL_NIC_TYPE_VIF:
+execute_vif:
+        args[nr++] = script;
+        args[nr++] = aorm->action == DEVICE_CONNECT ? "online" : "offline";
+        args[nr++] = libxl__strdup(gc, "type_if=vif");
+        args[nr++] = NULL;
+        what = GCSPRINTF("%s %s", args[0], aorm->action == DEVICE_CONNECT ?
+                                           "connect" : "disconnect");
+        LOG(DEBUG, "Calling hotplug script: %s %s %s",
+                   args[0], args[1], args[2]);
+        rc = libxl__hotplug_launch(gc, aorm, args[0], args, env, callback);
+        if (rc) {
+            LOGE(ERROR, "unable execute hotplug scripts for vif device 
%"PRIu32,
+                        aorm->dev->devid);
+            goto out;
+        }
+        break;
+    default:
+        /* Unknown network type */
+        LOG(DEBUG, "unknown network card type with id %"PRIu32,
+                   aorm->dev->devid);
+        return 0;
+    }
+
+    rc = 0;
+
+out:
+    return rc;
+}
+
 void libxl__device_hotplug(libxl__egc *egc, libxl__ao_device *aorm)
 {
     STATE_AO_GC(aorm->ao);
@@ -132,6 +256,10 @@ void libxl__device_hotplug(libxl__egc *egc, 
libxl__ao_device *aorm)
         aorm->rc = libxl__hotplug_disk(gc, aorm);
         if (aorm->rc) goto error;
         break;
+    case LIBXL__DEVICE_KIND_VIF:
+        aorm->rc = libxl__hotplug_nic(gc, aorm);
+        if (aorm->rc) goto error;
+        break;
     default:
         /* If no need to execute any hotplug scripts,
          * call the callback manually
-- 
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®.