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

[libvirt] [PATCH 2/2] Add lock for libxl api



Add long-running jobs for save, dump. Add normal job for the
api maybe modify the domain.

Signed-off-by: Bamvor Jian Zhang <bjzhang suse com>
---
 src/libxl/libxl_driver.c | 219 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 158 insertions(+), 61 deletions(-)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 05944ef..e87b71c 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -1507,9 +1507,13 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
         goto cleanup;
     def = NULL;
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (libxlVmStart(driver, vm, (flags & VIR_DOMAIN_START_PAUSED) != 0,
                      -1) < 0) {
-        virDomainRemoveInactive(&driver->domains, vm);
+        if (libxlDomainObjEndJob(driver, vm))
+            virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
         goto cleanup;
     }
@@ -1518,6 +1522,8 @@ libxlDomainCreateXML(virConnectPtr conn, const char *xml,
     if (dom)
         dom->id = vm->def->id;
 
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
 cleanup:
     virDomainDefFree(def);
     if (vm)
@@ -1624,9 +1630,13 @@ libxlDomainSuspend(virDomainPtr dom)
                        _("No domain with matching uuid '%s'"), uuidstr);
         goto cleanup;
     }
+
+    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running"));
-        goto cleanup;
+        goto endjob;
     }
 
     priv = vm->privateData;
@@ -1636,7 +1646,7 @@ libxlDomainSuspend(virDomainPtr dom)
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to suspend domain '%d' with libxenlight"),
                            dom->id);
-            goto cleanup;
+            goto endjob;
         }
 
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER);
@@ -1646,10 +1656,14 @@ libxlDomainSuspend(virDomainPtr dom)
     }
 
     if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
-        goto cleanup;
+        goto endjob;
 
     ret = 0;
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
@@ -1683,9 +1697,12 @@ libxlDomainResume(virDomainPtr dom)
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running"));
-        goto cleanup;
+        goto endjob;
     }
 
     priv = vm->privateData;
@@ -1695,7 +1712,7 @@ libxlDomainResume(virDomainPtr dom)
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to resume domain '%d' with libxenlight"),
                            dom->id);
-            goto cleanup;
+            goto endjob;
         }
 
         virDomainObjSetState(vm, VIR_DOMAIN_RUNNING,
@@ -1706,10 +1723,14 @@ libxlDomainResume(virDomainPtr dom)
     }
 
     if (virDomainSaveStatus(driver->caps, driver->stateDir, vm) < 0)
-        goto cleanup;
+        goto endjob;
 
     ret = 0;
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
@@ -1741,10 +1762,13 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("Domain is not running"));
-        goto cleanup;
+        goto endjob;
     }
 
     priv = vm->privateData;
@@ -1752,7 +1776,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Failed to shutdown domain '%d' with libxenlight"),
                        dom->id);
-        goto cleanup;
+        goto endjob;
     }
 
     /* vm is marked shutoff (or removed from domains list if not persistent)
@@ -1760,6 +1784,10 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
      */
     ret = 0;
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
@@ -1794,10 +1822,13 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags)
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("Domain is not running"));
-        goto cleanup;
+        goto endjob;
     }
 
     priv = vm->privateData;
@@ -1805,10 +1836,14 @@ libxlDomainReboot(virDomainPtr dom, unsigned int flags)
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Failed to reboot domain '%d' with libxenlight"),
                        dom->id);
-        goto cleanup;
+        goto endjob;
     }
     ret = 0;
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
@@ -1837,10 +1872,13 @@ libxlDomainDestroyFlags(virDomainPtr dom,
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_DESTROY) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("Domain is not running"));
-        goto cleanup;
+        goto endjob;
     }
 
     event = virDomainEventNewFromObj(vm,VIR_DOMAIN_EVENT_STOPPED,
@@ -1849,16 +1887,21 @@ libxlDomainDestroyFlags(virDomainPtr dom,
     if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_DESTROYED) != 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Failed to destroy domain '%d'"), dom->id);
-        goto cleanup;
+        goto endjob;
     }
 
     if (!vm->persistent) {
-        virDomainRemoveInactive(&driver->domains, vm);
+        if (libxlDomainObjEndJob(driver, vm))
+            virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
     }
 
     ret = 0;
 
