]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: disk migration verbose progress
authorTom Vijlbrief <tom.vijlbrief@xs4all.nl>
Wed, 17 Aug 2011 06:30:02 +0000 (08:30 +0200)
committerEric Blake <eblake@redhat.com>
Wed, 17 Aug 2011 14:01:12 +0000 (08:01 -0600)
A virsh command like:

migrate --live --copy-storage-all Guest qemu+ssh://user@host/system
--persistent --verbose

shows

Migration: [  0 %]

during the storage copy and does not start counting
until the ram transfer starts

Fix this by scraping optional disk transfer status, and adding it
into the progress meter.

AUTHORS
src/qemu/qemu_monitor_json.c
src/qemu/qemu_monitor_text.c

diff --git a/AUTHORS b/AUTHORS
index 2b61715f0a5f4f470102847a687f223bb9eb8a9d..2f8529bb30f3154ddc648401eaf0cf7c17973f87 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -189,6 +189,7 @@ Patches have also been contributed by:
   Nan Zhang            <nzhang@redhat.com>
   Wieland Hoffmann     <themineo@googlemail.com>
   Douglas Schilling Landgraf <dougsland@redhat.com>
+  Tom Vijlbrief        <tom.vijlbrief@xs4all.nl>
 
   [....send patches to get your name here....]
 
index 2a9a0782eca89e129e8c14375d4d2d905e0d75f6..7adfb264e82ea7ed70095bbf067e1e92435386c8 100644 (file)
@@ -1852,6 +1852,7 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
 {
     virJSONValuePtr ret;
     const char *statusstr;
+    unsigned long long t;
 
     if (!(ret = virJSONValueObjectGet(reply, "return"))) {
         qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1879,21 +1880,52 @@ qemuMonitorJSONGetMigrationStatusReply(virJSONValuePtr reply,
             return -1;
         }
 
-        if (virJSONValueObjectGetNumberUlong(ram, "transferred", transferred) < 0) {
+        if (virJSONValueObjectGetNumberUlong(ram, "transferred",
+                                             transferred) < 0) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                            _("migration was active, but RAM 'transferred' data was missing"));
+                            _("migration was active, but RAM 'transferred' "
+                              "data was missing"));
             return -1;
         }
         if (virJSONValueObjectGetNumberUlong(ram, "remaining", remaining) < 0) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                            _("migration was active, but RAM 'remaining' data was missing"));
+                            _("migration was active, but RAM 'remaining' "
+                              "data was missing"));
             return -1;
         }
         if (virJSONValueObjectGetNumberUlong(ram, "total", total) < 0) {
             qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                            _("migration was active, but RAM 'total' data was missing"));
+                            _("migration was active, but RAM 'total' "
+                              "data was missing"));
             return -1;
         }
+
+        virJSONValuePtr disk = virJSONValueObjectGet(ret, "disk");
+        if (!disk) {
+            return 0;
+        }
+
+        if (virJSONValueObjectGetNumberUlong(disk, "transferred", &t) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("disk migration was active, but 'transferred' "
+                              "data was missing"));
+            return -1;
+        }
+        *transferred += t;
+        if (virJSONValueObjectGetNumberUlong(disk, "remaining", &t) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("disk migration was active, but 'remaining' "
+                              "data was missing"));
+            return -1;
+        }
+        *remaining += t;
+        if (virJSONValueObjectGetNumberUlong(disk, "total", &t) < 0) {
+            qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                            _("disk migration was active, but 'total' "
+                              "data was missing"));
+            return -1;
+        }
+        *total += t;
     }
 
     return 0;
