[libvirt] [PATCH 00/12] Implement random number generator hot/cold (un)plug

Extension of Luyao's series with changes that were possible due to the prepare series for memory hotplug. Luyao Huang (7): qemu: Add helper to assign RNG device aliases qemu: refactor qemuBuildRNGDeviceArgs to allow reuse in RNG hotplug qemu: command: Make RNG backend device IDs unique audit: export virDomainAuditRNG conf: Add helpers to insert/remove/find RNG devices in domain def qemu: Implement random number generator hotplug qemu: Implement random number generator hotunplug Peter Krempa (5): conf: Introduce helper to find duplicate device address qemu: command: Shuffle around formatting of alias for RNG device backend qemu: command: Break some very long lines in qemuBuildRNGDevStr() qemu: command: Refactor creation of RNG device commandline qemu: Implement random number generator cold (un)plug src/conf/domain_audit.c | 2 +- src/conf/domain_audit.h | 7 + src/conf/domain_conf.c | 164 +++++++++++++++++ src/conf/domain_conf.h | 8 + src/libvirt_private.syms | 6 + src/qemu/qemu_command.c | 153 +++++++++++---- src/qemu/qemu_command.h | 9 + src/qemu/qemu_driver.c | 41 ++++- src/qemu/qemu_hotplug.c | 205 ++++++++++++++++++++- src/qemu/qemu_hotplug.h | 7 +- .../qemuxml2argv-aarch64-virt-virtio.args | 4 +- .../qemuxml2argv-arm-vexpressa9-virtio.args | 4 +- .../qemuxml2argv-arm-virt-virtio.args | 4 +- .../qemuxml2argv-s390-piix-controllers.args | 3 +- .../qemuxml2argv-s390-usb-none.args | 3 +- .../qemuxml2argv-virtio-rng-ccw.args | 4 +- .../qemuxml2argv-virtio-rng-default.args | 4 +- .../qemuxml2argv-virtio-rng-egd.args | 4 +- .../qemuxml2argv-virtio-rng-multiple.args | 8 +- .../qemuxml2argv-virtio-rng-random.args | 4 +- 20 files changed, 578 insertions(+), 66 deletions(-) -- 2.2.2

When adding devices to the definition it's useful to check whether the devices don't reside on a conflicting address. This patch adds a helper that iterates all device info and comapres the addresses with the given info. --- src/conf/domain_conf.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + 3 files changed, 103 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 4251b13..94289cf 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2715,6 +2715,90 @@ virDomainDeviceInfoNeedsFormat(virDomainDeviceInfoPtr info, unsigned int flags) return false; } +static bool +virDomainDeviceInfoAddressIsEqual(const virDomainDeviceInfo *a, + const virDomainDeviceInfo *b) +{ + + if (a->type != b->type) + return false; + + switch ((virDomainDeviceAddressType) a->type) { + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE: + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST: + /* address types below don't have any specific data */ + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO: + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390: + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: + /* the 'multi' field shouldn't be checked */ + if (a->addr.pci.domain != b->addr.pci.domain || + a->addr.pci.bus != b->addr.pci.bus || + a->addr.pci.slot != b->addr.pci.slot || + a->addr.pci.function != b->addr.pci.function) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: + if (memcmp(&a->addr.drive, &b->addr.drive, sizeof(a->addr.drive))) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL: + if (memcmp(&a->addr.vioserial, &b->addr.vioserial, sizeof(a->addr.vioserial))) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID: + if (memcmp(&a->addr.ccid, &b->addr.ccid, sizeof(a->addr.ccid))) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB: + if (memcmp(&a->addr.usb, &b->addr.usb, sizeof(a->addr.usb))) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO: + if (memcmp(&a->addr.spaprvio, &b->addr.spaprvio, sizeof(a->addr.spaprvio))) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW: + /* the 'assigned' field denotes that the address was generated */ + if (a->addr.ccw.cssid != b->addr.ccw.cssid || + a->addr.ccw.ssid != b->addr.ccw.ssid || + a->addr.ccw.devno != b->addr.ccw.devno) + return false; + break; + + case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_ISA: + if (memcmp(&a->addr.isa, &b->addr.isa, sizeof(a->addr.isa))) + return false; + break; + } + + return true; +} + + +static int +virDomainDeviceInfoFindByAddressIterator(virDomainDefPtr def ATTRIBUTE_UNUSED, + virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, + virDomainDeviceInfoPtr info, + void *opaque) +{ + virDomainDeviceInfoPtr needle = opaque; + + /* break iteration if the info was found */ + if (virDomainDeviceInfoAddressIsEqual(info, needle)) + return -1; + + return 0; +} + + int virDomainDeviceInfoCopy(virDomainDeviceInfoPtr dst, virDomainDeviceInfoPtr src) @@ -2967,6 +3051,20 @@ virDomainDeviceInfoIterate(virDomainDefPtr def, } +bool +virDomainDeviceInfoHasAddress(virDomainDefPtr def, + virDomainDeviceInfoPtr info) +{ + if (virDomainDeviceInfoIterateInternal(def, + virDomainDeviceInfoFindByAddressIterator, + true, + info) < 0) + return true; + + return false; +} + + static int virDomainDefRejectDuplicateControllers(virDomainDefPtr def) { diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 93f2314..d073a99 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2382,6 +2382,10 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, virDomainDeviceInfoCallback cb, void *opaque); +bool virDomainDeviceInfoHasAddress(virDomainDefPtr def, + virDomainDeviceInfoPtr info) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + void virDomainDefFree(virDomainDefPtr vm); virDomainChrDefPtr virDomainChrDefNew(void); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 376c69b..619bf79 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -215,6 +215,7 @@ virDomainDeviceDefParse; virDomainDeviceFindControllerModel; virDomainDeviceGetInfo; virDomainDeviceInfoCopy; +virDomainDeviceInfoHasAddress; virDomainDeviceInfoIterate; virDomainDeviceTypeToString; virDomainDiskBusTypeToString; -- 2.2.2

On Fri, Feb 06, 2015 at 04:32:15PM +0100, Peter Krempa wrote:
When adding devices to the definition it's useful to check whether the devices don't reside on a conflicting address. This patch adds a helper that iterates all device info and comapres the addresses with the given
s/comapres/compares/
info. --- src/conf/domain_conf.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + 3 files changed, 103 insertions(+)
--- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2382,6 +2382,10 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, virDomainDeviceInfoCallback cb, void *opaque);
+bool virDomainDeviceInfoHasAddress(virDomainDefPtr def, + virDomainDeviceInfoPtr info) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + void virDomainDefFree(virDomainDefPtr vm);
From the function name, I'd expect it to return true if there is an address specified in info. How about virDomainDefHasDeviceAddress? ACK regardless of the name. Jan

