qemuProcessStart is going to be split in three parts: qemuProcessInit,
qemuProcessLaunch, and qemuProcessFinish so that migration Prepare phase
can insert additional code in the process. qemuProcessStart will be a
small wrapper for all other callers.

qemuProcessInit prepares the domain up to the point when priv->qemuCaps
is initialized.

Signed-off-by: Jiri Denemark <jdene...@redhat.com>
---

Notes:
    Version 2:
    - avoid calling qemuProcessStop when starting fails with
      "VM is already active"

 src/qemu/qemu_process.c | 133 ++++++++++++++++++++++++++++++++----------------
 src/qemu/qemu_process.h |   4 ++
 2 files changed, 92 insertions(+), 45 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 2192ad8..784ae08 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4476,6 +4476,86 @@ qemuProcessMakeDir(virQEMUDriverPtr driver,
 }
 
 
+/**
+ * qemuProcessInit:
+ *
+ * Prepares the domain up to the point when priv->qemuCaps is initialized.
+ *
+ * @returns 0 on success,
+ *          -1 on error requiring qemuProcessStop to be called,
+ *          -2 on error when qemuProcessStop must NOT be called.
+ */
+int
+qemuProcessInit(virQEMUDriverPtr driver,
+                virDomainObjPtr vm,
+                bool migration)
+{
+    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+    virCapsPtr caps = NULL;
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int ret = -2;
+
+    VIR_DEBUG("vm=%p name=%s id=%d migration=%d",
+              vm, vm->def->name, vm->def->id, migration);
+
+    VIR_DEBUG("Beginning VM startup process");
+
+    if (virDomainObjIsActive(vm)) {
+        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+                       _("VM is already active"));
+        goto cleanup;
+    }
+
+    /* require qemuProcessStop to be called from now on */
+    ret = -1;
+
+    if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
+        goto cleanup;
+
+    /* Some things, paths, ... are generated here and we want them to persist.
+     * Fill them in prior to setting the domain def as transient. */
+    VIR_DEBUG("Generating paths");
+
+    if (qemuPrepareNVRAM(cfg, vm, migration) < 0)
+        goto cleanup;
+
+    /* Do this upfront, so any part of the startup process can add
+     * runtime state to vm->def that won't be persisted. This let's us
+     * report implicit runtime defaults in the XML, like vnc listen/socket
+     */
+    VIR_DEBUG("Setting current domain def as transient");
+    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm, true) < 0)
+        goto cleanup;
+
+    vm->def->id = qemuDriverAllocateID(driver);
+    qemuDomainSetFakeReboot(driver, vm, false);
+    virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
+
+    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
+        driver->inhibitCallback(true, driver->inhibitOpaque);
+
+    /* Run an early hook to set-up missing devices */
+    if (qemuProcessStartHook(driver, vm,
+                             VIR_HOOK_QEMU_OP_PREPARE,
+                             VIR_HOOK_SUBOP_BEGIN) < 0)
+        goto cleanup;
+
+    VIR_DEBUG("Determining emulator version");
+    virObjectUnref(priv->qemuCaps);
+    if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
+                                                      vm->def->emulator,
+                                                      vm->def->os.machine)))
+        goto cleanup;
+
+    ret = 0;
+
+ cleanup:
+    virObjectUnref(cfg);
+    virObjectUnref(caps);
+    return ret;
+}
+
+
 int qemuProcessStart(virConnectPtr conn,
                      virQEMUDriverPtr driver,
                      virDomainObjPtr vm,
@@ -4498,7 +4578,7 @@ int qemuProcessStart(virConnectPtr conn,
     size_t i;
     char *nodeset = NULL;
     unsigned int stop_flags;
-    virQEMUDriverConfigPtr cfg;
+    virQEMUDriverConfigPtr cfg = NULL;
     virCapsPtr caps = NULL;
     unsigned int hostdev_flags = 0;
     size_t nnicindexes = 0;
@@ -4516,6 +4596,13 @@ int qemuProcessStart(virConnectPtr conn,
                   VIR_QEMU_PROCESS_START_PAUSED |
                   VIR_QEMU_PROCESS_START_AUTODESTROY, -1);
 
+    if ((rv = qemuProcessInit(driver, vm, !!migrateFrom)) < 0) {
+        if (rv == -2)
+            goto cleanup;
+        else
+            goto error;
+    }
+
     cfg = virQEMUDriverGetConfig(driver);
 
     /* From now on until domain security labeling is done:
@@ -4534,53 +4621,9 @@ int qemuProcessStart(virConnectPtr conn,
     /* We don't increase cfg's reference counter here. */
     hookData.cfg = cfg;
 
-    VIR_DEBUG("Beginning VM startup process");
-
-    if (virDomainObjIsActive(vm)) {
-        virReportError(VIR_ERR_OPERATION_INVALID,
-                       "%s", _("VM is already active"));
-        virObjectUnref(cfg);
-        return -1;
-    }
-
     if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
         goto error;
 
-    /* Some things, paths, ... are generated here and we want them to persist.
-     * Fill them in prior to setting the domain def as transient. */
-    VIR_DEBUG("Generating paths");
-
-    if (qemuPrepareNVRAM(cfg, vm, !!migrateFrom) < 0)
-        goto error;
-
-    /* Do this upfront, so any part of the startup process can add
-     * runtime state to vm->def that won't be persisted. This let's us
-     * report implicit runtime defaults in the XML, like vnc listen/socket
-     */
-    VIR_DEBUG("Setting current domain def as transient");
-    if (virDomainObjSetDefTransient(caps, driver->xmlopt, vm, true) < 0)
-        goto error;
-
-    vm->def->id = qemuDriverAllocateID(driver);
-    qemuDomainSetFakeReboot(driver, vm, false);
-    virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_STARTING_UP);
-
-    if (virAtomicIntInc(&driver->nactive) == 1 && driver->inhibitCallback)
-        driver->inhibitCallback(true, driver->inhibitOpaque);
-
-    /* Run an early hook to set-up missing devices */
-    if (qemuProcessStartHook(driver, vm,
-                             VIR_HOOK_QEMU_OP_PREPARE,
-                             VIR_HOOK_SUBOP_BEGIN) < 0)
-        goto error;
-
-    VIR_DEBUG("Determining emulator version");
-    virObjectUnref(priv->qemuCaps);
-    if (!(priv->qemuCaps = virQEMUCapsCacheLookupCopy(driver->qemuCapsCache,
-                                                      vm->def->emulator,
-                                                      vm->def->os.machine)))
-        goto error;
-
     /* network devices must be "prepared" before hostdevs, because
      * setting up a network device might create a new hostdev that
      * will need to be setup.
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index dcb7e28..3948caf 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -81,6 +81,10 @@ int qemuProcessStart(virConnectPtr conn,
                      virNetDevVPortProfileOp vmop,
                      unsigned int flags);
 
+int qemuProcessInit(virQEMUDriverPtr driver,
+                    virDomainObjPtr vm,
+                    bool migration);
+
 typedef enum {
     VIR_QEMU_PROCESS_STOP_MIGRATED      = 1 << 0,
     VIR_QEMU_PROCESS_STOP_NO_RELABEL    = 1 << 1,
-- 
2.6.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to