A destroy operation can take considerable time on large memory domains due to scrubbing the domain's memory. Unlock the virDomainObj while libxl_domain_destroy is executing. Implement libxlDomainDestroyInternal wrapper to handle unlocking, calling destroy, and locking. Change all callers of libxl_domain_destroy to use the wrapper. Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx> --- V3: Provide a wrapper to unlock, destroy and lock domain instead of do so at each call site of libxl_domain_destroy. src/libxl/libxl_domain.c | 29 ++++++++++++++++++++++++++--- src/libxl/libxl_domain.h | 4 ++++ src/libxl/libxl_driver.c | 6 +++--- src/libxl/libxl_migration.c | 4 ++-- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index 37ed082..1b809ca 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -435,7 +435,7 @@ libxlDomainShutdownThread(void *opaque) libxlDomainEventQueue(driver, dom_event); dom_event = NULL; } - libxl_domain_destroy(cfg->ctx, vm->def->id, NULL); + libxlDomainDestroyInternal(driver, vm); libxlDomainCleanup(driver, vm, reason); if (!vm->persistent) virDomainObjListRemove(driver->domains, vm); @@ -447,7 +447,7 @@ libxlDomainShutdownThread(void *opaque) libxlDomainEventQueue(driver, dom_event); dom_event = NULL; } - libxl_domain_destroy(cfg->ctx, vm->def->id, NULL); + libxlDomainDestroyInternal(driver, vm); libxlDomainCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_SHUTDOWN); if (libxlDomainStart(driver, vm, false, -1) < 0) { virErrorPtr err = virGetLastError(); @@ -626,6 +626,29 @@ libxlDomainSaveImageOpen(libxlDriverPrivatePtr driver, } /* + * Internal domain destroy function. + * + * virDomainObjPtr must be locked on invocation + */ +int +libxlDomainDestroyInternal(libxlDriverPrivatePtr driver, + virDomainObjPtr vm) +{ + libxlDriverConfigPtr cfg = libxlDriverConfigGet(driver); + int ret = -1; + + /* Unlock virDomainObj during destroy, which can take considerable + * time on large memory domains. + */ + virObjectUnlock(vm); + ret = libxl_domain_destroy(cfg->ctx, vm->def->id, NULL); + virObjectLock(vm); + + virObjectUnref(cfg); + return ret; +} + +/* * Cleanup function for domain that has reached shutoff state. * * virDomainObjPtr must be locked on invocation @@ -1022,7 +1045,7 @@ libxlDomainStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm, libxl_evdisable_domain_death(cfg->ctx, priv->deathW); priv->deathW = NULL; } - libxl_domain_destroy(cfg->ctx, domid, NULL); + libxlDomainDestroyInternal(driver, vm); vm->def->id = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED); diff --git a/src/libxl/libxl_domain.h b/src/libxl/libxl_domain.h index 30855a2..aa647b8 100644 --- a/src/libxl/libxl_domain.h +++ b/src/libxl/libxl_domain.h @@ -103,6 +103,10 @@ libxlDomainSaveImageOpen(libxlDriverPrivatePtr driver, libxlSavefileHeaderPtr ret_hdr) ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5); +int +libxlDomainDestroyInternal(libxlDriverPrivatePtr driver, + virDomainObjPtr vm); + void libxlDomainCleanup(libxlDriverPrivatePtr driver, virDomainObjPtr vm, diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c index c9623ef..9eb071e 100644 --- a/src/libxl/libxl_driver.c +++ b/src/libxl/libxl_driver.c @@ -1252,7 +1252,7 @@ libxlDomainDestroyFlags(virDomainPtr dom, event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - if (libxl_domain_destroy(cfg->ctx, vm->def->id, NULL) < 0) { + if (libxlDomainDestroyInternal(driver, vm) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), vm->def->id); goto endjob; @@ -1595,7 +1595,7 @@ libxlDoDomainSave(libxlDriverPrivatePtr driver, virDomainObjPtr vm, event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_SAVED); - if (libxl_domain_destroy(cfg->ctx, vm->def->id, NULL) < 0) { + if (libxlDomainDestroyInternal(driver, vm) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), vm->def->id); goto cleanup; @@ -1802,7 +1802,7 @@ libxlDomainCoreDump(virDomainPtr dom, const char *to, unsigned int flags) } if (flags & VIR_DUMP_CRASH) { - if (libxl_domain_destroy(cfg->ctx, vm->def->id, NULL) < 0) { + if (libxlDomainDestroyInternal(driver, vm) < 0) { virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to destroy domain '%d'"), vm->def->id); goto unpause; diff --git a/src/libxl/libxl_migration.c b/src/libxl/libxl_migration.c index 3d0c96e..4010506 100644 --- a/src/libxl/libxl_migration.c +++ b/src/libxl/libxl_migration.c @@ -575,7 +575,7 @@ libxlDomainMigrationFinish(virConnectPtr dconn, cleanup: if (dom == NULL) { - libxl_domain_destroy(cfg->ctx, vm->def->id, NULL); + libxlDomainDestroyInternal(driver, vm); libxlDomainCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED); event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_FAILED); @@ -614,7 +614,7 @@ libxlDomainMigrationConfirm(libxlDriverPrivatePtr driver, goto cleanup; } - libxl_domain_destroy(cfg->ctx, vm->def->id, NULL); + libxlDomainDestroyInternal(driver, vm); libxlDomainCleanup(driver, vm, VIR_DOMAIN_SHUTOFF_MIGRATED); event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STOPPED, VIR_DOMAIN_EVENT_STOPPED_MIGRATED); -- 1.8.4.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list