+endjob:
+    if ( vm && !libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
@@ -1948,6 +1991,9 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     isActive = virDomainObjIsActive(vm);
 
     if (flags == VIR_DOMAIN_MEM_CURRENT) {
@@ -1966,17 +2012,17 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
     if (!isActive && (flags & VIR_DOMAIN_MEM_LIVE)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("cannot set memory on an inactive domain"));
-        goto cleanup;
+        goto endjob;
     }
 
     if (flags & VIR_DOMAIN_MEM_CONFIG) {
         if (!vm->persistent) {
             virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                            _("cannot change persistent config of a transient domain"));
-            goto cleanup;
+            goto endjob;
         }
         if (!(persistentDef = virDomainObjGetPersistentDef(driver->caps, vm)))
-            goto cleanup;
+            goto endjob;
     }
 
     if (flags & VIR_DOMAIN_MEM_MAXIMUM) {
@@ -1988,7 +2034,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("Failed to set maximum memory for domain '%d'"
                                  " with libxenlight"), dom->id);
-                goto cleanup;
+                goto endjob;
             }
         }
 
@@ -1999,7 +2045,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
             if (persistentDef->mem.cur_balloon > newmem)
                 persistentDef->mem.cur_balloon = newmem;
             ret = virDomainSaveConfig(driver->configDir, persistentDef);
-            goto cleanup;
+            goto endjob;
         }
 
     } else {
@@ -2008,7 +2054,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
         if (newmem > vm->def->mem.max_balloon) {
             virReportError(VIR_ERR_INVALID_ARG, "%s",
                            _("cannot set memory higher than max memory"));
-            goto cleanup;
+            goto endjob;
         }
 
         if (flags & VIR_DOMAIN_MEM_LIVE) {
@@ -2018,7 +2064,7 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
                 virReportError(VIR_ERR_INTERNAL_ERROR,
                                _("Failed to set memory for domain '%d'"
                                  " with libxenlight"), dom->id);
-                goto cleanup;
+                goto endjob;
             }
         }
 
@@ -2026,11 +2072,14 @@ libxlDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
             sa_assert(persistentDef);
             persistentDef->mem.cur_balloon = newmem;
             ret = virDomainSaveConfig(driver->configDir, persistentDef);
-            goto cleanup;
+            goto endjob;
         }
     }
 
     ret = 0;
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
 
 cleanup:
     if (vm)
@@ -2138,22 +2187,26 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
     int fd;
     int ret = -1;
 
+    if (libxlDomainObjBeginAsyncJobWithDriver(driver, vm,
+                                              LIBXL_ASYNC_JOB_SAVE) < 0)
+        goto cleanup;
+
     if (virDomainObjGetState(vm, NULL) == VIR_DOMAIN_PAUSED) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        _("Domain '%d' has to be running because libxenlight will"
                          " suspend it"), vm->def->id);
-        goto cleanup;
+        goto endjob;
     }
 
     if ((fd = virFileOpenAs(to, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR,
                             -1, -1, 0)) < 0) {
         virReportSystemError(-fd,
                              _("Failed to create domain save file '%s'"), to);
-        goto cleanup;
+        goto endjob;
     }
 
     if ((xml = virDomainDefFormat(vm->def, 0)) == NULL)
-        goto cleanup;
+        goto endjob;
     xml_len = strlen(xml) + 1;
 
     memset(&hdr, 0, sizeof(hdr));
@@ -2164,20 +2217,26 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
     if (safewrite(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) {
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                        _("Failed to write save file header"));
-        goto cleanup;
+        goto endjob;
     }
 
     if (safewrite(fd, xml, xml_len) != xml_len) {
         virReportError(VIR_ERR_OPERATION_FAILED, "%s",
                        _("Failed to write xml description"));
-        goto cleanup;
+        goto endjob;
     }
 
-    if (libxl_domain_suspend(&priv->ctx, NULL, vm->def->id, fd) != 0) {
+    virDomainObjUnlock(vm);
+    libxlDriverUnlock(driver);
+    ret = libxl_domain_suspend(&priv->ctx, NULL, vm->def->id, fd);
+    libxlDriverLock(driver);
+    virDomainObjLock(vm);
+
+    if (ret != 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Failed to save domain '%d' with libxenlight"),
                        vm->def->id);
-        goto cleanup;
+        goto endjob;
     }
 
     event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
@@ -2186,18 +2245,23 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
     if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_SAVED) != 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Failed to destroy domain '%d'"), vm->def->id);
