[libvirt] [PATCH 06/11] Fix vm usage after ExitMonitor on AttachDevice

Ján Tomko jtomko at redhat.com
Tue Dec 16 16:41:30 UTC 2014


If the domain has died while we were in the monitor,
do not clean up what was cleaned up in qemuProcessStop.
---
 src/qemu/qemu_hotplug.c | 83 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 56 insertions(+), 27 deletions(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 38471e3..94bc4a2 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -275,7 +275,8 @@ qemuDomainCheckEjectableMedia(virQEMUDriverPtr driver,
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
         table = qemuMonitorGetBlockInfo(priv->mon);
-        qemuDomainObjExitMonitor(driver, vm);
+        if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+            goto cleanup;
     }
 
     if (!table)
@@ -391,7 +392,10 @@ qemuDomainAttachVirtioDiskDevice(virConnectPtr conn,
             memcpy(&disk->info.addr.pci, &guestAddr, sizeof(guestAddr));
         }
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0) {
+        ret = -1;
+        goto cleanup;
+    }
 
     virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
 
@@ -485,7 +489,10 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
                                                  type,
                                                  &controller->info.addr.pci);
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0) {
+        ret = -1;
+        goto cleanup;
+    }
 
     if (ret == 0) {
         if (controller->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
@@ -636,7 +643,8 @@ qemuDomainAttachSCSIDisk(virConnectPtr conn,
             disk->info.addr.drive.unit = driveAddr.unit;
         }
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+        goto cleanup;
 
     virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
 
@@ -724,7 +732,8 @@ qemuDomainAttachUSBMassstorageDevice(virConnectPtr conn,
     } else {
         ret = qemuMonitorAddUSBDisk(priv->mon, src);
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+        goto cleanup;
 
     virDomainAuditDisk(vm, NULL, disk->src, "attach", ret >= 0);
 
@@ -1030,7 +1039,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         if (qemuMonitorAddNetdev(priv->mon, netstr,
                                  tapfd, tapfdName, tapfdSize,
                                  vhostfd, vhostfdName, vhostfdSize) < 0) {
-            qemuDomainObjExitMonitor(driver, vm);
+            if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+                goto cleanup;
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto cleanup;
         }
@@ -1038,7 +1048,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         if (qemuMonitorAddHostNetwork(priv->mon, netstr,
                                       tapfd, tapfdName, tapfdSize,
                                       vhostfd, vhostfdName, vhostfdSize) < 0) {
-            qemuDomainObjExitMonitor(driver, vm);
+            if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+                goto cleanup;
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto cleanup;
         }
@@ -1068,7 +1079,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
     qemuDomainObjEnterMonitor(driver, vm);
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
         if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
-            qemuDomainObjExitMonitor(driver, vm);
+            if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+                goto cleanup;
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto try_remove;
         }
@@ -1076,14 +1088,16 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
         guestAddr = net->info.addr.pci;
         if (qemuMonitorAddPCINetwork(priv->mon, nicstr,
                                      &guestAddr) < 0) {
-            qemuDomainObjExitMonitor(driver, vm);
+            if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+                goto cleanup;
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto try_remove;
         }
         net->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
         memcpy(&net->info.addr.pci, &guestAddr, sizeof(guestAddr));
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+        goto cleanup;
 
     /* set link state */
     if (net->linkstate == VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) {
@@ -1095,7 +1109,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
 
             if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
                 if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) {
-                    qemuDomainObjExitMonitor(driver, vm);
+                    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+                        goto cleanup;
                     virDomainAuditNet(vm, NULL, net, "attach", false);
                     goto try_remove;
                 }
@@ -1104,7 +1119,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
                                _("setting of link state not supported: Link is up"));
             }
 
-            qemuDomainObjExitMonitor(driver, vm);
+            if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+                goto cleanup;
         }
         /* link set to down */
     }