On Mon, Feb 09, 2015 at 16:51:24 +0100, Ján Tomko wrote:
On Fri, Feb 06, 2015 at 04:32:15PM +0100, Peter Krempa wrote:
When adding devices to the definition it's useful to check whether the devices don't reside on a conflicting address. This patch adds a helper that iterates all device info and comapres the addresses with the given
s/comapres/compares/
info. --- src/conf/domain_conf.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 ++ src/libvirt_private.syms | 1 + 3 files changed, 103 insertions(+)
--- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2382,6 +2382,10 @@ int virDomainDeviceInfoIterate(virDomainDefPtr def, virDomainDeviceInfoCallback cb, void *opaque);
+bool virDomainDeviceInfoHasAddress(virDomainDefPtr def, + virDomainDeviceInfoPtr info) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK; + void virDomainDefFree(virDomainDefPtr vm);
From the function name, I'd expect it to return true if there is an address specified in info.
How about virDomainDefHasDeviceAddress?
Indeed. I copied the name from the universal interator that is added a few lines above in the .c file. Your name makes more sense.
ACK regardless of the name.
Jan
Thanks. Peter

From: Luyao Huang <lhuang@redhat.com> This function is used to assign an alias for a RNG device. It will be later reused when hotplugging RNGs. Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 13 ++++++++++++- src/qemu/qemu_command.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3b6eddc..4447b9b 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1025,6 +1025,17 @@ qemuGetNextChrDevIndex(virDomainDefPtr def, int +qemuAssignDeviceRNGAlias(virDomainRNGDefPtr rng, + size_t idx) +{ + if (virAsprintf(&rng->info.alias, "rng%zu", idx) < 0) + return -1; + + return 0; +} + + +int qemuAssignDeviceChrAlias(virDomainDefPtr def, virDomainChrDefPtr chr, ssize_t idx) @@ -1149,7 +1160,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) return -1; } for (i = 0; i < def->nrngs; i++) { - if (virAsprintf(&def->rngs[i]->info.alias, "rng%zu", i) < 0) + if (qemuAssignDeviceRNGAlias(def->rngs[i], i) < 0) return -1; } if (def->tpm) { diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index ae36bd8..d8fea65 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -269,6 +269,7 @@ int qemuAssignDeviceRedirdevAlias(virDomainDefPtr def, virDomainRedirdevDefPtr r int qemuAssignDeviceChrAlias(virDomainDefPtr def, virDomainChrDefPtr chr, ssize_t idx); +int qemuAssignDeviceRNGAlias(virDomainRNGDefPtr rng, size_t idx); int qemuParseKeywords(const char *str, -- 2.2.2

From: Luyao Huang <lhuang@redhat.com> Rename qemuBuildRNGDeviceArgs to qemuBuildRNGDevStr and change the return type so that it can be reused in the device hotplug code later. Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 30 +++++++++++++++--------------- src/qemu/qemu_command.h | 4 ++++ 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4447b9b..8165fb0 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6211,21 +6211,19 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, } -static int -qemuBuildRNGDeviceArgs(virCommandPtr cmd, - virDomainDefPtr def, - virDomainRNGDefPtr dev, - virQEMUCapsPtr qemuCaps) +char * +qemuBuildRNGDevStr(virDomainDefPtr def, + virDomainRNGDefPtr dev, + virQEMUCapsPtr qemuCaps) { virBuffer buf = VIR_BUFFER_INITIALIZER; - int ret = -1; if (dev->model != VIR_DOMAIN_RNG_MODEL_VIRTIO || !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_RNG)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("this qemu doesn't support RNG device type '%s'"), virDomainRNGModelTypeToString(dev->model)); - goto cleanup; + goto error; } if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) @@ -6246,16 +6244,15 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd, } if (qemuBuildDeviceAddressStr(&buf, def, &dev->info, qemuCaps) < 0) - goto cleanup; - - virCommandAddArg(cmd, "-device"); - virCommandAddArgBuffer(cmd, &buf); + goto error; + if (virBufferCheckError(&buf) < 0) + goto error; - ret = 0; + return virBufferContentAndReset(&buf); - cleanup: + error: virBufferFreeAndReset(&buf); - return ret; + return NULL; } @@ -10145,13 +10142,16 @@ qemuBuildCommandLine(virConnectPtr conn, } for (i = 0; i < def->nrngs; i++) { + char *devstr; /* add the RNG source backend */ if (qemuBuildRNGBackendArgs(cmd, def->rngs[i], qemuCaps) < 0) goto error; /* add the device */ - if (qemuBuildRNGDeviceArgs(cmd, def, def->rngs[i], qemuCaps) < 0) + if (!(devstr = qemuBuildRNGDevStr(def, def->rngs[i], qemuCaps))) goto error; + virCommandAddArgList(cmd, "-device", devstr, NULL); + VIR_FREE(devstr); } if (def->nvram) { diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index d8fea65..e280497 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -171,6 +171,10 @@ char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def, const char *configfd, virQEMUCapsPtr qemuCaps); +char *qemuBuildRNGDevStr(virDomainDefPtr def, + virDomainRNGDefPtr dev, + virQEMUCapsPtr qemuCaps); + int qemuOpenPCIConfig(virDomainHostdevDefPtr dev); /* Legacy, pre device support */ -- 2.2.2

