[libvirt] [PATCH 0/5] qemu: hotplug: Media change improvements (blockdev-add saga)

First patch is not entirely relevant in this series. Peter Krempa (5): qemu: domain: Use VIR_AUTOFREE in qemuDomainObjPrivateXMLParseBlockjobs qemu: hotplug: Remove unused copies of virQEMUDriverConfigPtr qemu: hotplug: Use VIR_AUTOUNREF for virQEMUDriverConfigPtr qemu: hotplug: Disallow media change while blockjob is active qemu: domain: Forbid copy_on_read option also for floppies src/qemu/qemu_domain.c | 23 +++++++++++++------ src/qemu/qemu_hotplug.c | 51 ++++++++++++++++------------------------- 2 files changed, 36 insertions(+), 38 deletions(-) -- 2.20.1

Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 54afb6dd7b..e903d36fec 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -2668,14 +2668,13 @@ static int qemuDomainObjPrivateXMLParseBlockjobs(qemuDomainObjPrivatePtr priv, xmlXPathContextPtr ctxt) { - char *active; + VIR_AUTOFREE(char *) active = NULL; int tmp; if ((active = virXPathString("string(./blockjobs/@active)", ctxt)) && (tmp = virTristateBoolTypeFromString(active)) > 0) priv->reconnectBlockjobs = tmp; - VIR_FREE(active); return 0; } -- 2.20.1

On Fri, Mar 29, 2019 at 02:53:53PM +0100, Peter Krempa wrote:
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

qemuDomainChangeGraphicsPasswords and qemuDomainRemoveHostDevice don't use 'cfg' any more. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4e94d80f21..0318547bd8 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -4212,7 +4212,6 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver, const char *connected = NULL; const char *password; int ret = -1; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); if (!auth->passwd && !defaultPasswd) { ret = 0; @@ -4248,7 +4247,6 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver, ret = -1; cleanup: VIR_FREE(validTo); - virObjectUnref(cfg); return ret; } @@ -4657,7 +4655,6 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainHostdevDefPtr hostdev) { - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); virDomainNetDefPtr net = NULL; size_t i; int ret = -1; @@ -4768,7 +4765,6 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver, cleanup: VIR_FREE(drivealias); VIR_FREE(objAlias); - virObjectUnref(cfg); return ret; } -- 2.20.1

