[libvirt] [PATCHv2 0/3] Fix output of virsh vcpuinfo after cpu hotplug

A respin of the series fixing guest rollback, a memory leak and making the vCPU thread re-detection safe to use with older qemu versions. Peter Krempa (3): qemu: Refactor qemuDomainSetVcpusFlags qemu: Re-detect virtual cpu threads after cpu hot (un)plug. qemu: Don't skip detection of virtual cpu's on non KVM targets src/qemu/qemu_driver.c | 55 ++++++++++++++++++++++++++++++++-------------- src/qemu/qemu_process.c | 21 ++++++----------- 2 files changed, 46 insertions(+), 30 deletions(-) -- 1.7.3.4

This patch changes a switch statement into ifs when handling live vs. configuration modifications getting rid of redundant code in case when both live and persistent configuration gets changed. --- Diff to v1: - change order of live and config modifications - do the live modification first --- src/qemu/qemu_driver.c | 26 +++++++++----------------- 1 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c9e047e..b283c8c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3463,33 +3463,25 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, goto endjob; } - switch (flags) { - case VIR_DOMAIN_AFFECT_CONFIG: + if (flags & VIR_DOMAIN_AFFECT_LIVE) { + if (qemudDomainHotplugVcpus(driver, vm, nvcpus) < 0) + goto endjob; + } + + if (flags & VIR_DOMAIN_AFFECT_CONFIG) { if (maximum) { persistentDef->maxvcpus = nvcpus; if (nvcpus < persistentDef->vcpus) persistentDef->vcpus = nvcpus; } else { persistentDef->vcpus = nvcpus; } - ret = 0; - break; - - case VIR_DOMAIN_AFFECT_LIVE: - ret = qemudDomainHotplugVcpus(driver, vm, nvcpus); - break; - case VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG: - ret = qemudDomainHotplugVcpus(driver, vm, nvcpus); - if (ret == 0) { - persistentDef->vcpus = nvcpus; - } - break; + if (virDomainSaveConfig(driver->configDir, persistentDef) < 0) + goto endjob; } - /* Save the persistent config to disk */ - if (flags & VIR_DOMAIN_AFFECT_CONFIG) - ret = virDomainSaveConfig(driver->configDir, persistentDef); + ret = 0; endjob: if (qemuDomainObjEndJob(driver, vm) == 0) -- 1.7.3.4

On 05/11/2012 07:23 AM, Peter Krempa wrote:
This patch changes a switch statement into ifs when handling live vs. configuration modifications getting rid of redundant code in case when both live and persistent configuration gets changed. --- Diff to v1: - change order of live and config modifications - do the live modification first --- src/qemu/qemu_driver.c | 26 +++++++++----------------- 1 files changed, 9 insertions(+), 17 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c9e047e..b283c8c 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3463,33 +3463,25 @@ qemuDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus, goto endjob; }
- switch (flags) { - case VIR_DOMAIN_AFFECT_CONFIG: + if (flags & VIR_DOMAIN_AFFECT_LIVE) {
Indentation off by one. ACK with that fix. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

After a cpu hotplug the qemu driver did not refresh information about virtual processors used by qemu and their corresponding threads. This patch forces a re-detection as is done on start of QEMU. This ensures that correct information is reported by the virDomainGetVcpus API and "virsh vcpuinfo". A failure to obtain the thread<->vcpu mapping is treated non-fatal and the mapping is not updated in a case of failure as not all versions of QEMU report this in the info cpus command. --- Diff to v1: - don't fail the call if cpu thread detection fails - fix memory leak when overwriting the priv->vcpupids array --- src/qemu/qemu_driver.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index b283c8c..a18b4e0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -3343,6 +3343,8 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver, int ret = -1; int oldvcpus = vm->def->vcpus; int vcpus = oldvcpus; + pid_t *cpupids = NULL; + int ncpupids; qemuDomainObjEnterMonitor(driver, vm); @@ -3373,11 +3375,38 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver, } } + /* hotplug succeeded */ + ret = 0; + /* After hotplugging the CPUs we need to re-detect threads corresponding + * to the virtual CPUs. Some older versions don't provide the thread ID + * or don't have the "info cpus" (and they don't support mutliple CPUs + * anyways) command, so errors in the re-detection will not be treated + * fatal */ + if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) <= 0) { + virResetLastError(); + goto cleanup; + } + + if (ncpupids != vcpus) { + qemuReportError(VIR_ERR_INTERNAL_ERROR, + _("got wrong number of vCPU pids from QEMU monitor. " + "got %d, wanted %d"), + ncpupids, vcpus); + ret = -1; + goto cleanup; + } + + priv->nvcpupids = ncpupids; + VIR_FREE(priv->vcpupids); + priv->vcpupids = cpupids; + cpupids = NULL; + cleanup: qemuDomainObjExitMonitor(driver, vm); vm->def->vcpus = vcpus; + VIR_FREE(cpupids); virDomainAuditVcpu(vm, oldvcpus, nvcpus, "update", rc == 1); return ret; -- 1.7.3.4