From: Luyao Huang <lhuang@redhat.com> Libvirt didn't prefix the random number generator backend object alias with any string thus the device alias and object alias were identical. To avoid possible problems, rename the alias for the backend object and tweak tests to comply with the change. Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 12 ++++++------ tests/qemuxml2argvdata/qemuxml2argv-aarch64-virt-virtio.args | 4 ++-- .../qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args | 4 ++-- tests/qemuxml2argvdata/qemuxml2argv-arm-virt-virtio.args | 4 ++-- .../qemuxml2argvdata/qemuxml2argv-s390-piix-controllers.args | 3 ++- tests/qemuxml2argvdata/qemuxml2argv-s390-usb-none.args | 3 ++- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-ccw.args | 4 ++-- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-default.args | 4 ++-- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args | 4 ++-- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args | 8 ++++---- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args | 4 ++-- 11 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8165fb0..4fef942 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6171,7 +6171,7 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, goto cleanup; } - virBufferAsprintf(&buf, "rng-random,id=%s,filename=%s", + virBufferAsprintf(&buf, "rng-random,id=obj%s,filename=%s", dev->info.alias, dev->source.file); virCommandAddArg(cmd, "-object"); @@ -6194,7 +6194,7 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, virCommandAddArgList(cmd, "-chardev", backend, NULL); virCommandAddArg(cmd, "-object"); - virCommandAddArgFormat(cmd, "rng-egd,chardev=char%s,id=%s", + virCommandAddArgFormat(cmd, "rng-egd,chardev=char%s,id=obj%s", dev->info.alias, dev->info.alias); break; @@ -6227,13 +6227,13 @@ qemuBuildRNGDevStr(virDomainDefPtr def, } if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) - virBufferAsprintf(&buf, "virtio-rng-ccw,rng=%s", dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-ccw,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) - virBufferAsprintf(&buf, "virtio-rng-s390,rng=%s", dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-s390,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) - virBufferAsprintf(&buf, "virtio-rng-device,rng=%s", dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-device,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); else - virBufferAsprintf(&buf, "virtio-rng-pci,rng=%s", dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-pci,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); if (dev->rate > 0) { virBufferAsprintf(&buf, ",max-bytes=%u", dev->rate); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-virt-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-virt-virtio.args index 05f3629..d12e6e2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-aarch64-virt-virtio.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-aarch64-virt-virtio.args @@ -11,5 +11,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -net user,vlan=0,name=hostnet0 -serial pty -chardev pty,id=charconsole1 \ -device virtconsole,chardev=charconsole1,id=console1 \ -device virtio-balloon-device,id=balloon0 \ --object rng-random,id=rng0,filename=/dev/random \ --device virtio-rng-device,rng=rng0 +-object rng-random,id=objrng0,filename=/dev/random \ +-device virtio-rng-device,rng=objrng0,id=rng0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args index 62de9d3..dba74e1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-arm-vexpressa9-virtio.args @@ -10,5 +10,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -net user,vlan=0,name=hostnet0 -serial pty -chardev pty,id=charconsole1 \ -device virtconsole,chardev=charconsole1,id=console1 \ -device virtio-balloon-device,id=balloon0 \ --object rng-random,id=rng0,filename=/dev/random \ --device virtio-rng-device,rng=rng0 +-object rng-random,id=objrng0,filename=/dev/random \ +-device virtio-rng-device,rng=objrng0,id=rng0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-arm-virt-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-arm-virt-virtio.args index 5206ad8..c73022b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-arm-virt-virtio.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-arm-virt-virtio.args @@ -10,5 +10,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -net user,vlan=0,name=hostnet0 -serial pty -chardev pty,id=charconsole1 \ -device virtconsole,chardev=charconsole1,id=console1 \ -device virtio-balloon-device,id=balloon0 \ --object rng-random,id=rng0,filename=/dev/random \ --device virtio-rng-device,rng=rng0 +-object rng-random,id=objrng0,filename=/dev/random \ +-device virtio-rng-device,rng=objrng0,id=rng0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-s390-piix-controllers.args b/tests/qemuxml2argvdata/qemuxml2argv-s390-piix-controllers.args index c09382f..10aecea 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-s390-piix-controllers.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-s390-piix-controllers.args @@ -8,4 +8,5 @@ file=/dev/HostVG/QEMUGuest1,if=none,id=drive-virtio-disk0 \ -device virtio-blk-s390,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \ -chardev pty,id=charconsole0 \ -device virtconsole,chardev=charconsole0,id=console0 \ --object rng-random,id=rng0,filename=/dev/hwrng -device virtio-rng-s390,rng=rng0 +-object rng-random,id=objrng0,filename=/dev/hwrng \ +-device virtio-rng-s390,rng=objrng0,id=rng0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-s390-usb-none.args b/tests/qemuxml2argvdata/qemuxml2argv-s390-usb-none.args index 6d97156..51fcfa6 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-s390-usb-none.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-s390-usb-none.args @@ -8,4 +8,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -device virtio-blk-s390,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \ -chardev pty,id=charconsole0 \ -device virtconsole,chardev=charconsole0,id=console0 \ --object rng-random,id=rng0,filename=/dev/hwrng -device virtio-rng-s390,rng=rng0 +-object rng-random,id=objrng0,filename=/dev/hwrng \ +-device virtio-rng-s390,rng=objrng0,id=rng0 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-ccw.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-ccw.args index a1b2eb6..3a04ed1 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-ccw.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-ccw.args @@ -10,5 +10,5 @@ id=virtio-disk0,bootindex=1 \ -chardev pty,id=charconsole0 \ -device virtconsole,chardev=charconsole0,id=console0 \ -device virtio-balloon-ccw,id=balloon0,devno=fe.0.000a \ --object rng-random,id=rng0,filename=/dev/hwrng \ --device virtio-rng-ccw,rng=rng0,devno=fe.0.0002 +-object rng-random,id=objrng0,filename=/dev/hwrng \ +-device virtio-rng-ccw,rng=objrng0,id=rng0,devno=fe.0.0002 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-default.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-default.args index 58cc473..84aa5cd 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-default.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-default.args @@ -3,5 +3,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -S -M pc -m 214 -smp 1 -nographic -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ --object rng-random,id=rng0,filename=/dev/random \ --device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x7 +-object rng-random,id=objrng0,filename=/dev/random \ +-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x7 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args index 5530f7d..67c5047 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args @@ -4,5 +4,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ -chardev socket,id=charrng0,host=1.2.3.4,port=1234 \ --object rng-egd,chardev=charrng0,id=rng0 \ --device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x4 +-object rng-egd,chardev=charrng0,id=objrng0 \ +-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args index d1faf09..aa99384 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args @@ -3,8 +3,8 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -M pc -m 214 -smp 1 -nographic -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ --object rng-random,id=rng0,filename=/dev/random \ --device virtio-rng-pci,rng=rng0,bus=pci.0,addr=0x7 \ +-object rng-random,id=objrng0,filename=/dev/random \ +-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x7 \ -chardev socket,id=charrng1,host=1.2.3.4,port=1234 \ --object rng-egd,chardev=charrng1,id=rng1 \ --device virtio-rng-pci,rng=rng1,bus=pci.0,addr=0x4 +-object rng-egd,chardev=charrng1,id=objrng1 \ +-device virtio-rng-pci,rng=objrng1,id=rng1,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args index ecd510e..7fca098 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-random.args @@ -3,5 +3,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -S -M pc -m 214 -smp 1 -nographic -nodefaults \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ --object rng-random,id=rng0,filename=/dev/hwrng \ --device virtio-rng-pci,rng=rng0,max-bytes=123,period=1234,bus=pci.0,addr=0x4 +-object rng-random,id=objrng0,filename=/dev/hwrng \ +-device virtio-rng-pci,rng=objrng0,id=rng0,max-bytes=123,period=1234,bus=pci.0,addr=0x4 -- 2.2.2

