render / rpms / libvirt

Forked from rpms/libvirt 9 months ago
Clone
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