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