Move the alias name right after the object type for rng-egd backend so that we can later use the JSON to commandline generator to create the command line. --- src/qemu/qemu_command.c | 2 +- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args | 2 +- tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4fef942..7d4af4c 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6194,7 +6194,7 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, virCommandAddArgList(cmd, "-chardev", backend, NULL); virCommandAddArg(cmd, "-object"); - virCommandAddArgFormat(cmd, "rng-egd,chardev=char%s,id=obj%s", + virCommandAddArgFormat(cmd, "rng-egd,id=obj%s,chardev=char%s", dev->info.alias, dev->info.alias); break; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args index 67c5047..c6d8e2b 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-egd.args @@ -4,5 +4,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \ -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ -chardev socket,id=charrng0,host=1.2.3.4,port=1234 \ --object rng-egd,chardev=charrng0,id=objrng0 \ +-object rng-egd,id=objrng0,chardev=charrng0 \ -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args index aa99384..7fdf1ef 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args +++ b/tests/qemuxml2argvdata/qemuxml2argv-virtio-rng-multiple.args @@ -6,5 +6,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \ -object rng-random,id=objrng0,filename=/dev/random \ -device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.0,addr=0x7 \ -chardev socket,id=charrng1,host=1.2.3.4,port=1234 \ --object rng-egd,chardev=charrng1,id=objrng1 \ +-object rng-egd,id=objrng1,chardev=charrng1 \ -device virtio-rng-pci,rng=objrng1,id=rng1,bus=pci.0,addr=0x4 -- 2.2.2

--- src/qemu/qemu_command.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 7d4af4c..6380621 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6227,13 +6227,17 @@ qemuBuildRNGDevStr(virDomainDefPtr def, } if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) - virBufferAsprintf(&buf, "virtio-rng-ccw,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-ccw,rng=obj%s,id=%s", + dev->info.alias, dev->info.alias); else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390) - virBufferAsprintf(&buf, "virtio-rng-s390,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-s390,rng=obj%s,id=%s", + dev->info.alias, dev->info.alias); else if (dev->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_MMIO) - virBufferAsprintf(&buf, "virtio-rng-device,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-device,rng=obj%s,id=%s", + dev->info.alias, dev->info.alias); else - virBufferAsprintf(&buf, "virtio-rng-pci,rng=obj%s,id=%s", dev->info.alias, dev->info.alias); + virBufferAsprintf(&buf, "virtio-rng-pci,rng=obj%s,id=%s", + dev->info.alias, dev->info.alias); if (dev->rate > 0) { virBufferAsprintf(&buf, ",max-bytes=%u", dev->rate); -- 2.2.2

As the RNG device is using an -object as backend refactor the code to use the JSON to commandline generator so that we can reuse the code later in hotplug. --- src/qemu/qemu_command.c | 108 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6380621..9179c1f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6154,15 +6154,33 @@ qemuBuildSclpDevStr(virDomainChrDefPtr dev) static int -qemuBuildRNGBackendArgs(virCommandPtr cmd, - virDomainRNGDefPtr dev, - virQEMUCapsPtr qemuCaps) +qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng, + virQEMUCapsPtr qemuCaps, + char **chr) { - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *backend = NULL; + *chr = NULL; + + if (rng->backend != VIR_DOMAIN_RNG_BACKEND_EGD) + return 0; + + if (!(*chr = qemuBuildChrChardevStr(rng->source.chardev, + rng->info.alias, qemuCaps))) + return -1; + + return 0; +} + + +static int +qemuBuildRNGBackendProps(virDomainRNGDefPtr rng, + virQEMUCapsPtr qemuCaps, + const char **type, + virJSONValuePtr *props) +{ + char *charBackendAlias = NULL; int ret = -1; - switch ((virDomainRNGBackend) dev->backend) { + switch ((virDomainRNGBackend) rng->backend) { case VIR_DOMAIN_RNG_BACKEND_RANDOM: if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_RANDOM)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -6171,15 +6189,14 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, goto cleanup; } - virBufferAsprintf(&buf, "rng-random,id=obj%s,filename=%s", - dev->info.alias, dev->source.file); + *type = "rng-random"; - virCommandAddArg(cmd, "-object"); - virCommandAddArgBuffer(cmd, &buf); + if (virJSONValueObjectCreate(props, "s:filename", rng->source.file, + NULL) < 0) + goto cleanup; break; case VIR_DOMAIN_RNG_BACKEND_EGD: - if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_OBJECT_RNG_EGD)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("this qemu doesn't support the rng-egd " @@ -6187,15 +6204,15 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, goto cleanup; } - if (!(backend = qemuBuildChrChardevStr(dev->source.chardev, - dev->info.alias, qemuCaps))) + *type = "rng-egd"; + + if (virAsprintf(&charBackendAlias, "char%s", rng->info.alias) < 0) goto cleanup; - virCommandAddArgList(cmd, "-chardev", backend, NULL); + if (virJSONValueObjectCreate(props, "s:chardev", charBackendAlias, + NULL) < 0) + goto cleanup; - virCommandAddArg(cmd, "-object"); - virCommandAddArgFormat(cmd, "rng-egd,id=obj%s,chardev=char%s", - dev->info.alias, dev->info.alias); break; case VIR_DOMAIN_RNG_BACKEND_LAST: @@ -6205,8 +6222,31 @@ qemuBuildRNGBackendArgs(virCommandPtr cmd, ret = 0; cleanup: - virBufferFreeAndReset(&buf); - VIR_FREE(backend); + VIR_FREE(charBackendAlias); + return ret; +} + + +static char * +qemuBuildRNGBackendStr(virDomainRNGDefPtr rng, + virQEMUCapsPtr qemuCaps) +{ + const char *type = NULL; + char *alias = NULL; + virJSONValuePtr props = NULL; + char *ret = NULL; + + if (virAsprintf(&alias, "obj%s", rng->info.alias) < 0) + goto cleanup; + + if (qemuBuildRNGBackendProps(rng, qemuCaps, &type, &props) < 0) + goto cleanup; + + ret = qemuBuildObjectCommandlineFromJSON(type, alias, props); + + cleanup: + VIR_FREE(alias); + virJSONValueFree(props); return ret; } @@ -10146,16 +10186,36 @@ qemuBuildCommandLine(virConnectPtr conn, } for (i = 0; i < def->nrngs; i++) { - char *devstr; + virDomainRNGDefPtr rng = def->rngs[i]; + char *tmp; + + if (!rng->info.alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("RNG device is missing alias")); + goto error; + } + + /* possibly add character device for backend */ + if (qemuBuildRNGBackendChrdevStr(rng, qemuCaps, &tmp) < 0) + goto error; + + if (tmp) { + virCommandAddArgList(cmd, "-chardev", tmp, NULL); + VIR_FREE(tmp); + } + /* add the RNG source backend */ - if (qemuBuildRNGBackendArgs(cmd, def->rngs[i], qemuCaps) < 0) + if (!(tmp = qemuBuildRNGBackendStr(rng, qemuCaps))) goto error; + virCommandAddArgList(cmd, "-object", tmp, NULL); + VIR_FREE(tmp); + /* add the device */ - if (!(devstr = qemuBuildRNGDevStr(def, def->rngs[i], qemuCaps))) + if (!(tmp = qemuBuildRNGDevStr(def, rng, qemuCaps))) goto error; - virCommandAddArgList(cmd, "-device", devstr, NULL); - VIR_FREE(devstr); + virCommandAddArgList(cmd, "-device", tmp, NULL); + VIR_FREE(tmp); } if (def->nvram) { -- 2.2.2

On Fri, Feb 06, 2015 at 04:32:21PM +0100, Peter Krempa wrote:
As the RNG device is using an -object as backend refactor the code to use the JSON to commandline generator so that we can reuse the code later in hotplug. --- src/qemu/qemu_command.c | 108 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6380621..9179c1f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6154,15 +6154,33 @@ qemuBuildSclpDevStr(virDomainChrDefPtr dev)
static int -qemuBuildRNGBackendArgs(virCommandPtr cmd, - virDomainRNGDefPtr dev, - virQEMUCapsPtr qemuCaps) +qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng, + virQEMUCapsPtr qemuCaps, + char **chr) { - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *backend = NULL; + *chr = NULL; + + if (rng->backend != VIR_DOMAIN_RNG_BACKEND_EGD) + return 0;
Making this a switch ((virDomainRNGBackend)) would check if all the enum values are handled.
+ + if (!(*chr = qemuBuildChrChardevStr(rng->source.chardev, + rng->info.alias, qemuCaps))) + return -1; +
@@ -10146,16 +10186,36 @@ qemuBuildCommandLine(virConnectPtr conn, }
for (i = 0; i < def->nrngs; i++) { - char *devstr; + virDomainRNGDefPtr rng = def->rngs[i]; + char *tmp; + + if (!rng->info.alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("RNG device is missing alias")); + goto error; + }
Is it possible for the alias to be NULL at this point? But it's still better to check twice than crash. :) Jan

On Mon, Feb 09, 2015 at 16:54:00 +0100, Ján Tomko wrote:
On Fri, Feb 06, 2015 at 04:32:21PM +0100, Peter Krempa wrote:
As the RNG device is using an -object as backend refactor the code to use the JSON to commandline generator so that we can reuse the code later in hotplug. --- src/qemu/qemu_command.c | 108 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6380621..9179c1f 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6154,15 +6154,33 @@ qemuBuildSclpDevStr(virDomainChrDefPtr dev)
static int -qemuBuildRNGBackendArgs(virCommandPtr cmd, - virDomainRNGDefPtr dev, - virQEMUCapsPtr qemuCaps) +qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng, + virQEMUCapsPtr qemuCaps, + char **chr) { - virBuffer buf = VIR_BUFFER_INITIALIZER; - char *backend = NULL; + *chr = NULL; + + if (rng->backend != VIR_DOMAIN_RNG_BACKEND_EGD) + return 0;
Making this a switch ((virDomainRNGBackend)) would check if all the enum values are handled.
Indeed. Having the complier to complain is useful when adding new stuff. Consider it added. Peter

From: Luyao Huang <lhuang@redhat.com> Signed-off-by: Luyao Huang <lhuang@redhat.com> --- src/conf/domain_audit.c | 2 +- src/conf/domain_audit.h | 7 +++++++ src/libvirt_private.syms | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c index fcf9df7..159ebf5 100644 --- a/src/conf/domain_audit.c +++ b/src/conf/domain_audit.c @@ -242,7 +242,7 @@ virDomainAuditDisk(virDomainObjPtr vm, } -static void +void virDomainAuditRNG(virDomainObjPtr vm, virDomainRNGDefPtr oldDef, virDomainRNGDefPtr newDef, const char *reason, bool success) diff --git a/src/conf/domain_audit.h b/src/conf/domain_audit.h index 3434feb..4c1ef90 100644 --- a/src/conf/domain_audit.h +++ b/src/conf/domain_audit.h @@ -117,5 +117,12 @@ void virDomainAuditChardev(virDomainObjPtr vm, const char *reason, bool success) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); +void virDomainAuditRNG(virDomainObjPtr vm, + virDomainRNGDefPtr oldDef, + virDomainRNGDefPtr newDef, + const char *reason, + bool success) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); + #endif /* __VIR_DOMAIN_AUDIT_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 619bf79..8407b7c 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -123,6 +123,7 @@ virDomainAuditMemory; virDomainAuditNet; virDomainAuditNetDevice; virDomainAuditRedirdev; +virDomainAuditRNG; virDomainAuditSecurityLabel; virDomainAuditStart; virDomainAuditStop; -- 2.2.2

