https://bugzilla.redhat.com/show_bug.cgi?id=589465
Some guests (eg with badly configured grub, or Windows' installation cd)
require quick response from the console user. That's why we have a
"launchPaused" option in vdsm.
To implement it via libvirt, we need to ask libvirt not to call
qemuMonitorStartCPUs() after starting qemu. Calling virDomainStop
immediately after the domain is up is inherently raceful.
* src/qemu/qemu_driver.c (qemudStartVMDaemon): Add new parameter;
all callers adjusted.
(qemudDomainCreate): Implement support for new flag.
---
src/qemu/qemu_driver.c | 26 +++++++++++++++++---------
1 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 11bd2c2..9e5872e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -154,6 +154,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
struct qemud_driver *driver,
virDomainObjPtr vm,
const char *migrateFrom,
+ bool start_paused,
int stdin_fd,
const char *stdin_path);
@@ -3302,6 +3303,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
struct qemud_driver *driver,
virDomainObjPtr vm,
const char *migrateFrom,
+ bool start_paused,
int stdin_fd,
const char *stdin_path) {
const char **argv = NULL, **tmp;
@@ -3553,7 +3555,9 @@ static int qemudStartVMDaemon(virConnectPtr conn,
ret = 0;
}
- vm->state = migrateFrom ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
+ if (migrateFrom)
+ start_paused = true;
+ vm->state = start_paused ? VIR_DOMAIN_PAUSED : VIR_DOMAIN_RUNNING;
for (i = 0 ; argv[i] ; i++)
VIR_FREE(argv[i]);
@@ -3603,7 +3607,7 @@ static int qemudStartVMDaemon(virConnectPtr conn,
goto cleanup;
}
- if (migrateFrom == NULL) {
+ if (!start_paused) {
DEBUG0("Starting domain CPUs");
/* Allow the CPUS to start executing */
if (qemuMonitorStartCPUs(priv->mon, conn) < 0) {
@@ -4188,7 +4192,7 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char
*xml,
virDomainPtr dom = NULL;
virDomainEventPtr event = NULL;
- virCheckFlags(0, NULL);
+ virCheckFlags(VIR_DOMAIN_START_PAUSED, NULL);
qemuDriverLock(driver);
if (!(def = virDomainDefParseString(driver->caps, xml,
@@ -4217,7 +4221,9 @@ static virDomainPtr qemudDomainCreate(virConnectPtr conn, const char
*xml,
if (qemuDomainObjBeginJobWithDriver(driver, vm) < 0)
goto cleanup; /* XXXX free the 'vm' we created ? */
- if (qemudStartVMDaemon(conn, driver, vm, NULL, -1, NULL) < 0) {
+ if (qemudStartVMDaemon(conn, driver, vm, NULL,
+ (flags & VIR_DOMAIN_START_PAUSED) != 0,
+ -1, NULL) < 0) {
if (qemuDomainObjEndJob(vm) > 0)
virDomainRemoveInactive(&driver->domains,
vm);
@@ -6233,7 +6239,7 @@ qemudDomainSaveImageStartVM(virConnectPtr conn,
}
/* Set the migration source and start it up. */
- ret = qemudStartVMDaemon(conn, driver, vm, "stdio", fd, path);
+ ret = qemudStartVMDaemon(conn, driver, vm, "stdio", true, fd, path);
if (intermediate_pid != -1) {
/* Wait for intermediate process to exit */
@@ -6692,7 +6698,7 @@ static int qemudDomainObjStart(virConnectPtr conn,
goto cleanup;
}
- ret = qemudStartVMDaemon(conn, driver, vm, NULL, -1, NULL);
+ ret = qemudStartVMDaemon(conn, driver, vm, NULL, false, -1, NULL);
if (ret != -1) {
virDomainEventPtr event =
virDomainEventNewFromObj(vm,
@@ -10185,7 +10191,8 @@ qemudDomainMigratePrepareTunnel(virConnectPtr dconn,
/* Start the QEMU daemon, with the same command-line arguments plus
* -incoming unix:/path/to/file or exec:nc -U /path/to/file
*/
- internalret = qemudStartVMDaemon(dconn, driver, vm, migrateFrom, -1, NULL);
+ internalret = qemudStartVMDaemon(dconn, driver, vm, migrateFrom, true,
+ -1, NULL);
VIR_FREE(migrateFrom);
if (internalret < 0) {
/* Note that we don't set an error here because qemudStartVMDaemon
@@ -10403,7 +10410,8 @@ qemudDomainMigratePrepare2 (virConnectPtr dconn,
* -incoming tcp:0.0.0.0:port
*/
snprintf (migrateFrom, sizeof (migrateFrom), "tcp:0.0.0.0:%d", this_port);
- if (qemudStartVMDaemon (dconn, driver, vm, migrateFrom, -1, NULL) < 0) {
+ if (qemudStartVMDaemon (dconn, driver, vm, migrateFrom, true,
+ -1, NULL) < 0) {
/* Note that we don't set an error here because qemudStartVMDaemon
* should have already done that.
*/
@@ -11891,7 +11899,7 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr
snapshot,
goto endjob;
rc = qemudStartVMDaemon(snapshot->domain->conn, driver, vm, NULL,
- -1, NULL);
+ false, -1, NULL);
if (qemuDomainSnapshotSetInactive(vm, driver->snapshotDir) < 0)
goto endjob;
if (rc < 0)
--
1.7.0.1