QEMU_CAPS_SEAMLESS_MIGRATION capability says QEMU supports
SPICE_MIGRATE_COMPLETED event. Thus we can just drop all code which
polls query-spice and replace it with waiting for the event.

Signed-off-by: Jiri Denemark <jdene...@redhat.com>
---

Notes:
    ACKed in version 2
    
    Version 3:
    - no change
    
    Version 2:
    - new patch

 src/qemu/qemu_domain.c       |  1 +
 src/qemu/qemu_domain.h       |  1 +
 src/qemu/qemu_migration.c    | 38 ++++++++++------------------------
 src/qemu/qemu_monitor.c      | 10 ---------
 src/qemu/qemu_monitor.h      |  2 --
 src/qemu/qemu_monitor_json.c | 49 --------------------------------------------
 src/qemu/qemu_process.c      | 28 +++++++++++++++++++++++++
 tests/qemumonitorjsontest.c  | 40 ------------------------------------
 8 files changed, 41 insertions(+), 128 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 25fa8d3..c9bdf6b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -170,6 +170,7 @@ qemuDomainObjResetAsyncJob(qemuDomainObjPrivatePtr priv)
     job->mask = QEMU_JOB_DEFAULT_MASK;
     job->dump_memory_only = false;
     job->abortJob = false;
+    job->spiceMigrated = false;
     VIR_FREE(job->current);
 }
 
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index a3c5015..54e1e7b 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -136,6 +136,7 @@ struct qemuDomainJobObj {
     qemuDomainJobInfoPtr current;       /* async job progress data */
     qemuDomainJobInfoPtr completed;     /* statistics data of a recently 
completed job */
     bool abortJob;                      /* abort of the job requested */
+    bool spiceMigrated;                 /* spice migration completed */
 };
 
 typedef void (*qemuDomainCleanupCallback)(virQEMUDriverPtr driver,
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index d82a5ba..d5a9dea 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2390,45 +2390,29 @@ qemuMigrationSetPinAll(virQEMUDriverPtr driver,
 }
 
 static int
-qemuMigrationWaitForSpice(virQEMUDriverPtr driver,
-                          virDomainObjPtr vm)
+qemuMigrationWaitForSpice(virDomainObjPtr vm)
 {
     qemuDomainObjPrivatePtr priv = vm->privateData;
     bool wait_for_spice = false;
-    bool spice_migrated = false;
     size_t i = 0;
-    int rc;
 
-    if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION)) {
-        for (i = 0; i < vm->def->ngraphics; i++) {
-            if (vm->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
-                wait_for_spice = true;
-                break;
-            }
+    if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SEAMLESS_MIGRATION))
+        return 0;
+
+    for (i = 0; i < vm->def->ngraphics; i++) {
+        if (vm->def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) {
+            wait_for_spice = true;
+            break;
         }
     }
 
     if (!wait_for_spice)
         return 0;
 