From: Luyao Huang <lhuang@redhat.com> The helpers will be useful when implementing hotplug and coldplug of random number generator devices. Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/conf/domain_conf.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 4 +++ src/libvirt_private.syms | 3 +++ 3 files changed, 73 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 94289cf..526fb15 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -12173,6 +12173,72 @@ virDomainChrRemove(virDomainDefPtr vmdef, return ret; } + +int +virDomainRNGInsert(virDomainDefPtr def, + virDomainRNGDefPtr rng) +{ + return VIR_APPEND_ELEMENT(def->rngs, def->nrngs, rng); +} + + +ssize_t +virDomainRNGFind(virDomainDefPtr def, + virDomainRNGDefPtr rng) +{ + size_t i; + + for (i = 0; i < def->nrngs; i++) { + virDomainRNGDefPtr tmp = def->rngs[i]; + + if (rng->model != tmp->model || rng->backend != tmp->backend) + continue; + + if (rng->rate != tmp->rate || rng->period != tmp->period) + continue; + + switch ((virDomainRNGBackend) rng->backend) { + case VIR_DOMAIN_RNG_BACKEND_RANDOM: + if (STRNEQ_NULLABLE(rng->source.file, tmp->source.file)) + continue; + break; + + case VIR_DOMAIN_RNG_BACKEND_EGD: + if (!virDomainChrSourceDefIsEqual(rng->source.chardev, + tmp->source.chardev)) + continue; + break; + + case VIR_DOMAIN_RNG_BACKEND_LAST: + break; + } + + if (rng->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + !virDomainDeviceInfoAddressIsEqual(&rng->info, &tmp->info)) + continue; + + break; + } + + if (i < def->nrngs) + return i; + + return -1; +} + + +virDomainRNGDefPtr +virDomainRNGRemove(virDomainDefPtr def, + size_t idx) +{ + virDomainRNGDefPtr ret = def->rngs[idx]; + + VIR_DELETE_ELEMENT(def->rngs, idx, def->nrngs); + + return ret; +} + + char * virDomainDefGetDefaultEmulator(virDomainDefPtr def, virCapsPtr caps) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index d073a99..af6f733 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2665,6 +2665,10 @@ virDomainChrDefPtr virDomainChrRemove(virDomainDefPtr vmdef, virDomainChrDefPtr chr); +int virDomainRNGInsert(virDomainDefPtr def, virDomainRNGDefPtr rng); +ssize_t virDomainRNGFind(virDomainDefPtr def, virDomainRNGDefPtr rng); +virDomainRNGDefPtr virDomainRNGRemove(virDomainDefPtr def, size_t idx); + int virDomainSaveXML(const char *configDir, virDomainDefPtr def, const char *xml); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 8407b7c..07f0fd5 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -380,7 +380,10 @@ virDomainPMSuspendedReasonTypeToString; virDomainRedirdevBusTypeFromString; virDomainRedirdevBusTypeToString; virDomainRNGBackendTypeToString; +virDomainRNGFind; +virDomainRNGInsert; virDomainRNGModelTypeToString; +virDomainRNGRemove; virDomainRunningReasonTypeFromString; virDomainRunningReasonTypeToString; virDomainSaveConfig; -- 2.2.2

