[libvirt] [PATCH v2 11/14] libxl: support network device attach/detach

Marek Marczykowski-Górecki marmarek at invisiblethingslab.com
Thu Jun 13 01:54:13 UTC 2013


Both live and config.

Signed-off-by: Marek Marczykowski-Górecki <marmarek at invisiblethingslab.com>
---
 src/libxl/libxl_driver.c | 164 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 161 insertions(+), 3 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 7b50853..ae0d4f7 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3417,6 +3417,111 @@ cleanup:
 }
 
 static int
+libxlDomainAttachDeviceNetLive(libxlDriverPrivatePtr driver,
+                               libxlDomainObjPrivatePtr priv,
+                               virDomainObjPtr vm,
+                               virDomainDeviceDefPtr dev)
+{
+    virDomainNetDefPtr l_net = dev->data.net;
+    libxl_device_nic x_nic;
+    char mac[VIR_MAC_STRING_BUFLEN];
+    int ret = -1;
+
+    switch (dev->data.net->type)  {
+        case VIR_DOMAIN_NET_TYPE_ETHERNET:
+        case VIR_DOMAIN_NET_TYPE_BRIDGE:
+            /* -2 means "multiple matches" so then fail also */
+            if (virDomainNetFindIdx(vm->def, dev->data.net) != -1) {
+                virReportError(VIR_ERR_OPERATION_FAILED,
+                        _("device matching mac address %s already exists"),
+                        virMacAddrFormat(&dev->data.net->mac, mac));
+                goto cleanup;
+            }
+
+            if (libxlMakeNic(driver, l_net, &x_nic) < 0)
+                goto cleanup;
+
+            if ((ret = libxl_device_nic_add(priv->ctx, vm->def->id,
+                            &x_nic, NULL)) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("libxenlight failed to attach net '%s'"),
+                        virMacAddrFormat(&dev->data.net->mac, mac));
+                goto cleanup;
+            }
+
+            virDomainNetInsert(vm->def, l_net);
+
+            break;
+        default:
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                    _("net device type '%s' cannot be hotplugged"),
+                    virDomainNetTypeToString(l_net->type));
+            break;
+    }
+
+cleanup:
+    return ret;
+}
+
+static int
+libxlDomainDetachDeviceNetLive(libxlDriverPrivatePtr driver,
+                               libxlDomainObjPrivatePtr priv,
+                               virDomainObjPtr vm,
+                               virDomainDeviceDefPtr dev)
+{
+    virDomainNetDefPtr l_net = NULL;
+    libxl_device_nic x_nic;
+    char mac[VIR_MAC_STRING_BUFLEN];
+    int i;
+    int ret = -1;
+
+    switch (dev->data.net->type)  {
+        case VIR_DOMAIN_NET_TYPE_ETHERNET:
+        case VIR_DOMAIN_NET_TYPE_BRIDGE:
+            if ((i = virDomainNetFindIdx(vm->def, dev->data.net)) < 0) {
+                if (i == -2) {
+
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                            _("multiple devices matching mac address %s found"),
+                            virMacAddrFormat(&dev->data.net->mac, mac));
+                }
+                else {
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                            _("network device %s not found"),
+                            virMacAddrFormat(&dev->data.net->mac, mac));
+                }
+                goto cleanup;
+            }
+
+            l_net = vm->def->nets[i];
+
+            if (libxlMakeNic(driver, l_net, &x_nic) < 0)
+                goto cleanup;
+
+            if ((ret = libxl_device_nic_remove(priv->ctx, vm->def->id,
+                            &x_nic, NULL)) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR,
+                        _("libxenlight failed to detach nic '%d'"),
+                        i);
+                goto cleanup;
+            }
+
+            virDomainNetRemove(vm->def, i);
+            virDomainNetDefFree(l_net);
+
+            break;
+        default:
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("net device type '%s' cannot hot unplugged"),
+                           virDomainNetTypeToString(dev->data.net->type));
+            break;
+    }
+
+cleanup:
+    return ret;
+}
+
+static int
 libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
                             libxlDomainObjPrivatePtr priv, virDomainObjPtr vm,
                             virDomainDeviceDefPtr dev)
