]> xenbits.xensource.com Git - libvirt.git/commitdiff
test_driver: provide basic NIC hotplug support
authorJohn Levon <john.levon@nutanix.com>
Thu, 1 Aug 2024 11:47:40 +0000 (12:47 +0100)
committerMartin Kletzander <mkletzan@redhat.com>
Thu, 3 Oct 2024 07:10:22 +0000 (09:10 +0200)
Provide minimal support for hotplugging ETHERNET or BRIDGE type NICs in
the test driver.

Signed-off-by: John Levon <john.levon@nutanix.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
src/test/test_driver.c

index 7cb77f044de9787853821cf8492fb47f8c7aeeeb..f55bbf6c87c264949b074272dc9e996abdd2c7ec 100644 (file)
@@ -10115,6 +10115,91 @@ testDomainAttachHostPCIDevice(testDriver *driver G_GNUC_UNUSED,
 }
 
 
+static int
+testDomainDeviceAliasIndex(const virDomainDeviceInfo *info,
+                           const char *prefix)
+{
+    int idx;
+
+    if (!info->alias)
+        return -1;
+    if (!STRPREFIX(info->alias, prefix))
+        return -1;
+
+    if (virStrToLong_i(info->alias + strlen(prefix), NULL, 10, &idx) < 0)
+        return -1;
+
+    return idx;
+}
+
+
+static void
+testAssignDeviceNetAlias(virDomainDef *def,
+                         virDomainNetDef *net,
+                         int idx)
+{
+    if (net->info.alias)
+        return;
+
+    if (idx == -1) {
+        size_t i;
+
+        idx = 0;
+        for (i = 0; i < def->nnets; i++) {
+            int thisidx;
+
+            if ((thisidx = testDomainDeviceAliasIndex(&def->nets[i]->info, "net")) < 0)
+                continue; /* failure could be due to "hostdevN" */
+            if (thisidx >= idx)
+                idx = thisidx + 1;
+        }
+    }
+
+    net->info.alias = g_strdup_printf("net%d", idx);
+}
+
+
+static int
+testDomainAttachNetDevice(testDriver *driver G_GNUC_UNUSED,
+                          virDomainObj *vm,
+                          virDomainNetDef *net)
+{
+    virDomainNetType actualType;
+
+    actualType = virDomainNetGetActualType(net);
+
+    testAssignDeviceNetAlias(vm->def, net, -1);
+
+    switch (actualType) {
+    case VIR_DOMAIN_NET_TYPE_ETHERNET:
+    case VIR_DOMAIN_NET_TYPE_BRIDGE:
+        break;
+
+    case VIR_DOMAIN_NET_TYPE_USER:
+    case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
+    case VIR_DOMAIN_NET_TYPE_SERVER:
+    case VIR_DOMAIN_NET_TYPE_CLIENT:
+    case VIR_DOMAIN_NET_TYPE_MCAST:
+    case VIR_DOMAIN_NET_TYPE_NETWORK:
+    case VIR_DOMAIN_NET_TYPE_INTERNAL:
+    case VIR_DOMAIN_NET_TYPE_DIRECT:
+    case VIR_DOMAIN_NET_TYPE_HOSTDEV:
+    case VIR_DOMAIN_NET_TYPE_UDP:
+    case VIR_DOMAIN_NET_TYPE_VDPA:
+    case VIR_DOMAIN_NET_TYPE_NULL:
+    case VIR_DOMAIN_NET_TYPE_VDS:
+    case VIR_DOMAIN_NET_TYPE_LAST:
+        virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+                       _("hotplug of interface type of %1$s is not implemented yet"),
+                       virDomainNetTypeToString(actualType));
+        return -1;
+    }
+
+    VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net);
+
+    return 0;
+}
+
 static int
 testDomainAttachHostDevice(testDriver *driver,
                            virDomainObj *vm,
@@ -10144,28 +10229,68 @@ testDomainAttachDeviceLive(virDomainObj *vm,
                            testDriver *driver)
 {
     const char *alias = NULL;
+    int ret = -1;
 
-    if (dev->type != VIR_DOMAIN_DEVICE_HOSTDEV) {
+    switch (dev->type) {
+    case VIR_DOMAIN_DEVICE_NET:
+        testDomainObjCheckNetTaint(vm, dev->data.net);
+        ret = testDomainAttachNetDevice(driver, vm, dev->data.net);
+        if (ret == 0) {
+            alias = dev->data.net->info.alias;
+            dev->data.net = NULL;
+        }
+        break;
+
+    case VIR_DOMAIN_DEVICE_HOSTDEV:
+        testDomainObjCheckHostdevTaint(vm, dev->data.hostdev);
+        ret = testDomainAttachHostDevice(driver, vm,
+                                         dev->data.hostdev);
+        if (ret == 0) {
+            alias = dev->data.hostdev->info->alias;
+            dev->data.hostdev = NULL;
+        }
+        break;
+
+    case VIR_DOMAIN_DEVICE_NONE:
+    case VIR_DOMAIN_DEVICE_DISK:
+    case VIR_DOMAIN_DEVICE_LEASE:
+    case VIR_DOMAIN_DEVICE_FS:
+    case VIR_DOMAIN_DEVICE_INPUT:
+    case VIR_DOMAIN_DEVICE_SOUND:
+    case VIR_DOMAIN_DEVICE_VIDEO:
+    case VIR_DOMAIN_DEVICE_WATCHDOG:
+    case VIR_DOMAIN_DEVICE_CONTROLLER:
+    case VIR_DOMAIN_DEVICE_GRAPHICS:
+    case VIR_DOMAIN_DEVICE_HUB:
+    case VIR_DOMAIN_DEVICE_REDIRDEV:
+    case VIR_DOMAIN_DEVICE_SMARTCARD:
+    case VIR_DOMAIN_DEVICE_CHR:
+    case VIR_DOMAIN_DEVICE_MEMBALLOON:
+    case VIR_DOMAIN_DEVICE_NVRAM:
+    case VIR_DOMAIN_DEVICE_RNG:
+    case VIR_DOMAIN_DEVICE_SHMEM:
+    case VIR_DOMAIN_DEVICE_TPM:
+    case VIR_DOMAIN_DEVICE_PANIC:
+    case VIR_DOMAIN_DEVICE_MEMORY:
+    case VIR_DOMAIN_DEVICE_IOMMU:
+    case VIR_DOMAIN_DEVICE_VSOCK:
+    case VIR_DOMAIN_DEVICE_AUDIO:
+    case VIR_DOMAIN_DEVICE_CRYPTO:
+    case VIR_DOMAIN_DEVICE_PSTORE:
+    case VIR_DOMAIN_DEVICE_LAST:
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
                        _("live attach of device '%1$s' is not supported"),
                        virDomainDeviceTypeToString(dev->type));
         return -1;
     }
 
-    testDomainObjCheckHostdevTaint(vm, dev->data.hostdev);
-    if (testDomainAttachHostDevice(driver, vm, dev->data.hostdev) < 0)
-        return -1;
-
-    alias = dev->data.hostdev->info->alias;
-    dev->data.hostdev = NULL;
-
     if (alias) {
         virObjectEvent *event;
         event = virDomainEventDeviceAddedNewFromObj(vm, alias);
         virObjectEventStateQueue(driver->eventState, event);
     }
 
-    return 0;
+    return ret;
 }