Add support for using the attach/detach device APIs on the inactive configuration to add RNG devices. --- src/libvirt_private.syms | 1 + src/qemu/qemu_driver.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 07f0fd5..eb5bd1a 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -380,6 +380,7 @@ virDomainPMSuspendedReasonTypeToString; virDomainRedirdevBusTypeFromString; virDomainRedirdevBusTypeToString; virDomainRNGBackendTypeToString; +virDomainRNGDefFree; virDomainRNGFind; virDomainRNGInsert; virDomainRNGModelTypeToString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index cf351e6..717b384 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7427,6 +7427,23 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, dev->data.fs = NULL; break; + case VIR_DOMAIN_DEVICE_RNG: + if (dev->data.rng->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && + virDomainDeviceInfoHasAddress(vmdef, &dev->data.rng->info)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("a device with the same address already exists ")); + return -1; + } + + if (virDomainRNGInsert(vmdef, dev->data.rng) < 0) + return -1; + + if (qemuDomainAssignAddresses(vmdef, qemuCaps, NULL) < 0) + return -1; + + dev->data.rng = NULL; + break; + case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: @@ -7436,7 +7453,6 @@ qemuDomainAttachDeviceConfig(virQEMUCapsPtr qemuCaps, case VIR_DOMAIN_DEVICE_SMARTCARD: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_NONE: @@ -7543,6 +7559,16 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainFSDefFree(fs); break; + case VIR_DOMAIN_DEVICE_RNG: + if ((idx = virDomainRNGFind(vmdef, dev->data.rng)) < 0) { + virReportError(VIR_ERR_OPERATION_FAILED, "%s", + _("no matching RNG device was found")); + return -1; + } + + virDomainRNGDefFree(virDomainRNGRemove(vmdef, idx)); + break; + case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: case VIR_DOMAIN_DEVICE_VIDEO: @@ -7552,7 +7578,6 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, case VIR_DOMAIN_DEVICE_SMARTCARD: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_NONE: -- 2.2.2

From: Luyao Huang <lhuang@redhat.com> Export the required helpers and add backend code to hotplug RNG devices. Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_command.h | 4 ++ src/qemu/qemu_driver.c | 8 +++- src/qemu/qemu_hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_hotplug.h | 3 ++ 5 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9179c1f..9068f50 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6171,7 +6171,7 @@ qemuBuildRNGBackendChrdevStr(virDomainRNGDefPtr rng, } -static int +int qemuBuildRNGBackendProps(virDomainRNGDefPtr rng, virQEMUCapsPtr qemuCaps, const char **type, diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index e280497..89e8351 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -174,6 +174,10 @@ char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def, char *qemuBuildRNGDevStr(virDomainDefPtr def, virDomainRNGDefPtr dev, virQEMUCapsPtr qemuCaps); +int qemuBuildRNGBackendProps(virDomainRNGDefPtr rng, + virQEMUCapsPtr qemuCaps, + const char **type, + virJSONValuePtr *props); int qemuOpenPCIConfig(virDomainHostdevDefPtr dev); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 717b384..9e5bdee 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7109,6 +7109,13 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, dev->data.chr = NULL; break; + case VIR_DOMAIN_DEVICE_RNG: + ret = qemuDomainAttachRNGDevice(driver, vm, + dev->data.rng); + if (!ret) + dev->data.rng = NULL; + break; + case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: @@ -7120,7 +7127,6 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_SMARTCARD: 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: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 033b281..6dd7360 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1569,6 +1569,105 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, return ret; } + +int +qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + char *devstr = NULL; + char *charAlias = NULL; + char *objAlias = NULL; + virJSONValuePtr props = NULL; + const char *type; + int ret = -1; + + if (qemuAssignDeviceRNGAlias(rng, vm->def->nrngs) < 0) + return -1; + + if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + if (STRPREFIX(vm->def->os.machine, "s390-ccw") && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_CCW)) { + rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW; + } else if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_VIRTIO_S390)) { + rng->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_S390; + } + } + + if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE || + rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + if (virDomainPCIAddressEnsureAddr(priv->pciaddrs, &rng->info) < 0) + return -1; + } else if (rng->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { + if (virDomainCCWAddressAssign(&rng->info, priv->ccwaddrs, + !rng->info.addr.ccw.assigned) < 0) + return -1; + } + + /* build required metadata */ + if (!(devstr = qemuBuildRNGDevStr(vm->def, rng, priv->qemuCaps))) + goto cleanup; + + if (qemuBuildRNGBackendProps(rng, priv->qemuCaps, &type, &props) < 0) + goto cleanup; + + if (virAsprintf(&objAlias, "obj%s", rng->info.alias) < 0) + goto cleanup; + + if (virAsprintf(&charAlias, "char%s", rng->info.alias) < 0) + goto cleanup; + + /* attach the device - up to a 3 stage process */ + qemuDomainObjEnterMonitor(driver, vm); + + if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && + qemuMonitorAttachCharDev(priv->mon, charAlias, + rng->source.chardev) < 0) + goto failchardev; + + if (qemuMonitorAddObject(priv->mon, type, objAlias, props) < 0) + goto failbackend; + + if (qemuMonitorAddDevice(priv->mon, devstr) < 0) + goto failfrontend; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + vm = NULL; + goto cleanup; + } + + if (virDomainRNGInsert(vm->def, rng) < 0) + goto audit; + + ret = 0; + + audit: + virDomainAuditRNG(vm, NULL, rng, "attach", ret == 0); + cleanup: + if (vm) + qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL); + VIR_FREE(charAlias); + VIR_FREE(objAlias); + VIR_FREE(devstr); + return ret; + + /* rollback */ + failfrontend: + ignore_value(qemuMonitorDelObject(priv->mon, objAlias)); + failbackend: + if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) + ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); + failchardev: + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + vm = NULL; + goto cleanup; + } + + goto audit; +} + + static int qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index a30788d..4f28a9d 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -97,6 +97,9 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver, int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainChrDefPtr chr); +int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng); int -- 2.2.2

