[PATCH] qemu: monitor: fix unsafe monitor access

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: root <root@localhost.localdomain>

qemuDomainObjExitMonitor is unsafe

domain lock released when qemuDomainObjEnterMonitor finish,
So other thread (qemuProcessStop) has chance to modify priv->mon
to NULL. qemuDomainObjExitMonitor will never release the mon->lock,

that may cause problem:
thread get monitor ptr early, and then try to get mon->lock,
it will block forerver cause mon->lock not released by
qemuDomainObjExitMonitor.

Signed-off-by: Wang Yechao <wang.yechao255@xxxxxxxxxx>
Signed-off-by: Peng Hao <peng.hao2@xxxxxxxxxx>
---
 src/qemu/THREADS.txt             |  12 +-
 src/qemu/qemu_block.c            |   5 +-
 src/qemu/qemu_domain.c           |  64 +++++----
 src/qemu/qemu_domain.h           |  12 +-
 src/qemu/qemu_driver.c           | 258 ++++++++++++++++++++--------------
 src/qemu/qemu_hotplug.c          | 296 ++++++++++++++++++++++-----------------
 src/qemu/qemu_migration.c        | 104 ++++++++------
 src/qemu/qemu_migration_cookie.c |   5 +-
 src/qemu/qemu_process.c          | 108 ++++++++------
 9 files changed, 507 insertions(+), 357 deletions(-)
 mode change 100644 => 100755 src/qemu/THREADS.txt
 mode change 100644 => 100755 src/qemu/qemu_block.c
 mode change 100644 => 100755 src/qemu/qemu_domain.c
 mode change 100644 => 100755 src/qemu/qemu_domain.h
 mode change 100644 => 100755 src/qemu/qemu_driver.c
 mode change 100644 => 100755 src/qemu/qemu_hotplug.c
 mode change 100644 => 100755 src/qemu/qemu_migration.c
 mode change 100644 => 100755 src/qemu/qemu_migration_cookie.c
 mode change 100644 => 100755 src/qemu/qemu_process.c

diff --git a/src/qemu/THREADS.txt b/src/qemu/THREADS.txt
old mode 100644
new mode 100755
index 7243161..6a56003
--- a/src/qemu/THREADS.txt
+++ b/src/qemu/THREADS.txt
@@ -228,6 +228,7 @@ Design patterns
 
      virDomainObjPtr obj;
      qemuDomainObjPrivatePtr priv;
+     qemuMonitorPtr mon;
 
      obj = qemuDomObjFromDomain(dom);
 
@@ -236,9 +237,9 @@ Design patterns
      ...do prep work...
 
      if (virDomainObjIsActive(vm)) {
-         qemuDomainObjEnterMonitor(obj);
+         mon = qemuDomainObjEnterMonitor(obj);
          qemuMonitorXXXX(priv->mon);
-         qemuDomainObjExitMonitor(obj);
+         qemuDomainObjExitMonitor(obj, mon);
      }
 
      ...do final work...
@@ -251,6 +252,7 @@ Design patterns
 
      virDomainObjPtr obj;
      qemuDomainObjPrivatePtr priv;
+     qemuMonitorPtr mon;
 
      obj = qemuDomObjFromDomain(dom);
 
@@ -260,12 +262,12 @@ Design patterns
      ...do prep work...
 
      if (qemuDomainObjEnterMonitorAsync(driver, obj,
-                                        QEMU_ASYNC_JOB_TYPE) < 0) {
+                                        QEMU_ASYNC_JOB_TYPE, &mon) < 0) {
          /* domain died in the meantime */
          goto error;
      }
      ...start qemu job...
-     qemuDomainObjExitMonitor(driver, obj);
+     qemuDomainObjExitMonitor(driver, obj, mon);
 
      while (!finished) {
          if (qemuDomainObjEnterMonitorAsync(driver, obj,
@@ -274,7 +276,7 @@ Design patterns
              goto error;
          }
          ...monitor job progress...
-         qemuDomainObjExitMonitor(driver, obj);
+         qemuDomainObjExitMonitor(driver, obj, mon);
 
          virObjectUnlock(obj);
          sleep(aWhile);
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
old mode 100644
new mode 100755
index 585f025..d437802
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -327,17 +327,18 @@ qemuBlockNodeNamesDetect(virQEMUDriverPtr driver,
     virDomainDiskDefPtr disk;
     size_t i;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_QUERY_NAMED_BLOCK_NODES))
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     data = qemuMonitorQueryNamedBlockNodes(qemuDomainGetMonitor(vm));
     blockstats = qemuMonitorQueryBlockstats(qemuDomainGetMonitor(vm));
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || !data || !blockstats)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || !data || !blockstats)
         goto cleanup;
 
     if (!(disktable = qemuBlockNodeNameGetBackingChain(data, blockstats)))
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
old mode 100644
new mode 100755
index aa65295..a09235e
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -5602,15 +5602,16 @@ qemuDomainObjEnterMonitorInternal(virQEMUDriverPtr driver,
 
 static void ATTRIBUTE_NONNULL(1)
 qemuDomainObjExitMonitorInternal(virQEMUDriverPtr driver,
-                                 virDomainObjPtr obj)
+                                 virDomainObjPtr obj,
+                                 qemuMonitorPtr mon)
 {
     qemuDomainObjPrivatePtr priv = obj->privateData;
     bool hasRefs;
 
-    hasRefs = virObjectUnref(priv->mon);
+    hasRefs = virObjectUnref(mon);
 
     if (hasRefs)
-        virObjectUnlock(priv->mon);
+        virObjectUnlock(mon);
 
     virObjectLock(obj);
     VIR_DEBUG("Exited monitor (mon=%p vm=%p name=%s)",
@@ -5624,11 +5625,13 @@ qemuDomainObjExitMonitorInternal(virQEMUDriverPtr driver,
         qemuDomainObjEndJob(driver, obj);
 }
 
-void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
+qemuMonitorPtr qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
                                virDomainObjPtr obj)
 {
+    qemuMonitorPtr mon = qemuDomainGetMonitor(obj);
     ignore_value(qemuDomainObjEnterMonitorInternal(driver, obj,
                                                    QEMU_ASYNC_JOB_NONE));
+    return mon;
 }
 
 /* obj must NOT be locked before calling
@@ -5642,9 +5645,10 @@ void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
  * from the live definition could no longer be valid.
  */
 int qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
-                             virDomainObjPtr obj)
+                             virDomainObjPtr obj,
+                             qemuMonitorPtr mon)
 {
-    qemuDomainObjExitMonitorInternal(driver, obj);
+    qemuDomainObjExitMonitorInternal(driver, obj, mon);
     if (!virDomainObjIsActive(obj)) {
         if (!virGetLastError())
             virReportError(VIR_ERR_OPERATION_FAILED, "%s",
@@ -5671,8 +5675,10 @@ int qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
 int
 qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
                                virDomainObjPtr obj,
-                               qemuDomainAsyncJob asyncJob)
+                               qemuDomainAsyncJob asyncJob,
+                               qemuMonitorPtr *mon)
 {
+    *mon = qemuDomainGetMonitor(obj);
     return qemuDomainObjEnterMonitorInternal(driver, obj, asyncJob);
 }
 
@@ -6621,6 +6627,7 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
 {
     char *snapFile = NULL;
     int ret = -1;
+    qemuMonitorPtr mon;
     qemuDomainObjPrivatePtr priv;
     virDomainSnapshotObjPtr parentsnap = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
@@ -6633,10 +6640,10 @@ qemuDomainSnapshotDiscard(virQEMUDriverPtr driver,
                 goto cleanup;
         } else {
             priv = vm->privateData;
-            qemuDomainObjEnterMonitor(driver, vm);
+            mon = qemuDomainObjEnterMonitor(driver, vm);
             /* we continue on even in the face of error */
             qemuMonitorDeleteSnapshot(priv->mon, snap->def->name);
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         }
     }
 
@@ -7477,14 +7484,15 @@ qemuDomainUpdateDeviceList(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char **aliases;
     int rc;
+    qemuMonitorPtr mon;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
     rc = qemuMonitorGetDeviceAliases(priv->mon, &aliases);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
     if (rc < 0)
         return -1;
@@ -7504,16 +7512,17 @@ qemuDomainUpdateMemoryDeviceInfo(virQEMUDriverPtr driver,
     virHashTablePtr meminfo = NULL;
     int rc;
     size_t i;
+    qemuMonitorPtr mon;
 
     if (vm->def->nmems == 0)
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     rc = qemuMonitorGetMemoryDeviceInfo(priv->mon, &meminfo);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         virHashFree(meminfo);
         return -1;
     }
@@ -8243,6 +8252,7 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
                                   virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
     unsigned long long balloon;
     int ret = -1;
 
@@ -8275,9 +8285,9 @@ qemuDomainUpdateCurrentMemorySize(virQEMUDriverPtr driver,
             goto endjob;
         }
 
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorGetBalloonInfo(priv->mon, &balloon);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
 
  endjob:
@@ -8608,15 +8618,16 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
     bool hotplug;
     int rc;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     hotplug = qemuDomainSupportsNewVcpuHotplug(vm);
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus, hotplug);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (rc < 0)
@@ -8721,6 +8732,7 @@ qemuDomainRefreshVcpuHalted(virQEMUDriverPtr driver,
     virBitmapPtr haltedmap = NULL;
     size_t i;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     /* Not supported currently for TCG, see qemuDomainRefreshVcpuInfo */
     if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
@@ -8731,12 +8743,12 @@ qemuDomainRefreshVcpuHalted(virQEMUDriverPtr driver,
     if (!ARCH_IS_S390(vm->def->os.arch))
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     haltedmap = qemuMonitorGetCpuHalted(qemuDomainGetMonitor(vm), maxvcpus);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || !haltedmap)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || !haltedmap)
         goto cleanup;
 
     for (i = 0; i < maxvcpus; i++) {
@@ -9081,13 +9093,14 @@ qemuDomainCheckMonitor(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     ret = qemuMonitorCheck(priv->mon);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     return ret;
@@ -11399,13 +11412,14 @@ qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
     char **capStr;
     int ret = -1;
     int rc;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     rc = qemuMonitorGetMigrationCapabilities(priv->mon, &caps);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         goto cleanup;
 
     if (!caps) {
@@ -11429,14 +11443,14 @@ qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
     }
 
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT)) {
-        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
             goto cleanup;
 
         rc = qemuMonitorSetMigrationCapability(priv->mon,
                                                QEMU_MONITOR_MIGRATION_CAPS_EVENTS,
                                                true);
 
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
 
         if (rc < 0) {
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
old mode 100644
new mode 100755
index f3ec5d8..ceee781
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -517,17 +517,19 @@ void qemuDomainObjReleaseAsyncJob(virDomainObjPtr obj);
 
 qemuMonitorPtr qemuDomainGetMonitor(virDomainObjPtr vm)
     ATTRIBUTE_NONNULL(1);
-void qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
+qemuMonitorPtr qemuDomainObjEnterMonitor(virQEMUDriverPtr driver,
                                virDomainObjPtr obj)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 int qemuDomainObjExitMonitor(virQEMUDriverPtr driver,
-                             virDomainObjPtr obj)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
+                             virDomainObjPtr obj,
+                             qemuMonitorPtr mon)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
     ATTRIBUTE_RETURN_CHECK;
 int qemuDomainObjEnterMonitorAsync(virQEMUDriverPtr driver,
                                    virDomainObjPtr obj,
-                                   qemuDomainAsyncJob asyncJob)
-    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
+                                   qemuDomainAsyncJob asyncJob,
+                                   qemuMonitorPtr *mon)
+    ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
 
 
 qemuAgentPtr qemuDomainObjEnterAgent(virDomainObjPtr obj)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
old mode 100644
new mode 100755
index 8d77d89..ef84596
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1987,6 +1987,7 @@ static int qemuDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
+    qemuMonitorPtr mon;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
     bool useAgent = false, agentRequested, acpiRequested;
@@ -2057,9 +2058,9 @@ static int qemuDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
         }
 
         qemuDomainSetFakeReboot(driver, vm, isReboot);
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorSystemPowerdown(priv->mon);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
     }
 