-        goto cleanup;
+        goto endjob;
     }
 
     vm->hasManagedSave = true;
 
     if (!vm->persistent) {
-        virDomainRemoveInactive(&driver->domains, vm);
+        if (libxlDomainObjEndAsyncJob(driver, vm))
+            virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
     }
 
     ret = 0;
 
+endjob:
+    if ( vm && !libxlDomainObjEndAsyncJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     VIR_FREE(xml);
     if (VIR_CLOSE(fd) < 0)
@@ -2285,12 +2349,18 @@ libxlDomainRestoreFlags(virConnectPtr conn, const char *from,
 
     def = NULL;
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if ((ret = libxlVmStart(driver, vm, false, fd)) < 0 &&
         !vm->persistent) {
-        virDomainRemoveInactive(&driver->domains, vm);
+        if (libxlDomainObjEndAsyncJob(driver, vm))
+            virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
     }
 
+    if (vm && !libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
 cleanup:
     if (VIR_CLOSE(fd) < 0)
         virReportSystemError(errno, "%s", _("cannot close file"));
@@ -2321,7 +2391,6 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
 
     libxlDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
-    libxlDriverUnlock(driver);
 
     if (!vm) {
         char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -2331,9 +2400,13 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginAsyncJobWithDriver(driver, vm,
+                                              LIBXL_ASYNC_JOB_DUMP) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not running"));
-        goto cleanup;
+        goto endjob;
     }
 
     priv = vm->privateData;
@@ -2345,25 +2418,29 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
                            _("Before dumping core, failed to suspend domain '%d'"
                              " with libxenlight"),
                            dom->id);
-            goto cleanup;
+            goto endjob;
         }
         virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_DUMP);
         paused = true;
     }
 
-    if (libxl_domain_core_dump(&priv->ctx, dom->id, to) != 0) {
+    virDomainObjUnlock(vm);
+    libxlDriverUnlock(driver);
+    ret = libxl_domain_core_dump(&priv->ctx, dom->id, to);
+    libxlDriverLock(driver);
+    virDomainObjLock(vm);
+    if (ret != 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Failed to dump core of domain '%d' with libxenlight"),
                        dom->id);
-        goto cleanup_unpause;
+        goto endjob_unpause;
     }
 
-    libxlDriverLock(driver);
     if (flags & VIR_DUMP_CRASH) {
         if (libxlVmReap(driver, vm, 1, VIR_DOMAIN_SHUTOFF_CRASHED) != 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to destroy domain '%d'"), dom->id);
-            goto cleanup_unlock;
+            goto endjob_unpause;
         }
 
         event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED,
@@ -2371,15 +2448,14 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags)
     }
 
     if ((flags & VIR_DUMP_CRASH) && !vm->persistent) {
-        virDomainRemoveInactive(&driver->domains, vm);
+        if (libxlDomainObjEndAsyncJob(driver, vm))
+            virDomainRemoveInactive(&driver->domains, vm);
         vm = NULL;
     }
 
     ret = 0;
 
-cleanup_unlock:
-    libxlDriverUnlock(driver);
-cleanup_unpause:
+endjob_unpause:
     if (virDomainObjIsActive(vm) && paused) {
         if (libxl_domain_unpause(&priv->ctx, dom->id) != 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -2390,14 +2466,15 @@ cleanup_unpause:
                                  VIR_DOMAIN_RUNNING_UNPAUSED);
         }
     }
+endjob:
+    if (vm && !libxlDomainObjEndAsyncJob(driver, vm))
+        vm = NULL;
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
-    if (event) {
-        libxlDriverLock(driver);
+    if (event)
         libxlDomainEventQueue(driver, event);
-        libxlDriverUnlock(driver);
-    }
+    libxlDriverUnlock(driver);
     return ret;
 }
 
@@ -2574,22 +2651,25 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJob(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (!virDomainObjIsActive(vm) && (flags & VIR_DOMAIN_VCPU_LIVE)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("cannot set vcpus on an inactive domain"));
-        goto cleanup;
+        goto endjob;
     }
 
     if (!vm->persistent && (flags & VIR_DOMAIN_VCPU_CONFIG)) {
         virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                        _("cannot change persistent config of a transient domain"));
-        goto cleanup;
+        goto endjob;
     }
 
     if ((max = libxlGetMaxVcpus(dom->conn, NULL)) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("could not determine max vcpus for the domain"));
