Add long-running jobs for save, dump. Add normal job for the api maybe modify the domain. Signed-off-by: Bamvor Jian Zhang <bjzhang@xxxxxxxx> --- 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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list