[libvirt] [PATCH v2 14/22] qemu: Refactor qemuMigrationUpdateJobStatus

Jiri Denemark jdenemar at redhat.com
Tue Jun 2 12:34:19 UTC 2015


Once we start waiting for migration events instead of polling
query-migrate, priv->job.current will not be regularly updated anymore
because we will get the current status directly from the events. Thus
virDomainGetJob{Info,Stats} will have to query QEMU, but they can't just
blindly update priv->job.current structure. This patch introduces
qemuMigrationFetchJobStatus which just fills in a caller supplied
structure and makes qemuMigrationUpdateJobStatus a tiny wrapper around
it.

Signed-off-by: Jiri Denemark <jdenemar at redhat.com>
---

Notes:
    Version 2:
    - new patch

 src/qemu/qemu_migration.c | 133 ++++++++++++++++++++++++++++++----------------
 src/qemu/qemu_migration.h |   5 ++
 2 files changed, 93 insertions(+), 45 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 84a66d6..08ea706 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2401,67 +2401,110 @@ qemuMigrationWaitForSpice(virDomainObjPtr vm)
     return 0;
 }
 
-static int
-qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
-                             virDomainObjPtr vm,
-                             const char *job,
-                             qemuDomainAsyncJob asyncJob)
+
+static void
+qemuMigrationUpdateJobType(qemuDomainJobInfoPtr jobInfo)
 {
-    qemuDomainObjPrivatePtr priv = vm->privateData;
-    qemuMonitorMigrationStatus status;
-    qemuDomainJobInfoPtr jobInfo;
-    int ret;
-
-    memset(&status, 0, sizeof(status));
-
-    ret = qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob);
-    if (ret < 0) {
-        /* Guest already exited or waiting for the job timed out; nothing
-         * further to update. */
-        return ret;
-    }
-    ret = qemuMonitorGetMigrationStatus(priv->mon, &status);
-
-    if (qemuDomainObjExitMonitor(driver, vm) < 0)
-        return -1;
-
-    if (ret < 0 ||
-        qemuDomainJobInfoUpdateTime(priv->job.current) < 0)
-        return -1;
-
-    ret = -1;
-    jobInfo = priv->job.current;
-    switch (status.status) {
+    switch (jobInfo->status.status) {
     case QEMU_MONITOR_MIGRATION_STATUS_COMPLETED:
         jobInfo->type = VIR_DOMAIN_JOB_COMPLETED;
-        /* fall through */
-    case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
-    case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
-    case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
-        ret = 0;
         break;
 
     case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
         jobInfo->type = VIR_DOMAIN_JOB_NONE;
-        virReportError(VIR_ERR_OPERATION_FAILED,
-                       _("%s: %s"), job, _("is not active"));
         break;
 
     case QEMU_MONITOR_MIGRATION_STATUS_ERROR:
         jobInfo->type = VIR_DOMAIN_JOB_FAILED;
-        virReportError(VIR_ERR_OPERATION_FAILED,
-                       _("%s: %s"), job, _("unexpectedly failed"));
         break;
 
     case QEMU_MONITOR_MIGRATION_STATUS_CANCELLED:
         jobInfo->type = VIR_DOMAIN_JOB_CANCELLED;
+        break;
+
+    case QEMU_MONITOR_MIGRATION_STATUS_SETUP:
+    case QEMU_MONITOR_MIGRATION_STATUS_ACTIVE:
+    case QEMU_MONITOR_MIGRATION_STATUS_CANCELLING:
+        break;
+    }
+}
+
+
+int
+qemuMigrationFetchJobStatus(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            qemuDomainAsyncJob asyncJob,
+                            qemuDomainJobInfoPtr jobInfo)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    int rv;
+
+    if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+        return -1;
+
+    memset(&jobInfo->status, 0, sizeof(jobInfo->status));
+    rv = qemuMonitorGetMigrationStatus(priv->mon, &jobInfo->status);
+
+    if (qemuDomainObjExitMonitor(driver, vm) < 0 || rv < 0)
+        return -1;
+
+    qemuMigrationUpdateJobType(jobInfo);
+    return qemuDomainJobInfoUpdateTime(jobInfo);
+}
+
+
+static int
+qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
+                             virDomainObjPtr vm,
+                             qemuDomainAsyncJob asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobInfoPtr jobInfo = priv->job.current;
+    qemuDomainJobInfo newInfo = *jobInfo;
+
+    if (qemuMigrationFetchJobStatus(driver, vm, asyncJob, &newInfo) < 0)
+        return -1;
+
+    *jobInfo = newInfo;
+    return 0;
+}
+
+
+static int
+qemuMigrationCheckJobStatus(virQEMUDriverPtr driver,
+                            virDomainObjPtr vm,
+                            const char *job,
+                            qemuDomainAsyncJob asyncJob)
+{
+    qemuDomainObjPrivatePtr priv = vm->privateData;
+    qemuDomainJobInfoPtr jobInfo = priv->job.current;
+
+    if (qemuMigrationUpdateJobStatus(driver, vm, asyncJob) < 0)
+        return -1;
+
+    switch (jobInfo->type) {
+    case VIR_DOMAIN_JOB_NONE:
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       _("%s: %s"), job, _("is not active"));
+        return -1;
+
+    case VIR_DOMAIN_JOB_FAILED:
+        virReportError(VIR_ERR_OPERATION_FAILED,
+                       _("%s: %s"), job, _("unexpectedly failed"));
+        return -1;
+
+    case VIR_DOMAIN_JOB_CANCELLED:
         virReportError(VIR_ERR_OPERATION_ABORTED,
                        _("%s: %s"), job, _("canceled by client"));
+        return -1;
+
+    case VIR_DOMAIN_JOB_BOUNDED:
+    case VIR_DOMAIN_JOB_UNBOUNDED:
+    case VIR_DOMAIN_JOB_COMPLETED:
+    case VIR_DOMAIN_JOB_LAST:
         break;
     }
