Once qemuProcessInit was called, qemuProcessLaunch will launch a new
QEMU process with stopped virtual CPUs.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_process.c | 162 ++++++++++++++++++++++++++++++++----------------
src/qemu/qemu_process.h | 9 +++
2 files changed, 118 insertions(+), 53 deletions(-)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5735935..0314c4a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -4538,16 +4538,20 @@ qemuProcessInit(virQEMUDriverPtr driver,
}
-int qemuProcessStart(virConnectPtr conn,
- virQEMUDriverPtr driver,
- virDomainObjPtr vm,
- qemuDomainAsyncJob asyncJob,
- const char *migrateFrom,
- int migrateFd,
- const char *migratePath,
- virDomainSnapshotObjPtr snapshot,
- virNetDevVPortProfileOp vmop,
- unsigned int flags)
+/**
+ * qemuProcessLaunch:
+ *
+ * Launch a new QEMU process with stopped virtual CPUs.
+ */
+int
+qemuProcessLaunch(virConnectPtr conn,
+ virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob,
+ qemuProcessIncomingDefPtr incoming,
+ virDomainSnapshotObjPtr snapshot,
+ virNetDevVPortProfileOp vmop,
+ unsigned int flags)
{
int ret = -1;
int rv;
@@ -4560,17 +4564,22 @@ int qemuProcessStart(virConnectPtr conn,
size_t i;
char *nodeset = NULL;
unsigned int stop_flags;
- virQEMUDriverConfigPtr cfg = NULL;
+ virQEMUDriverConfigPtr cfg;
virCapsPtr caps = NULL;
unsigned int hostdev_flags = 0;
size_t nnicindexes = 0;
int *nicindexes = NULL;
- qemuProcessIncomingDefPtr incoming = NULL;
- VIR_DEBUG("vm=%p name=%s id=%d asyncJob=%d migrateFrom=%s migrateFd=%d "
- "migratePath=%s snapshot=%p vmop=%d flags=0x%x",
- vm, vm->def->name, vm->def->id, asyncJob,
NULLSTR(migrateFrom),
- migrateFd, NULLSTR(migratePath), snapshot, vmop, flags);
+ VIR_DEBUG("vm=%p name=%s id=%d asyncJob=%d "
+ "incoming.launchURI=%s incoming.deferredURI=%s "
+ "incoming.fd=%d incoming.path=%s "
+ "snapshot=%p vmop=%d flags=0x%x",
+ vm, vm->def->name, vm->def->id, asyncJob,
+ NULLSTR(incoming ? incoming->launchURI : NULL),
+ NULLSTR(incoming ? incoming->deferredURI : NULL),
+ incoming ? incoming->fd : -1,
+ NULLSTR(incoming ? incoming->path : NULL),
+ snapshot, vmop, flags);
/* Okay, these are just internal flags,
* but doesn't hurt to check */
@@ -4578,9 +4587,6 @@ int qemuProcessStart(virConnectPtr conn,
VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_AUTODESTROY, -1);
- if (qemuProcessInit(driver, vm, !!migrateFrom) < 0)
- goto error;
-
cfg = virQEMUDriverGetConfig(driver);
/* From now on until domain security labeling is done:
@@ -4590,7 +4596,7 @@ int qemuProcessStart(virConnectPtr conn,
stop_flags = VIR_QEMU_PROCESS_STOP_NO_RELABEL;
/* If we fail while doing incoming migration, then we must not
* relabel, as the source is still using the files. */
- if (migrateFrom)
+ if (incoming)
stop_flags |= VIR_QEMU_PROCESS_STOP_MIGRATED;
hookData.conn = conn;
@@ -4614,7 +4620,7 @@ int qemuProcessStart(virConnectPtr conn,
VIR_DEBUG("Preparing host devices");
if (!cfg->relaxedACS)
hostdev_flags |= VIR_HOSTDEV_STRICT_ACS_CHECK;
- if (!migrateFrom)
+ if (!incoming)
hostdev_flags |= VIR_HOSTDEV_COLD_BOOT;
if (qemuHostdevPrepareDomainDevices(driver, vm->def, priv->qemuCaps,
hostdev_flags) < 0)
@@ -4715,7 +4721,7 @@ int qemuProcessStart(virConnectPtr conn,
goto error;
}
- if (!migrateFrom && !snapshot &&
+ if (!incoming && !snapshot &&
virDomainDefCheckDuplicateDiskInfo(vm->def) < 0)
goto error;
@@ -4778,13 +4784,6 @@ int qemuProcessStart(virConnectPtr conn,
goto error;
}
- if (migrateFrom) {
- incoming = qemuProcessIncomingDefNew(priv->qemuCaps, migrateFrom,
- migrateFd, migratePath);
- if (!incoming)
- goto error;
- }
-
VIR_DEBUG("Building emulator command line");
if (!(cmd = qemuBuildCommandLine(conn, driver, vm->def, priv->monConfig,
priv->monJSON, priv->qemuCaps,
@@ -4888,8 +4887,9 @@ int qemuProcessStart(virConnectPtr conn,
goto error;
VIR_DEBUG("Setting domain security labels");
- if (virSecurityManagerSetAllLabel(driver->securityManager,
- vm->def, migratePath) < 0)
+ if (incoming &&
+ virSecurityManagerSetAllLabel(driver->securityManager,
+ vm->def, incoming->path) < 0)
goto error;
/* Security manager labeled all devices, therefore
@@ -4898,7 +4898,7 @@ int qemuProcessStart(virConnectPtr conn,
* (hidden under qemuProcessStop) we need to restore labels. */
stop_flags &= ~VIR_QEMU_PROCESS_STOP_NO_RELABEL;
- if (migrateFd != -1) {
+ if (incoming && incoming->fd != -1) {
/* if there's an fd to migrate from, and it's a pipe, put the
* proper security label on it
*/
@@ -4906,13 +4906,14 @@ int qemuProcessStart(virConnectPtr conn,
VIR_DEBUG("setting security label on pipe used for migration");
- if (fstat(migrateFd, &stdin_sb) < 0) {
+ if (fstat(incoming->fd, &stdin_sb) < 0) {
virReportSystemError(errno,
- _("cannot stat fd %d"), migrateFd);
+ _("cannot stat fd %d"), incoming->fd);
goto error;
}
if (S_ISFIFO(stdin_sb.st_mode) &&
- virSecurityManagerSetImageFDLabel(driver->securityManager, vm->def,
migrateFd) < 0)
+ virSecurityManagerSetImageFDLabel(driver->securityManager,
+ vm->def, incoming->fd) < 0)
goto error;
}
@@ -5028,6 +5029,73 @@ int qemuProcessStart(virConnectPtr conn,
if (qemuProcessUpdateVideoRamSize(driver, vm, asyncJob) < 0)
goto error;
+ if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
+ qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
+ goto error;
+
+ ret = 0;
+
+ cleanup:
+ virCommandFree(cmd);
+ VIR_FORCE_CLOSE(logfile);
+ virObjectUnref(cfg);
+ virObjectUnref(caps);
+ VIR_FREE(nicindexes);
+ VIR_FREE(nodeset);
+ return ret;
+
+ error:
+ /* We jump here if we failed to start the VM for any reason, or
+ * if we failed to initialize the now running VM. kill it off and
+ * pretend we never started it */
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
+ goto cleanup;
+}
+
+
+int
+qemuProcessStart(virConnectPtr conn,
+ virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob,
+ const char *migrateFrom,
+ int migrateFd,
+ const char *migratePath,
+ virDomainSnapshotObjPtr snapshot,
+ virNetDevVPortProfileOp vmop,
+ unsigned int flags)
+{
+ virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+ qemuProcessIncomingDefPtr incoming = NULL;
+ int ret = -1;
+
+ VIR_DEBUG("conn=%p driver=%p vm=%p name=%s id=%d asyncJob=%s "
+ "migrateFrom=%s migrateFd=%d migratePath=%s "
+ "snapshot=%p vmop=%d flags=0x%x",
+ conn, driver, vm, vm->def->name, vm->def->id,
+ qemuDomainAsyncJobTypeToString(asyncJob),
+ NULLSTR(migrateFrom), migrateFd, NULLSTR(migratePath),
+ snapshot, vmop, flags);
+
+ virCheckFlagsGoto(VIR_QEMU_PROCESS_START_COLD |
+ VIR_QEMU_PROCESS_START_PAUSED |
+ VIR_QEMU_PROCESS_START_AUTODESTROY, cleanup);
+
+ if (qemuProcessInit(driver, vm, !!migrateFrom) < 0)
+ goto error;
+
+ if (migrateFrom) {
+ incoming = qemuProcessIncomingDefNew(priv->qemuCaps, migrateFrom,
+ migrateFd, migratePath);
+ if (!incoming)
+ goto error;
+ }
+
+ if (qemuProcessLaunch(conn, driver, vm, asyncJob, incoming,
+ snapshot, vmop, flags) < 0)
+ goto error;
+
if (incoming &&
incoming->deferredURI &&
qemuMigrationRunIncoming(driver, vm, incoming->deferredURI, asyncJob) < 0)
@@ -5051,20 +5119,15 @@ int qemuProcessStart(virConnectPtr conn,
VIR_DOMAIN_PAUSED_USER);
}
- if (flags & VIR_QEMU_PROCESS_START_AUTODESTROY &&
- qemuProcessAutoDestroyAdd(driver, vm, conn) < 0)
- goto error;
-
- VIR_DEBUG("Writing domain status to disk");
- if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
- goto error;
-
- /* finally we can call the 'started' hook script if any */
if (qemuProcessStartHook(driver, vm,
VIR_HOOK_QEMU_OP_STARTED,
VIR_HOOK_SUBOP_BEGIN) < 0)
goto error;
+ VIR_DEBUG("Writing domain status to disk");
+ if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm) < 0)
+ goto error;
+
/* Keep watching qemu log for errors during incoming migration, otherwise
* unset reporting errors from qemu log. */
if (!incoming)
@@ -5073,20 +5136,13 @@ int qemuProcessStart(virConnectPtr conn,
ret = 0;
cleanup:
- virCommandFree(cmd);
- VIR_FORCE_CLOSE(logfile);
virObjectUnref(cfg);
- virObjectUnref(caps);
- VIR_FREE(nicindexes);
- VIR_FREE(nodeset);
qemuProcessIncomingDefFree(incoming);
return ret;
error:
- /* We jump here if we failed to start the VM for any reason, or
- * if we failed to initialize the now running VM. kill it off and
- * pretend we never started it */
- qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED, stop_flags);
+ qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_FAILED,
+ incoming ? VIR_QEMU_PROCESS_STOP_MIGRATED : 0);
goto cleanup;
}
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 3948caf..54009c5 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -85,6 +85,15 @@ int qemuProcessInit(virQEMUDriverPtr driver,
virDomainObjPtr vm,
bool migration);
+int qemuProcessLaunch(virConnectPtr conn,
+ virQEMUDriverPtr driver,
+ virDomainObjPtr vm,
+ qemuDomainAsyncJob asyncJob,
+ qemuProcessIncomingDefPtr incoming,
+ virDomainSnapshotObjPtr snapshot,
+ virNetDevVPortProfileOp vmop,
+ unsigned int flags);
+
typedef enum {
VIR_QEMU_PROCESS_STOP_MIGRATED = 1 << 0,
VIR_QEMU_PROCESS_STOP_NO_RELABEL = 1 << 1,
--
2.6.3