On Fri, Feb 06, 2015 at 04:32:25PM +0100, Peter Krempa wrote:
From: Luyao Huang <lhuang@redhat.com>
Export the required helpers and add backend code to hotplug RNG devices.
Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_command.h | 4 ++ src/qemu/qemu_driver.c | 8 +++- src/qemu/qemu_hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_hotplug.h | 3 ++ 5 files changed, 114 insertions(+), 2 deletions(-)
-- 8< 8< 8< --
+ + /* attach the device - up to a 3 stage process */ + qemuDomainObjEnterMonitor(driver, vm); + + if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && + qemuMonitorAttachCharDev(priv->mon, charAlias, + rng->source.chardev) < 0) + goto failchardev; + + if (qemuMonitorAddObject(priv->mon, type, objAlias, props) < 0) + goto failbackend; + + if (qemuMonitorAddDevice(priv->mon, devstr) < 0) + goto failfrontend; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + vm = NULL; + goto cleanup; + }
I know an OOM error at this exact location is not that likely, but it would be nicer to prealloc the space in vm->def before entering the monitor so that the operation below cannot fail, like we do when hotplugging other devices. Jan

On Mon, Feb 09, 2015 at 16:57:17 +0100, Ján Tomko wrote:
On Fri, Feb 06, 2015 at 04:32:25PM +0100, Peter Krempa wrote:
From: Luyao Huang <lhuang@redhat.com>
Export the required helpers and add backend code to hotplug RNG devices.
Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_command.c | 2 +- src/qemu/qemu_command.h | 4 ++ src/qemu/qemu_driver.c | 8 +++- src/qemu/qemu_hotplug.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++ src/qemu/qemu_hotplug.h | 3 ++ 5 files changed, 114 insertions(+), 2 deletions(-)
-- 8< 8< 8< --
+ + /* attach the device - up to a 3 stage process */ + qemuDomainObjEnterMonitor(driver, vm); + + if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && + qemuMonitorAttachCharDev(priv->mon, charAlias, + rng->source.chardev) < 0) + goto failchardev; + + if (qemuMonitorAddObject(priv->mon, type, objAlias, props) < 0) + goto failbackend; + + if (qemuMonitorAddDevice(priv->mon, devstr) < 0) + goto failfrontend; + + if (qemuDomainObjExitMonitor(driver, vm) < 0) { + vm = NULL; + goto cleanup; + }
I know an OOM error at this exact location is not that likely, but it would be nicer to prealloc the space in vm->def before entering the monitor so that the operation below cannot fail, like we do when hotplugging other devices.
Sigh. Okay. I've switched to the preallocation approach as we do usually in this case.
Jan
Peter

