]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add API for running 'info migration' monitor command
authorDaniel P. Berrange <berrange@redhat.com>
Wed, 23 Sep 2009 13:27:12 +0000 (14:27 +0100)
committerDaniel P. Berrange <berrange@redhat.com>
Tue, 29 Sep 2009 10:56:44 +0000 (11:56 +0100)
* 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
src/qemu/qemu_monitor_text.c
src/qemu/qemu_monitor_text.h

index a44b99be5e3a004c3fedeac88a77dcb4045a84f7..7722e064cd1761019b9eca7f23e2705d4fc11f26 100644 (file)
@@ -6498,6 +6498,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);
@@ -6561,14 +6563,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;
     }
 
index e68d993f20d26646a85bbee7c331be89ce53c4c6..fd137beec113149ae27678fcc0f029a56659a5f4 100644 (file)
@@ -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;
+}
index 2bf7931b4cfee12d144cd976ac8c946e9bb90f77..cd6f1f1914d79ad7abaaac937422852dc8629a4e 100644 (file)
@@ -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 */