]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: hotplug: Reset device removal waiting code after vCPU unplug
authorPeter Krempa <pkrempa@redhat.com>
Fri, 3 Mar 2017 15:04:57 +0000 (16:04 +0100)
committerPeter Krempa <pkrempa@redhat.com>
Fri, 10 Mar 2017 07:18:20 +0000 (08:18 +0100)
If the delivery of the DEVICE_DELETED event for the vCPU being deleted
would time out, the code would not call 'qemuDomainResetDeviceRemoval'.

Since the waiting thread did not unregister itself prior to stopping the
waiting the monitor code would try to wake it up instead of dispatching
it to the event worker. As a result the unplug process would not be
completed and the definition would not be updated.

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1428893
          https://bugzilla.redhat.com/show_bug.cgi?id=1427801

src/qemu/qemu_hotplug.c

index b421340dde60f9cb7c2419fc3923d6bbb623c8b3..c33c6b9f2ede19e68ecc2e9a7af4391b10ef9b4b 100644 (file)
@@ -5355,6 +5355,7 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
     int oldvcpus = virDomainDefGetVcpus(vm->def);
     unsigned int nvcpus = vcpupriv->vcpus;
     int rc;
+    int ret = -1;
 
     if (!vcpupriv->alias) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -5369,11 +5370,11 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
     rc = qemuMonitorDelDevice(qemuDomainGetMonitor(vm), vcpupriv->alias);
 
     if (qemuDomainObjExitMonitor(driver, vm) < 0)
-        return -1;
+        goto cleanup;
 
     if (rc < 0) {
         virDomainAuditVcpu(vm, oldvcpus, oldvcpus - nvcpus, "update", false);
-        return -1;
+        goto cleanup;
     }
 
     if ((rc = qemuDomainWaitForDeviceRemoval(vm)) <= 0) {
@@ -5381,10 +5382,17 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
             virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                            _("vcpu unplug request timed out"));
 
-        return -1;
+        goto cleanup;
     }
 
-    return qemuDomainRemoveVcpu(driver, vm, vcpu);
+    if (qemuDomainRemoveVcpu(driver, vm, vcpu) < 0)
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    qemuDomainResetDeviceRemoval(vm);
+    return ret;
 }