Introduce libxlDomainStartPerform as part of decomposing libxlDomainStart. Perform all operations that are part of starting a domain. On error the domain is destroyed from libxl's perspective, but the operations perfomed in libxlDomainStartPrepare must be unwound by libxlDomainStart. Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx> --- src/libxl/libxl_domain.c | 87 ++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 35 deletions(-) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index d564165807..c656cba3a3 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -1273,21 +1273,16 @@ libxlDomainStartPrepare(libxlDriverPrivate *driver, return -1; } -/* - * Start a domain through libxenlight. - * - * virDomainObj *must be locked and a job acquired on invocation - */ static int -libxlDomainStart(libxlDriverPrivate *driver, - virDomainObj *vm, - bool start_paused, - int restore_fd, - uint32_t restore_ver) +libxlDomainStartPerform(libxlDriverPrivate *driver, + virDomainObj *vm, + bool start_paused, + int restore_fd, + uint32_t restore_ver) { libxl_domain_config d_config; - virObjectEvent *event = NULL; int ret = -1; + int libxlret = -1; uint32_t domid = 0; g_autofree char *dom_xml = NULL; libxlDomainObjPrivate *priv = vm->privateData; @@ -1296,17 +1291,14 @@ libxlDomainStart(libxlDriverPrivate *driver, libxl_domain_restore_params params; g_autofree char *config_json = NULL; - if (libxlDomainStartPrepare(driver, vm) < 0) - return -1; - libxl_domain_config_init(&d_config); if (libxlBuildDomainConfig(driver->reservedGraphicsPorts, vm->def, cfg, &d_config) < 0) - goto cleanup_dom; + goto cleanup; if (cfg->autoballoon && libxlDomainFreeMem(cfg->ctx, &d_config) < 0) - goto cleanup_dom; + goto cleanup; /* now that we know it is about to start call the hook if present */ if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) { @@ -1322,7 +1314,7 @@ libxlDomainStart(libxlDriverPrivate *driver, * If the script raised an error abort the launch */ if (hookret < 0) - goto cleanup_dom; + goto cleanup; } if (priv->hookRun) { @@ -1341,19 +1333,19 @@ libxlDomainStart(libxlDriverPrivate *driver, aop_console_how.for_callback = vm; aop_console_how.callback = libxlConsoleCallback; if (restore_fd < 0) { - ret = libxl_domain_create_new(cfg->ctx, &d_config, + libxlret = libxl_domain_create_new(cfg->ctx, &d_config, &domid, NULL, &aop_console_how); } else { libxl_domain_restore_params_init(¶ms); params.stream_version = restore_ver; - ret = libxlDomainCreateRestoreWrapper(cfg->ctx, &d_config, &domid, + libxlret = libxlDomainCreateRestoreWrapper(cfg->ctx, &d_config, &domid, restore_fd, ¶ms, &aop_console_how); libxl_domain_restore_params_dispose(¶ms); } virObjectLock(vm); - if (ret) { + if (libxlret) { if (restore_fd < 0) virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to create new domain '%s'"), @@ -1362,7 +1354,7 @@ libxlDomainStart(libxlDriverPrivate *driver, virReportError(VIR_ERR_INTERNAL_ERROR, _("libxenlight failed to restore domain '%s'"), d_config.c_info.name); - goto cleanup_dom; + goto cleanup; } /* @@ -1412,9 +1404,6 @@ libxlDomainStart(libxlDriverPrivate *driver, if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0) goto destroy_dom; - if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) - driver->inhibitCallback(true, driver->inhibitOpaque); - /* finally we can call the 'started' hook script if any */ if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) { char *xml = virDomainDefFormat(vm->def, driver->xmlopt, 0); @@ -1432,24 +1421,52 @@ libxlDomainStart(libxlDriverPrivate *driver, goto destroy_dom; } - event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, - restore_fd < 0 ? - VIR_DOMAIN_EVENT_STARTED_BOOTED : - VIR_DOMAIN_EVENT_STARTED_RESTORED); - virObjectEventStateQueue(driver->domainEventState, event); - - libxl_domain_config_dispose(&d_config); - return 0; + ret = 0; + goto cleanup; destroy_dom: libxlDomainDestroyInternal(driver, vm); vm->def->id = -1; virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, VIR_DOMAIN_SHUTOFF_FAILED); - cleanup_dom: - libxlDomainCleanup(driver, vm); + cleanup: libxl_domain_config_dispose(&d_config); - return -1; + return ret; +} + +/* + * Start a domain through libxenlight. + * + * virDomainObj must be locked and a job acquired on invocation + */ +static int +libxlDomainStart(libxlDriverPrivate *driver, + virDomainObj *vm, + bool start_paused, + int restore_fd, + uint32_t restore_ver) +{ + virObjectEvent *event = NULL; + + if (libxlDomainStartPrepare(driver, vm) < 0) + return -1; + + if (libxlDomainStartPerform(driver, vm, start_paused, + restore_fd, restore_ver) < 0) { + libxlDomainCleanup(driver, vm); + return -1; + } + + if (g_atomic_int_add(&driver->nactive, 1) == 0 && driver->inhibitCallback) + driver->inhibitCallback(true, driver->inhibitOpaque); + + event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, + restore_fd < 0 ? + VIR_DOMAIN_EVENT_STARTED_BOOTED : + VIR_DOMAIN_EVENT_STARTED_RESTORED); + virObjectEventStateQueue(driver->domainEventState, event); + + return 0; } int -- 2.31.1