-    while (!spice_migrated) {
-        /* Poll every 50ms for progress & to allow cancellation */
-        struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
-
-        if (qemuDomainObjEnterMonitorAsync(driver, vm,
-                                           QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+    while (!priv->job.spiceMigrated && !priv->job.abortJob) {
+        if (virDomainObjWait(vm) < 0)
             return -1;
-
-        rc = qemuMonitorGetSpiceMigrationStatus(priv->mon, &spice_migrated);
-        if (qemuDomainObjExitMonitor(driver, vm) < 0)
-            return -1;
-        if (rc < 0)
-            return -1;
-        virObjectUnlock(vm);
-        nanosleep(&ts, NULL);
-        virObjectLock(vm);
     }
-
     return 0;
 }
 
@@ -3602,7 +3586,7 @@ qemuMigrationConfirmPhase(virQEMUDriverPtr driver,
     if (retcode == 0) {
         /* If guest uses SPICE and supports seamless migration we have to hold
          * up domain shutdown until SPICE server transfers its data */
-        qemuMigrationWaitForSpice(driver, vm);
+        qemuMigrationWaitForSpice(vm);
 
         qemuProcessStop(driver, vm, VIR_DOMAIN_SHUTOFF_MIGRATED,
                         VIR_QEMU_PROCESS_STOP_MIGRATED);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index b7de846..94b0007 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2117,16 +2117,6 @@ qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
 
 
 int
-qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
-                                   bool *spice_migrated)
-{
-    QEMU_CHECK_MONITOR_JSON(mon);
-
-    return qemuMonitorJSONGetSpiceMigrationStatus(mon, spice_migrated);
-}
-
-
-int
 qemuMonitorMigrateToFd(qemuMonitorPtr mon,
                        unsigned int flags,
                        int fd)
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index a29c505..1afc344 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -498,8 +498,6 @@ struct _qemuMonitorMigrationStatus {
 
 int qemuMonitorGetMigrationStatus(qemuMonitorPtr mon,
                                   qemuMonitorMigrationStatusPtr status);
-int qemuMonitorGetSpiceMigrationStatus(qemuMonitorPtr mon,
-                                       bool *spice_migrated);
 
 typedef enum {
     QEMU_MONITOR_MIGRATION_CAPS_XBZRLE,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 04ae339..0ba549e 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -2684,55 +2684,6 @@ int qemuMonitorJSONGetMigrationStatus(qemuMonitorPtr mon,
 }
 
 
-static int
-qemuMonitorJSONSpiceGetMigrationStatusReply(virJSONValuePtr reply,
-                                            bool *spice_migrated)
-{
-    virJSONValuePtr ret;
-
-    if (!(ret = virJSONValueObjectGet(reply, "return"))) {
-        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                       _("query-spice reply was missing return data"));
-        return -1;
-    }
-
-    if (virJSONValueObjectGetBoolean(ret, "migrated", spice_migrated) < 0) {
-        /* Deliberately don't report error here as we are
-         * probably dealing with older qemu which doesn't
-         * report this yet. Pretend spice is migrated. */
-        *spice_migrated = true;
-    }
-
-    return 0;
-}
-
-
-int qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitorPtr mon,
-                                           bool *spice_migrated)
-{
-    int ret;
-    virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-spice",
-                                                     NULL);
-    virJSONValuePtr reply = NULL;
-
-    if (!cmd)
-        return -1;
-
-    ret = qemuMonitorJSONCommand(mon, cmd, &reply);
-
-    if (ret == 0)
-        ret = qemuMonitorJSONCheckError(cmd, reply);
-
-    if (ret == 0)
-        ret = qemuMonitorJSONSpiceGetMigrationStatusReply(reply,
-                                                          spice_migrated);
-
-    virJSONValueFree(cmd);
-    virJSONValueFree(reply);
-    return ret;
-}
-
-
 int qemuMonitorJSONMigrate(qemuMonitorPtr mon,
                            unsigned int flags,
                            const char *uri)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 5be0002..ba84182 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1481,6 +1481,33 @@ qemuProcessHandleSerialChanged(qemuMonitorPtr mon 
ATTRIBUTE_UNUSED,
 }
 
 
+static int
+qemuProcessHandleSpiceMigrated(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
+                               virDomainObjPtr vm,
+                               void *opaque ATTRIBUTE_UNUSED)
+{
+    qemuDomainObjPrivatePtr priv;
+
+    virObjectLock(vm);
+
+    VIR_DEBUG("Spice migration completed for domain %p %s",
+              vm, vm->def->name);
+
+    priv = vm->privateData;
+    if (priv->job.asyncJob != QEMU_ASYNC_JOB_MIGRATION_OUT) {
+        VIR_DEBUG("got SPICE_MIGRATE_COMPLETED event without a migration job");
+        goto cleanup;
+    }
+
+    priv->job.spiceMigrated = true;
+    virDomainObjSignal(vm);
+
+ cleanup:
+    virObjectUnlock(vm);
+    return 0;
+}
+
+
 static qemuMonitorCallbacks monitorCallbacks = {
     .eofNotify = qemuProcessHandleMonitorEOF,
     .errorNotify = qemuProcessHandleMonitorError,
@@ -1504,6 +1531,7 @@ static qemuMonitorCallbacks monitorCallbacks = {
     .domainDeviceDeleted = qemuProcessHandleDeviceDeleted,
     .domainNicRxFilterChanged = qemuProcessHandleNicRxFilterChanged,
     .domainSerialChange = qemuProcessHandleSerialChanged,
+    .domainSpiceMigrated = qemuProcessHandleSpiceMigrated,
 };
 
 static int
diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 0f82fd8..0623275 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -1706,45 +1706,6 @@ 
testQemuMonitorJSONqemuMonitorJSONGetMigrationStatus(const void *data)
 }
 
 static int
-testQemuMonitorJSONqemuMonitorJSONGetSpiceMigrationStatus(const void *data)
-{
-    virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
-    qemuMonitorTestPtr test = qemuMonitorTestNewSimple(true, xmlopt);
-    int ret = -1;
-    bool spiceMigrated;
-
-    if (!test)
-        return -1;
-
-    if (qemuMonitorTestAddItem(test, "query-spice",
-                               "{"
-                               "    \"return\": {"
-                               "        \"migrated\": true,"
-                               "        \"enabled\": false,"
-                               "        \"mouse-mode\": \"client\""
-                               "    },"
-                               "    \"id\": \"libvirt-14\""
-                               "}") < 0)
-        goto cleanup;
-
-    if (qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitorTestGetMonitor(test),
-                                               &spiceMigrated) < 0)
-        goto cleanup;
-
-    if (!spiceMigrated) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       "Invalid spice migration status: %d, expecting 1",
-                       spiceMigrated);
-        goto cleanup;
-    }
-
-    ret = 0;
- cleanup:
-    qemuMonitorTestFree(test);
-    return ret;
-}
-
-static int
 testHashEqualChardevInfo(const void *value1, const void *value2)
 {
     const qemuMonitorChardevInfo *info1 = value1;
@@ -2400,7 +2361,6 @@ mymain(void)
     DO_TEST(qemuMonitorJSONGetBlockStatsInfo);
     DO_TEST(qemuMonitorJSONGetMigrationCacheSize);
     DO_TEST(qemuMonitorJSONGetMigrationStatus);
-    DO_TEST(qemuMonitorJSONGetSpiceMigrationStatus);
     DO_TEST(qemuMonitorJSONGetChardevInfo);
     DO_TEST(qemuMonitorJSONSetBlockIoThrottle);
     DO_TEST(qemuMonitorJSONGetTargetArch);
-- 
2.4.3

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to