-        goto cleanup;
+        goto endjob;
     }
 
     if (!(flags & VIR_DOMAIN_VCPU_MAXIMUM) && vm->def->maxvcpus < max) {
@@ -2600,18 +2680,18 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
         virReportError(VIR_ERR_INVALID_ARG,
                        _("requested vcpus is greater than max allowable"
                          " vcpus for the domain: %d > %d"), nvcpus, max);
-        goto cleanup;
+        goto endjob;
     }
 
     priv = vm->privateData;
 
     if (!(def = virDomainObjGetPersistentDef(driver->caps, vm)))
-        goto cleanup;
+        goto endjob;
 
     maplen = VIR_CPU_MAPLEN(nvcpus);
     if (VIR_ALLOC_N(bitmask, maplen) < 0) {
         virReportOOMError();
-        goto cleanup;
+        goto endjob;
     }
 
     for (i = 0; i < nvcpus; ++i) {
@@ -2638,7 +2718,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to set vcpus for domain '%d'"
                              " with libxenlight"), dom->id);
-            goto cleanup;
+            goto endjob;
         }
         break;
 
@@ -2647,7 +2727,7 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Failed to set vcpus for domain '%d'"
                              " with libxenlight"), dom->id);
-            goto cleanup;
+            goto endjob;
         }
         def->vcpus = nvcpus;
         break;
@@ -2658,6 +2738,9 @@ libxlDomainSetVcpusFlags(virDomainPtr dom, unsigned int nvcpus,
     if (flags & VIR_DOMAIN_VCPU_CONFIG)
         ret = virDomainSaveConfig(driver->configDir, def);
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
 cleanup:
     VIR_FREE(bitmask);
      if (vm)
@@ -3026,14 +3109,21 @@ libxlDomainCreateWithFlags(virDomainPtr dom,
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (virDomainObjIsActive(vm)) {
         virReportError(VIR_ERR_OPERATION_INVALID,
                        "%s", _("Domain is already running"));
-        goto cleanup;
+        goto endjob;
     }
 
     ret = libxlVmStart(driver, vm, (flags & VIR_DOMAIN_START_PAUSED) != 0, -1);
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     if (vm)
         virDomainObjUnlock(vm);
@@ -3558,6 +3648,9 @@ libxlDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
         goto cleanup;
     }
 
+    if (libxlDomainObjBeginJobWithDriver(driver, vm, LIBXL_JOB_MODIFY) < 0)
+        goto cleanup;
+
     if (virDomainObjIsActive(vm)) {
         if (flags == VIR_DOMAIN_DEVICE_MODIFY_CURRENT)
             flags |= VIR_DOMAIN_DEVICE_MODIFY_LIVE;
@@ -3568,14 +3661,14 @@ libxlDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
         if (flags & VIR_DOMAIN_DEVICE_MODIFY_LIVE) {
             virReportError(VIR_ERR_OPERATION_INVALID,
                            "%s", _("Domain is not running"));
-            goto cleanup;
+            goto endjob;
         }
     }
 
     if ((flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) && !vm->persistent) {
          virReportError(VIR_ERR_OPERATION_INVALID,
                         "%s", _("cannot modify device on transient domain"));
-         goto cleanup;
+         goto endjob;
     }
 
     priv = vm->privateData;
@@ -3583,11 +3676,11 @@ libxlDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
     if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
         if (!(dev = virDomainDeviceDefParse(driver->caps, vm->def, xml,
                                             VIR_DOMAIN_XML_INACTIVE)))
-            goto cleanup;
+            goto endjob;
 
         /* Make a copy for updated domain. */
         if (!(vmdef = virDomainObjCopyPersistentDef(driver->caps, vm)))
-            goto cleanup;
+            goto endjob;
 
         switch (action) {
             case LIBXL_DEVICE_ATTACH:
@@ -3611,7 +3704,7 @@ libxlDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
         virDomainDeviceDefFree(dev);
         if (!(dev = virDomainDeviceDefParse(driver->caps, vm->def, xml,
                                             VIR_DOMAIN_XML_INACTIVE)))
-            goto cleanup;
+            goto endjob;
 
         switch (action) {
             case LIBXL_DEVICE_ATTACH:
@@ -3644,6 +3737,10 @@ libxlDomainModifyDeviceFlags(virDomainPtr dom, const char *xml,
         }
     }
 
+endjob:
+    if (!libxlDomainObjEndJob(driver, vm))
+        vm = NULL;
+
 cleanup:
     virDomainDefFree(vmdef);
     virDomainDeviceDefFree(dev);
-- 
1.7.12


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