-    jobInfo->status = status;
-
-    return ret;
+    return 0;
 }
 
 
@@ -2502,7 +2545,7 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
         /* Poll every 50ms for progress & to allow cancellation */
         struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
 
-        if (qemuMigrationUpdateJobStatus(driver, vm, job, asyncJob) == -1)
+        if (qemuMigrationCheckJobStatus(driver, vm, job, asyncJob) < 0)
             goto error;
 
         if (storage &&
@@ -4108,8 +4151,8 @@ qemuMigrationRun(virQEMUDriverPtr driver,
          * rather failed later on.  Check its status before waiting for a
          * connection from qemu which may never be initiated.
          */
-        if (qemuMigrationUpdateJobStatus(driver, vm, _("migration job"),
-                                         QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
+        if (qemuMigrationCheckJobStatus(driver, vm, _("migration job"),
+                                        QEMU_ASYNC_JOB_MIGRATION_OUT) < 0)
             goto cancel;
 
         while ((fd = accept(spec->dest.unix_socket.sock, NULL, NULL)) < 0) {
diff --git a/src/qemu/qemu_migration.h b/src/qemu/qemu_migration.h
index e47bde5..65dfdec 100644
--- a/src/qemu/qemu_migration.h
+++ b/src/qemu/qemu_migration.h
@@ -180,4 +180,9 @@ int qemuMigrationToFile(virQEMUDriverPtr driver, virDomainObjPtr vm,
 int qemuMigrationCancel(virQEMUDriverPtr driver,
                         virDomainObjPtr vm);
 
+int qemuMigrationFetchJobStatus(virQEMUDriverPtr driver,
+                                virDomainObjPtr vm,
+                                qemuDomainAsyncJob asyncJob,
+                                qemuDomainJobInfoPtr jobInfo);
+
 #endif /* __QEMU_MIGRATION_H__ */
-- 
2.4.1




More information about the libvir-list mailing list