On Fri, Jan 29, 2016 at 05:02:02PM +0100, Peter Krempa wrote:
Now that qemuDomainDetectVcpuPids is able to refresh the vCPU pid
information it can be reused in the hotplug and hotunplug code paths
rather than open-coding a very similar algorithm.
A slight algoirithm change is necessary for unplug since the vCPU needs
*algorithm, as John pointed out in the review of v1.
to be marked offline prior to calling the thread detector function
and
eventually rolled back if something fails.
---
Notes:
v2: fix bugs regarding error codes from redetection
src/qemu/qemu_driver.c | 86 +++++++++++++++++---------------------------------
1 file changed, 29 insertions(+), 57 deletions(-)
@@ -4887,49 +4865,43 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr
driver,
return -1;
}
+ vcpuinfo->online = false;
+
qemuDomainObjEnterMonitor(driver, vm);
rc = qemuMonitorSetCPU(priv->mon, vcpu, false);
- if (rc == 0)
- ncpupids = qemuMonitorGetCPUInfo(priv->mon, &cpupids);
-
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto cleanup;
- virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update",
- rc == 0 && ncpupids == oldvcpus -1);
+ if (rc < 0)
+ rc = qemuDomainDetectVcpuPids(driver, vm, QEMU_ASYNC_JOB_NONE);
I would expect 'goto cleanup' if SetCPU failed and re-detecting the CPUs
if it succeeded.
- if (rc < 0 || ncpupids < 0)
- goto cleanup;
+ virDomainAuditVcpu(vm, oldvcpus, oldvcpus - 1, "update", rc >= 0);
+
If SetCPU failed, this would audit the return value of DetectVcpuPids.
+ /* Free vcpupin setting */
+ virDomainPinDel(&vm->def->cputune.vcpupin,
+ &vm->def->cputune.nvcpupin,
+ vcpu);
And if the domain crashed while DetectVcpuPids was in the monitor,
vm->def would be a stale pointer here.
+
+ if (rc <= 0) {
+ if (rc == 0)
+ ret = 0;
- /* check if hotunplug has failed */
- if (ncpupids != oldvcpus - 1) {
- virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
- _("qemu didn't unplug vCPU '%u' properly"),
vcpu);
goto cleanup;
}
- vcpuinfo->online = false;
-
if (qemuDomainDelCgroupForThread(priv->cgroup,
VIR_CGROUP_THREAD_VCPU, vcpu) < 0)
goto cleanup;
- /* Free vcpupin setting */
- virDomainPinDel(&vm->def->cputune.vcpupin,
- &vm->def->cputune.nvcpupin,
- vcpu);
-
- priv->nvcpupids = ncpupids;
- VIR_FREE(priv->vcpupids);
- priv->vcpupids = cpupids;
- cpupids = NULL;
-
ret = 0;
cleanup:
- VIR_FREE(cpupids);
+ /* rollback the cpu state */
+ if (ret < 0)
+ vcpuinfo->online = true;
+
vcpuinfo points into vm->def. It might be freed if the domain crashed.
Also, should the vcpu be marked as online if we got here because
DelCgroupForThread failed?
Jan