提交 4f061ea6 编写于 作者: J Jiri Denemark

qemu: Avoid dangling migration-in job on shutoff domains

Destination daemon should not rely on the client or source daemon
(depending on the type of migration) to call Finish when migration
fails, because the client may crash before it can do so. The domain
prepared for incoming migration is set to be destroyed (and migration
job cleaned up) when connection with the client closes but this is not
enough. If the associated qemu process crashes after Prepare step and
the domain is cleaned up before the connection gets closed, autodestroy
is not called for the domain and migration jobs remains set. In case the
domain is defined on destination host (i.e., it is not completely
removed once destroyed) we keep the job set for ever. To fix this, we
register a cleanup callback which is responsible to clean migration-in
job when a domain dies anywhere between Prepare and Finish steps. Note
that we can't blindly clean any job when spotting EOF on monitor since
normally an API is running at that time.
上级 bf9f0a97
...@@ -51,7 +51,6 @@ ...@@ -51,7 +51,6 @@
(VIR_DOMAIN_XML_SECURE | \ (VIR_DOMAIN_XML_SECURE | \
VIR_DOMAIN_XML_UPDATE_CPU) VIR_DOMAIN_XML_UPDATE_CPU)
VIR_ENUM_DECL(qemuDomainJob)
VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST, VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST,
"none", "none",
"query", "query",
...@@ -64,7 +63,6 @@ VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST, ...@@ -64,7 +63,6 @@ VIR_ENUM_IMPL(qemuDomainJob, QEMU_JOB_LAST,
"async nested", "async nested",
); );
VIR_ENUM_DECL(qemuDomainAsyncJob)
VIR_ENUM_IMPL(qemuDomainAsyncJob, QEMU_ASYNC_JOB_LAST, VIR_ENUM_IMPL(qemuDomainAsyncJob, QEMU_ASYNC_JOB_LAST,
"none", "none",
"migration out", "migration out",
......
...@@ -71,6 +71,7 @@ enum qemuDomainJob { ...@@ -71,6 +71,7 @@ enum qemuDomainJob {
QEMU_JOB_LAST QEMU_JOB_LAST
}; };
VIR_ENUM_DECL(qemuDomainJob)
/* Async job consists of a series of jobs that may change state. Independent /* Async job consists of a series of jobs that may change state. Independent
* jobs that do not change state (and possibly others if explicitly allowed by * jobs that do not change state (and possibly others if explicitly allowed by
...@@ -85,6 +86,7 @@ enum qemuDomainAsyncJob { ...@@ -85,6 +86,7 @@ enum qemuDomainAsyncJob {
QEMU_ASYNC_JOB_LAST QEMU_ASYNC_JOB_LAST
}; };
VIR_ENUM_DECL(qemuDomainAsyncJob)
struct qemuDomainJobObj { struct qemuDomainJobObj {
virCond cond; /* Use to coordinate jobs */ virCond cond; /* Use to coordinate jobs */
......
...@@ -1107,6 +1107,23 @@ cleanup: ...@@ -1107,6 +1107,23 @@ cleanup:
/* Prepare is the first step, and it runs on the destination host. /* Prepare is the first step, and it runs on the destination host.
*/ */
static void
qemuMigrationPrepareCleanup(struct qemud_driver *driver,
virDomainObjPtr vm)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
VIR_DEBUG("driver=%p, vm=%s, job=%s, asyncJob=%s",
driver,
vm->def->name,
qemuDomainJobTypeToString(priv->job.active),
qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
if (!qemuMigrationJobIsActive(vm, QEMU_ASYNC_JOB_MIGRATION_IN))
return;
qemuDomainObjDiscardAsyncJob(driver, vm);
}
static int static int
qemuMigrationPrepareAny(struct qemud_driver *driver, qemuMigrationPrepareAny(struct qemud_driver *driver,
virConnectPtr dconn, virConnectPtr dconn,
...@@ -1264,6 +1281,9 @@ qemuMigrationPrepareAny(struct qemud_driver *driver, ...@@ -1264,6 +1281,9 @@ qemuMigrationPrepareAny(struct qemud_driver *driver,
VIR_WARN("Unable to encode migration cookie"); VIR_WARN("Unable to encode migration cookie");
} }
if (qemuDomainCleanupAdd(vm, qemuMigrationPrepareCleanup) < 0)
goto endjob;
virDomainAuditStart(vm, "migrated", true); virDomainAuditStart(vm, "migrated", true);
event = virDomainEventNewFromObj(vm, event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STARTED, VIR_DOMAIN_EVENT_STARTED,
...@@ -2703,6 +2723,8 @@ qemuMigrationFinish(struct qemud_driver *driver, ...@@ -2703,6 +2723,8 @@ qemuMigrationFinish(struct qemud_driver *driver,
v3proto ? QEMU_MIGRATION_PHASE_FINISH3 v3proto ? QEMU_MIGRATION_PHASE_FINISH3
: QEMU_MIGRATION_PHASE_FINISH2); : QEMU_MIGRATION_PHASE_FINISH2);
qemuDomainCleanupRemove(vm, qemuMigrationPrepareCleanup);
if (flags & VIR_MIGRATE_PERSIST_DEST) if (flags & VIR_MIGRATE_PERSIST_DEST)
cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT; cookie_flags |= QEMU_MIGRATION_COOKIE_PERSISTENT;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册