@@ -1116,7 +1132,7 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
  cleanup:
     if (!ret) {
         vm->def->nets[vm->def->nnets++] = net;
-    } else {
+    } else if (virDomainObjIsActive(vm)) {
         if (releaseaddr)
             qemuDomainReleaseDeviceAddress(vm, &net->info, NULL);
 
@@ -1293,7 +1309,8 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
         qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
                                          configfd, configfd_name);
-        qemuDomainObjExitMonitor(driver, vm);
+        if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+            goto cleanup;
     } else {
         virDevicePCIAddressPtr guestAddr = &hostdev->info->addr.pci;
         virDevicePCIAddressPtr hostAddr = &hostdev->source.subsys.u.pci.addr;
@@ -1309,7 +1326,8 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
 
         qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorAddPCIHostDevice(priv->mon, hostAddr, guestAddr);
-        qemuDomainObjExitMonitor(driver, vm);
+        if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+            goto cleanup;
 
         hostdev->info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI;
     }
@@ -1373,12 +1391,11 @@ int qemuDomainAttachRedirdevDevice(virQEMUDriverPtr driver,
         goto error;
 
     qemuDomainObjEnterMonitor(driver, vm);
-    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE))
-        ret = qemuMonitorAddDevice(priv->mon, devstr);
-    else
+    ret = qemuMonitorAddDevice(priv->mon, devstr);
+
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
         goto error;
 
-    qemuDomainObjExitMonitor(driver, vm);
     virDomainAuditRedirdev(vm, redirdev, "attach", ret == 0);
     if (ret < 0)
         goto error;
@@ -1500,17 +1517,26 @@ int qemuDomainAttachChrDevice(virQEMUDriverPtr driver,
 
     qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorAttachCharDev(priv->mon, charAlias, &chr->source) < 0) {
-        qemuDomainObjExitMonitor(driver, vm);
+        if (qemuDomainObjExitMonitorAlive(driver, vm) < 0) {
+            need_remove = false;
+            goto cleanup;
+        }
         goto audit;
     }
 
     if (devstr && qemuMonitorAddDevice(priv->mon, devstr) < 0) {
         /* detach associated chardev on error */
         qemuMonitorDetachCharDev(priv->mon, charAlias);
-        qemuDomainObjExitMonitor(driver, vm);
+        if (qemuDomainObjExitMonitorAlive(driver, vm) < 0) {
+            need_remove = false;
+            goto cleanup;
+        }
         goto audit;
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0) {
+        need_remove = false;
+        goto cleanup;
+    }
 
     ret = 0;
  audit:
@@ -1566,7 +1592,8 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
         ret = qemuMonitorAddUSBDeviceExact(priv->mon,
                                            hostdev->source.subsys.u.usb.bus,
                                            hostdev->source.subsys.u.usb.device);
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+        goto cleanup;
     virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
     if (ret < 0)
         goto cleanup;
@@ -1575,7 +1602,7 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
 
     ret = 0;
  cleanup:
-    if (ret < 0) {
+    if (ret < 0 && virDomainObjIsActive(vm)) {
         if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
             VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
         if (teardownlabel &&
@@ -1669,7 +1696,8 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
             }
         }
     }
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+        goto cleanup;
 
     virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
     if (ret < 0)
@@ -1679,7 +1707,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
 
     ret = 0;
  cleanup:
-    if (ret < 0) {
+    if (ret < 0 && virDomainObjIsActive(vm)) {
         qemuDomainReAttachHostSCSIDevices(driver, vm->def->name, &hostdev, 1);
         if (teardowncgroup && qemuTeardownHostdevCgroup(vm, hostdev) < 0)
             VIR_WARN("Unable to remove host device cgroup ACL on hotplug fail");
@@ -1869,7 +1897,8 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
     dev->linkstate = linkstate;
 
  cleanup:
-    qemuDomainObjExitMonitor(driver, vm);
+    if (qemuDomainObjExitMonitorAlive(driver, vm) < 0)
+        return -1;
 
     return ret;
 }
-- 
2.0.4




More information about the libvir-list mailing list