Introduce libxlDomainStartPrepare as part of decomposing libxlDomainStart. Perform all prepratory operations such as hostdevs, network devs, etc. Also ensure all such operations are properly unwound on error. Signed-off-by: Jim Fehlig <jfehlig@xxxxxxxx> --- src/libxl/libxl_domain.c | 99 ++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c index f957c29d0d..d564165807 100644 --- a/src/libxl/libxl_domain.c +++ b/src/libxl/libxl_domain.c @@ -1224,6 +1224,55 @@ libxlDomainCreateChannelPTY(virDomainDef *def, libxl_ctx *ctx) libxl_device_channel_dispose(&x_channels[i]); } +static int +libxlDomainStartPrepare(libxlDriverPrivate *driver, + virDomainObj *vm) +{ + virHostdevManager *hostdev_mgr = driver->hostdevMgr; + unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI | VIR_HOSTDEV_SP_USB; + + if (virDomainObjSetDefTransient(driver->xmlopt, vm, NULL) < 0) + return -1; + + /* Run an early hook to set-up missing devices */ + if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) { + g_autofree char *xml = virDomainDefFormat(vm->def, driver->xmlopt, 0); + int hookret; + + hookret = virHookCall(VIR_HOOK_DRIVER_LIBXL, vm->def->name, + VIR_HOOK_LIBXL_OP_PREPARE, VIR_HOOK_SUBOP_BEGIN, + NULL, xml, NULL); + /* + * If the script raised an error abort the launch + */ + if (hookret < 0) + goto error; + } + + if (virDomainLockProcessStart(driver->lockManager, + "xen:///system", + vm, + true, + NULL) < 0) + goto error; + + if (libxlNetworkPrepareDevices(vm->def) < 0) + goto error; + + if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_INTERNAL_NAME, + vm->def, hostdev_flags) < 0) + goto error; + + return 0; + + error: + libxlNetworkUnwindDevices(vm->def); + virHostdevReAttachDomainDevices(hostdev_mgr, LIBXL_DRIVER_INTERNAL_NAME, + vm->def, hostdev_flags); + virDomainObjRemoveTransientDef(vm); + return -1; +} + /* * Start a domain through libxenlight. * @@ -1243,46 +1292,15 @@ libxlDomainStart(libxlDriverPrivate *driver, g_autofree char *dom_xml = NULL; libxlDomainObjPrivate *priv = vm->privateData; g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver); - virHostdevManager *hostdev_mgr = driver->hostdevMgr; libxl_asyncprogress_how aop_console_how; libxl_domain_restore_params params; - unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI; g_autofree char *config_json = NULL; - hostdev_flags |= VIR_HOSTDEV_SP_USB; + if (libxlDomainStartPrepare(driver, vm) < 0) + return -1; libxl_domain_config_init(&d_config); - if (virDomainObjSetDefTransient(driver->xmlopt, vm, NULL) < 0) - goto cleanup; - - /* Run an early hook to set-up missing devices */ - if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) { - char *xml = virDomainDefFormat(vm->def, driver->xmlopt, 0); - int hookret; - - hookret = virHookCall(VIR_HOOK_DRIVER_LIBXL, vm->def->name, - VIR_HOOK_LIBXL_OP_PREPARE, VIR_HOOK_SUBOP_BEGIN, - NULL, xml, NULL); - VIR_FREE(xml); - - /* - * If the script raised an error abort the launch - */ - if (hookret < 0) - goto cleanup_dom; - } - - if (virDomainLockProcessStart(driver->lockManager, - "xen:///system", - vm, - true, - NULL) < 0) - goto cleanup; - - if (libxlNetworkPrepareDevices(vm->def) < 0) - goto cleanup_dom; - if (libxlBuildDomainConfig(driver->reservedGraphicsPorts, vm->def, cfg, &d_config) < 0) goto cleanup_dom; @@ -1290,10 +1308,6 @@ libxlDomainStart(libxlDriverPrivate *driver, if (cfg->autoballoon && libxlDomainFreeMem(cfg->ctx, &d_config) < 0) goto cleanup_dom; - if (virHostdevPrepareDomainDevices(hostdev_mgr, LIBXL_DRIVER_INTERNAL_NAME, - vm->def, hostdev_flags) < 0) - goto cleanup_dom; - /* now that we know it is about to start call the hook if present */ if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) { char *xml = virDomainDefFormat(vm->def, driver->xmlopt, 0); @@ -1415,7 +1429,7 @@ libxlDomainStart(libxlDriverPrivate *driver, * If the script raised an error abort the launch */ if (hookret < 0) - goto cleanup_dom; + goto destroy_dom; } event = virDomainEventLifecycleNewFromObj(vm, VIR_DOMAIN_EVENT_STARTED, @@ -1424,21 +1438,18 @@ libxlDomainStart(libxlDriverPrivate *driver, VIR_DOMAIN_EVENT_STARTED_RESTORED); virObjectEventStateQueue(driver->domainEventState, event); - ret = 0; - goto cleanup; + libxl_domain_config_dispose(&d_config); + return 0; destroy_dom: - ret = -1; 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 ret; + return -1; } int -- 2.31.1