|
|
7a3408 |
From c08ee284b60c8c52faba6b0b4586fc9fdf018ddb Mon Sep 17 00:00:00 2001
|
|
|
7a3408 |
Message-Id: <c08ee284b60c8c52faba6b0b4586fc9fdf018ddb@dist-git>
|
|
|
7a3408 |
From: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
Date: Fri, 29 May 2015 08:38:44 +0200
|
|
|
7a3408 |
Subject: [PATCH] qemu: Wait for migration events on domain condition
|
|
|
7a3408 |
|
|
|
7a3408 |
Since we already support the MIGRATION event, we just need to make sure
|
|
|
7a3408 |
the domain condition is signalled whenever a p2p connection drops or the
|
|
|
7a3408 |
domain is paused due to IO error and we can avoid waking up every 50 ms
|
|
|
7a3408 |
to check whether something happened.
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
(cherry picked from commit 3409f5bc4e0ea870982f4eee3bb6f97fe9f9f883)
|
|
|
7a3408 |
|
|
|
7a3408 |
https://bugzilla.redhat.com/show_bug.cgi?id=1212077
|
|
|
7a3408 |
|
|
|
7a3408 |
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
|
|
|
7a3408 |
---
|
|
|
7a3408 |
src/qemu/qemu_domain.h | 3 +++
|
|
|
7a3408 |
src/qemu/qemu_migration.c | 45 +++++++++++++++++++++++++++++++++++++++------
|
|
|
7a3408 |
src/qemu/qemu_process.c | 3 +++
|
|
|
7a3408 |
3 files changed, 45 insertions(+), 6 deletions(-)
|
|
|
7a3408 |
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
|
|
|
7a3408 |
index 66dbcf5..2af7c59 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_domain.h
|
|
|
7a3408 |
+++ b/src/qemu/qemu_domain.h
|
|
|
7a3408 |
@@ -199,6 +199,9 @@ struct _qemuDomainObjPrivate {
|
|
|
7a3408 |
/* Bitmaps below hold data from the auto NUMA feature */
|
|
|
7a3408 |
virBitmapPtr autoNodeset;
|
|
|
7a3408 |
virBitmapPtr autoCpuset;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ bool signalIOError; /* true if the domain condition should be signalled on
|
|
|
7a3408 |
+ I/O error */
|
|
|
7a3408 |
};
|
|
|
7a3408 |
|
|
|
7a3408 |
# define QEMU_DOMAIN_DISK_PRIVATE(disk) \
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
|
|
7a3408 |
index 9a50923..7257182 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_migration.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_migration.c
|
|
|
7a3408 |
@@ -2661,20 +2661,28 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
|
|
|
7a3408 |
{
|
|
|
7a3408 |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
7a3408 |
qemuDomainJobInfoPtr jobInfo = priv->job.current;
|
|
|
7a3408 |
+ bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
|
|
|
7a3408 |
int rv;
|
|
|
7a3408 |
|
|
|
7a3408 |
jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
|
|
|
7a3408 |
while ((rv = qemuMigrationCompleted(driver, vm, asyncJob, dconn,
|
|
|
7a3408 |
abort_on_error, storage)) != 1) {
|
|
|
7a3408 |
- /* Poll every 50ms for progress & to allow cancellation */
|
|
|
7a3408 |
- struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
|
|
|
7a3408 |
-
|
|
|
7a3408 |
if (rv < 0)
|
|
|
7a3408 |
return rv;
|
|
|
7a3408 |
|
|
|
7a3408 |
- virObjectUnlock(vm);
|
|
|
7a3408 |
- nanosleep(&ts, NULL);
|
|
|
7a3408 |
- virObjectLock(vm);
|
|
|
7a3408 |
+ if (events) {
|
|
|
7a3408 |
+ if (virDomainObjWait(vm) < 0) {
|
|
|
7a3408 |
+ jobInfo->type = VIR_DOMAIN_JOB_FAILED;
|
|
|
7a3408 |
+ return -2;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+ } else {
|
|
|
7a3408 |
+ /* Poll every 50ms for progress & to allow cancellation */
|
|
|
7a3408 |
+ struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ virObjectUnlock(vm);
|
|
|
7a3408 |
+ nanosleep(&ts, NULL);
|
|
|
7a3408 |
+ virObjectLock(vm);
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
qemuDomainJobInfoUpdateDowntime(jobInfo);
|
|
|
7a3408 |
@@ -4148,6 +4156,7 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|
|
7a3408 |
virErrorPtr orig_err = NULL;
|
|
|
7a3408 |
unsigned int cookieFlags = 0;
|
|
|
7a3408 |
bool abort_on_error = !!(flags & VIR_MIGRATE_ABORT_ON_ERROR);
|
|
|
7a3408 |
+ bool events = virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MIGRATION_EVENT);
|
|
|
7a3408 |
int rc;
|
|
|
7a3408 |
|
|
|
7a3408 |
VIR_DEBUG("driver=%p, vm=%p, cookiein=%s, cookieinlen=%d, "
|
|
|
7a3408 |
@@ -4178,6 +4187,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|
|
7a3408 |
return -1;
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (events)
|
|
|
7a3408 |
+ priv->signalIOError = abort_on_error;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
mig = qemuMigrationEatCookie(driver, vm, cookiein, cookieinlen,
|
|
|
7a3408 |
cookieFlags | QEMU_MIGRATION_COOKIE_GRAPHICS);
|
|
|
7a3408 |
if (!mig)
|
|
|
7a3408 |
@@ -4387,6 +4399,9 @@ qemuMigrationRun(virQEMUDriverPtr driver,
|
|
|
7a3408 |
|
|
|
7a3408 |
qemuMigrationCookieFree(mig);
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (events)
|
|
|
7a3408 |
+ priv->signalIOError = false;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
if (orig_err) {
|
|
|
7a3408 |
virSetError(orig_err);
|
|
|
7a3408 |
virFreeError(orig_err);
|
|
|
7a3408 |
@@ -5029,6 +5044,18 @@ doPeer2PeerMigrate3(virQEMUDriverPtr driver,
|
|
|
7a3408 |
}
|
|
|
7a3408 |
|
|
|
7a3408 |
|
|
|
7a3408 |
+static void
|
|
|
7a3408 |
+qemuMigrationConnectionClosed(virConnectPtr conn,
|
|
|
7a3408 |
+ int reason,
|
|
|
7a3408 |
+ void *opaque)
|
|
|
7a3408 |
+{
|
|
|
7a3408 |
+ virDomainObjPtr vm = opaque;
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+ VIR_DEBUG("conn=%p, reason=%d, vm=%s", conn, reason, vm->def->name);
|
|
|
7a3408 |
+ virDomainObjBroadcast(vm);
|
|
|
7a3408 |
+}
|
|
|
7a3408 |
+
|
|
|
7a3408 |
+
|
|
|
7a3408 |
static int virConnectCredType[] = {
|
|
|
7a3408 |
VIR_CRED_AUTHNAME,
|
|
|
7a3408 |
VIR_CRED_PASSPHRASE,
|
|
|
7a3408 |
@@ -5104,6 +5131,11 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
|
|
|
7a3408 |
cfg->keepAliveCount) < 0)
|
|
|
7a3408 |
goto cleanup;
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (virConnectRegisterCloseCallback(dconn, qemuMigrationConnectionClosed,
|
|
|
7a3408 |
+ vm, NULL) < 0) {
|
|
|
7a3408 |
+ goto cleanup;
|
|
|
7a3408 |
+ }
|
|
|
7a3408 |
+
|
|
|
7a3408 |
qemuDomainObjEnterRemote(vm);
|
|
|
7a3408 |
p2p = VIR_DRV_SUPPORTS_FEATURE(dconn->driver, dconn,
|
|
|
7a3408 |
VIR_DRV_FEATURE_MIGRATION_P2P);
|
|
|
7a3408 |
@@ -5169,6 +5201,7 @@ static int doPeer2PeerMigrate(virQEMUDriverPtr driver,
|
|
|
7a3408 |
cleanup:
|
|
|
7a3408 |
orig_err = virSaveLastError();
|
|
|
7a3408 |
qemuDomainObjEnterRemote(vm);
|
|
|
7a3408 |
+ virConnectUnregisterCloseCallback(dconn, qemuMigrationConnectionClosed);
|
|
|
7a3408 |
virObjectUnref(dconn);
|
|
|
7a3408 |
qemuDomainObjExitRemote(vm);
|
|
|
7a3408 |
if (orig_err) {
|
|
|
7a3408 |
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
|
|
7a3408 |
index 577f309..7abeaae 100644
|
|
|
7a3408 |
--- a/src/qemu/qemu_process.c
|
|
|
7a3408 |
+++ b/src/qemu/qemu_process.c
|
|
|
7a3408 |
@@ -952,6 +952,9 @@ qemuProcessHandleIOError(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
|
|
|
7a3408 |
qemuDomainObjPrivatePtr priv = vm->privateData;
|
|
|
7a3408 |
VIR_DEBUG("Transitioned guest %s to paused state due to IO error", vm->def->name);
|
|
|
7a3408 |
|
|
|
7a3408 |
+ if (priv->signalIOError)
|
|
|
7a3408 |
+ virDomainObjBroadcast(vm);
|
|
|
7a3408 |
+
|
|
|
7a3408 |
virDomainObjSetState(vm, VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_IOERROR);
|
|
|
7a3408 |
lifecycleEvent = virDomainEventLifecycleNewFromObj(vm,
|
|
|
7a3408 |
VIR_DOMAIN_EVENT_SUSPENDED,
|
|
|
7a3408 |
--
|
|
|
7a3408 |
2.4.5
|
|
|
7a3408 |
|