From: Luyao Huang <lhuang@redhat.com> Signed-off-by: Luyao Huang <lhuang@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_driver.c | 4 +- src/qemu/qemu_hotplug.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++- src/qemu/qemu_hotplug.h | 4 +- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 9e5bdee..c8e067e 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7190,6 +7190,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainDetachChrDevice(driver, vm, dev->data.chr); break; + case VIR_DOMAIN_DEVICE_RNG: + ret = qemuDomainDetachRNGDevice(driver, vm, dev->data.rng); + break; case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: case VIR_DOMAIN_DEVICE_SOUND: @@ -7200,7 +7203,6 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm, case VIR_DOMAIN_DEVICE_SMARTCARD: case VIR_DOMAIN_DEVICE_MEMBALLOON: case VIR_DOMAIN_DEVICE_NVRAM: - case VIR_DOMAIN_DEVICE_RNG: case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_NONE: diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 6dd7360..5a89fc9 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2986,6 +2986,58 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver, } +static int +qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng) +{ + virObjectEventPtr event; + char *charAlias = NULL; + char *objAlias = NULL; + qemuDomainObjPrivatePtr priv = vm->privateData; + ssize_t idx; + int ret = -1; + int rc; + + VIR_DEBUG("Removing RNG device %s from domain %p %s", + rng->info.alias, vm, vm->def->name); + + if (virAsprintf(&objAlias, "obj%s", rng->info.alias) < 0) + goto cleanup; + + if (virAsprintf(&charAlias, "char%s", rng->info.alias) < 0) + goto cleanup; + + qemuDomainObjEnterMonitor(driver, vm); + rc = qemuMonitorDelObject(priv->mon, objAlias); + + if (rc == 0 && rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD) + ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias)); + + if (qemuDomainObjExitMonitor(driver, vm) < 0) + goto cleanup; + + virDomainAuditRNG(vm, rng, NULL, "detach", rc == 0); + + if (rc < 0) + goto cleanup; + + if ((event = virDomainEventDeviceRemovedNewFromObj(vm, rng->info.alias))) + qemuDomainEventQueue(driver, event); + + if ((idx = virDomainRNGFind(vm->def, rng)) >= 0) + virDomainRNGRemove(vm->def, idx); + qemuDomainReleaseDeviceAddress(vm, &rng->info, NULL); + virDomainRNGDefFree(rng); + ret = 0; + + cleanup: + VIR_FREE(charAlias); + VIR_FREE(objAlias); + return ret; +} + + int qemuDomainRemoveDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, @@ -3009,6 +3061,9 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_DEVICE_CHR: ret = qemuDomainRemoveChrDevice(driver, vm, dev->data.chr); break; + case VIR_DOMAIN_DEVICE_RNG: + qemuDomainRemoveRNGDevice(driver, vm, dev->data.rng); + break; case VIR_DOMAIN_DEVICE_NONE: case VIR_DOMAIN_DEVICE_LEASE: @@ -3023,7 +3078,6 @@ qemuDomainRemoveDevice(virQEMUDriverPtr driver, case VIR_DOMAIN_DEVICE_SMARTCARD: 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: @@ -3910,3 +3964,53 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, VIR_FREE(devstr); return ret; } + + +int +qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + ssize_t idx; + virDomainRNGDefPtr tmpRNG; + int rc; + int ret = -1; + + if ((idx = virDomainRNGFind(vm->def, rng) < 0)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("device not present in domain configuration")); + return -1; + } + + tmpRNG = vm->def->rngs[idx]; + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) { + virReportError(VIR_ERR_OPERATION_INVALID, "%s", + _("qemu does not support -device")); + return -1; + } + + if (!tmpRNG->info.alias) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("alias not set for RNG device")); + return -1; + } + + qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info); + + qemuDomainObjEnterMonitor(driver, vm); + rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias); + if (qemuDomainObjExitMonitor(driver, vm) || rc < 0) + goto cleanup; + + rc = qemuDomainWaitForDeviceRemoval(vm); + if (rc == 0 || rc == 1) + ret = qemuDomainRemoveRNGDevice(driver, vm, tmpRNG); + else + ret = 0; + + cleanup: + qemuDomainResetDeviceRemoval(vm); + return ret; +} diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index 4f28a9d..8a0b313 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -100,7 +100,9 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver, int qemuDomainAttachRNGDevice(virQEMUDriverPtr driver, virDomainObjPtr vm, virDomainRNGDefPtr rng); - +int qemuDomainDetachRNGDevice(virQEMUDriverPtr driver, + virDomainObjPtr vm, + virDomainRNGDefPtr rng); int qemuDomainChrInsert(virDomainDefPtr vmdef, -- 2.2.2

On Fri, Feb 06, 2015 at 04:32:14PM +0100, Peter Krempa wrote:
Extension of Luyao's series with changes that were possible due to the prepare series for memory hotplug.
Luyao Huang (7): qemu: Add helper to assign RNG device aliases qemu: refactor qemuBuildRNGDeviceArgs to allow reuse in RNG hotplug qemu: command: Make RNG backend device IDs unique audit: export virDomainAuditRNG conf: Add helpers to insert/remove/find RNG devices in domain def qemu: Implement random number generator hotplug qemu: Implement random number generator hotunplug
Peter Krempa (5): conf: Introduce helper to find duplicate device address qemu: command: Shuffle around formatting of alias for RNG device backend qemu: command: Break some very long lines in qemuBuildRNGDevStr() qemu: command: Refactor creation of RNG device commandline qemu: Implement random number generator cold (un)plug
src/conf/domain_audit.c | 2 +- src/conf/domain_audit.h | 7 + src/conf/domain_conf.c | 164 +++++++++++++++++ src/conf/domain_conf.h | 8 + src/libvirt_private.syms | 6 + src/qemu/qemu_command.c | 153 +++++++++++---- src/qemu/qemu_command.h | 9 + src/qemu/qemu_driver.c | 41 ++++- src/qemu/qemu_hotplug.c | 205 ++++++++++++++++++++- src/qemu/qemu_hotplug.h | 7 +- .../qemuxml2argv-aarch64-virt-virtio.args | 4 +- .../qemuxml2argv-arm-vexpressa9-virtio.args | 4 +- .../qemuxml2argv-arm-virt-virtio.args | 4 +- .../qemuxml2argv-s390-piix-controllers.args | 3 +- .../qemuxml2argv-s390-usb-none.args | 3 +- .../qemuxml2argv-virtio-rng-ccw.args | 4 +- .../qemuxml2argv-virtio-rng-default.args | 4 +- .../qemuxml2argv-virtio-rng-egd.args | 4 +- .../qemuxml2argv-virtio-rng-multiple.args | 8 +- .../qemuxml2argv-virtio-rng-random.args | 4 +- 20 files changed, 578 insertions(+), 66 deletions(-)
ACK series, see my replies to individual patches for some minor nits. Jan

On Mon, Feb 09, 2015 at 16:58:07 +0100, Ján Tomko wrote:
On Fri, Feb 06, 2015 at 04:32:14PM +0100, Peter Krempa wrote:
Extension of Luyao's series with changes that were possible due to the prepare series for memory hotplug.
ACK series, see my replies to individual patches for some minor nits.
I've fixed all of them and pushed the series after a final test. Thanks for the review.
Jan
Peter

On 02/10/2015 08:10 PM, Peter Krempa wrote:
On Mon, Feb 09, 2015 at 16:58:07 +0100, Ján Tomko wrote:
On Fri, Feb 06, 2015 at 04:32:14PM +0100, Peter Krempa wrote:
Extension of Luyao's series with changes that were possible due to the prepare series for memory hotplug.
ACK series, see my replies to individual patches for some minor nits. I've fixed all of them and pushed the series after a final test. Thanks for the review.
Thanks Peter's help, refactor and new patches :) Also thanks a lot for Jan's review :)
Jan
Peter
Luyao
participants (3)
-
Ján Tomko
-
Luyao Huang
-
Peter Krempa