From 3163682b585da7e894c9ea069741755fc316bdb3 Mon Sep 17 00:00:00 2001 From: Peter Krempa Date: Mon, 7 May 2012 13:56:17 +0200 Subject: [PATCH] qemu: Re-detect virtual cpu threads after cpu hot (un)plug. 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. --- src/qemu/qemu_driver.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 538dc25958..385b8615da 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" command (and they don't support multiple + * CPUs anyways), 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;