[libvirt] [PATCH 2/3] libxl: support hotplug of <interface>

Chunyan Liu cyliu at suse.com
Tue Jul 15 05:03:15 UTC 2014


Add code to support attach/detaching a network device.

Signed-off-by: Chunyan Liu <cyliu at suse.com>
---
 src/libxl/libxl_domain.c |  12 +++-
 src/libxl/libxl_driver.c | 146 ++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 149 insertions(+), 9 deletions(-)

diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 0c86601..6780e34 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -482,8 +482,16 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
         STRNEQ(def->os.type, "hvm"))
         dev->data.chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN;
 
-    if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) {
-        virDomainHostdevDefPtr hostdev = dev->data.hostdev;
+    if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV ||
+        (dev->type == VIR_DOMAIN_DEVICE_NET &&
+         dev->data.net->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
+
+        virDomainHostdevDefPtr hostdev;
+
+        if (dev->type == VIR_DOMAIN_DEVICE_NET)
+            hostdev = &(dev->data.net)->data.hostdev.def;
+        else
+            hostdev = dev->data.hostdev;
 
         /* forbid capabilities mode hostdev in this kind of hypervisor */
         if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES) {
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 5e08bba..9cd56b5 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -55,6 +55,7 @@
 #include "viraccessapicheck.h"
 #include "viratomic.h"
 #include "virhostdev.h"
+#include "network/bridge_driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_LIBXL
 
@@ -2674,10 +2675,8 @@ static int
 libxlDomainAttachHostDevice(libxlDriverPrivatePtr driver,
                             libxlDomainObjPrivatePtr priv,
                             virDomainObjPtr vm,
-                            virDomainDeviceDefPtr dev)
+                            virDomainHostdevDefPtr hostdev)
 {
-    virDomainHostdevDefPtr hostdev = dev->data.hostdev;
-
     if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                        _("hostdev mode '%s' not supported"),
@@ -2756,6 +2755,60 @@ libxlDomainDetachDeviceDiskLive(libxlDomainObjPrivatePtr priv,
 }
 
 static int
+libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
+                           libxlDomainObjPrivatePtr priv,
+                           virDomainObjPtr vm,
+                           virDomainNetDefPtr net)
+{
+    int actualType;
+    libxl_device_nic nic;
+    int ret = -1;
+
+    /* preallocate new slot for device */
+    if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
+        return -1;
+
+    /* If appropriate, grab a physical device from the configured
+     * network's pool of devices, or resolve bridge device name
+     * to the one defined in the network definition.
+     */
+    if (networkAllocateActualDevice(vm->def, net) < 0)
+        return -1;
+
+    actualType = virDomainNetGetActualType(net);
+
+    if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+        /* This is really a "smart hostdev", so it should be attached
+         * as a hostdev (the hostdev code will reach over into the
+         * netdev-specific code as appropriate), then also added to
+         * the nets list (see out:) if successful.
+         */
+        ret = libxlDomainAttachHostDevice(driver, priv, vm,
+                                          virDomainNetGetActualHostdev(net));
+        goto out;
+    }
+
+    libxl_device_nic_init(&nic);
+    if (libxlMakeNic(vm->def, net, &nic) < 0)
+        goto cleanup;
+
+    if (libxl_device_nic_add(priv->ctx, vm->def->id, &nic, 0)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("libxenlight failed to attach network device"));
+        goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    libxl_device_nic_dispose(&nic);
+ out:
+    if (!ret)
+        vm->def->nets[vm->def->nnets++] = net;
+    return ret;
+}
+
+static int
 libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
                             libxlDomainObjPrivatePtr priv,
                             virDomainObjPtr vm,
@@ -2770,8 +2823,16 @@ libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
                 dev->data.disk = NULL;
             break;
 
+        case VIR_DOMAIN_DEVICE_NET:
+            ret = libxlDomainAttachNetDevice(driver, priv, vm,
+                                             dev->data.net);
+            if (!ret)
+                dev->data.net = NULL;
+            break;
+
         case VIR_DOMAIN_DEVICE_HOSTDEV:
-            ret = libxlDomainAttachHostDevice(driver, priv, vm, dev);
+            ret = libxlDomainAttachHostDevice(driver, priv, vm,
+                                              dev->data.hostdev);
             if (!ret)
                 dev->data.hostdev = NULL;
             break;
