libxl / LXC / QEMU drivers share some common codes in their DomainDetachDeviceConfig functions, so extract them to domain_conf and use them with xmlopt etc to deduplicate the bigger function. At the same time, this will enable test driver to test these functions in the future. Signed-off-by: Luke Yue <lukedyue@xxxxxxxxx> --- Compare to the v3, I remove the random comments, and align the error messages, also add virDomainDetachChrDeviceConfig by using xmlopt. Then I got a lot of choices here: 1. Just cleanup these functions and using them in drivers, just like what I did in the previous patch. 2. Add a bigger de-duplicated function to de-duplicate the function in libxl / LXC / QEMU drivers, and this is what I choose in this patch. 3. Merge all the functions into the bigger one, instead of splitting them This would still de-duplicate the functions in libxl / LXC / QEMU drivers. I choose the second here as I think there would be a situation that both these single device detach functions and the bigger function would be used in drivers. --- src/conf/domain_conf.c | 487 +++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 78 +++++++ src/libvirt_private.syms | 18 ++ src/libxl/libxl_driver.c | 73 +----- src/lxc/lxc_driver.c | 62 +---- src/qemu/qemu_driver.c | 207 +---------------- 6 files changed, 610 insertions(+), 315 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 27643cab16..ab2e1f2e36 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -31576,3 +31576,490 @@ virDomainObjGetMessages(virDomainObj *vm, return rv; } + + +int +virDomainDetachDiskDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainDiskDef *disk; + virDomainDiskDef *det_disk; + + disk = dev->data.disk; + if (!(det_disk = virDomainDiskRemoveByName(vmdef, disk->dst))) { + virReportError(VIR_ERR_DEVICE_MISSING, + _("no matching disk device %s was found"), + disk->dst); + return -1; + } + + virDomainDiskDefFree(det_disk); + + return 0; +} + + +int +virDomainDetachNetDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainNetDef *net; + int idx; + + net = dev->data.net; + if ((idx = virDomainNetFindIdx(vmdef, net)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching net device was found")); + return -1; + } + + virDomainNetDefFree(virDomainNetRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachSoundDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainSoundDef *sound; + int idx; + + sound = dev->data.sound; + if ((idx = virDomainSoundDefFind(vmdef, sound)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching sound device was found")); + return -1; + } + + virDomainSoundDefFree(virDomainSoundDefRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachHostdevDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainHostdevDef *hostdev; + virDomainHostdevDef *det_hostdev; + int idx; + + hostdev = dev->data.hostdev; + if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching hostdev device was found")); + return -1; + } + + virDomainHostdevDefFree(virDomainHostdevRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachLeaseDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainLeaseDef *lease; + virDomainLeaseDef *det_lease; + + lease = dev->data.lease; + if (!(det_lease = virDomainLeaseRemove(vmdef, lease))) { + virReportError(VIR_ERR_DEVICE_MISSING, + _("no matching lease %s in lockspace %s was found"), + lease->key, NULLSTR(lease->lockspace)); + return -1; + } + + virDomainLeaseDefFree(det_lease); + + return 0; +} + + +int +virDomainDetachControllerDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainControllerDef *cont; + int idx; + + cont = dev->data.controller; + if ((idx = virDomainControllerFind(vmdef, cont->type, cont->idx)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching controller device was found")); + return -1; + } + + virDomainControllerDefFree(virDomainControllerRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachFSDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainFSDef *fs; + int idx; + + fs = dev->data.fs; + if ((idx = virDomainFSIndexByName(vmdef, fs->dst)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching filesystem device was found")); + return -1; + } + + virDomainFSDefFree(virDomainFSRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachRNGDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + int idx; + + if ((idx = virDomainRNGFind(vmdef, dev->data.rng)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching RNG device was found")); + return -1; + } + + virDomainRNGDefFree(virDomainRNGRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachMemoryDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + virDomainMemoryDef *mem; + int idx; + + if ((idx = virDomainMemoryFindInactiveByDef(vmdef, + dev->data.memory)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching memory device was found")); + return -1; + } + + mem = virDomainMemoryRemove(vmdef, idx); + vmdef->mem.cur_balloon -= mem->size; + virDomainMemoryDefFree(mem); + + return 0; +} + + +int +virDomainDetachRedirdevDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + int idx; + + if ((idx = virDomainRedirdevDefFind(vmdef, + dev->data.redirdev)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching redirdev was found")); + return -1; + } + + virDomainRedirdevDefFree(virDomainRedirdevDefRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachShmemDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + int idx; + + if ((idx = virDomainShmemDefFind(vmdef, dev->data.shmem)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching shmem device was found")); + return -1; + } + + virDomainShmemDefFree(virDomainShmemDefRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachWatchdogDeviceConfig(virDomainDef *vmdef) +{ + if (!vmdef->watchdog) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching watch dog device was found")); + return -1; + } + + virDomainWatchdogDefFree(vmdef->watchdog); + vmdef->watchdog = NULL; + + return 0; +} + + +int +virDomainDetachInputDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + int idx; + + if ((idx = virDomainInputDefFind(vmdef, dev->data.input)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching input device was found")); + return -1; + } + + virDomainInputDefFree(virDomainInputDefRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachVsockDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + if (!vmdef->vsock || + !virDomainVsockDefEquals(dev->data.vsock, vmdef->vsock)) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching vsock device was found")); + return -1; + } + + virDomainVsockDefFree(vmdef->vsock); + vmdef->vsock = NULL; + + return 0; +} + + +int +virDomainDetachTPMDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev) +{ + int idx; + + if ((idx = virDomainTPMDefFind(vmdef, dev->data.tpm)) < 0) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching tpm device was found")); + return -1; + } + + virDomainTPMDefFree(virDomainTPMDefRemove(vmdef, idx)); + + return 0; +} + + +int +virDomainDetachChrDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev, + virDomainXMLOption *xmlopt, + unsigned int flags) +{ + virDomainChrDef *chr; + + if (xmlopt && xmlopt->deviceOps.detachChr) { + return xmlopt->deviceOps.detachChr(vmdef, dev, flags); + } + + if (!(chr = virDomainChrRemove(vmdef, dev->data.chr))) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching char device was found")); + return -1; + } + + virDomainChrDefFree(chr); + + return 0; +} + + +int +virDomainDetachMemballoonDeviceConfig(virDomainDef *vmdef, + virDomainXMLOption *xmlopt, + unsigned int flags) +{ + if (xmlopt && xmlopt->deviceOps.detachMemballoon) { + return xmlopt->deviceOps.detachMemballoon(vmdef, NULL, flags); + } + + if (!vmdef->memballoon) { + virReportError(VIR_ERR_DEVICE_MISSING, "%s", + _("no matching memballoon device was found")); + return -1; + } + + virDomainMemballoonDefFree(vmdef->memballoon); + vmdef->memballoon = NULL; + + return 0; +} + + +int +virDomainDetachDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev, + void *parseOpaque, + unsigned int flags, + unsigned int parse_flags, + virDomainXMLOption *xmlopt) +{ + int ret = 0; + + if (!(xmlopt->deviceOps.detachFlags & (1 << dev->type))) { + ret = -1; + goto error; + } + + switch ((virDomainDeviceType) dev->type) { + case VIR_DOMAIN_DEVICE_DISK: + if (virDomainDetachDiskDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_NET: + if (virDomainDetachNetDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_SOUND: + if (virDomainDetachSoundDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_HOSTDEV: + if (virDomainDetachHostdevDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_LEASE: + if (virDomainDetachLeaseDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_CONTROLLER: + if (virDomainDetachControllerDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_FS: + if (virDomainDetachFSDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_RNG: + if (virDomainDetachRNGDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_MEMORY: + if (virDomainDetachMemoryDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_REDIRDEV: + if (virDomainDetachRedirdevDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_SHMEM: + if (virDomainDetachShmemDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_WATCHDOG: + if (virDomainDetachWatchdogDeviceConfig(vmdef) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_INPUT: + if (virDomainDetachInputDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_VSOCK: + if (virDomainDetachVsockDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_CHR: + if (virDomainDetachChrDeviceConfig(vmdef, dev, xmlopt, flags) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_TPM: + if (virDomainDetachTPMDeviceConfig(vmdef, dev) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_MEMBALLOON: + if (virDomainDetachMemballoonDeviceConfig(vmdef, xmlopt, flags) < 0) + return -1; + + break; + + case VIR_DOMAIN_DEVICE_VIDEO: + case VIR_DOMAIN_DEVICE_GRAPHICS: + case VIR_DOMAIN_DEVICE_HUB: + case VIR_DOMAIN_DEVICE_SMARTCARD: + case VIR_DOMAIN_DEVICE_NVRAM: + case VIR_DOMAIN_DEVICE_NONE: + case VIR_DOMAIN_DEVICE_PANIC: + case VIR_DOMAIN_DEVICE_IOMMU: + case VIR_DOMAIN_DEVICE_AUDIO: + case VIR_DOMAIN_DEVICE_LAST: + ret = -1; + goto error; + } + + if (parseOpaque) { + if (virDomainDefPostParse(vmdef, parse_flags, xmlopt, parseOpaque) < 0) + return -1; + } + + error: + if (ret < 0) { + /* When using in test driver, flags may + contain VIR_DOMAIN_AFFECT_LIVE */ + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, + _("%sdetach of device '%s' is not supported"), + (!(flags & VIR_DOMAIN_AFFECT_LIVE)) ? "persistent " : "", + virDomainDeviceTypeToString(dev->type)); + return -1; + } + return 0; +} diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 89031639cb..5348773668 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -4311,3 +4311,81 @@ int virDomainObjGetMessages(virDomainObj *vm, char ***msgs, unsigned int flags); + +int +virDomainDetachDiskDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachNetDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachSoundDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachHostdevDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachLeaseDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachControllerDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachFSDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachRNGDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachMemoryDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachRedirdevDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachShmemDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachWatchdogDeviceConfig(virDomainDef *vmdef); + +int +virDomainDetachInputDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachVsockDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachTPMDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev); + +int +virDomainDetachMemballoonDeviceConfig(virDomainDef *vmdef, + virDomainXMLOption *xmlopt, + unsigned int flags); + +int +virDomainDetachChrDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev, + virDomainXMLOption *xmlopt, + unsigned int flags); + +int +virDomainDetachDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev, + void *parseOpaque, + unsigned int flags, + unsigned int parse_flags, + virDomainXMLOption *xmlopt); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index b6b8606063..1b0b3d357d 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -352,6 +352,24 @@ virDomainDefSetVcpus; virDomainDefSetVcpusMax; virDomainDefVcpuOrderClear; virDomainDeleteConfig; +virDomainDetachChrDeviceConfig; +virDomainDetachControllerDeviceConfig; +virDomainDetachDeviceConfig; +virDomainDetachDiskDeviceConfig; +virDomainDetachFSDeviceConfig; +virDomainDetachHostdevDeviceConfig; +virDomainDetachInputDeviceConfig; +virDomainDetachLeaseDeviceConfig; +virDomainDetachMemballoonDeviceConfig; +virDomainDetachMemoryDeviceConfig; +virDomainDetachNetDeviceConfig; +virDomainDetachRedirdevDeviceConfig; +virDomainDetachRNGDeviceConfig; +virDomainDetachShmemDeviceConfig; +virDomainDetachSoundDeviceConfig; +virDomainDetachTPMDeviceConfig; +virDomainDetachVsockDeviceConfig; +virDomainDetachWatchdogDeviceConfig; virDomainDeviceAliasIsUserAlias; virDomainDeviceDefCopy; virDomainDeviceDefFree; diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index 2d9385654c..26e02497b4 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -3897,68 +3897,14 @@ libxlDomainDetachDeviceLive(libxlDriverPrivate *driver, static int -libxlDomainDetachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev) +libxlDomainDetachDeviceConfig(virDomainDef *vmdef, + virDomainDeviceDef *dev, + unsigned int flags, + unsigned int parse_flags, + virDomainXMLOption *xmlopt) { - virDomainDiskDef *disk; - virDomainDiskDef *detach; - virDomainHostdevDef *hostdev; - virDomainHostdevDef *det_hostdev; - virDomainControllerDef *cont; - virDomainControllerDef *det_cont; - virDomainNetDef *net; - int idx; - - switch (dev->type) { - case VIR_DOMAIN_DEVICE_DISK: - disk = dev->data.disk; - if (!(detach = virDomainDiskRemoveByName(vmdef, disk->dst))) { - virReportError(VIR_ERR_INVALID_ARG, - _("no target device %s"), disk->dst); - return -1; - } - virDomainDiskDefFree(detach); - break; - - case VIR_DOMAIN_DEVICE_CONTROLLER: - cont = dev->data.controller; - if ((idx = virDomainControllerFind(vmdef, cont->type, - cont->idx)) < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("device not present in domain configuration")); - return -1; - } - det_cont = virDomainControllerRemove(vmdef, idx); - virDomainControllerDefFree(det_cont); - break; - - case VIR_DOMAIN_DEVICE_NET: - net = dev->data.net; - if ((idx = virDomainNetFindIdx(vmdef, net)) < 0) - return -1; - - /* this is guaranteed to succeed */ - virDomainNetDefFree(virDomainNetRemove(vmdef, idx)); - break; - - case VIR_DOMAIN_DEVICE_HOSTDEV: { - hostdev = dev->data.hostdev; - if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("device not present in domain configuration")); - return -1; - } - virDomainHostdevRemove(vmdef, idx); - virDomainHostdevDefFree(det_hostdev); - break; - } - - default: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("persistent detach of device is not supported")); - return -1; - } - - return 0; + return virDomainDetachDeviceConfig(vmdef, dev, NULL, flags, + parse_flags, xmlopt); } static int @@ -4190,7 +4136,10 @@ libxlDomainDetachDeviceFlags(virDomainPtr dom, const char *xml, if (!(vmdef = virDomainObjCopyPersistentDef(vm, driver->xmlopt, NULL))) goto endjob; - if (libxlDomainDetachDeviceConfig(vmdef, dev) < 0) + if (libxlDomainDetachDeviceConfig(vmdef, dev, flags, + VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE, + driver->xmlopt) < 0) goto endjob; } diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c index 3d17b87e8c..b6eb839f4f 100644 --- a/src/lxc/lxc_driver.c +++ b/src/lxc/lxc_driver.c @@ -3093,58 +3093,13 @@ lxcDomainUpdateDeviceConfig(virDomainDef *vmdef, static int lxcDomainDetachDeviceConfig(virDomainDef *vmdef, - virDomainDeviceDef *dev) + virDomainDeviceDef *dev, + unsigned int flags, + unsigned int parse_flags, + virDomainXMLOption *xmlopt) { - int ret = -1; - virDomainDiskDef *disk; - virDomainDiskDef *det_disk; - virDomainNetDef *net; - virDomainHostdevDef *hostdev; - virDomainHostdevDef *det_hostdev; - int idx; - - switch (dev->type) { - case VIR_DOMAIN_DEVICE_DISK: - disk = dev->data.disk; - if (!(det_disk = virDomainDiskRemoveByName(vmdef, disk->dst))) { - virReportError(VIR_ERR_INVALID_ARG, - _("no target device %s"), disk->dst); - return -1; - } - virDomainDiskDefFree(det_disk); - ret = 0; - break; - - case VIR_DOMAIN_DEVICE_NET: - net = dev->data.net; - if ((idx = virDomainNetFindIdx(vmdef, net)) < 0) - return -1; - - /* this is guaranteed to succeed */ - virDomainNetDefFree(virDomainNetRemove(vmdef, idx)); - ret = 0; - break; - - case VIR_DOMAIN_DEVICE_HOSTDEV: { - hostdev = dev->data.hostdev; - if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("device not present in domain configuration")); - return -1; - } - virDomainHostdevRemove(vmdef, idx); - virDomainHostdevDefFree(det_hostdev); - ret = 0; - break; - } - - default: - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("persistent detach of device is not supported")); - break; - } - - return ret; + return virDomainDetachDeviceConfig(vmdef, dev, NULL, flags, + parse_flags, xmlopt); } @@ -4475,7 +4430,10 @@ static int lxcDomainDetachDeviceFlags(virDomainPtr dom, if (!vmdef) goto endjob; - if ((ret = lxcDomainDetachDeviceConfig(vmdef, dev_copy)) < 0) + if ((ret = lxcDomainDetachDeviceConfig(vmdef, dev, flags, + VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE, + driver->xmlopt)) < 0) goto endjob; } diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 864ea10685..d625c9be0e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7338,207 +7338,12 @@ static int qemuDomainDetachDeviceConfig(virDomainDef *vmdef, virDomainDeviceDef *dev, virQEMUCaps *qemuCaps, + unsigned int flags, unsigned int parse_flags, virDomainXMLOption *xmlopt) { - virDomainDiskDef *disk; - virDomainDiskDef *det_disk; - virDomainNetDef *net; - virDomainSoundDef *sound; - virDomainHostdevDef *hostdev; - virDomainHostdevDef *det_hostdev; - virDomainLeaseDef *lease; - virDomainLeaseDef *det_lease; - virDomainControllerDef *cont; - virDomainControllerDef *det_cont; - virDomainChrDef *chr; - virDomainFSDef *fs; - virDomainMemoryDef *mem; - int idx; - - switch ((virDomainDeviceType)dev->type) { - case VIR_DOMAIN_DEVICE_DISK: - disk = dev->data.disk; - if (!(det_disk = virDomainDiskRemoveByName(vmdef, disk->dst))) { - virReportError(VIR_ERR_DEVICE_MISSING, - _("no target device %s"), disk->dst); - return -1; - } - virDomainDiskDefFree(det_disk); - break; - - case VIR_DOMAIN_DEVICE_NET: - net = dev->data.net; - if ((idx = virDomainNetFindIdx(vmdef, net)) < 0) - return -1; - - /* this is guaranteed to succeed */ - virDomainNetDefFree(virDomainNetRemove(vmdef, idx)); - break; - - case VIR_DOMAIN_DEVICE_SOUND: - sound = dev->data.sound; - if ((idx = virDomainSoundDefFind(vmdef, sound)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("device not present in domain configuration")); - return -1; - } - virDomainSoundDefFree(virDomainSoundDefRemove(vmdef, idx)); - break; - - case VIR_DOMAIN_DEVICE_HOSTDEV: { - hostdev = dev->data.hostdev; - if ((idx = virDomainHostdevFind(vmdef, hostdev, &det_hostdev)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("device not present in domain configuration")); - return -1; - } - virDomainHostdevRemove(vmdef, idx); - virDomainHostdevDefFree(det_hostdev); - break; - } - - case VIR_DOMAIN_DEVICE_LEASE: - lease = dev->data.lease; - if (!(det_lease = virDomainLeaseRemove(vmdef, lease))) { - virReportError(VIR_ERR_DEVICE_MISSING, - _("Lease %s in lockspace %s does not exist"), - lease->key, NULLSTR(lease->lockspace)); - return -1; - } - virDomainLeaseDefFree(det_lease); - break; - - case VIR_DOMAIN_DEVICE_CONTROLLER: - cont = dev->data.controller; - if ((idx = virDomainControllerFind(vmdef, cont->type, - cont->idx)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("device not present in domain configuration")); - return -1; - } - det_cont = virDomainControllerRemove(vmdef, idx); - virDomainControllerDefFree(det_cont); - - break; - - case VIR_DOMAIN_DEVICE_CHR: - if (!(chr = qemuDomainChrRemove(vmdef, dev->data.chr))) - return -1; - - virDomainChrDefFree(chr); - break; - - case VIR_DOMAIN_DEVICE_FS: - fs = dev->data.fs; - idx = virDomainFSIndexByName(vmdef, fs->dst); - if (idx < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("no matching filesystem device was found")); - return -1; - } - - fs = virDomainFSRemove(vmdef, idx); - virDomainFSDefFree(fs); - break; - - case VIR_DOMAIN_DEVICE_RNG: - if ((idx = virDomainRNGFind(vmdef, dev->data.rng)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("no matching RNG device was found")); - return -1; - } - - virDomainRNGDefFree(virDomainRNGRemove(vmdef, idx)); - break; - - case VIR_DOMAIN_DEVICE_MEMORY: - if ((idx = virDomainMemoryFindInactiveByDef(vmdef, - dev->data.memory)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("matching memory device was not found")); - return -1; - } - mem = virDomainMemoryRemove(vmdef, idx); - vmdef->mem.cur_balloon -= mem->size; - virDomainMemoryDefFree(mem); - break; - - case VIR_DOMAIN_DEVICE_REDIRDEV: - if ((idx = virDomainRedirdevDefFind(vmdef, - dev->data.redirdev)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("no matching redirdev was not found")); - return -1; - } - - virDomainRedirdevDefFree(virDomainRedirdevDefRemove(vmdef, idx)); - break; - - case VIR_DOMAIN_DEVICE_SHMEM: - if ((idx = virDomainShmemDefFind(vmdef, dev->data.shmem)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("matching shmem device was not found")); - return -1; - } - - virDomainShmemDefFree(virDomainShmemDefRemove(vmdef, idx)); - break; - - - case VIR_DOMAIN_DEVICE_WATCHDOG: - if (!vmdef->watchdog) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("domain has no watchdog")); - return -1; - } - virDomainWatchdogDefFree(vmdef->watchdog); - vmdef->watchdog = NULL; - break; - - case VIR_DOMAIN_DEVICE_INPUT: - if ((idx = virDomainInputDefFind(vmdef, dev->data.input)) < 0) { - virReportError(VIR_ERR_DEVICE_MISSING, "%s", - _("matching input device not found")); - return -1; - } - - virDomainInputDefFree(virDomainInputDefRemove(vmdef, idx)); - break; - - case VIR_DOMAIN_DEVICE_VSOCK: - if (!vmdef->vsock || - !virDomainVsockDefEquals(dev->data.vsock, vmdef->vsock)) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("matching vsock device not found")); - return -1; - } - virDomainVsockDefFree(vmdef->vsock); - vmdef->vsock = NULL; - break; - - case VIR_DOMAIN_DEVICE_VIDEO: - case VIR_DOMAIN_DEVICE_GRAPHICS: - case VIR_DOMAIN_DEVICE_HUB: - case VIR_DOMAIN_DEVICE_SMARTCARD: - case VIR_DOMAIN_DEVICE_MEMBALLOON: - case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_NONE: - case VIR_DOMAIN_DEVICE_TPM: - case VIR_DOMAIN_DEVICE_PANIC: - case VIR_DOMAIN_DEVICE_IOMMU: - case VIR_DOMAIN_DEVICE_AUDIO: - case VIR_DOMAIN_DEVICE_LAST: - virReportError(VIR_ERR_OPERATION_UNSUPPORTED, - _("persistent detach of device '%s' is not supported"), - virDomainDeviceTypeToString(dev->type)); - return -1; - } - - if (virDomainDefPostParse(vmdef, parse_flags, xmlopt, qemuCaps) < 0) - return -1; - - return 0; + return virDomainDetachDeviceConfig(vmdef, dev, qemuCaps, flags, + parse_flags, xmlopt); } static int @@ -7982,8 +7787,8 @@ qemuDomainDetachDeviceLiveAndConfig(virQEMUDriver *driver, if (!vmdef) goto cleanup; - if (qemuDomainDetachDeviceConfig(vmdef, dev_copy, priv->qemuCaps, - parse_flags, + if (qemuDomainDetachDeviceConfig(vmdef, dev, priv->qemuCaps, + flags, parse_flags, driver->xmlopt) < 0) goto cleanup; } @@ -8052,7 +7857,7 @@ qemuDomainDetachDeviceAliasLiveAndConfig(virQEMUDriver *driver, if (virDomainDefFindDevice(vmdef, alias, &dev, true) < 0) return -1; - if (qemuDomainDetachDeviceConfig(vmdef, &dev, priv->qemuCaps, + if (qemuDomainDetachDeviceConfig(vmdef, &dev, priv->qemuCaps, flags, parse_flags, driver->xmlopt) < 0) return -1; } -- 2.35.1