[libvirt] [PATCH 13/27] Add API for running 'info migration' monitor command

Daniel P. Berrange berrange at redhat.com
Thu Sep 24 15:00:15 UTC 2009


* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h: Add new
  qemuMonitorGetMigrationStatus() command.
* src/qemu/qemu_driver.c: Use new qemuMonitorGetMigrationStatus()
  command to check completion status.
---
 src/qemu/qemu_driver.c       |   15 +++++--
 src/qemu/qemu_monitor_text.c |   91 ++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_monitor_text.h |   16 +++++++
 3 files changed, 117 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ccc13c4..a6300c9 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6499,6 +6499,8 @@ qemudDomainMigratePerform (virDomainPtr dom,
     char *info = NULL;
     int ret = -1;
     int paused = 0;
+    int status;
+    unsigned long long transferred, remaining, total;
 
     qemuDriverLock(driver);
     vm = virDomainFindByUUID(&driver->domains, dom->uuid);
@@ -6562,14 +6564,17 @@ qemudDomainMigratePerform (virDomainPtr dom,
      * rather failed later on.  Check the output of "info migrate"
      */
     VIR_FREE(info);
-    if (qemudMonitorCommand(vm, "info migrate", &info) < 0) {
-        qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-                          "%s", _("could not get info about migration"));
+
+    if (qemuMonitorGetMigrationStatus(vm, &status,
+                                      &transferred,
+                                      &remaining,
+                                      &total) < 0) {
         goto cleanup;
     }
-    if (strstr(info, "fail") != NULL) {
+
+    if (status != QEMU_MONITOR_MIGRATION_STATUS_COMPLETED) {
         qemudReportError (dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED,
-                          _("migrate failed: %s"), info);
+                          "%s", _("migrate did not successfully complete"));
         goto cleanup;
     }
 
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index d9227a2..0b746b9 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -28,6 +28,7 @@
 #include <sys/un.h>
 #include <poll.h>
 #include <unistd.h>
+#include <string.h>
 
 #include "qemu_monitor_text.h"
 #include "qemu_conf.h"
@@ -997,3 +998,93 @@ cleanup:
     VIR_FREE(cmd);
     return ret;
 }
+
+
+#define MIGRATION_PREFIX "Migration status: "
+#define MIGRATION_TRANSFER_PREFIX "transferred ram: "
+#define MIGRATION_REMAINING_PREFIX "remaining ram: "
+#define MIGRATION_TOTAL_PREFIX "total ram: "
+
+VIR_ENUM_DECL(qemuMonitorMigrationStatus)
+VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
+              QEMU_MONITOR_MIGRATION_STATUS_LAST,
+              "inactive", "active", "completed", "failed", "cancelled")
+
+int qemuMonitorGetMigrationStatus(const virDomainObjPtr vm,
+                                  int *status,
+                                  unsigned long long *transferred,
+                                  unsigned long long *remaining,
+                                  unsigned long long *total) {
+    char *reply;
+    char *tmp;
+    char *end;
+    int ret = -1;
+
+    *status = QEMU_MONITOR_MIGRATION_STATUS_INACTIVE;
+    *transferred = 0;
+    *remaining = 0;
+    *total = 0;
+
+    if (qemudMonitorCommand(vm, "info migration", &reply) < 0) {
+        qemudReportError(NULL, NULL, NULL, VIR_ERR_OPERATION_FAILED,
+                         "%s", _("cannot query migration status"));
+        return -1;
+    }
+
+    if ((tmp = strstr(reply, MIGRATION_PREFIX)) != NULL) {
+        tmp += strlen(MIGRATION_PREFIX);
+        end = strchr(tmp, '\n');
+        *end = '\0';
+
+        if ((*status = qemuMonitorMigrationStatusTypeFromString(tmp)) < 0) {
+            qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                             _("unexpected migration status in %s"), reply);
+            goto cleanup;
+        }
+
+        if (*status == QEMU_MONITOR_MIGRATION_STATUS_ACTIVE) {
+            tmp = end + 1;
+
+            if (!(tmp = strstr(tmp, MIGRATION_TRANSFER_PREFIX)))
+                goto done;
+            tmp += strlen(MIGRATION_TRANSFER_PREFIX);
+
+            if (virStrToLong_ull(tmp, NULL, 10, transferred) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                 _("cannot parse migration data transferred statistic %s"), tmp);
+                goto cleanup;
+            }
+            *transferred *= 1024;
+
+            if (!(tmp = strstr(tmp, MIGRATION_REMAINING_PREFIX)))
+                goto done;
+            tmp += strlen(MIGRATION_REMAINING_PREFIX);
+
+            if (virStrToLong_ull(tmp, NULL, 10, remaining) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                 _("cannot parse migration data remaining statistic %s"), tmp);
+                goto cleanup;
+            }
+            *remaining *= 1024;
+
+            if (!(tmp = strstr(tmp, MIGRATION_TOTAL_PREFIX)))
+                goto done;
+            tmp += strlen(MIGRATION_TOTAL_PREFIX);
+
+            if (virStrToLong_ull(tmp, NULL, 10, total) < 0) {
+                qemudReportError(NULL, NULL, NULL, VIR_ERR_INTERNAL_ERROR,
+                                 _("cannot parse migration data total statistic %s"), tmp);
+                goto cleanup;
+            }
+            *total *= 1024;
+
+        }
+    }
+
+done:
+    ret = 0;
+
+cleanup:
+    VIR_FREE(reply);
+    return ret;
+}
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index 0591f3c..c972672 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -112,4 +112,20 @@ int qemuMonitorSavePhysicalMemory(const virDomainObjPtr vm,
 int qemuMonitorSetMigrationSpeed(const virDomainObjPtr vm,
                                  unsigned long bandwidth);
 
+enum {
+    QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
+    QEMU_MONITOR_MIGRATION_STATUS_ACTIVE,
+    QEMU_MONITOR_MIGRATION_STATUS_COMPLETED,
+    QEMU_MONITOR_MIGRATION_STATUS_ERROR,
+    QEMU_MONITOR_MIGRATION_STATUS_CANCELLED,
+
+    QEMU_MONITOR_MIGRATION_STATUS_LAST
+};
+
+int qemuMonitorGetMigrationStatus(const virDomainObjPtr vm,
+                                  int *status,
+                                  unsigned long long *transferred,
+                                  unsigned long long *remaining,
+                                  unsigned long long *total);
+
 #endif /* QEMU_MONITOR_TEXT_H */
-- 
1.6.2.5




More information about the libvir-list mailing list