On Fri, Mar 29, 2019 at 02:53:54PM +0100, Peter Krempa wrote:
qemuDomainChangeGraphicsPasswords and qemuDomainRemoveHostDevice don't use 'cfg' any more.
Unused since 802c59d4b9dcd780cd58daec8d2362988c1662f0 and 4327df7eee75c5bec485703eb5b5f439f2fd371f
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 4 ---- 1 file changed, 4 deletions(-)
With the commit message amended: Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Unref the config pointer automatically in code paths which get a local copy. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 0318547bd8..150da34b4a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -151,7 +151,7 @@ qemuHotplugPrepareDiskSourceAccess(virQEMUDriverPtr driver, virStorageSourcePtr src, bool teardown) { - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); const char *srcstr = NULLSTR(src->path); int ret = -1; virErrorPtr orig_err = NULL; @@ -195,7 +195,6 @@ qemuHotplugPrepareDiskSourceAccess(virQEMUDriverPtr driver, cleanup: virErrorRestore(&orig_err); - virObjectUnref(cfg); return ret; } @@ -850,7 +849,7 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, virStorageSourcePtr newsrc, bool force) { - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; virStorageSourcePtr oldsrc = disk->src; bool sharedAdded = false; @@ -917,7 +916,6 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, if (oldsrc) disk->src = oldsrc; - virObjectUnref(cfg); return ret; } @@ -936,7 +934,7 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; qemuHotplugDiskSourceDataPtr diskdata = NULL; char *devstr = NULL; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); if (qemuHotplugPrepareDiskSourceAccess(driver, vm, disk->src, false) < 0) goto cleanup; @@ -987,7 +985,6 @@ qemuDomainAttachDiskGeneric(virQEMUDriverPtr driver, qemuHotplugDiskSourceDataFree(diskdata); qemuDomainSecretDiskDestroy(disk); VIR_FREE(devstr); - virObjectUnref(cfg); return ret; exit_monitor: @@ -1367,7 +1364,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, bool iface_connected = false; virDomainNetType actualType; virNetDevBandwidthPtr actualBandwidth; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); virDomainCCWAddressSetPtr ccwaddrs = NULL; size_t i; char *charDevAlias = NULL; @@ -1707,7 +1704,6 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, VIR_FREE(vhostfd); VIR_FREE(vhostfdName); VIR_FREE(charDevAlias); - virObjectUnref(cfg); virDomainCCWAddressSetFree(ccwaddrs); return ret; @@ -1752,7 +1748,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, bool teardownlabel = false; bool teardowndevice = false; int backend; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); unsigned int flags = 0; if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0) @@ -1868,7 +1864,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, VIR_FREE(devstr); VIR_FREE(configfd_name); VIR_FORCE_CLOSE(configfd); - virObjectUnref(cfg); return 0; @@ -1892,7 +1887,6 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver, VIR_FORCE_CLOSE(configfd); cleanup: - virObjectUnref(cfg); return -1; } @@ -2005,7 +1999,7 @@ qemuDomainAddChardevTLSObjects(virQEMUDriverPtr driver, const char **secAlias) { int ret = -1; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; qemuDomainChrSourcePrivatePtr chrSourcePriv; qemuDomainSecretInfoPtr secinfo = NULL; @@ -2050,7 +2044,6 @@ qemuDomainAddChardevTLSObjects(virQEMUDriverPtr driver, cleanup: virJSONValueFree(tlsProps); virJSONValueFree(secProps); - virObjectUnref(cfg); return ret; } @@ -2063,7 +2056,7 @@ qemuDomainDelChardevTLSObjects(virQEMUDriverPtr driver, const char *inAlias) { int ret = -1; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; char *tlsAlias = NULL; char *secAlias = NULL; @@ -2099,7 +2092,6 @@ qemuDomainDelChardevTLSObjects(virQEMUDriverPtr driver, cleanup: VIR_FREE(tlsAlias); VIR_FREE(secAlias); - virObjectUnref(cfg); return ret; } @@ -2590,7 +2582,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, { qemuDomainObjPrivatePtr priv = vm->privateData; virErrorPtr orig_err; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); unsigned long long oldmem = virDomainDefGetMemoryTotal(vm->def); unsigned long long newmem = oldmem + mem->size; char *devstr = NULL; @@ -2691,7 +2683,6 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, } virJSONValueFree(props); - virObjectUnref(cfg); VIR_FREE(devstr); VIR_FREE(objalias); virDomainMemoryDefFree(mem); @@ -3569,7 +3560,7 @@ qemuDomainAttachLease(virQEMUDriverPtr driver, virDomainLeaseDefPtr lease) { int ret = -1; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); if (virDomainLeaseInsertPreAlloc(vm->def) < 0) goto cleanup; @@ -3584,7 +3575,6 @@ qemuDomainAttachLease(virQEMUDriverPtr driver, ret = 0; cleanup: - virObjectUnref(cfg); return ret; } @@ -4257,7 +4247,7 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver, virDomainGraphicsDefPtr dev) { virDomainGraphicsDefPtr olddev = qemuDomainFindGraphics(vm, dev); - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); const char *type = virDomainGraphicsTypeToString(dev->type); size_t i; int ret = -1; @@ -4436,7 +4426,6 @@ qemuDomainChangeGraphics(virQEMUDriverPtr driver, } cleanup: - virObjectUnref(cfg); return ret; } @@ -4774,7 +4763,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainNetDefPtr net) { - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; char *hostnet_name = NULL; char *charDevAlias = NULL; @@ -4863,7 +4852,6 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver, ret = 0; cleanup: - virObjectUnref(cfg); VIR_FREE(charDevAlias); VIR_FREE(hostnet_name); return ret; @@ -6543,7 +6531,7 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver, unsigned int nvcpus, bool hotpluggable) { - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); virBitmapPtr vcpumap = NULL; bool enable; int ret = -1; @@ -6584,7 +6572,6 @@ qemuDomainSetVcpusInternal(virQEMUDriverPtr driver, cleanup: virBitmapFree(vcpumap); - virObjectUnref(cfg); return ret; } @@ -6739,7 +6726,7 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, virBitmapPtr map, bool state) { - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); virBitmapPtr livevcpus = NULL; int ret = -1; @@ -6785,6 +6772,5 @@ qemuDomainSetVcpuInternal(virQEMUDriverPtr driver, cleanup: virBitmapFree(livevcpus); - virObjectUnref(cfg); return ret; } -- 2.20.1

