]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
libxl: Introduce libxlDomainStartPrepare
authorJim Fehlig <jfehlig@suse.com>
Tue, 29 Jun 2021 23:32:37 +0000 (17:32 -0600)
committerJim Fehlig <jfehlig@suse.com>
Mon, 12 Jul 2021 20:02:18 +0000 (14:02 -0600)
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@suse.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/libxl/libxl_domain.c

index 513621f6dd59aa4dfcd24e84e141a8060b8b8541..e860da197a5323131aaf4eabb109b1c6fa44510c 100644 (file)
@@ -1223,53 +1223,29 @@ libxlDomainCreateChannelPTY(virDomainDef *def, libxl_ctx *ctx)
         libxl_device_channel_dispose(&x_channels[i]);
 }
 
-/*
- * 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)
+libxlDomainStartPrepare(libxlDriverPrivate *driver,
+                        virDomainObj *vm)
 {
-    libxl_domain_config d_config;
-    virObjectEvent *event = NULL;
-    int ret = -1;
-    uint32_t domid = 0;
-    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;
-
-    libxl_domain_config_init(&d_config);
+    unsigned int hostdev_flags = VIR_HOSTDEV_SP_PCI | VIR_HOSTDEV_SP_USB;
 
     if (virDomainObjSetDefTransient(driver->xmlopt, vm, NULL) < 0)
-        goto cleanup;
+        return -1;
 
     /* Run an early hook to set-up missing devices */
     if (virHookPresent(VIR_HOOK_DRIVER_LIBXL)) {
-        char *xml = virDomainDefFormat(vm->def, driver->xmlopt, 0);
+        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);
-        VIR_FREE(xml);
-
         /*
          * If the script raised an error abort the launch
          */
         if (hookret < 0)
-            goto cleanup_dom;
+            goto error;
     }
 
     if (virDomainLockProcessStart(driver->lockManager,
@@ -1277,10 +1253,52 @@ libxlDomainStart(libxlDriverPrivate *driver,
                                   vm,
                                   true,
                                   NULL) < 0)
-        goto cleanup;
+        goto error;
 
     if (libxlNetworkPrepareDevices(vm->def) < 0)
-        goto cleanup_dom;
+        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.
+ *
+ * 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)
+{
+    libxl_domain_config d_config;
+    virObjectEvent *event = NULL;
+    int ret = -1;
+    uint32_t domid = 0;
+    g_autofree char *dom_xml = NULL;
+    libxlDomainObjPrivate *priv = vm->privateData;
+    g_autoptr(libxlDriverConfig) cfg = libxlDriverConfigGet(driver);
+    libxl_asyncprogress_how aop_console_how;
+    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)
@@ -1289,10 +1307,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);
@@ -1414,7 +1428,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,
@@ -1423,21 +1437,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