[PATCH 4/5] ch: implement network device hot detach

Stefan Kober posted 5 patches 3 weeks ago
[PATCH 4/5] ch: implement network device hot detach
Posted by Stefan Kober 3 weeks ago
On-behalf-of: SAP stefan.kober@sap.com
Signed-off-by: Stefan Kober <stefan.kober@cyberus-technology.de>
---
 src/ch/ch_hotplug.c | 69 ++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 65 insertions(+), 4 deletions(-)

diff --git a/src/ch/ch_hotplug.c b/src/ch/ch_hotplug.c
index 25058e08f3..480acf93a6 100644
--- a/src/ch/ch_hotplug.c
+++ b/src/ch/ch_hotplug.c
@@ -24,6 +24,7 @@
 #include "ch_process.h"
 
 #include "domain_event.h"
+#include "domain_interface.h"
 #include "domain_validate.h"
 #include "virlog.h"
 
@@ -220,6 +221,50 @@ chDomainFindDisk(virDomainObj *vm,
 }
 
 
+static int
+chFindNetID(virDomainDef *def, const char *dst)
+{
+    size_t i;
+
+    for (i = 0; i < def->nnets; i++) {
+        if (STREQ(def->nets[i]->ifname, dst))
+            return i;
+    }
+
+    return -1;
+}
+
+/**
+ * chDomainFindNet
+ *
+ * Helper function to find a network device definition of a domain.
+ *
+ * Searches through the network devices of a domain by comparing to 'match' and
+ * returns any match via the 'detach' out parameter.
+ */
+static int
+chDomainFindNet(virDomainObj *vm,
+                virDomainNetDef *match,
+                virDomainNetDef **detach)
+{
+    int idx;
+
+    if (!match->ifname) {
+        virReportError(VIR_ERR_DEVICE_MISSING, "%s",
+                       _("no interface name specified"));
+        return -1;
+    }
+    if ((idx = chFindNetID(vm->def, match->ifname)) < 0) {
+        virReportError(VIR_ERR_DEVICE_MISSING,
+                       _("net %1$s not found"), match->ifname);
+        return -1;
+    }
+    *detach = vm->def->nets[idx];
+
+    return 0;
+}
+
+
 static int
 chDomainRemoveDevice(virDomainObj *vm,
                      virDomainDeviceDef *device)
@@ -239,9 +284,19 @@ chDomainRemoveDevice(virDomainObj *vm,
             }
         }
         break;
+    case VIR_DOMAIN_DEVICE_NET:
+        virDomainInterfaceStopDevice(device->data.net);
+        virDomainInterfaceDeleteDevice(vm->def, device->data.net, false, NULL);
+        for (i = 0; i < vm->def->nnets; i++) {
+            if (vm->def->nets[i] == device->data.net) {
+                virDomainNetRemove(vm->def, i);
+                g_clear_pointer(&device->data.net, virDomainNetDefFree);
+                break;
+            }
+        }
+        break;
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_FS:
-    case VIR_DOMAIN_DEVICE_NET:
     case VIR_DOMAIN_DEVICE_INPUT:
     case VIR_DOMAIN_DEVICE_SOUND:
     case VIR_DOMAIN_DEVICE_VIDEO:
@@ -296,9 +351,14 @@ chDomainDetachDeviceLive(virCHDriver *driver,
             return -1;
         }
         break;
+    case VIR_DOMAIN_DEVICE_NET:
+        if (chDomainFindNet(vm, match->data.net,
+                            &detach.data.net) < 0) {
+            return -1;
+        }
+        break;
     case VIR_DOMAIN_DEVICE_LEASE:
     case VIR_DOMAIN_DEVICE_FS:
-    case VIR_DOMAIN_DEVICE_NET:
     case VIR_DOMAIN_DEVICE_INPUT:
     case VIR_DOMAIN_DEVICE_SOUND:
     case VIR_DOMAIN_DEVICE_VIDEO:
@@ -360,8 +420,9 @@ chDomainDetachDeviceLive(virCHDriver *driver,
     alias = g_strdup(info->alias);
 
     if (virCHMonitorRemoveDevice(priv->monitor, info->alias) < 0) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("Invalid response from CH. Disk removal failed."));
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("Invalid response from CH. Device removal failed for device %1$s."),
+                       info->alias);
         return -1;
     }
 
-- 
2.51.0