@@ -2790,6 +2851,7 @@ static int
 libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk;
+    virDomainNetDefPtr net;
     virDomainHostdevDefPtr hostdev;
     virDomainHostdevDefPtr found;
 
@@ -2806,6 +2868,14 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
             /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
             dev->data.disk = NULL;
             break;
+
+        case VIR_DOMAIN_DEVICE_NET:
+            net = dev->data.net;
+            if (virDomainNetInsert(vmdef, net))
+                return -1;
+            dev->data.net = NULL;
+            break;
+
         case VIR_DOMAIN_DEVICE_HOSTDEV:
             hostdev = dev->data.hostdev;
 
@@ -2928,9 +2998,8 @@ static int
 libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
                             libxlDomainObjPrivatePtr priv,
                             virDomainObjPtr vm,
-                            virDomainDeviceDefPtr dev)
+                            virDomainHostdevDefPtr hostdev)
 {
-    virDomainHostdevDefPtr hostdev = dev->data.hostdev;
     virDomainHostdevSubsysPtr subsys = &hostdev->source.subsys;
 
     if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
@@ -2954,6 +3023,53 @@ libxlDomainDetachHostDevice(libxlDriverPrivatePtr driver,
 }
 
 static int
+libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
+                           libxlDomainObjPrivatePtr priv,
+                           virDomainObjPtr vm,
+                           virDomainNetDefPtr net)
+{
+    int detachidx;
+    virDomainNetDefPtr detach = NULL;
+    libxl_device_nic nic;
+    char mac[VIR_MAC_STRING_BUFLEN];
+    int ret = -1;
+
+    if ((detachidx = virDomainNetFindIdx(vm->def, net)) < 0)
+        return -1;
+
+    detach = vm->def->nets[detachidx];
+
+    if (virDomainNetGetActualType(detach) == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+        /* This is really a "smart hostdev", so it should be attached as a
+         * hostdev, then also removed from nets list (see out:) if successful.
+         */
+        ret = libxlDomainDetachHostDevice(driver, priv, vm,
+                                          virDomainNetGetActualHostdev(detach));
+        goto out;
+    }
+
+    libxl_device_nic_init(&nic);
+    if (libxl_mac_to_device_nic(priv->ctx, vm->def->id,
+                                virMacAddrFormat(&detach->mac, mac), &nic))
+        goto cleanup;
+
+    if (libxl_device_nic_remove(priv->ctx, vm->def->id, &nic, 0)) {
+        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                       _("libxenlight failed to detach network device"));
+        goto cleanup;
+    }
+
+    ret = 0;
+
+ cleanup:
+    libxl_device_nic_dispose(&nic);
+ out:
+    if (!ret)
+        virDomainNetRemove(vm->def, detachidx);
+    return ret;
+}
+
+static int
 libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
                             libxlDomainObjPrivatePtr priv,
                             virDomainObjPtr vm,
@@ -2966,8 +3082,14 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
             ret = libxlDomainDetachDeviceDiskLive(priv, vm, dev);
             break;
 
+        case VIR_DOMAIN_DEVICE_NET:
+            ret = libxlDomainDetachNetDevice(driver, priv, vm,
+                                             dev->data.net);
+            break;
+
         case VIR_DOMAIN_DEVICE_HOSTDEV:
-            ret = libxlDomainDetachHostDevice(driver, priv, vm, dev);
+            ret = libxlDomainDetachHostDevice(driver, priv, vm,
+                                              dev->data.hostdev);
             break;
 
         default:
@@ -2986,6 +3108,7 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk, detach;
     virDomainHostdevDefPtr hostdev, det_hostdev;
+    virDomainNetDefPtr net;
     int idx;
 
     switch (dev->type) {
@@ -2999,6 +3122,15 @@ libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
             virDomainDiskDefFree(detach);
             break;
 
+        case VIR_DOMAIN_DEVICE_NET:
+            net = dev->data.net;
+            if ((idx = virDomainNetFindIdx(vmdef, net)) < 0)
+                return -1;
+
+            /* this is guaranteed to succeed */
+            virDomainNetDefFree(virDomainNetRemove(vmdef, idx));
+            break;
+
         case VIR_DOMAIN_DEVICE_HOSTDEV: {
             hostdev = dev->data.hostdev;
             if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) {
-- 
1.8.4.5




More information about the libvir-list mailing list