index 7bf733da7b7ace5675fb78332b5a91a3a6f05fad..335e39ee95a0a06a3756b46ed844fa936800bb8c 100644 (file)
@@ -149,7 +149,7 @@ int qemuMonitorTextIOProcess(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
             passwd = strstr(start, PASSWORD_PROMPT);
             if (passwd) {
 #if DEBUG_IO
-                VIR_DEBUG("Seen a passwowrd prompt [%s]", data + used);
+                VIR_DEBUG("Seen a password prompt [%s]", data + used);
 #endif
                 if (msg->passwordHandler) {
                     int i;
@@ -1183,6 +1183,9 @@ cleanup:
 #define MIGRATION_TRANSFER_PREFIX "transferred ram: "
 #define MIGRATION_REMAINING_PREFIX "remaining ram: "
 #define MIGRATION_TOTAL_PREFIX "total ram: "
+#define MIGRATION_DISK_TRANSFER_PREFIX "transferred disk: "
+#define MIGRATION_DISK_REMAINING_PREFIX "remaining disk: "
+#define MIGRATION_DISK_TOTAL_PREFIX "total disk: "
 
 int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
                                       int *status,
@@ -1192,6 +1195,9 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
     char *reply;
     char *tmp;
     char *end;
+    unsigned long long disk_transferred = 0;
+    unsigned long long disk_remaining = 0;
+    unsigned long long disk_total = 0;
     int ret = -1;
 
     *status = QEMU_MONITOR_MIGRATION_STATUS_INACTIVE;
@@ -1230,7 +1236,8 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
 
             if (virStrToLong_ull(tmp, &end, 10, transferred) < 0) {
                 qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("cannot parse migration data transferred statistic %s"), tmp);
+                                _("cannot parse migration data transferred "
+                                  "statistic %s"), tmp);
                 goto cleanup;
             }
             *transferred *= 1024;
@@ -1242,10 +1249,12 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
 
             if (virStrToLong_ull(tmp, &end, 10, remaining) < 0) {
                 qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("cannot parse migration data remaining statistic %s"), tmp);
+                                _("cannot parse migration data remaining "
+                                  "statistic %s"), tmp);
                 goto cleanup;
             }
             *remaining *= 1024;
+            tmp = end;
 
             if (!(tmp = strstr(tmp, MIGRATION_TOTAL_PREFIX)))
                 goto done;
@@ -1253,11 +1262,53 @@ int qemuMonitorTextGetMigrationStatus(qemuMonitorPtr mon,
 
             if (virStrToLong_ull(tmp, &end, 10, total) < 0) {
                 qemuReportError(VIR_ERR_INTERNAL_ERROR,
-                                _("cannot parse migration data total statistic %s"), tmp);
+                                _("cannot parse migration data total "
+                                  "statistic %s"), tmp);
                 goto cleanup;
             }
             *total *= 1024;
+            tmp = end;
+
+            /*
+             * Check for Optional Disk Migration status
+             */
+            if (!(tmp = strstr(tmp, MIGRATION_DISK_TRANSFER_PREFIX)))
+                goto done;
+            tmp += strlen(MIGRATION_DISK_TRANSFER_PREFIX);
+
+            if (virStrToLong_ull(tmp, &end, 10, &disk_transferred) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                                _("cannot parse disk migration data "
+                                  "transferred statistic %s"), tmp);
+                goto cleanup;
+            }
+            *transferred += disk_transferred * 1024;
+            tmp = end;
+
+            if (!(tmp = strstr(tmp, MIGRATION_DISK_REMAINING_PREFIX)))
+                goto done;
+            tmp += strlen(MIGRATION_DISK_REMAINING_PREFIX);
 
+            if (virStrToLong_ull(tmp, &end, 10, &disk_remaining) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                                _("cannot parse disk migration data remaining "
+                                  "statistic %s"), tmp);
+                goto cleanup;
+            }
+            *remaining += disk_remaining * 1024;
+            tmp = end;
+
+            if (!(tmp = strstr(tmp, MIGRATION_DISK_TOTAL_PREFIX)))
+                goto done;
+            tmp += strlen(MIGRATION_DISK_TOTAL_PREFIX);
+
+            if (virStrToLong_ull(tmp, &end, 10, &disk_total) < 0) {
+                qemuReportError(VIR_ERR_INTERNAL_ERROR,
+                                _("cannot parse disk migration data total "
+                                  "statistic %s"), tmp);
+                goto cleanup;
+            }
+            *total += disk_total * 1024;
         }
     }