On 05/11/2012 07:23 AM, Peter Krempa wrote:
After a cpu hotplug the qemu driver did not refresh information about virtual processors used by qemu and their corresponding threads. This patch forces a re-detection as is done on start of QEMU.
This ensures that correct information is reported by the virDomainGetVcpus API and "virsh vcpuinfo".
A failure to obtain the thread<->vcpu mapping is treated non-fatal and the mapping is not updated in a case of failure as not all versions of QEMU report this in the info cpus command. --- Diff to v1: - don't fail the call if cpu thread detection fails - fix memory leak when overwriting the priv->vcpupids array --- src/qemu/qemu_driver.c | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
@@ -3373,11 +3375,38 @@ static int qemudDomainHotplugVcpus(struct qemud_driver *driver, } }
+ /* hotplug succeeded */ + ret = 0;
+ /* After hotplugging the CPUs we need to re-detect threads corresponding + * to the virtual CPUs. Some older versions don't provide the thread ID + * or don't have the "info cpus" (and they don't support mutliple CPUs
s/mutliple/multiple/
+ * anyways) command, so errors in the re-detection will not be treated
s/"info cpus" (...) command/"info cpus" command (...)/ ACK with comment fix. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

This patch lifts the limit of calling thread detection code only on KVM guests. With upstream qemu the thread mappings are reported also on non-KVM machines. QEMU adoppted the thread_id information from the kvm branch. To remain compatible with older upstream versions of qemu the check is attempted but the failure to detect threads (or even run the monitor command - on older versions without SMP support) is treated non-fatal and the code reports one vCPU with pid of the hypervisor (in same fashion this was done on non-KVM guests). --- Diff to v1: - Try to detect vCPU threads on all types of guests but fall back gracefully if the hypervisor doesn't support it. --- src/qemu/qemu_process.c | 21 ++++++++------------- 1 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index b7c53ea..d226067 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -1613,29 +1613,24 @@ qemuProcessDetectVcpuPIDs(struct qemud_driver *driver, int ncpupids; qemuDomainObjPrivatePtr priv = vm->privateData; - if (vm->def->virtType != VIR_DOMAIN_VIRT_KVM) { + qemuDomainObjEnterMonitorWithDriver(driver, vm); + /* failure to get the VCPU<-> PID mapping or to execute the query + * command will not be treated fatal as some versions of qemu don't + * support this command */ + if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) <= 0) { + qemuDomainObjExitMonitorWithDriver(driver, vm); + virResetLastError(); + priv->nvcpupids = 1; if (VIR_ALLOC_N(priv->vcpupids, priv->nvcpupids) < 0) { virReportOOMError(); return -1; } priv->vcpupids[0] = vm->pid; return 0; } - - /* What follows is now all KVM specific */ - - qemuDomainObjEnterMonitorWithDriver(driver, vm); - if ((ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids)) < 0) { - qemuDomainObjExitMonitorWithDriver(driver, vm); - return -1; - } qemuDomainObjExitMonitorWithDriver(driver, vm); - /* Treat failure to get VCPU<->PID mapping as non-fatal */ - if (ncpupids == 0) - return 0; - if (ncpupids != vm->def->vcpus) { qemuReportError(VIR_ERR_INTERNAL_ERROR, _("got wrong number of vCPU pids from QEMU monitor. " -- 1.7.3.4

On 05/11/2012 07:23 AM, Peter Krempa wrote:
This patch lifts the limit of calling thread detection code only on KVM guests. With upstream qemu the thread mappings are reported also on non-KVM machines.
QEMU adoppted the thread_id information from the kvm branch.
s/adoppted/adopted/
To remain compatible with older upstream versions of qemu the check is attempted but the failure to detect threads (or even run the monitor command - on older versions without SMP support) is treated non-fatal and the code reports one vCPU with pid of the hypervisor (in same fashion this was done on non-KVM guests). --- Diff to v1: - Try to detect vCPU threads on all types of guests but fall back gracefully if the hypervisor doesn't support it. --- src/qemu/qemu_process.c | 21 ++++++++------------- 1 files changed, 8 insertions(+), 13 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 05/11/2012 04:12 PM, Eric Blake wrote:
On 05/11/2012 07:23 AM, Peter Krempa wrote:
This patch lifts the limit of calling thread detection code only on KVM guests. With upstream qemu the thread mappings are reported also on non-KVM machines.
QEMU adoppted the thread_id information from the kvm branch.
s/adoppted/adopted/
To remain compatible with older upstream versions of qemu the check is attempted but the failure to detect threads (or even run the monitor command - on older versions without SMP support) is treated non-fatal and the code reports one vCPU with pid of the hypervisor (in same fashion this was done on non-KVM guests). --- Diff to v1: - Try to detect vCPU threads on all types of guests but fall back gracefully if the hypervisor doesn't support it. --- src/qemu/qemu_process.c | 21 ++++++++------------- 1 files changed, 8 insertions(+), 13 deletions(-)
ACK.
Thanks; I fixed the nits and pushed the series. Peter
participants (2)
-
Eric Blake
-
Peter Krempa