Provide minimal support for hotunplugging ETHERNET or BRIDGE type NICs in the test driver. Signed-off-by: John Levon <john.levon@xxxxxxxxxxx> --- src/test/test_driver.c | 159 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 146 insertions(+), 13 deletions(-) diff --git a/src/test/test_driver.c b/src/test/test_driver.c index 4915c13a25..9a25e9548c 100644 --- a/src/test/test_driver.c +++ b/src/test/test_driver.c @@ -10568,6 +10568,22 @@ testDomainDetachPrepHostdev(virDomainObj *vm, } +static int +testDomainDetachPrepNet(virDomainObj *vm, + virDomainNetDef *match, + virDomainNetDef **detach) +{ + int detachidx; + + if ((detachidx = virDomainNetFindIdx(vm->def, match)) < 0) + return -1; + + *detach = vm->def->nets[detachidx]; + + return 0; +} + + static int testDomainRemoveHostDevice(testDriver *driver G_GNUC_UNUSED, virDomainObj *vm, @@ -10590,6 +10606,55 @@ testDomainRemoveHostDevice(testDriver *driver G_GNUC_UNUSED, } +static int +testDomainRemoveNetDevice(testDriver *driver G_GNUC_UNUSED, + virDomainObj *vm, + virDomainNetDef *net) +{ + size_t i; + int actualType = virDomainNetGetActualType(net); + + 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, + _("live detach of interface type %1$s is not implemented yet"), + virDomainNetTypeToString(actualType)); + return -1; + } + + VIR_DEBUG("Removing network interface %s from domain %p %s", + net->info.alias, vm, vm->def->name); + + virDomainAuditNet(vm, net, NULL, "detach", true); + + for (i = 0; i < vm->def->nnets; i++) { + if (vm->def->nets[i] == net) { + virDomainNetRemove(vm->def, i); + break; + } + } + + virDomainNetDefFree(net); + return 0; +} + static int testDomainRemoveDevice(testDriver *driver, virDomainObj *vm, @@ -10598,13 +10663,6 @@ testDomainRemoveDevice(testDriver *driver, virDomainDeviceInfo *info = NULL; g_autofree char *alias = NULL; - if (dev->type != VIR_DOMAIN_DEVICE_HOSTDEV) { - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("don't know how to remove a %1$s device"), - virDomainDeviceTypeToString(dev->type)); - return -1; - } - /* * save the alias to use when sending a DEVICE_REMOVED event after * all other teardown is complete @@ -10613,8 +10671,47 @@ testDomainRemoveDevice(testDriver *driver, alias = g_strdup(info->alias); } - if (testDomainRemoveHostDevice(driver, vm, dev->data.hostdev) < 0) + switch (dev->type) { + case VIR_DOMAIN_DEVICE_NET: + if (testDomainRemoveNetDevice(driver, vm, dev->data.net) < 0) + return -1; + break; + case VIR_DOMAIN_DEVICE_HOSTDEV: + if (testDomainRemoveHostDevice(driver, vm, dev->data.hostdev) < 0) + return -1; + 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 detach of device '%1$s' is not supported"), + virDomainDeviceTypeToString(dev->type)); return -1; + } if (alias) { virObjectEvent *event; @@ -10634,17 +10731,53 @@ testDomainDetachDeviceLive(testDriver *driver, virDomainDeviceDef detach = { .type = match->type }; virDomainDeviceInfo *info = NULL; - if (match->type != VIR_DOMAIN_DEVICE_HOSTDEV) { + switch (match->type) { + case VIR_DOMAIN_DEVICE_NET: + if (testDomainDetachPrepNet(vm, match->data.net, + &detach.data.net) < 0) { + return -1; + } + break; + case VIR_DOMAIN_DEVICE_HOSTDEV: + if (testDomainDetachPrepHostdev(vm, match->data.hostdev, + &detach.data.hostdev) < 0) { + return -1; + } + 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 detach of device '%1$s' is not supported"), virDomainDeviceTypeToString(match->type)); return -1; } - if (testDomainDetachPrepHostdev(vm, match->data.hostdev, - &detach.data.hostdev) < 0) - return -1; - /* "detach" now points to the actual device we want to detach */ if (!(info = virDomainDeviceGetInfo(&detach))) { -- 2.34.1