On Fri, Mar 29, 2019 at 02:53:55PM +0100, Peter Krempa wrote:
Unref the config pointer automatically in code paths which get a local copy.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 40 +++++++++++++--------------------------- 1 file changed, 13 insertions(+), 27 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 0318547bd8..150da34b4a 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1367,7 +1364,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver, bool iface_connected = false; virDomainNetType actualType; virNetDevBandwidthPtr actualBandwidth; - virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver);
Nice, this fixes a memory leak on two 'return's below.
virDomainCCWAddressSetPtr ccwaddrs = NULL; size_t i; char *charDevAlias = NULL;
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Until the block job completes we can't change the disk chain. Removal would fail as the block job still has reference to the chain. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 150da34b4a..34249bd030 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -852,10 +852,17 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver, VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver); qemuDomainObjPrivatePtr priv = vm->privateData; virStorageSourcePtr oldsrc = disk->src; + qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk); bool sharedAdded = false; int ret = -1; int rc; + if (diskPriv->blockjob && qemuBlockJobIsRunning(diskPriv->blockjob)) { + virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s", + _("can't change media while a block job is running on the device")); + return -1; + } + disk->src = newsrc; if (virDomainDiskTranslateSourcePool(disk) < 0) -- 2.20.1

On Fri, Mar 29, 2019 at 02:53:56PM +0100, Peter Krempa wrote:
Until the block job completes we can't change the disk chain. Removal would fail as the block job still has reference to the chain.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_hotplug.c | 7 +++++++ 1 file changed, 7 insertions(+)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano

Using copy_on_read for removable disks is a hassle. It also does not work for CDROMs at all as the image is supposed to be read-only and we might ignore it for floppies when they are started as empty. Forbid it for floppies completely rather than trying to support what probably nobody is using. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index e903d36fec..2480211194 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5041,11 +5041,21 @@ qemuDomainDeviceDefValidateDisk(const virDomainDiskDef *disk, return -1; } - if (disk->src->readonly && disk->copy_on_read == VIR_TRISTATE_SWITCH_ON) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("copy_on_read is not compatible with read-only disk '%s'"), - disk->dst); - return -1; + if (disk->copy_on_read == VIR_TRISTATE_SWITCH_ON) { + if (disk->src->readonly) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("copy_on_read is not compatible with read-only disk '%s'"), + disk->dst); + return -1; + } + + if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM || + disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("copy_on_read is not supported with removable disk '%s'"), + disk->dst); + return -1; + } } if (disk->geometry.cylinders > 0 && -- 2.20.1

On Fri, Mar 29, 2019 at 02:53:57PM +0100, Peter Krempa wrote:
Using copy_on_read for removable disks is a hassle. It also does not work for CDROMs at all as the image is supposed to be read-only and we might ignore it for floppies when they are started as empty. Forbid it for floppies completely rather than trying to support what probably nobody is using.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_domain.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-)
Reviewed-by: Ján Tomko <jtomko@redhat.com> Jano
participants (2)
-
Ján Tomko
-
Peter Krempa