@@ -3430,6 +3535,12 @@ libxlDomainAttachDeviceLive(libxlDriverPrivatePtr driver,
                 dev->data.disk = NULL;
             break;
 
+        case VIR_DOMAIN_DEVICE_NET:
+            ret = libxlDomainAttachDeviceNetLive(driver, priv, vm, dev);
+            if (!ret)
+                dev->data.net = NULL;
+            break;
+
         default:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("device type '%s' cannot be attached"),
@@ -3444,6 +3555,8 @@ static int
 libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 {
     virDomainDiskDefPtr disk;
+    virDomainNetDefPtr net;
+    char mac[VIR_MAC_STRING_BUFLEN];
 
     switch (dev->type) {
         case VIR_DOMAIN_DEVICE_DISK:
@@ -3461,6 +3574,22 @@ libxlDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
             dev->data.disk = NULL;
             break;
 
+        case VIR_DOMAIN_DEVICE_NET:
+            net = dev->data.net;
+            if (virDomainNetFindIdx(vmdef, net) >= 0) {
+                virReportError(VIR_ERR_INVALID_ARG,
+                               _("net device with mac %s already exists."),
+                               virMacAddrFormat(&net->mac, mac));
+                return -1;
+            }
+            if (virDomainNetInsert(vmdef, net)) {
+                virReportOOMError();
+                return -1;
+            }
+            /* vmdef has the pointer. Generic codes for vmdef will do all jobs */
+            dev->data.net = NULL;
+            break;
+
         default:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("persistent attach of device is not supported"));
@@ -3482,6 +3611,10 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
             ret = libxlDomainDetachDeviceDiskLive(driver, priv, vm, dev);
             break;
 
+        case VIR_DOMAIN_DEVICE_NET:
+            ret = libxlDomainDetachDeviceNetLive(driver, priv, vm, dev);
+            break;
+
         default:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
                            _("device type '%s' cannot be detached"),
@@ -3495,20 +3628,45 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
 static int
 libxlDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev)
 {
-    virDomainDiskDefPtr disk, detach;
+    virDomainDiskDefPtr disk, disk_detach;
+    virDomainNetDefPtr net, net_detach;
+    char mac[VIR_MAC_STRING_BUFLEN];
+    int net_idx;
     int ret = -1;
 
     switch (dev->type) {
         case VIR_DOMAIN_DEVICE_DISK:
             disk = dev->data.disk;
-            if (!(detach = virDomainDiskRemoveByName(vmdef, disk->dst))) {
+            if (!(disk_detach = virDomainDiskRemoveByName(vmdef, disk->dst))) {
                 virReportError(VIR_ERR_INVALID_ARG,
                                _("no target device %s"), disk->dst);
                 break;
             }
-            virDomainDiskDefFree(detach);
+            virDomainDiskDefFree(disk_detach);
+            ret = 0;
+            break;
+
+        case VIR_DOMAIN_DEVICE_NET:
+            net = dev->data.net;
+            if ((net_idx = virDomainNetFindIdx(vmdef, net)) < 0) {
+                if (net_idx == -2) {
+
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                            _("multiple devices matching mac address %s found"),
+                            virMacAddrFormat(&dev->data.net->mac, mac));
+                }
+                else {
+                    virReportError(VIR_ERR_OPERATION_FAILED,
+                            _("network device %s not found"),
+                            virMacAddrFormat(&dev->data.net->mac, mac));
+                }
+                return -1;
+            }
+            net_detach = virDomainNetRemove(vmdef, net_idx);
+            virDomainNetDefFree(net_detach);
             ret = 0;
             break;
+
         default:
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                            _("persistent detach of device is not supported"));
-- 
1.8.1.4




More information about the libvir-list mailing list