@@ -2082,6 +2083,7 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
+    qemuMonitorPtr mon;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
     bool useAgent = false, agentRequested, acpiRequested;
@@ -2159,9 +2161,9 @@ qemuDomainReboot(virDomainPtr dom, unsigned int flags)
         }
 #endif
         qemuDomainSetFakeReboot(driver, vm, isReboot);
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorSystemPowerdown(priv->mon);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
     }
 
@@ -2179,6 +2181,7 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags)
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
+    qemuMonitorPtr mon;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
     virDomainState state;
@@ -2201,9 +2204,9 @@ qemuDomainReset(virDomainPtr dom, unsigned int flags)
     }
 
     priv = vm->privateData;
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorSystemReset(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     priv->fakeReboot = false;
@@ -2360,6 +2363,7 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     virDomainObjPtr vm;
     virDomainDefPtr def;
     virDomainDefPtr persistentDef;
+    qemuMonitorPtr mon;
     int ret = -1, r;
     virQEMUDriverConfigPtr cfg = NULL;
 
@@ -2438,9 +2442,9 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
 
         if (def) {
             priv = vm->privateData;
-            qemuDomainObjEnterMonitor(driver, vm);
+            mon = qemuDomainObjEnterMonitor(driver, vm);
             r = qemuMonitorSetBalloon(priv->mon, newmem);
-            if (qemuDomainObjExitMonitor(driver, vm) < 0 || r < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || r < 0)
                 goto endjob;
 
             /* Lack of balloon support is a fatal error */
@@ -2488,6 +2492,7 @@ static int qemuDomainSetMemoryStatsPeriod(virDomainPtr dom, int period,
     virDomainObjPtr vm;
     virDomainDefPtr def;
     virDomainDefPtr persistentDef;
+    qemuMonitorPtr mon;
     int ret = -1, r;
     virQEMUDriverConfigPtr cfg = NULL;
 
@@ -2520,9 +2525,9 @@ static int qemuDomainSetMemoryStatsPeriod(virDomainPtr dom, int period,
             goto endjob;
         }
 
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         r = qemuMonitorSetMemoryStatsPeriod(priv->mon, def->memballoon, period);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto endjob;
         if (r < 0) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -2562,6 +2567,7 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
 {
     virQEMUDriverPtr driver = domain->conn->privateData;
     virDomainObjPtr vm = NULL;
+    qemuMonitorPtr mon;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
 
@@ -2584,9 +2590,9 @@ static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorInjectNMI(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -2608,6 +2614,7 @@ static int qemuDomainSendKey(virDomainPtr domain,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
 
     virCheckFlags(0, -1);
 
@@ -2647,9 +2654,9 @@ static int qemuDomainSendKey(virDomainPtr domain,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorSendKey(priv->mon, holdtime, keycodes, nkeycodes);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -3806,6 +3813,7 @@ qemuDumpToFd(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     bool detach = false;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DUMP_GUEST_MEMORY)) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
@@ -3825,7 +3833,7 @@ qemuDumpToFd(virQEMUDriverPtr driver,
         priv->job.dump_memory_only = true;
     }
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     if (dumpformat) {
@@ -3837,14 +3845,14 @@ qemuDumpToFd(virQEMUDriverPtr driver,
                              "for this QEMU binary"),
                            dumpformat);
             ret = -1;
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             goto cleanup;
         }
     }
 
     ret = qemuMonitorDumpToFd(priv->mon, fd, dumpformat, detach);
 
-    if ((qemuDomainObjExitMonitor(driver, vm) < 0) || ret < 0)
+    if ((qemuDomainObjExitMonitor(driver, vm, mon) < 0) || ret < 0)
         goto cleanup;
 
     if (detach)
@@ -3961,6 +3969,7 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
+    qemuMonitorPtr mon;
     qemuDomainObjPrivatePtr priv = NULL;
     bool resume = false, paused = false;
     int ret = -1;
@@ -4025,9 +4034,9 @@ qemuDomainCoreDumpWithFormat(virDomainPtr dom,
     } else if (((resume && paused) || (flags & VIR_DUMP_RESET)) &&
                virDomainObjIsActive(vm)) {
         if ((ret == 0) && (flags & VIR_DUMP_RESET)) {
-            qemuDomainObjEnterMonitor(driver, vm);
+            mon = qemuDomainObjEnterMonitor(driver, vm);
             ret = qemuMonitorSystemReset(priv->mon);
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 ret = -1;
         }
 
@@ -4075,6 +4084,7 @@ qemuDomainScreenshot(virDomainPtr dom,
 {
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
+    qemuMonitorPtr mon;
     qemuDomainObjPrivatePtr priv;
     char *tmp = NULL;
     int tmp_fd = -1;
@@ -4122,12 +4132,12 @@ qemuDomainScreenshot(virDomainPtr dom,
 
     qemuSecuritySetSavedStateLabel(driver->securityManager, vm->def, tmp);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorScreendump(priv->mon, tmp) < 0) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         goto endjob;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto endjob;
 
     if (VIR_CLOSE(tmp_fd) < 0) {
@@ -4603,6 +4613,7 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDeviceDef dev;
     virDomainNetDefPtr def;
+    qemuMonitorPtr mon;
     virNetDevRxFilterPtr guestFilter = NULL;
     virNetDevRxFilterPtr hostFilter = NULL;
     int ret;
@@ -4648,9 +4659,9 @@ processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
     VIR_DEBUG("process NIC_RX_FILTER_CHANGED event for network "
               "device %s in domain %s", def->info.alias, vm->def->name);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorQueryRxFilter(priv->mon, devAlias, &guestFilter);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     if (ret < 0)
         goto endjob;
@@ -5552,6 +5563,7 @@ qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv;
     qemuMonitorIOThreadInfoPtr *iothreads = NULL;
     virDomainIOThreadInfoPtr *info_ret = NULL;
+    qemuMonitorPtr mon;
     int niothreads = 0;
     size_t i;
     int ret = -1;
@@ -5572,9 +5584,9 @@ qemuDomainGetIOThreadsLive(virQEMUDriverPtr driver,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     niothreads = qemuMonitorGetIOThreads(priv->mon, &iothreads);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto endjob;
     if (niothreads < 0)
         goto endjob;
@@ -5872,11 +5884,12 @@ qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver,
     int new_niothreads = 0;
     qemuMonitorIOThreadInfoPtr *new_iothreads = NULL;
     virDomainIOThreadIDDefPtr iothrid;
+    qemuMonitorPtr mon;
 
     if (virAsprintf(&alias, "iothread%u", iothread_id) < 0)
         return -1;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     rc = qemuMonitorAddObject(priv->mon, "iothread", alias, NULL);
     exp_niothreads++;
@@ -5891,7 +5904,7 @@ qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver,
                                                   &new_iothreads)) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (new_niothreads != exp_niothreads) {
@@ -5940,7 +5953,7 @@ qemuDomainHotplugAddIOThread(virQEMUDriverPtr driver,
     return ret;
 
  exit_monitor:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     goto cleanup;
 }
 
@@ -5958,11 +5971,12 @@ qemuDomainHotplugDelIOThread(virQEMUDriverPtr driver,
     unsigned int exp_niothreads = vm->def->niothreadids;
     int new_niothreads = 0;
     qemuMonitorIOThreadInfoPtr *new_iothreads = NULL;
+    qemuMonitorPtr mon;
 
     if (virAsprintf(&alias, "iothread%u", iothread_id) < 0)
         return -1;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     rc = qemuMonitorDelObject(priv->mon, alias);
     exp_niothreads--;
@@ -5973,7 +5987,7 @@ qemuDomainHotplugDelIOThread(virQEMUDriverPtr driver,
                                                   &new_iothreads)) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (new_niothreads != exp_niothreads) {
@@ -6004,7 +6018,7 @@ qemuDomainHotplugDelIOThread(virQEMUDriverPtr driver,
     return ret;
 
  exit_monitor:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     goto cleanup;
 }
 
@@ -10826,6 +10840,7 @@ qemuDomainBlockResize(virDomainPtr dom,
     int ret = -1;
     char *device = NULL;
     virDomainDiskDefPtr disk = NULL;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_DOMAIN_BLOCK_RESIZE_BYTES, -1);
 
@@ -10879,12 +10894,12 @@ qemuDomainBlockResize(virDomainPtr dom,
     if (!(device = qemuAliasFromDisk(disk)))
         goto endjob;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorBlockResize(priv->mon, device, size) < 0) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         goto endjob;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto endjob;
 
     ret = 0;
@@ -10945,6 +10960,7 @@ qemuDomainBlocksStatsGather(virQEMUDriverPtr driver,
     virDomainDiskDefPtr disk;
     virHashTablePtr blockstats = NULL;
     qemuBlockStatsPtr stats;
+    qemuMonitorPtr mon;
     int nstats;
     char *diskAlias = NULL;
     int ret = -1;
@@ -10965,9 +10981,9 @@ qemuDomainBlocksStatsGather(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     nstats = qemuMonitorGetAllBlockStatsInfo(priv->mon, &blockstats, false);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || nstats < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || nstats < 0)
         goto cleanup;
 
     if (VIR_ALLOC(*retstats) < 0)
@@ -11499,6 +11515,7 @@ qemuDomainMemoryStatsInternal(virQEMUDriverPtr driver,
 {
     int ret = -1;
     long rss;
+    qemuMonitorPtr mon;
 
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -11508,10 +11525,10 @@ qemuDomainMemoryStatsInternal(virQEMUDriverPtr driver,
 
     if (vm->def->memballoon &&
         vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO) {
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorGetMemoryStats(qemuDomainGetMonitor(vm),
                                         vm->def->memballoon, stats, nr_stats);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
 
         if (ret < 0 || ret >= nr_stats)
@@ -11634,6 +11651,7 @@ qemuDomainMemoryPeek(virDomainPtr dom,
     int fd = -1, ret = -1;
     qemuDomainObjPrivatePtr priv;
     virQEMUDriverConfigPtr cfg = NULL;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_MEMORY_VIRTUAL | VIR_MEMORY_PHYSICAL, -1);
 
@@ -11673,19 +11691,19 @@ qemuDomainMemoryPeek(virDomainPtr dom,
     qemuSecuritySetSavedStateLabel(driver->securityManager, vm->def, tmp);
 
     priv = vm->privateData;
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (flags == VIR_MEMORY_VIRTUAL) {
         if (qemuMonitorSaveVirtualMemory(priv->mon, offset, size, tmp) < 0) {
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             goto endjob;
         }
     } else {
         if (qemuMonitorSavePhysicalMemory(priv->mon, offset, size, tmp) < 0) {
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             goto endjob;
         }
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto endjob;
 
     /* Read the memory file into buffer. */
@@ -11898,6 +11916,7 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
     virHashTablePtr stats = NULL;
     qemuBlockStats *entry;
     char *alias = NULL;
+    qemuMonitorPtr mon;
 
     virCheckFlags(0, -1);
 
@@ -11945,14 +11964,14 @@ qemuDomainGetBlockInfo(virDomainPtr dom,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorGetAllBlockStatsInfo(qemuDomainGetMonitor(vm),
                                          &stats, false);
     if (rc >= 0)
         rc = qemuMonitorBlockStatsUpdateCapacity(qemuDomainGetMonitor(vm),
                                                  stats, false);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         goto endjob;
 
     if (!(entry = virHashLookup(stats, alias))) {
@@ -13239,13 +13258,14 @@ qemuDomainGetJobInfoDumpStats(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuMonitorDumpStats stats = { 0 };
     int rc;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, QEMU_ASYNC_JOB_NONE, &mon) < 0)
         return -1;
 
     rc = qemuMonitorQueryDump(priv->mon, &stats);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         return -1;
 
     jobInfo->stats.dump = stats;
@@ -13431,6 +13451,7 @@ static int qemuDomainAbortJob(virDomainPtr dom)
     virDomainObjPtr vm;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     int reason;
 
     if (!(vm = qemuDomObjFromDomain(dom)))
@@ -13474,9 +13495,9 @@ static int qemuDomainAbortJob(virDomainPtr dom)
 
     VIR_DEBUG("Cancelling job at client request");
     qemuDomainObjAbortAsyncJob(vm);
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorMigrateCancel(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -13496,6 +13517,7 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -13518,9 +13540,9 @@ qemuDomainMigrateSetMaxDowntime(virDomainPtr dom,
     priv = vm->privateData;
 
     VIR_DEBUG("Setting migration downtime to %llums", downtime);
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorSetMigrationDowntime(priv->mon, downtime);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -13540,6 +13562,7 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     qemuMonitorMigrationParams migparams = { 0 };
     int ret = -1;
 
@@ -13561,7 +13584,7 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom,
     }
 
     priv = vm->privateData;
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (qemuMonitorGetMigrationParams(priv->mon, &migparams) == 0) {
         if (migparams.downtimeLimit_set) {
@@ -13574,7 +13597,7 @@ qemuDomainMigrateGetMaxDowntime(virDomainPtr dom,
         }
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -13594,6 +13617,7 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -13622,11 +13646,11 @@ qemuDomainMigrateGetCompressionCache(virDomainPtr dom,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ret = qemuMonitorGetMigrationCacheSize(priv->mon, cacheSize);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -13645,6 +13669,7 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -13673,12 +13698,12 @@ qemuDomainMigrateSetCompressionCache(virDomainPtr dom,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     VIR_DEBUG("Setting compression cache to %llu B", cacheSize);
     ret = qemuMonitorSetMigrationCacheSize(priv->mon, cacheSize);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -13697,6 +13722,7 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -13727,9 +13753,9 @@ qemuDomainMigrateSetMaxSpeed(virDomainPtr dom,
         }
 
         VIR_DEBUG("Setting migration bandwidth to %luMbs", bandwidth);
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorSetMigrationSpeed(priv->mon, bandwidth);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
 
         if (ret == 0)
@@ -13782,6 +13808,7 @@ qemuDomainMigrateStartPostCopy(virDomainPtr dom,
     virQEMUDriverPtr driver = dom->conn->privateData;
     virDomainObjPtr vm;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     int ret = -1;
 
     virCheckFlags(0, -1);
@@ -13818,9 +13845,9 @@ qemuDomainMigrateStartPostCopy(virDomainPtr dom,
     }
 
     VIR_DEBUG("Starting post-copy");
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorMigrateStartPostCopy(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -14018,6 +14045,7 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn,
     virObjectEventPtr event = NULL;
     bool resume = false;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!qemuMigrationIsAllowed(driver, vm, false, 0))
         goto cleanup;
@@ -14040,13 +14068,13 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn,
     }
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                       QEMU_ASYNC_JOB_SNAPSHOT) < 0) {
+                                       QEMU_ASYNC_JOB_SNAPSHOT, &mon) < 0) {
         resume = false;
         goto cleanup;
     }
 
     ret = qemuMonitorCreateSnapshot(priv->mon, snap->def->name);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     if (ret < 0)
         goto cleanup;
@@ -14696,6 +14724,7 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
     char *source = NULL;
     const char *formatStr = NULL;
     int ret = -1, rc;
+    qemuMonitorPtr mon;
 
     if (!(device = qemuAliasFromDisk(dd->disk)))
         goto cleanup;
@@ -14728,13 +14757,13 @@ qemuDomainSnapshotCreateSingleDiskActive(virQEMUDriverPtr driver,
      * Otherwise the following monitor command only constructs the command.
      */
     if (!actions &&
-        qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
 
     ret = rc = qemuMonitorDiskSnapshot(priv->mon, actions, device, source,
                                        formatStr, reuse);
     if (!actions) {
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
     }
 
@@ -14765,6 +14794,7 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     virQEMUDriverConfigPtr cfg = NULL;
     qemuDomainSnapshotDiskDataPtr diskdata = NULL;
     virErrorPtr orig_err = NULL;
+    qemuMonitorPtr mon;
 
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -14812,12 +14842,12 @@ qemuDomainSnapshotCreateDiskActive(virQEMUDriverPtr driver,
     }
 
     if (actions && do_transaction) {
-        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
             goto cleanup;
 
         ret = qemuMonitorTransaction(priv->mon, actions);
 
-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0) {
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || ret < 0) {
             ret = -1;
             goto error;
         }
@@ -15755,6 +15785,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
     bool was_stopped = false;
     qemuDomainSaveCookiePtr cookie;
     virCPUDefPtr origCPU = NULL;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_DOMAIN_SNAPSHOT_REVERT_RUNNING |
                   VIR_DOMAIN_SNAPSHOT_REVERT_PAUSED |
@@ -15942,10 +15973,10 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
             }
 
             if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                               QEMU_ASYNC_JOB_START) < 0)
+                                               QEMU_ASYNC_JOB_START, &mon) < 0)
                 goto endjob;
             rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name);
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 goto endjob;
             if (rc < 0) {
                 /* XXX resume domain if it was running before the
@@ -16307,6 +16338,7 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     bool hmp;
 
     virCheckFlags(VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP, -1);
@@ -16332,9 +16364,9 @@ static int qemuDomainQemuMonitorCommand(virDomainPtr domain, const char *cmd,
 
     hmp = !!(flags & VIR_DOMAIN_QEMU_MONITOR_COMMAND_HMP);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorArbitraryCommand(priv->mon, cmd, result, hmp);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -16608,6 +16640,7 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
     qemuMonitorBlockJobInfo info;
     virStorageSourcePtr oldsrc = NULL;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuMonitorPtr mon;
 
     if (!disk->mirror) {
         virReportError(VIR_ERR_OPERATION_INVALID,
@@ -16618,9 +16651,9 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
 
     /* Probe the status, if needed.  */
     if (!disk->mirrorState) {
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         rc = qemuMonitorGetBlockJobInfo(priv->mon, disk->info.alias, &info);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
         if (rc < 0)
             goto cleanup;
@@ -16687,9 +16720,9 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
      * that pivot failed, we need to reflect that failure into the
      * overall return value.  */
     disk->mirrorState = VIR_DOMAIN_DISK_MIRROR_STATE_PIVOT;
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDrivePivot(priv->mon, device);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         ret = -1;
         goto cleanup;
     }
@@ -16729,6 +16762,7 @@ qemuDomainBlockPullCommon(virQEMUDriverPtr driver,
     char *backingPath = NULL;
     unsigned long long speed = bandwidth;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (flags & VIR_DOMAIN_BLOCK_REBASE_RELATIVE && !base) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -16797,14 +16831,14 @@ qemuDomainBlockPullCommon(virQEMUDriverPtr driver,
         speed <<= 20;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (baseSource)
         basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
                                              baseSource);
     if (!baseSource || basePath)
         ret = qemuMonitorBlockStream(priv->mon, device, basePath, backingPath,
                                      speed);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret < 0)
@@ -16843,6 +16877,7 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
     bool async = !!(flags & VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC);
     virDomainObjPtr vm;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC |
                   VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT, -1);
@@ -16891,9 +16926,9 @@ qemuDomainBlockJobAbort(virDomainPtr dom,
             save = true;
         }
 
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorBlockJobCancel(qemuDomainGetMonitor(vm), device);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
             ret = -1;
             goto endjob;
         }
@@ -16994,6 +17029,7 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom,
     virDomainDiskDefPtr disk;
     int ret = -1;
     qemuMonitorBlockJobInfo rawInfo;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_DOMAIN_BLOCK_JOB_INFO_BANDWIDTH_BYTES, -1);
 
@@ -17022,10 +17058,10 @@ qemuDomainGetBlockJobInfo(virDomainPtr dom,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorGetBlockJobInfo(qemuDomainGetMonitor(vm),
                                      disk->info.alias, &rawInfo);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     if (ret <= 0)
         goto endjob;
@@ -17071,6 +17107,7 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom,
     virDomainObjPtr vm;
     const char *device;
     unsigned long long speed = bandwidth;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_DOMAIN_BLOCK_JOB_SPEED_BANDWIDTH_BYTES, -1);
 
@@ -17109,11 +17146,11 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom,
     if (!(device = qemuAliasFromDisk(disk)))
         goto endjob;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorBlockJobSetSpeed(qemuDomainGetMonitor(vm),
                                       device,
                                       speed);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -17206,6 +17243,7 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     const char *format = NULL;
     virErrorPtr monitor_error = NULL;
     bool reuse = !!(flags & VIR_DOMAIN_BLOCK_COPY_REUSE_EXT);
+    qemuMonitorPtr mon;
 
     /* Preliminaries: find the disk we are editing, sanity checks */
     virCheckFlags(VIR_DOMAIN_BLOCK_COPY_SHALLOW |
@@ -17325,13 +17363,13 @@ qemuDomainBlockCopyCommon(virDomainObjPtr vm,
     }
 
     /* Actually start the mirroring */
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     /* qemuMonitorDriveMirror needs to honor the REUSE_EXT flag as specified
      * by the user regardless of how @reuse was modified */
     ret = qemuMonitorDriveMirror(priv->mon, device, mirror->path, format,
                                  bandwidth, granularity, buf_size, flags);
     virDomainAuditDisk(vm, NULL, mirror, "mirror", ret >= 0);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     if (ret < 0) {
         monitor_error = virSaveLastError();
@@ -17565,6 +17603,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
     char *backingPath = NULL;
     virStorageSourcePtr mirror = NULL;
     unsigned long long speed = bandwidth;
+    qemuMonitorPtr mon;
 
     /* XXX Add support for COMMIT_DELETE */
     virCheckFlags(VIR_DOMAIN_BLOCK_COMMIT_SHALLOW |
@@ -17728,7 +17767,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
         disk->mirror = mirror;
         disk->mirrorJob = VIR_DOMAIN_BLOCK_JOB_TYPE_ACTIVE_COMMIT;
     }
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     basePath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
                                          baseSource);
     topPath = qemuMonitorDiskNameLookup(priv->mon, device, disk->src,
@@ -17737,7 +17776,7 @@ qemuDomainBlockCommit(virDomainPtr dom,
         ret = qemuMonitorBlockCommit(priv->mon, device,
                                      topPath, basePath, backingPath,
                                      speed);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         ret = -1;
         goto endjob;
     }
@@ -17790,6 +17829,7 @@ qemuDomainOpenGraphics(virDomainPtr dom,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     const char *protocol;
 
     virCheckFlags(VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH, -1);
@@ -17833,10 +17873,10 @@ qemuDomainOpenGraphics(virDomainPtr dom,
     if (qemuSecuritySetImageFDLabel(driver->securityManager, vm->def, fd) < 0)
         goto endjob;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorOpenGraphics(priv->mon, protocol, fd, "graphicsfd",
                                   (flags & VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH) != 0);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -17856,6 +17896,7 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom,
     virDomainObjPtr vm = NULL;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
     const char *protocol;
     int pair[2] = {-1, -1};
 
@@ -17905,10 +17946,10 @@ qemuDomainOpenGraphicsFD(virDomainPtr dom,
 
     if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
         goto cleanup;
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorOpenGraphics(priv->mon, protocol, pair[1], "graphicsfd",
                                   (flags & VIR_DOMAIN_OPEN_GRAPHICS_SKIPAUTH));
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     qemuDomainObjEndJob(driver, vm);
     if (ret < 0)
@@ -18023,6 +18064,7 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
     virTypedParameterPtr eventParams = NULL;
     int eventNparams = 0;
     int eventMaxparams = 0;
+    qemuMonitorPtr mon;
 
     virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
                   VIR_DOMAIN_AFFECT_CONFIG, -1);
@@ -18287,12 +18329,12 @@ qemuDomainSetBlockIoTune(virDomainPtr dom,
          /* NB: Let's let QEMU decide how to handle issues with _length
           * via the JSON error code from the block_set_io_throttle call */
 
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorSetBlockIoThrottle(priv->mon, device,
                                             &info, supportMaxOptions,
                                             set_fields & QEMU_BLOCK_IOTUNE_SET_GROUP_NAME,
                                             supportMaxLengthOptions);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
         if (ret < 0)
             goto endjob;
@@ -18360,6 +18402,7 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
     virDomainDefPtr def = NULL;
     virDomainDefPtr persistentDef = NULL;
     virDomainBlockIoTuneInfo reply = {0};
+    qemuMonitorPtr mon;
     char *device = NULL;
     int ret = -1;
     int maxparams;
@@ -18423,9 +18466,9 @@ qemuDomainGetBlockIoTune(virDomainPtr dom,
 
         if (!(device = qemuAliasFromDisk(disk)))
             goto endjob;
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ret = qemuMonitorGetBlockIoThrottle(priv->mon, device, &reply);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto endjob;
         if (ret < 0)
             goto endjob;
@@ -18514,6 +18557,7 @@ qemuDomainGetDiskErrors(virDomainPtr dom,
     virDomainObjPtr vm = NULL;
     qemuDomainObjPrivatePtr priv;
     virHashTablePtr table = NULL;
+    qemuMonitorPtr mon;
     int ret = -1;
     size_t i;
     int n = 0;
@@ -18542,9 +18586,9 @@ qemuDomainGetDiskErrors(virDomainPtr dom,
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     table = qemuMonitorGetBlockInfo(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto endjob;
     if (!table)
         goto endjob;
@@ -18799,6 +18843,7 @@ qemuDomainPMWakeup(virDomainPtr dom,
     virDomainObjPtr vm;
     int ret = -1;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
 
     virCheckFlags(0, -1);
 
@@ -18826,9 +18871,9 @@ qemuDomainPMWakeup(virDomainPtr dom,
        goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorSystemWakeup(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
  endjob:
@@ -19206,6 +19251,7 @@ qemuDomainSetTime(virDomainPtr dom,
     qemuDomainObjPrivatePtr priv;
     virDomainObjPtr vm;
     qemuAgentPtr agent;
+    qemuMonitorPtr mon;
     bool rtcSync = flags & VIR_DOMAIN_TIME_SYNC;
     int ret = -1;
     int rv;
@@ -19259,9 +19305,9 @@ qemuDomainSetTime(virDomainPtr dom,
 
     /* Don't try to call rtc-reset-reinjection if it's not available */
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_RTC_RESET_REINJECTION)) {
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         rv = qemuMonitorRTCResetReinjection(priv->mon);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto endjob;
 
         if (rv < 0)
@@ -20062,6 +20108,7 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
     virHashTablePtr stats = NULL;
     virHashTablePtr nodestats = NULL;
     virJSONValuePtr nodedata = NULL;
+    qemuMonitorPtr mon;
     qemuDomainObjPrivatePtr priv = dom->privateData;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     bool fetchnodedata = virQEMUCapsGet(priv->qemuCaps,
@@ -20071,7 +20118,7 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
     bool visitBacking = !!(privflags & QEMU_DOMAIN_STATS_BACKING);
 
     if (HAVE_JOB(privflags) && virDomainObjIsActive(dom)) {
-        qemuDomainObjEnterMonitor(driver, dom);
+        mon = qemuDomainObjEnterMonitor(driver, dom);
         rc = qemuMonitorGetAllBlockStatsInfo(priv->mon, &stats,
                                              visitBacking);
         if (rc >= 0)
@@ -20081,7 +20128,7 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
         if (fetchnodedata)
             nodedata = qemuMonitorQueryNamedBlockNodes(priv->mon);
 
-        if (qemuDomainObjExitMonitor(driver, dom) < 0)
+        if (qemuDomainObjExitMonitor(driver, dom, mon) < 0)
             goto cleanup;
 
         /* failure to retrieve stats is fine at this point */
@@ -21096,6 +21143,7 @@ qemuDomainSetBlockThreshold(virDomainPtr dom,
     qemuDomainObjPrivatePtr priv;
     virDomainObjPtr vm = NULL;
     virStorageSourcePtr src;
+    qemuMonitorPtr mon;
     char *nodename = NULL;
     int rc;
     int ret = -1;
@@ -21142,9 +21190,9 @@ qemuDomainSetBlockThreshold(virDomainPtr dom,
     if (VIR_STRDUP(nodename, src->nodestorage) < 0)
         goto endjob;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorSetBlockThreshold(priv->mon, nodename, threshold);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         goto endjob;
 
     ret = 0;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
old mode 100644
new mode 100755
index 53bfe47..6f436e0
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -203,6 +203,7 @@ qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
 {
     unsigned long long now;
     int rc;
+    qemuMonitorPtr mon;
 
     if (virTimeMillisNow(&now) < 0)
         return -1;
@@ -223,9 +224,9 @@ qemuHotplugWaitForTrayEject(virQEMUDriverPtr driver,
     }
 
     /* re-issue ejection command to pop out the media */
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorEjectMedia(qemuDomainGetMonitor(vm), driveAlias, false);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         return -1;
 
     return 0;
@@ -260,6 +261,7 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
     qemuDomainDiskPrivatePtr diskPriv = QEMU_DOMAIN_DISK_PRIVATE(disk);
     qemuDomainStorageSourcePrivatePtr srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
     qemuDomainSecretInfoPtr secinfo = NULL;
+    qemuMonitorPtr mon;
     const char *format = NULL;
     char *sourcestr = NULL;
 
@@ -286,9 +288,9 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
     if (!(driveAlias = qemuAliasFromDisk(disk)))
         goto error;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorEjectMedia(priv->mon, driveAlias, force);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     /* If the tray is present and tray change event is supported wait for it to open. */
@@ -315,12 +317,12 @@ qemuDomainChangeEjectableMedia(virQEMUDriverPtr driver,
                     format = virStorageFileFormatTypeToString(disk->src->format);
             }
         }
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         rc = qemuMonitorChangeMedia(priv->mon,
                                     driveAlias,
                                     sourcestr,
                                     format);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
     }
 
@@ -377,6 +379,7 @@ qemuDomainAttachDiskGeneric(virConnectPtr conn,
     qemuDomainStorageSourcePrivatePtr srcPriv;
     qemuDomainSecretInfoPtr secinfo = NULL;
     qemuDomainSecretInfoPtr encinfo = NULL;
+    qemuMonitorPtr mon;
 
     if (qemuHotplugPrepareDiskAccess(driver, vm, disk, NULL, false) < 0)
         goto cleanup;
@@ -418,7 +421,7 @@ qemuDomainAttachDiskGeneric(virConnectPtr conn,
     if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0)
         goto error;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (secobjProps) {
         rv = qemuMonitorAddObject(priv->mon, "secret", secinfo->s.aes.alias,
@@ -445,7 +448,7 @@ qemuDomainAttachDiskGeneric(virConnectPtr conn,
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         ret = -2;
         goto error;
     }
@@ -475,7 +478,7 @@ qemuDomainAttachDiskGeneric(virConnectPtr conn,
         ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
     if (encobjAdded)
         ignore_value(qemuMonitorDelObject(priv->mon, encinfo->s.aes.alias));
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -2;
     virErrorRestore(&orig_err);
 
@@ -523,6 +526,7 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
     virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_CONTROLLER,
                                { .controller = controller } };
     bool releaseaddr = false;
+    qemuMonitorPtr mon;
 
     if (controller->type != VIR_DOMAIN_CONTROLLER_TYPE_SCSI) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -561,9 +565,9 @@ int qemuDomainAttachControllerDevice(virQEMUDriverPtr driver,
     if (VIR_REALLOC_N(vm->def->controllers, vm->def->ncontrollers+1) < 0)
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorAddDevice(priv->mon, devstr);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         releaseaddr = false;
         ret = -1;
         goto cleanup;
@@ -846,6 +850,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
     bool charDevPlugged = false;
     bool netdevPlugged = false;
     bool hostPlugged = false;
+    qemuMonitorPtr mon;
 
     /* preallocate new slot for device */
     if (VIR_REALLOC_N(vm->def->nets, vm->def->nnets + 1) < 0)
@@ -1081,11 +1086,11 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
         if (qemuMonitorAttachCharDev(priv->mon, charDevAlias, net->data.vhostuser) < 0) {
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto cleanup;
         }
@@ -1096,7 +1101,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
         if (qemuMonitorAddNetdev(priv->mon, netstr,
                                  tapfd, tapfdName, tapfdSize,
                                  vhostfd, vhostfdName, vhostfdSize) < 0) {
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto try_remove;
         }
@@ -1105,14 +1110,14 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
         if (qemuMonitorAddHostNetwork(priv->mon, netstr,
                                       tapfd, tapfdName, tapfdSize,
                                       vhostfd, vhostfdName, vhostfdSize) < 0) {
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             virDomainAuditNet(vm, NULL, net, "attach", false);
             goto try_remove;
         }
         hostPlugged = true;
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     for (i = 0; i < tapfdSize; i++)
@@ -1124,13 +1129,13 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
                                       queueSize, priv->qemuCaps)))
         goto try_remove;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorAddDevice(priv->mon, nicstr) < 0) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         virDomainAuditNet(vm, NULL, net, "attach", false);
         goto try_remove;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     /* set link state */
@@ -1139,11 +1144,11 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
             virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                            _("device alias not found: cannot set link state to down"));
         } else {
-            qemuDomainObjEnterMonitor(driver, vm);
+            mon = qemuDomainObjEnterMonitor(driver, vm);
 
             if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
                 if (qemuMonitorSetLink(priv->mon, net->info.alias, VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DOWN) < 0) {
-                    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+                    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
                     virDomainAuditNet(vm, NULL, net, "attach", false);
                     goto try_remove;
                 }
@@ -1152,7 +1157,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
                                _("setting of link state not supported: Link is up"));
             }
 
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 goto cleanup;
         }
         /* link set to down */
@@ -1220,7 +1225,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
         if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
             char *netdev_name;
             if (virAsprintf(&netdev_name, "host%s", net->info.alias) >= 0) {
-                qemuDomainObjEnterMonitor(driver, vm);
+                mon = qemuDomainObjEnterMonitor(driver, vm);
                 if (charDevPlugged &&
                     qemuMonitorDetachCharDev(priv->mon, charDevAlias) < 0)
                     VIR_WARN("Failed to remove associated chardev %s", charDevAlias);
@@ -1228,7 +1233,7 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
                     qemuMonitorRemoveNetdev(priv->mon, netdev_name) < 0)
                     VIR_WARN("Failed to remove network backend for netdev %s",
                              netdev_name);
-                ignore_value(qemuDomainObjExitMonitor(driver, vm));
+                ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
                 VIR_FREE(netdev_name);
             }
         } else {
@@ -1237,12 +1242,12 @@ qemuDomainAttachNetDevice(virQEMUDriverPtr driver,
     } else {
         char *hostnet_name;
         if (virAsprintf(&hostnet_name, "host%s", net->info.alias) >= 0) {
-            qemuDomainObjEnterMonitor(driver, vm);
+            mon = qemuDomainObjEnterMonitor(driver, vm);
             if (hostPlugged &&
                 qemuMonitorRemoveHostNetwork(priv->mon, vlan, hostnet_name) < 0)
                 VIR_WARN("Failed to remove network backend for vlan %d, net %s",
                          vlan, hostnet_name);
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             VIR_FREE(hostnet_name);
         }
     }
@@ -1271,6 +1276,7 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
     int backend;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     unsigned int flags = 0;
+    qemuMonitorPtr mon;
 
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
         goto cleanup;
@@ -1363,10 +1369,10 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
                                              configfd_name, priv->qemuCaps)))
         goto error;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr,
                                      configfd, configfd_name);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto error;
 
     virDomainAuditHostdev(vm, hostdev, "attach", ret == 0);
@@ -1416,13 +1422,14 @@ qemuDomainDelTLSObjects(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virErrorPtr orig_err;
+    qemuMonitorPtr mon;
 
     if (!tlsAlias && !secAlias)
         return;
 
     virErrorPreserveLast(&orig_err);
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
 
     if (tlsAlias)
@@ -1431,7 +1438,7 @@ qemuDomainDelTLSObjects(virQEMUDriverPtr driver,
     if (secAlias)
         ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
 
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
 
  cleanup:
     virErrorRestore(&orig_err);
@@ -1450,11 +1457,12 @@ qemuDomainAddTLSObjects(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int rc;
     virErrorPtr orig_err;
+    qemuMonitorPtr mon;
 
     if (!tlsAlias && !secAlias)
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     if (secAlias) {
@@ -1473,11 +1481,11 @@ qemuDomainAddTLSObjects(virQEMUDriverPtr driver,
             goto error;
     }
 
-    return qemuDomainObjExitMonitor(driver, vm);
+    return qemuDomainObjExitMonitor(driver, vm, mon);
 
  error:
     virErrorPreserveLast(&orig_err);
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     virErrorRestore(&orig_err);
     qemuDomainDelTLSObjects(driver, vm, asyncJob, secAlias, tlsAlias);
 
@@ -1588,6 +1596,7 @@ qemuDomainDelChardevTLSObjects(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     char *tlsAlias = NULL;
     char *secAlias = NULL;
+    qemuMonitorPtr mon;
 
     if (dev->type != VIR_DOMAIN_CHR_TYPE_TCP ||
         dev->data.tcp.haveTLS != VIR_TRISTATE_BOOL_YES) {
@@ -1606,13 +1615,13 @@ qemuDomainDelChardevTLSObjects(virQEMUDriverPtr driver,
         !(secAlias = qemuDomainGetSecretAESAlias(inAlias, false)))
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ignore_value(qemuMonitorDelObject(priv->mon, tlsAlias));
     if (secAlias)
         ignore_value(qemuMonitorDelObject(priv->mon, secAlias));
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     ret = 0;
@@ -1640,6 +1649,7 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
     char *secAlias = NULL;
     bool need_release = false;
     virErrorPtr orig_err;
+    qemuMonitorPtr mon;
 
     if (qemuAssignDeviceRedirdevAlias(def, redirdev, -1) < 0)
         goto cleanup;
@@ -1662,7 +1672,7 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
                                        &tlsAlias, &secAlias) < 0)
         goto audit;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (qemuMonitorAttachCharDev(priv->mon,
                                  charAlias,
@@ -1673,7 +1683,7 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto audit;
 
     def->redirdevs[def->nredirdevs++] = redirdev;
@@ -1694,7 +1704,7 @@ int qemuDomainAttachRedirdevDevice(virConnectPtr conn,
     /* detach associated chardev on error */
     if (chardevAdded)
         ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     virErrorRestore(&orig_err);
     qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
                             secAlias, tlsAlias);
@@ -1882,6 +1892,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
     char *tlsAlias = NULL;
     char *secAlias = NULL;
     bool need_release = false;
+    qemuMonitorPtr mon;
 
     if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
         qemuDomainPrepareChannel(chr, priv->channelTargetDir) < 0)
@@ -1921,7 +1932,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
                                        &tlsAlias, &secAlias) < 0)
         goto audit;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (qemuMonitorAttachCharDev(priv->mon, charAlias, chr->source) < 0)
         goto exit_monitor;
@@ -1930,7 +1941,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto audit;
 
     qemuDomainChrInsertPreAlloced(vmdef, chr);
@@ -1961,7 +1972,7 @@ int qemuDomainAttachChrDevice(virConnectPtr conn,
     /* detach associated chardev on error */
     if (chardevAttached)
         qemuMonitorDetachCharDev(priv->mon, charAlias);
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     virErrorRestore(&orig_err);
 
     qemuDomainDelTLSObjects(driver, vm, QEMU_ASYNC_JOB_NONE,
@@ -1993,6 +2004,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
     const char *type;
     int ret = -1;
     int rv;
+    qemuMonitorPtr mon;
 
     if (qemuAssignDeviceRNGAlias(vm->def, rng) < 0)
         goto cleanup;
@@ -2033,7 +2045,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
             goto audit;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
         qemuMonitorAttachCharDev(priv->mon, charAlias,
@@ -2050,7 +2062,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         releaseaddr = false;
         goto cleanup;
     }
@@ -2085,7 +2097,7 @@ qemuDomainAttachRNGDevice(virConnectPtr conn,
         ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
     if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD && chardevAdded)
         ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         releaseaddr = false;
     virErrorRestore(&orig_err);
 
@@ -2127,6 +2139,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     int id;
     int ret = -1;
     int rv;
+    qemuMonitorPtr mon;
 
     qemuDomainMemoryDeviceAlignSize(vm->def, mem);
 
@@ -2172,7 +2185,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     if (qemuDomainAdjustMaxMemLock(vm) < 0)
         goto removedef;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rv = qemuMonitorAddObject(priv->mon, backendType, objalias, props);
     props = NULL; /* qemuMonitorAddObject consumes */
     if (rv < 0)
@@ -2182,7 +2195,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         /* we shouldn't touch mem now, as the def might be freed */
         mem = NULL;
         goto audit;
@@ -2227,7 +2240,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
     virErrorPreserveLast(&orig_err);
     if (objAdded)
         ignore_value(qemuMonitorDelObject(priv->mon, objalias));
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         mem = NULL;
     virErrorRestore(&orig_err);
     if (!mem)
@@ -2261,6 +2274,7 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
     bool teardownlabel = false;
     bool teardowndevice = false;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (priv->usbaddrs) {
         if (virDomainUSBAddressEnsure(priv->usbaddrs, hostdev->info) < 0)
@@ -2293,9 +2307,9 @@ qemuDomainAttachHostUSBDevice(virQEMUDriverPtr driver,
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs+1) < 0)
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorAddDevice(priv->mon, devstr);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         ret = -1;
         goto cleanup;
     }
@@ -2348,6 +2362,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
     virJSONValuePtr secobjProps = NULL;
     virDomainHostdevSubsysSCSIPtr scsisrc = &hostdev->source.subsys.u.scsi;
     qemuDomainSecretInfoPtr secinfo = NULL;
+    qemuMonitorPtr mon;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -2411,7 +2426,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (secobjProps) {
         rv = qemuMonitorAddObject(priv->mon, "secret", secinfo->s.aes.alias,
@@ -2429,7 +2444,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     virDomainAuditHostdev(vm, hostdev, "attach", true);
@@ -2466,7 +2481,7 @@ qemuDomainAttachHostSCSIDevice(virConnectPtr conn,
     }
     if (secobjAdded)
         ignore_value(qemuMonitorDelObject(priv->mon, secinfo->s.aes.alias));
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     virErrorRestore(&orig_err);
 
     virDomainAuditHostdev(vm, hostdev, "attach", false);
@@ -2491,6 +2506,7 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver,
     bool teardownlabel = false;
     bool teardowndevice = false;
     bool releaseaddr = false;
+    qemuMonitorPtr mon;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_SCSI_GENERIC)) {
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
@@ -2550,11 +2566,11 @@ qemuDomainAttachSCSIVHostDevice(virQEMUDriverPtr driver,
     if (VIR_REALLOC_N(vm->def->hostdevs, vm->def->nhostdevs + 1) < 0)
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ret = qemuMonitorAddDeviceWithFd(priv->mon, devstr, vhostfd, vhostfdName);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || ret < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || ret < 0)
         goto audit;
 
     vm->def->hostdevs[vm->def->nhostdevs++] = hostdev;
@@ -2652,6 +2668,7 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver,
     virJSONValuePtr props = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainDeviceDef dev = { VIR_DOMAIN_DEVICE_SHMEM, { .shmem = shmem } };
+    qemuMonitorPtr mon;
 
     switch ((virDomainShmemModel)shmem->model) {
     case VIR_DOMAIN_SHMEM_MODEL_IVSHMEM_PLAIN:
@@ -2695,7 +2712,7 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (shmem->server.enabled) {
         if (qemuMonitorAttachCharDev(priv->mon, charAlias,
@@ -2715,7 +2732,7 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver,
     if (qemuMonitorAddDevice(priv->mon, shmstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         release_address = false;
         goto cleanup;
     }
@@ -2750,7 +2767,7 @@ qemuDomainAttachShmemDevice(virQEMUDriverPtr driver,
             ignore_value(qemuMonitorDelObject(priv->mon, memAlias));
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         release_address = false;
 
     virErrorRestore(&orig_err);
@@ -2772,6 +2789,7 @@ qemuDomainAttachWatchdog(virQEMUDriverPtr driver,
     char *watchdogstr = NULL;
     bool releaseAddress = false;
     int rv;
+    qemuMonitorPtr mon;
 
     if (vm->def->watchdog) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -2804,14 +2822,14 @@ qemuDomainAttachWatchdog(virQEMUDriverPtr driver,
 
     actionStr = virDomainWatchdogActionTypeToString(actualAction);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     rv = qemuMonitorSetWatchdogAction(priv->mon, actionStr);
 
     if (rv >= 0)
         rv = qemuMonitorAddDevice(priv->mon, watchdogstr);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         releaseAddress = false;
         goto cleanup;
     }
@@ -2846,6 +2864,7 @@ qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
     bool teardowndevice = false;
     bool teardownlabel = false;
     bool teardowncgroup = false;
+    qemuMonitorPtr mon;
 
     if (input->bus != VIR_DOMAIN_INPUT_BUS_USB &&
         input->bus != VIR_DOMAIN_INPUT_BUS_VIRTIO) {
@@ -2887,11 +2906,11 @@ qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
     if (VIR_REALLOC_N(vm->def->inputs, vm->def->ninputs + 1) < 0)
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorAddDevice(priv->mon, devstr) < 0)
         goto exit_monitor;
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         releaseaddr = false;
         goto cleanup;
     }
@@ -2921,7 +2940,7 @@ qemuDomainAttachInputDevice(virQEMUDriverPtr driver,
     return ret;
 
  exit_monitor:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0) {
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0) {
         releaseaddr = false;
         goto cleanup;
     }
@@ -3026,6 +3045,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if (!dev->info.alias) {
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
@@ -3035,7 +3055,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
 
     VIR_DEBUG("dev: %s, state: %d", dev->info.alias, linkstate);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ret = qemuMonitorSetLink(priv->mon, dev->info.alias, linkstate);
     if (ret < 0)
@@ -3045,7 +3065,7 @@ int qemuDomainChangeNetLinkState(virQEMUDriverPtr driver,
     dev->linkstate = linkstate;
 
  cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     return ret;
@@ -3733,6 +3753,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
     char *drivestr;
     char *objAlias = NULL;
     char *encAlias = NULL;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing disk %s from domain %p %s",
               disk->info.alias, vm, vm->def->name);
@@ -3770,7 +3791,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
         }
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     qemuMonitorDriveDel(priv->mon, drivestr);
     VIR_FREE(drivestr);
@@ -3788,7 +3809,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
     if (disk->src->haveTLS)
         ignore_value(qemuMonitorDelObject(priv->mon, disk->src->tlsAlias));
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     virDomainAuditDisk(vm, disk->src, NULL, "detach", true);
@@ -3867,6 +3888,7 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
     char *backendAlias = NULL;
     int rc;
     int idx;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing memory device %s from domain %p %s",
               mem->info.alias, vm, vm->def->name);
@@ -3874,9 +3896,9 @@ qemuDomainRemoveMemoryDevice(virQEMUDriverPtr driver,
     if (virAsprintf(&backendAlias, "mem%s", mem->info.alias) < 0)
         return -1;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorDelObject(priv->mon, backendAlias);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         rc = -1;
 
     VIR_FREE(backendAlias);
@@ -3963,6 +3985,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
     char *drivealias = NULL;
     char *objAlias = NULL;
     bool is_vfio = false;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing host device %s from domain %p %s",
               hostdev->info->alias, vm, vm->def->name);
@@ -3989,14 +4012,14 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
                 goto cleanup;
         }
 
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         qemuMonitorDriveDel(priv->mon, drivealias);
 
         /* If it fails, then so be it - it was a best shot */
         if (objAlias)
             ignore_value(qemuMonitorDelObject(priv->mon, objAlias));
 
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
     }
 
@@ -4086,6 +4109,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
     size_t i;
     int ret = -1;
     int actualType = virDomainNetGetActualType(net);
+    qemuMonitorPtr mon;
 
     if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
         /* this function handles all hostdev and netdev cleanup */
@@ -4102,10 +4126,10 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
         goto cleanup;
 
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV)) {
         if (qemuMonitorRemoveNetdev(priv->mon, hostnet_name) < 0) {
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 goto cleanup;
             virDomainAuditNet(vm, net, NULL, "detach", false);
             goto cleanup;
@@ -4118,7 +4142,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
                 virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                                _("unable to determine original VLAN"));
             }
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 goto cleanup;
             virDomainAuditNet(vm, net, NULL, "detach", false);
             goto cleanup;
@@ -4135,7 +4159,7 @@ qemuDomainRemoveNetDevice(virQEMUDriverPtr driver,
         }
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     virDomainAuditNet(vm, net, NULL, "detach", true);
@@ -4192,6 +4216,7 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
     int rc;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing character device %s from domain %p %s",
               chr->info.alias, vm, vm->def->name);
@@ -4199,10 +4224,10 @@ qemuDomainRemoveChrDevice(virQEMUDriverPtr driver,
     if (!(charAlias = qemuAliasChardevFromDevAlias(chr->info.alias)))
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (rc == 0 &&
@@ -4248,6 +4273,7 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
     ssize_t idx;
     int ret = -1;
     int rc;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing RNG device %s from domain %p %s",
               rng->info.alias, vm, vm->def->name);
@@ -4259,11 +4285,11 @@ qemuDomainRemoveRNGDevice(virQEMUDriverPtr driver,
     if (!(charAlias = qemuAliasChardevFromDevAlias(rng->info.alias)))
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     rc = qemuMonitorDelObject(priv->mon, objAlias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (rng->backend == VIR_DOMAIN_RNG_BACKEND_EGD &&
@@ -4311,6 +4337,7 @@ qemuDomainRemoveShmemDevice(virQEMUDriverPtr driver,
     char *memAlias = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virObjectEventPtr event = NULL;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing shmem device %s from domain %p %s",
               shmem->info.alias, vm, vm->def->name);
@@ -4323,14 +4350,14 @@ qemuDomainRemoveShmemDevice(virQEMUDriverPtr driver,
             return -1;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (shmem->server.enabled)
         rc = qemuMonitorDetachCharDev(priv->mon, charAlias);
     else
         rc = qemuMonitorDelObject(priv->mon, memAlias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     virDomainAuditShmem(vm, shmem, "detach", rc == 0);
@@ -4418,6 +4445,7 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriverPtr driver,
     char *charAlias = NULL;
     ssize_t idx;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Removing redirdev device %s from domain %p %s",
               dev->info.alias, vm, vm->def->name);
@@ -4425,13 +4453,13 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriverPtr driver,
     if (!(charAlias = qemuAliasChardevFromDevAlias(dev->info.alias)))
         goto cleanup;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     /* DeviceDel from Detach may remove chardev,
      * so we cannot rely on return status to delete TLS chardevs.
      */
     ignore_value(qemuMonitorDetachCharDev(priv->mon, charAlias));
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (qemuDomainDelChardevTLSObjects(driver, vm, dev->source, charAlias) < 0)
@@ -4629,6 +4657,7 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if (qemuIsMultiFunctionDevice(vm->def, &detach->info)) {
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -4644,14 +4673,14 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
         virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -4669,20 +4698,21 @@ qemuDomainDetachDiskDevice(virQEMUDriverPtr driver,
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if (qemuDomainDiskBlockJobIsActive(detach))
         goto cleanup;
 
     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
         virDomainAuditDisk(vm, detach->src, NULL, "detach", false);
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -4812,6 +4842,7 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
     int idx, ret = -1;
     virDomainControllerDefPtr detach = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if ((idx = virDomainControllerFind(vm->def,
                                        dev->data.controller->type,
@@ -4861,12 +4892,12 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias)) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -4885,6 +4916,7 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainHostdevSubsysPCIPtr pcisrc = &detach->source.subsys.u.pci;
     int ret;
+    qemuMonitorPtr mon;
 
     if (qemuIsMultiFunctionDevice(vm->def, detach->info)) {
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -4896,9 +4928,9 @@ qemuDomainDetachHostPCIDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -4911,6 +4943,7 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret;
+    qemuMonitorPtr mon;
 
     if (!detach->info->alias) {
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -4920,9 +4953,9 @@ qemuDomainDetachHostUSBDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -4935,6 +4968,7 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!detach->info->alias) {
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -4944,10 +4978,10 @@ qemuDomainDetachHostSCSIDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     return ret;
@@ -4960,6 +4994,7 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!detach->info->alias) {
         virReportError(VIR_ERR_OPERATION_FAILED,
@@ -4969,10 +5004,10 @@ qemuDomainDetachSCSIVHostDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorDelDevice(priv->mon, detach->info->alias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     return ret;
@@ -5107,6 +5142,7 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
     ssize_t idx = -1;
     virDomainShmemDefPtr shmem = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if ((idx = virDomainShmemDefFind(vm->def, dev)) < 0) {
         virReportError(VIR_ERR_DEVICE_MISSING,
@@ -5133,11 +5169,11 @@ qemuDomainDetachShmemDevice(virQEMUDriverPtr driver,
     }
 
     qemuDomainMarkDeviceForRemoval(vm, &shmem->info);
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ret = qemuMonitorDelDevice(priv->mon, shmem->info.alias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret == 0) {
@@ -5160,6 +5196,7 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
     int ret = -1;
     virDomainWatchdogDefPtr watchdog = vm->def->watchdog;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     /* While domains can have up to one watchdog, the one supplied by the user
      * doesn't necessarily match the one domain has. Refuse to detach in such
@@ -5183,11 +5220,11 @@ qemuDomainDetachWatchdog(virQEMUDriverPtr driver,
     }
 
     qemuDomainMarkDeviceForRemoval(vm, &watchdog->info);
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ret = qemuMonitorDelDevice(priv->mon, watchdog->info.alias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret == 0) {
@@ -5211,6 +5248,7 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainRedirdevDefPtr tmpRedirdevDef;
     ssize_t idx;
+    qemuMonitorPtr mon;
 
     if ((idx = virDomainRedirdevDefFind(vm->def, dev)) < 0) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
@@ -5228,12 +5266,12 @@ qemuDomainDetachRedirdevDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &tmpRedirdevDef->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, tmpRedirdevDef->info.alias) < 0) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -5253,6 +5291,7 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
     int detachidx, ret = -1;
     virDomainNetDefPtr detach = NULL;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if ((detachidx = virDomainNetFindIdx(vm->def, dev->data.net)) < 0)
         goto cleanup;
@@ -5291,14 +5330,14 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
         virDomainAuditNet(vm, detach, NULL, "detach", false);
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -5325,6 +5364,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
     const char *password;
     int ret = -1;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuMonitorPtr mon;
 
     if (!auth->passwd && !defaultPasswd) {
         ret = 0;
@@ -5335,7 +5375,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
     if (auth->connected)
         connected = virDomainGraphicsAuthConnectedTypeToString(auth->connected);
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
     ret = qemuMonitorSetPassword(priv->mon, type, password, connected);
 
@@ -5376,7 +5416,7 @@ qemuDomainChangeGraphicsPasswords(virQEMUDriverPtr driver,
     }
 
  end_job:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
  cleanup:
     VIR_FREE(validTo);
@@ -5439,6 +5479,7 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
     virDomainDefPtr vmdef = vm->def;
     virDomainChrDefPtr tmpChr;
     char *devstr = NULL;
+    qemuMonitorPtr mon;
 
     if (!(tmpChr = virDomainChrFind(vmdef, chr))) {
         virReportError(VIR_ERR_DEVICE_MISSING,
@@ -5458,12 +5499,12 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &tmpChr->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (devstr && qemuMonitorDelDevice(priv->mon, tmpChr->info.alias) < 0) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1) {
@@ -5488,6 +5529,7 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
     virDomainRNGDefPtr tmpRNG;
     int rc;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if ((idx = virDomainRNGFind(vm->def, rng)) < 0) {
         virReportError(VIR_ERR_DEVICE_MISSING,
@@ -5507,9 +5549,9 @@ qemuDomainDetachRNGDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &tmpRNG->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorDelDevice(priv->mon, tmpRNG->info.alias);
-    if (qemuDomainObjExitMonitor(driver, vm) || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) || rc < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -5531,6 +5573,7 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
     int idx;
     int rc;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     qemuDomainMemoryDeviceAlignSize(vm->def, memdef);
 
@@ -5552,9 +5595,9 @@ qemuDomainDetachMemoryDevice(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceForRemoval(vm, &mem->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorDelDevice(priv->mon, mem->info.alias);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
@@ -5645,6 +5688,7 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
     unsigned int nvcpus = vcpupriv->vcpus;
     int rc;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!vcpupriv->alias) {
         virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
@@ -5654,11 +5698,11 @@ qemuDomainHotplugDelVcpu(virQEMUDriverPtr driver,
 
     qemuDomainMarkDeviceAliasForRemoval(vm, vcpupriv->alias);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     rc = qemuMonitorDelDevice(qemuDomainGetMonitor(vm), vcpupriv->alias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if (rc < 0) {
@@ -5705,6 +5749,7 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
     int rc;
     int oldvcpus = virDomainDefGetVcpus(vm->def);
     size_t i;
+    qemuMonitorPtr mon;
 
     if (newhotplug) {
         if (virAsprintf(&vcpupriv->alias, "vcpu%u", vcpu) < 0)
@@ -5714,7 +5759,7 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
             goto cleanup;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     if (newhotplug) {
         rc = qemuMonitorAddDeviceArgs(qemuDomainGetMonitor(vm), vcpuprops);
@@ -5723,7 +5768,7 @@ qemuDomainHotplugAddVcpu(virQEMUDriverPtr driver,
         rc = qemuMonitorSetCPU(qemuDomainGetMonitor(vm), vcpu, true);
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     virDomainAuditVcpu(vm, oldvcpus, oldvcpus + nvcpus, "update", rc == 0);
@@ -6236,6 +6281,7 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
     virDomainInputDefPtr input;
     int ret = -1;
     int idx;
+    qemuMonitorPtr mon;
 
     if ((idx = virDomainInputDefFind(vm->def, def)) < 0) {
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
@@ -6261,12 +6307,12 @@ qemuDomainDetachInputDevice(virDomainObjPtr vm,
 
     qemuDomainMarkDeviceForRemoval(vm, &input->info);
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorDelDevice(priv->mon, input->info.alias)) {
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
         goto cleanup;
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
 
     if ((ret = qemuDomainWaitForDeviceRemoval(vm)) == 1)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
old mode 100644
new mode 100755
index 5ee9e5c..9acff21
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -106,8 +106,9 @@ qemuMigrationCheckTLSCreds(virQEMUDriverPtr driver,
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuMonitorMigrationParams migParams = { 0 };
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     if (qemuMonitorGetMigrationParams(priv->mon, &migParams) < 0)
@@ -119,7 +120,7 @@ qemuMigrationCheckTLSCreds(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     qemuMigrationParamsClear(&migParams);
@@ -501,6 +502,7 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
     unsigned short port = 0;
     char *diskAlias = NULL;
     size_t i;
+    qemuMonitorPtr mon;
 
     if (nbdPort < 0 || nbdPort > USHRT_MAX) {
         virReportError(VIR_ERR_INVALID_ARG, "%s",
@@ -527,7 +529,7 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
             goto cleanup;
 
         if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                           QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
+                                           QEMU_ASYNC_JOB_MIGRATION_IN, &mon) < 0)
             goto cleanup;
 
         if (port == 0) {
@@ -542,7 +544,7 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
 
         if (qemuMonitorNBDServerAdd(priv->mon, diskAlias, true) < 0)
             goto exit_monitor;
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
     }
 
@@ -556,7 +558,7 @@ qemuMigrationStartNBDServer(virQEMUDriverPtr driver,
     return ret;
 
  exit_monitor:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     goto cleanup;
 }
 
@@ -567,17 +569,18 @@ qemuMigrationStopNBDServer(virQEMUDriverPtr driver,
                            qemuMigrationCookiePtr mig)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if (!mig->nbd)
         return 0;
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                       QEMU_ASYNC_JOB_MIGRATION_IN) < 0)
+                                       QEMU_ASYNC_JOB_MIGRATION_IN, &mon) < 0)
         return -1;
 
     if (qemuMonitorNBDServerStop(priv->mon) < 0)
         VIR_WARN("Unable to stop NBD server");
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     virPortAllocatorRelease(driver->migrationPorts, priv->nbdPort);
@@ -756,6 +759,7 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
     int ret = -1;
     int status;
     int rv;
+    qemuMonitorPtr mon;
 
     status = qemuBlockJobUpdate(driver, vm, asyncJob, disk, &error);
     switch (status) {
@@ -781,12 +785,12 @@ qemuMigrationCancelOneDriveMirror(virQEMUDriverPtr driver,
     if (!(diskAlias = qemuAliasFromDisk(disk)))
         return -1;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
 
     rv = qemuMonitorBlockJobCancel(priv->mon, diskAlias);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rv < 0)
         goto cleanup;
 
     ret = 0;
@@ -920,6 +924,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
     unsigned int mirror_flags = VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
     int rv;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Starting drive mirrors for domain %s", vm->def->name);
 
@@ -961,7 +966,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
             goto cleanup;
 
         if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                           QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+                                           QEMU_ASYNC_JOB_MIGRATION_OUT, &mon) < 0)
             goto cleanup;
 
         qemuBlockJobSyncBegin(disk);
@@ -971,7 +976,7 @@ qemuMigrationDriveMirror(virQEMUDriverPtr driver,
         VIR_FREE(diskAlias);
         VIR_FREE(nbd_dest);
 
-        if (qemuDomainObjExitMonitor(driver, vm) < 0 || mon_ret < 0) {
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || mon_ret < 0) {
             qemuBlockJobSyncEnd(driver, vm, QEMU_ASYNC_JOB_MIGRATION_OUT, disk);
             goto cleanup;
         }
@@ -1296,6 +1301,7 @@ qemuMigrationSetOption(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret;
+    qemuMonitorPtr mon;
 
     if (!qemuMigrationCapsGet(vm, capability)) {
         if (!state) {
@@ -1317,12 +1323,12 @@ qemuMigrationSetOption(virQEMUDriverPtr driver,
         return -1;
     }
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, job, &mon) < 0)
         return -1;
 
     ret = qemuMonitorSetMigrationCapability(priv->mon, capability, state);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -1416,13 +1422,14 @@ qemuMigrationFetchStats(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     qemuMonitorMigrationStats stats;
     int rv;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     rv = qemuMonitorGetMigrationStats(priv->mon, &stats, error);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rv < 0)
         return -1;
 
     jobInfo->stats.mig = stats;
@@ -1702,6 +1709,7 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
     int port = -1;
     int tlsPort = -1;
     const char *tlsSubject = NULL;
+    qemuMonitorPtr mon;
 
     if (!cookie || (!cookie->graphics && !graphicsuri))
         return 0;
@@ -1772,11 +1780,11 @@ qemuDomainMigrateGraphicsRelocate(virQEMUDriverPtr driver,
     }
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                       QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
+                                       QEMU_ASYNC_JOB_MIGRATION_OUT, &mon) == 0) {
         ret = qemuMonitorGraphicsRelocate(priv->mon, type, listenAddress,
                                           port, tlsPort, tlsSubject);
         priv->job.spiceMigration = !ret;
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
     }
 
@@ -1872,15 +1880,16 @@ qemuMigrationRunIncoming(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
     int rv;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Setting up incoming migration with URI %s", uri);
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     rv = qemuMonitorMigrateIncoming(priv->mon, uri);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rv < 0)
         goto cleanup;
 
     if (asyncJob == QEMU_ASYNC_JOB_MIGRATION_IN) {
@@ -2326,6 +2335,7 @@ qemuMigrationSetCompression(virQEMUDriverPtr driver,
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     if (qemuMigrationSetOption(driver, vm,
                                QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
@@ -2341,7 +2351,7 @@ qemuMigrationSetCompression(virQEMUDriverPtr driver,
                                job) < 0)
         return -1;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, job, &mon) < 0)
         return -1;
 
     migParams->compressLevel_set = compression->level_set;
@@ -2361,7 +2371,7 @@ qemuMigrationSetCompression(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -2478,8 +2488,9 @@ qemuMigrationSetParams(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, job) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, job, &mon) < 0)
         return -1;
 
     if (qemuMonitorSetMigrationParams(priv->mon, migParams) < 0)
@@ -2488,7 +2499,7 @@ qemuMigrationSetParams(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -3644,13 +3655,14 @@ qemuMigrationContinue(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     ret = qemuMonitorMigrateContinue(priv->mon, status);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -3694,6 +3706,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
     virDomainDefPtr persistDef = NULL;
     char *timestamp;
     int rc;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
               "cookieout=%p, cookieoutlen=%p, flags=0x%lx, resource=%lu, "
@@ -3836,7 +3849,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
         goto error;
 
     if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                       QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+                                       QEMU_ASYNC_JOB_MIGRATION_OUT, &mon) < 0)
         goto error;
 
     if (priv->job.abortJob) {
@@ -3893,7 +3906,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
         break;
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         goto error;
 
     /* From this point onwards we *must* call cancel to abort the
@@ -4026,9 +4039,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
         priv->job.current->status != QEMU_DOMAIN_JOB_STATUS_QEMU_COMPLETED &&
         virDomainObjIsActive(vm) &&
         qemuDomainObjEnterMonitorAsync(driver, vm,
-                                       QEMU_ASYNC_JOB_MIGRATION_OUT) == 0) {
+                                       QEMU_ASYNC_JOB_MIGRATION_OUT, &mon) == 0) {
         qemuMonitorMigrateCancel(priv->mon);
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     }
 
     /* cancel any outstanding NBD jobs */
@@ -4046,7 +4059,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
     goto cleanup;
 
  exit_monitor:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     goto error;
 }
 
@@ -5550,14 +5563,15 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
     unsigned long saveMigBandwidth = priv->migMaxBandwidth;
     char *errbuf = NULL;
     virErrorPtr orig_err = NULL;
+    qemuMonitorPtr mon;
 
     /* Increase migration bandwidth to unlimited since target is a file.
      * Failure to change migration speed is not fatal. */
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) == 0) {
         qemuMonitorSetMigrationSpeed(priv->mon,
                                      QEMU_DOMAIN_MIG_BANDWIDTH_MAX);
         priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             return -1;
     }
 
@@ -5582,7 +5596,7 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
                                     compressor ? pipeFD[1] : fd) < 0)
         goto cleanup;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
 
     if (!compressor) {
@@ -5605,11 +5619,11 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
         if (virSetCloseExec(pipeFD[1]) < 0) {
             virReportSystemError(errno, "%s",
                                  _("Unable to set cloexec flag"));
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             goto cleanup;
         }
         if (virCommandRunAsync(cmd, NULL) < 0) {
-            ignore_value(qemuDomainObjExitMonitor(driver, vm));
+            ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             goto cleanup;
         }
         rc = qemuMonitorMigrateToFd(priv->mon,
@@ -5619,7 +5633,7 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
             VIR_CLOSE(pipeFD[1]) < 0)
             VIR_WARN("failed to close intermediate pipe");
     }
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
     if (rc < 0)
         goto cleanup;
@@ -5631,9 +5645,9 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
             orig_err = virSaveLastError();
             virCommandAbort(cmd);
             if (virDomainObjIsActive(vm) &&
-                qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+                qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) == 0) {
                 qemuMonitorMigrateCancel(priv->mon);
-                ignore_value(qemuDomainObjExitMonitor(driver, vm));
+                ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
             }
         }
         goto cleanup;
@@ -5651,10 +5665,10 @@ qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
 
     /* Restore max migration bandwidth */
     if (virDomainObjIsActive(vm) &&
-        qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+        qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) == 0) {
         qemuMonitorSetMigrationSpeed(priv->mon, saveMigBandwidth);
         priv->migMaxBandwidth = saveMigBandwidth;
-        ignore_value(qemuDomainObjExitMonitor(driver, vm));
+        ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     }
 
     VIR_FORCE_CLOSE(pipeFD[0]);
@@ -5683,6 +5697,7 @@ qemuMigrationCancel(virQEMUDriverPtr driver,
     bool storage = false;
     size_t i;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Canceling unfinished outgoing migration of domain %s",
               vm->def->name);
@@ -5695,13 +5710,13 @@ qemuMigrationCancel(virQEMUDriverPtr driver,
         }
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
 
     ignore_value(qemuMonitorMigrateCancel(priv->mon));
     if (storage)
         blockJobs = qemuMonitorGetAllBlockJobInfo(priv->mon);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || (storage && !blockJobs))
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || (storage && !blockJobs))
         goto endsyncjob;
 
     if (!storage) {
@@ -6071,6 +6086,7 @@ qemuMigrationFetchMirrorStats(virQEMUDriverPtr driver,
     bool nbd = false;
     virHashTablePtr blockinfo = NULL;
     qemuDomainMirrorStatsPtr stats = &jobInfo->mirrorStats;
+    qemuMonitorPtr mon;
 
     for (i = 0; i < vm->def->ndisks; i++) {
         virDomainDiskDefPtr disk = vm->def->disks[i];
@@ -6083,12 +6099,12 @@ qemuMigrationFetchMirrorStats(virQEMUDriverPtr driver,
     if (!nbd)
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     blockinfo = qemuMonitorGetAllBlockJobInfo(priv->mon);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || !blockinfo)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || !blockinfo)
         return -1;
 
     memset(stats, 0, sizeof(*stats));
diff --git a/src/qemu/qemu_migration_cookie.c b/src/qemu/qemu_migration_cookie.c
old mode 100644
new mode 100755
index 945530c..27003c6
--- a/src/qemu/qemu_migration_cookie.c
+++ b/src/qemu/qemu_migration_cookie.c
@@ -452,6 +452,7 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
     virHashTablePtr stats = NULL;
     size_t i;
     int ret = -1, rc;
+    qemuMonitorPtr mon;
 
     /* It is not a bug if there already is a NBD data */
     qemuMigrationCookieNBDFree(mig->nbd);
@@ -473,10 +474,10 @@ qemuMigrationCookieAddNBD(qemuMigrationCookiePtr mig,
                 goto cleanup;
 
             if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                               priv->job.asyncJob) < 0)
+                                               priv->job.asyncJob, &mon) < 0)
                 goto cleanup;
             rc = qemuMonitorBlockStatsUpdateCapacity(priv->mon, stats, false);
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 goto cleanup;
             if (rc < 0)
                 goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
old mode 100644
new mode 100755
index c1da3bb..6961348
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -543,6 +543,7 @@ qemuProcessFakeReboot(void *opaque)
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virDomainRunningReason reason = VIR_DOMAIN_RUNNING_BOOTED;
     int ret = -1, rc;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("vm=%p", vm);
     virObjectLock(vm);
@@ -555,10 +556,10 @@ qemuProcessFakeReboot(void *opaque)
         goto endjob;
     }
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     rc = qemuMonitorSystemReset(priv->mon);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto endjob;
 
     if (rc < 0)
@@ -1767,13 +1768,14 @@ qemuProcessInitMonitor(virQEMUDriverPtr driver,
                        qemuDomainAsyncJob asyncJob)
 {
     int ret;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     ret = qemuMonitorSetCapabilities(QEMU_DOMAIN_PRIVATE(vm)->mon);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     return ret;
@@ -2094,12 +2096,13 @@ qemuRefreshVirtioChannelState(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virHashTablePtr info = NULL;
     int ret = -1;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
 
     ret = qemuMonitorGetChardevInfo(priv->mon, &info);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret < 0)
@@ -2121,15 +2124,16 @@ qemuRefreshRTC(virQEMUDriverPtr driver,
     struct tm thenbits;
     long localOffset;
     int rv;
+    qemuMonitorPtr mon;
 
     if (vm->def->clock.offset != VIR_DOMAIN_CLOCK_OFFSET_VARIABLE)
         return;
 
     memset(&thenbits, 0, sizeof(thenbits));
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     now = time(NULL);
     rv = qemuMonitorGetRTCTime(priv->mon, &thenbits);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         rv = -1;
 
     if (rv < 0)
@@ -2156,6 +2160,7 @@ qemuProcessRefreshBalloonState(virQEMUDriverPtr driver,
 {
     unsigned long long balloon;
     int rc;
+    qemuMonitorPtr mon;
 
     /* if no ballooning is available, the current size equals to the current
      * full memory size */
@@ -2164,11 +2169,11 @@ qemuProcessRefreshBalloonState(virQEMUDriverPtr driver,
         return 0;
     }
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     rc = qemuMonitorGetBalloonInfo(qemuDomainGetMonitor(vm), &balloon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0 || rc < 0)
         return -1;
 
     vm->def->mem.cur_balloon = balloon;
@@ -2186,6 +2191,7 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
     int ret = -1;
     virHashTablePtr info = NULL;
     qemuDomainObjPrivatePtr priv;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
     if (qemuConnectMonitor(driver, vm, asyncJob, logCtxt) < 0)
@@ -2196,11 +2202,11 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
      * Note that the monitor itself can be on a pty, so we still need to try the
      * log output method. */
     priv = vm->privateData;
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
     ret = qemuMonitorGetChardevInfo(priv->mon, &info);
     VIR_DEBUG("qemuMonitorGetChardevInfo returned %i", ret);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret == 0) {
@@ -2235,6 +2241,7 @@ qemuProcessDetectIOThreadPIDs(virQEMUDriverPtr driver,
     int niothreads = 0;
     int ret = -1;
     size_t i;
+    qemuMonitorPtr mon;
 
     if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_OBJECT_IOTHREAD)) {
         ret = 0;
@@ -2242,10 +2249,10 @@ qemuProcessDetectIOThreadPIDs(virQEMUDriverPtr driver,
     }
 
     /* Get the list of IOThreads from qemu */
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
     niothreads = qemuMonitorGetIOThreads(priv->mon, &iothreads);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto cleanup;
     if (niothreads < 0)
         goto cleanup;
@@ -2374,8 +2381,9 @@ qemuProcessSetLinkStates(virQEMUDriverPtr driver,
     size_t i;
     int ret = -1;
     int rv;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     for (i = 0; i < def->nnets; i++) {
@@ -2409,7 +2417,7 @@ qemuProcessSetLinkStates(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     return ret;
 }
@@ -2578,6 +2586,7 @@ qemuProcessInitPasswords(virConnectPtr conn,
     size_t i;
     char *alias = NULL;
     char *secret = NULL;
+    qemuMonitorPtr mon;
 
     for (i = 0; i < vm->def->ngraphics; ++i) {
         virDomainGraphicsDefPtr graphics = vm->def->graphics[i];
@@ -2621,10 +2630,10 @@ qemuProcessInitPasswords(virConnectPtr conn,
         VIR_FREE(alias);
         if (!(alias = qemuAliasFromDisk(vm->def->disks[i])))
             goto cleanup;
-        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
             goto cleanup;
         ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             ret = -1;
         if (ret < 0)
             goto cleanup;
@@ -2695,8 +2704,9 @@ qemuProcessUpdateVideoRamSize(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainVideoDefPtr video = NULL;
     virQEMUDriverConfigPtr cfg = NULL;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     for (i = 0; i < vm->def->nvideos; i++) {
@@ -2748,7 +2758,7 @@ qemuProcessUpdateVideoRamSize(virQEMUDriverPtr driver,
 
     }
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     cfg = virQEMUDriverGetConfig(driver);
@@ -2758,7 +2768,7 @@ qemuProcessUpdateVideoRamSize(virQEMUDriverPtr driver,
     return ret;
 
  error:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
     return -1;
 }
 
@@ -2862,6 +2872,7 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    qemuMonitorPtr mon;
 
     /* Bring up netdevs before starting CPUs */
     if (qemuInterfaceStartDevices(vm->def) < 0)
@@ -2878,11 +2889,11 @@ qemuProcessStartCPUs(virQEMUDriverPtr driver, virDomainObjPtr vm,
     }
     VIR_FREE(priv->lockState);
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto release;
 
     ret = qemuMonitorStartCPUs(priv->mon, conn);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret < 0)
@@ -2909,14 +2920,15 @@ int qemuProcessStopCPUs(virQEMUDriverPtr driver,
 {
     int ret = -1;
     qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuMonitorPtr mon;
 
     VIR_FREE(priv->lockState);
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto cleanup;
 
     ret = qemuMonitorStopCPUs(priv->mon);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
 
     if (ret < 0)
@@ -2986,10 +2998,11 @@ qemuProcessUpdateState(virQEMUDriverPtr driver, virDomainObjPtr vm)
     bool running;
     char *msg = NULL;
     int ret;
+    qemuMonitorPtr mon;
 
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     ret = qemuMonitorGetStatus(priv->mon, &running, &reason);
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         return -1;
 
     if (ret < 0)
@@ -3203,6 +3216,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainState state;
     int reason;
+    qemuMonitorPtr mon;
 
     state = virDomainObjGetState(vm, &reason);
 
@@ -3222,9 +3236,9 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
     case QEMU_ASYNC_JOB_SAVE:
     case QEMU_ASYNC_JOB_DUMP:
     case QEMU_ASYNC_JOB_SNAPSHOT:
-        qemuDomainObjEnterMonitor(driver, vm);
+        mon = qemuDomainObjEnterMonitor(driver, vm);
         ignore_value(qemuMonitorMigrateCancel(priv->mon));
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             return -1;
         /* resume the domain but only if it was paused as a result of
          * running a migration-to-file operation.  Although we are
@@ -3814,6 +3828,7 @@ qemuProcessFetchGuestCPU(virQEMUDriverPtr driver,
     virCPUDataPtr dataEnabled = NULL;
     virCPUDataPtr dataDisabled = NULL;
     int rc;
+    qemuMonitorPtr mon;
 
     *enabled = NULL;
     *disabled = NULL;
@@ -3821,13 +3836,13 @@ qemuProcessFetchGuestCPU(virQEMUDriverPtr driver,
     if (!ARCH_IS_X86(vm->def->os.arch))
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto error;
 
     rc = qemuMonitorGetGuestCPU(priv->mon, vm->def->os.arch,
                                 &dataEnabled, &dataDisabled);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto error;
 
     if (rc == -1)
@@ -3945,13 +3960,14 @@ qemuProcessFetchCPUDefinitions(virQEMUDriverPtr driver,
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     virDomainCapsCPUModelsPtr models = NULL;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         goto error;
 
     models = virQEMUCapsFetchCPUDefinitions(priv->mon);
 
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto error;
 
     return models;
@@ -4569,11 +4585,12 @@ qemuProcessSetupBalloon(virQEMUDriverPtr driver,
     unsigned long long balloon = vm->def->mem.cur_balloon;
     qemuDomainObjPrivatePtr priv = vm->privateData;
     int ret = -1;
+    qemuMonitorPtr mon;
 
     if (!virDomainDefHasMemballoon(vm->def))
         return 0;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
         return -1;
 
     if (vm->def->memballoon->period)
@@ -4585,7 +4602,7 @@ qemuProcessSetupBalloon(virQEMUDriverPtr driver,
     ret = 0;
 
  cleanup:
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         ret = -1;
     return ret;
 }
@@ -5322,6 +5339,7 @@ qemuProcessSetupHotpluggableVcpus(virQEMUDriverPtr driver,
     size_t i;
     int ret = -1;
     int rc;
+    qemuMonitorPtr mon;
 
     virDomainVcpuDefPtr *bootHotplug = NULL;
     size_t nbootHotplug = 0;
@@ -5357,13 +5375,13 @@ qemuProcessSetupHotpluggableVcpus(virQEMUDriverPtr driver,
         if (!(vcpuprops = qemuBuildHotpluggableCPUProps(vcpu)))
             goto cleanup;
 
-        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) < 0)
             goto cleanup;
 
         rc = qemuMonitorAddDeviceArgs(qemuDomainGetMonitor(vm), vcpuprops);
         vcpuprops = NULL;
 
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
 
         if (rc < 0)
@@ -6765,6 +6783,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
     virCapsPtr caps = NULL;
     bool active = false;
+    qemuMonitorPtr mon;
 
     VIR_DEBUG("Beginning VM attach process");
 
@@ -6911,14 +6930,14 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
         goto error;
 
     VIR_DEBUG("Getting initial memory amount");
-    qemuDomainObjEnterMonitor(driver, vm);
+    mon = qemuDomainObjEnterMonitor(driver, vm);
     if (qemuMonitorGetBalloonInfo(priv->mon, &vm->def->mem.cur_balloon) < 0)
         goto exit_monitor;
     if (qemuMonitorGetStatus(priv->mon, &running, &reason) < 0)
         goto exit_monitor;
     if (qemuMonitorGetVirtType(priv->mon, &vm->def->virtType) < 0)
         goto exit_monitor;
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
+    if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
         goto error;
 
     if (running) {
@@ -6927,10 +6946,10 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
         if (vm->def->memballoon &&
             vm->def->memballoon->model == VIR_DOMAIN_MEMBALLOON_MODEL_VIRTIO &&
             vm->def->memballoon->period) {
-            qemuDomainObjEnterMonitor(driver, vm);
+            mon = qemuDomainObjEnterMonitor(driver, vm);
             qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon,
                                             vm->def->memballoon->period);
-            if (qemuDomainObjExitMonitor(driver, vm) < 0)
+            if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
                 goto error;
         }
     } else {
@@ -6967,7 +6986,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
     return 0;
 
  exit_monitor:
-    ignore_value(qemuDomainObjExitMonitor(driver, vm));
+    ignore_value(qemuDomainObjExitMonitor(driver, vm, mon));
  error:
     /* We jump here if we failed to attach to the VM for any reason.
      * Leave the domain running, but pretend we never attempted to
@@ -7075,10 +7094,11 @@ qemuProcessRefreshDisks(virQEMUDriverPtr driver,
     virHashTablePtr table = NULL;
     int ret = -1;
     size_t i;
+    qemuMonitorPtr mon;
 
-    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) == 0) {
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob, &mon) == 0) {
         table = qemuMonitorGetBlockInfo(priv->mon);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
+        if (qemuDomainObjExitMonitor(driver, vm, mon) < 0)
             goto cleanup;
     }
 
-- 
1.8.3.1

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]

  Powered by Linux