Provide minimal support for hotplugging ETHERNET or BRIDGE type NICs in the test driver. Signed-off-by: John Levon <john.levon@xxxxxxxxxxx> --- src/test/test_driver.c | 146 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 9 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 7cb77f044d..4915c13a25 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -38,6 +38,7 @@ #include "virnetworkobj.h" #include "interface_conf.h" #include "checkpoint_conf.h" +#include "domain_audit.h" #include "domain_conf.h" #include "domain_driver.h" #include "domain_event.h" @@ -10115,6 +10116,93 @@ 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); + + virDomainAuditNet(vm, NULL, net, "attach", true); + + return 0; +} + static int testDomainAttachHostDevice(testDriver *driver, virDomainObj *vm, @@ -10144,28 +10232,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) { + 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) { + 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; } -- 2.34.1