We only started an async job for incoming migration from another host.
When we were starting a domain from scratch or restoring from a saved
state (migration from file) we didn't set any async job. Let's introduce
a new QEMU_ASYNC_JOB_START for these cases.
Signed-off-by: Jiri Denemark <jdenemar(a)redhat.com>
---
src/qemu/qemu_domain.c | 3 +++
src/qemu/qemu_domain.h | 1 +
src/qemu/qemu_driver.c | 72 +++++++++++++++++++++++++++----------------------
src/qemu/qemu_process.c | 30 ++++++++++++++++++++-
src/qemu/qemu_process.h | 7 ++++-
5 files changed, 79 insertions(+), 34 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3d2b7a0..4aebd90 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -73,6 +73,7 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob, QEMU_ASYNC_JOB_LAST,
"save",
"dump",
"snapshot",
+ "start",
);
@@ -88,6 +89,7 @@ qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job,
case QEMU_ASYNC_JOB_SAVE:
case QEMU_ASYNC_JOB_DUMP:
case QEMU_ASYNC_JOB_SNAPSHOT:
+ case QEMU_ASYNC_JOB_START:
case QEMU_ASYNC_JOB_NONE:
case QEMU_ASYNC_JOB_LAST:
; /* fall through */
@@ -111,6 +113,7 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job,
case QEMU_ASYNC_JOB_SAVE:
case QEMU_ASYNC_JOB_DUMP:
case QEMU_ASYNC_JOB_SNAPSHOT:
+ case QEMU_ASYNC_JOB_START:
case QEMU_ASYNC_JOB_NONE:
case QEMU_ASYNC_JOB_LAST:
; /* fall through */
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 4be998c..4ef25e2 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -90,6 +90,7 @@ typedef enum {
QEMU_ASYNC_JOB_SAVE,
QEMU_ASYNC_JOB_DUMP,
QEMU_ASYNC_JOB_SNAPSHOT,
+ QEMU_ASYNC_JOB_START,
QEMU_ASYNC_JOB_LAST
} qemuDomainAsyncJob;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 42f76fa..65ccf99 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -155,7 +155,8 @@ static int qemuStateCleanup(void);
static int qemuDomainObjStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
- unsigned int flags);
+ unsigned int flags,
+ qemuDomainAsyncJob asyncJob);
static int qemuDomainGetMaxVcpus(virDomainPtr dom);
@@ -287,8 +288,7 @@ qemuAutostartDomain(virDomainObjPtr vm,
virResetLastError();
if (vm->autostart &&
!virDomainObjIsActive(vm)) {
- if (qemuDomainObjBeginJob(data->driver, vm,
- QEMU_JOB_MODIFY) < 0) {
+ if (qemuProcessBeginJob(data->driver, vm) < 0) {
err = virGetLastError();
VIR_ERROR(_("Failed to start job on VM '%s': %s"),
vm->def->name,
@@ -296,14 +296,15 @@ qemuAutostartDomain(virDomainObjPtr vm,
goto cleanup;
}
- if (qemuDomainObjStart(data->conn, data->driver, vm, flags) < 0) {
+ if (qemuDomainObjStart(data->conn, data->driver, vm, flags,
+ QEMU_ASYNC_JOB_START) < 0) {
err = virGetLastError();
VIR_ERROR(_("Failed to autostart VM '%s': %s"),
vm->def->name,
err ? err->message : _("unknown error"));
}
- qemuDomainObjEndJob(data->driver, vm);
+ qemuProcessEndJob(data->driver, vm);
}
ret = 0;
@@ -1754,17 +1755,17 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
virObjectRef(vm);
def = NULL;
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0) {
+ if (qemuProcessBeginJob(driver, vm) < 0) {
qemuDomainRemoveInactive(driver, vm);
goto cleanup;
}
- if (qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_NONE,
+ if (qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_START,
NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags) < 0) {
virDomainAuditStart(vm, "booted", false);
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
qemuDomainRemoveInactive(driver, vm);
goto cleanup;
}
@@ -1788,7 +1789,7 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
if (dom)
dom->id = vm->def->id;
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
cleanup:
virDomainDefFree(def);
@@ -6634,7 +6635,8 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
int *fd,
const virQEMUSaveHeader *header,
const char *path,
- bool start_paused)
+ bool start_paused,
+ qemuDomainAsyncJob asyncJob)
{
int ret = -1;
virObjectEventPtr event;
@@ -6663,7 +6665,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
}
/* Set the migration source and start it up. */
- ret = qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_NONE,
+ ret = qemuProcessStart(conn, driver, vm, asyncJob,
"stdio", *fd, path, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
VIR_QEMU_PROCESS_START_PAUSED);
@@ -6707,7 +6709,7 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
if (header->was_running && !start_paused) {
if (qemuProcessStartCPUs(driver, vm, conn,
VIR_DOMAIN_RUNNING_RESTORED,
- QEMU_ASYNC_JOB_NONE) < 0) {
+ asyncJob) < 0) {
if (virGetLastError() == NULL)
virReportError(VIR_ERR_OPERATION_FAILED,
"%s", _("failed to resume domain"));
@@ -6819,15 +6821,15 @@ qemuDomainRestoreFlags(virConnectPtr conn,
priv->hookRun = true;
}
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ if (qemuProcessBeginJob(driver, vm) < 0)
goto cleanup;
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
- false);
+ false, QEMU_ASYNC_JOB_START);
if (virFileWrapperFdClose(wrapperFd) < 0)
VIR_WARN("Failed to close %s", path);
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
cleanup:
virDomainDefFree(def);
@@ -6970,7 +6972,8 @@ qemuDomainObjRestore(virConnectPtr conn,
virDomainObjPtr vm,
const char *path,
bool start_paused,
- bool bypass_cache)
+ bool bypass_cache,
+ qemuDomainAsyncJob asyncJob)
{
virDomainDefPtr def = NULL;
qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -7030,7 +7033,7 @@ qemuDomainObjRestore(virConnectPtr conn,
def = NULL;
ret = qemuDomainSaveImageStartVM(conn, driver, vm, &fd, &header, path,
- start_paused);
+ start_paused, asyncJob);
if (virFileWrapperFdClose(wrapperFd) < 0)
VIR_WARN("Failed to close %s", path);
@@ -7325,7 +7328,8 @@ static int
qemuDomainObjStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
- unsigned int flags)
+ unsigned int flags,
+ qemuDomainAsyncJob asyncJob)
{
int ret = -1;
char *managed_save;
@@ -7358,7 +7362,7 @@ qemuDomainObjStart(virConnectPtr conn,
vm->hasManagedSave = false;
} else {
ret = qemuDomainObjRestore(conn, driver, vm, managed_save,
- start_paused, bypass_cache);
+ start_paused, bypass_cache, asyncJob);
if (ret == 0) {
if (unlink(managed_save) < 0)
@@ -7377,7 +7381,7 @@ qemuDomainObjStart(virConnectPtr conn,
}
}
- ret = qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_NONE,
+ ret = qemuProcessStart(conn, driver, vm, asyncJob,
NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags);
virDomainAuditStart(vm, "booted", ret >= 0);
@@ -7422,7 +7426,7 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
if (virDomainCreateWithFlagsEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ if (qemuProcessBeginJob(driver, vm) < 0)
goto cleanup;
if (virDomainObjIsActive(vm)) {
@@ -7431,13 +7435,14 @@ qemuDomainCreateWithFlags(virDomainPtr dom, unsigned int flags)
goto endjob;
}
- if (qemuDomainObjStart(dom->conn, driver, vm, flags) < 0)
+ if (qemuDomainObjStart(dom->conn, driver, vm, flags,
+ QEMU_ASYNC_JOB_START) < 0)
goto endjob;
ret = 0;
endjob:
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
cleanup:
virDomainObjEndAPI(&vm);
@@ -15334,7 +15339,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto cleanup;
}
- if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
+ if (qemuProcessBeginJob(driver, vm) < 0)
goto cleanup;
if (!(snap = qemuSnapObjFromSnapshot(vm, snapshot)))
@@ -15439,7 +15444,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
was_running = true;
if (qemuProcessStopCPUs(driver, vm,
VIR_DOMAIN_PAUSED_FROM_SNAPSHOT,
- QEMU_ASYNC_JOB_NONE) < 0)
+ QEMU_ASYNC_JOB_START) < 0)
goto endjob;
/* Create an event now in case the restore fails, so
* that user will be alerted that they are now paused.
@@ -15454,7 +15459,10 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
goto endjob;
}
}
- qemuDomainObjEnterMonitor(driver, vm);
+
+ if (qemuDomainObjEnterMonitorAsync(driver, vm,
+ QEMU_ASYNC_JOB_START) < 0)
+ goto endjob;
rc = qemuMonitorLoadSnapshot(priv->mon, snap->def->name);
if (qemuDomainObjExitMonitor(driver, vm) < 0)
goto endjob;
@@ -15473,7 +15481,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
virDomainObjAssignDef(vm, config, false, NULL);
rc = qemuProcessStart(snapshot->domain->conn, driver, vm,
- QEMU_ASYNC_JOB_NONE, NULL, -1, NULL, snap,
+ QEMU_ASYNC_JOB_START, NULL, -1, NULL, snap,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
VIR_QEMU_PROCESS_START_PAUSED);
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
@@ -15508,7 +15516,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
}
rc = qemuProcessStartCPUs(driver, vm, snapshot->domain->conn,
VIR_DOMAIN_RUNNING_FROM_SNAPSHOT,
- QEMU_ASYNC_JOB_NONE);
+ QEMU_ASYNC_JOB_START);
if (rc < 0)
goto endjob;
virObjectUnref(event);
@@ -15549,7 +15557,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
}
if (qemuDomainSnapshotRevertInactive(driver, vm, snap) < 0) {
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
qemuDomainRemoveInactive(driver, vm);
goto cleanup;
}
@@ -15566,12 +15574,12 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
qemuDomainEventQueue(driver, event);
rc = qemuProcessStart(snapshot->domain->conn, driver, vm,
- QEMU_ASYNC_JOB_NONE, NULL, -1, NULL, NULL,
+ QEMU_ASYNC_JOB_START, NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags);
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
if (rc < 0) {
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
qemuDomainRemoveInactive(driver, vm);
goto cleanup;
}
@@ -15607,7 +15615,7 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
ret = 0;
endjob:
- qemuDomainObjEndJob(driver, vm);
+ qemuProcessEndJob(driver, vm);
cleanup:
if (ret == 0) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 638ad02..f85e876 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3412,6 +3412,10 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
}
break;
+ case QEMU_ASYNC_JOB_START:
+ /* Already handled in VIR_DOMAIN_PAUSED_STARTING_UP check. */
+ break;
+
case QEMU_ASYNC_JOB_NONE:
case QEMU_ASYNC_JOB_LAST:
break;
@@ -4197,10 +4201,34 @@ qemuProcessIncomingDefNew(virQEMUCapsPtr qemuCaps,
}
+int
+qemuProcessBeginJob(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjPrivatePtr priv = vm->privateData;
+
+ if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_START) < 0)
+ return -1;
+
+ qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
+ priv->job.current->type = VIR_DOMAIN_JOB_UNBOUNDED;
+
+ return 0;
+}
+
+
+void
+qemuProcessEndJob(virQEMUDriverPtr driver,
+ virDomainObjPtr vm)
+{
+ qemuDomainObjEndAsyncJob(driver, vm);
+}
+
+
int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
- int asyncJob,
+ qemuDomainAsyncJob asyncJob,
const char *migrateFrom,
int stdin_fd,
const char *stdin_path,
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 7eee2b2..dcba728 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -58,6 +58,11 @@ qemuProcessIncomingDefPtr qemuProcessIncomingDefNew(virQEMUCapsPtr
qemuCaps,
const char *path);
void qemuProcessIncomingDefFree(qemuProcessIncomingDefPtr inc);
+int qemuProcessBeginJob(virQEMUDriverPtr driver,
+ virDomainObjPtr vm);
+void qemuProcessEndJob(virQEMUDriverPtr driver,
+ virDomainObjPtr vm);
+
typedef enum {
VIR_QEMU_PROCESS_START_COLD = 1 << 0,
VIR_QEMU_PROCESS_START_PAUSED = 1 << 1,
@@ -67,7 +72,7 @@ typedef enum {
int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
- int asyncJob,
+ qemuDomainAsyncJob asyncJob,
const char *migrateFrom,
int stdin_fd,
const char *stdin_path,
--
2.6.3