[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[libvirt] [PATCH 2/3] show mig progress



Signed-off-by: Wen Congyang <wency cn fujitsu com>

---
 tools/virsh.c   |   78 +++++++++++++++++++++++++++++++++++++++++++-----------
 tools/virsh.pod |    4 ++-
 2 files changed, 65 insertions(+), 17 deletions(-)

diff --git a/tools/virsh.c b/tools/virsh.c
index aba4fd1..ee8d769 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -3413,6 +3413,7 @@ static const vshCmdOptDef opts_migrate[] = {
     {"suspend", VSH_OT_BOOL, 0, N_("do not restart the domain on the destination host")},
     {"copy-storage-all", VSH_OT_BOOL, 0, N_("migration with non-shared storage with full disk copy")},
     {"copy-storage-inc", VSH_OT_BOOL, 0, N_("migration with non-shared storage with incremental copy (same base image shared between source and destination)")},
+    {"verbose", VSH_OT_BOOL, 0, N_("display the progress of migration")},
     {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
     {"desturi", VSH_OT_DATA, VSH_OFLAG_REQ, N_("connection URI of the destination host as seen from the client(normal migration) or source(p2p migration)")},
     {"migrateuri", VSH_OT_DATA, 0, N_("migration URI, usually can be omitted")},
@@ -3513,6 +3514,28 @@ out_sig:
     ignore_value(safewrite(data->writefd, &ret, sizeof(ret)));
 }
 
+static void
+print_job_progress(unsigned long long remaining, unsigned long long total)
+{
+    int progress;
+
+    if (total == 0)
+        /* migration has not been started */
+        return;
+
+    if (remaining == 0) {
+        /* migration has completed */
+        progress = 100;
+    } else if (remaining * 100 / total == 0) {
+        /* migration has not completed, do not print [100 %] */
+        progress = 99;
+    } else {
+        progress = 100 - remaining * 100 / total;
+    }
+
+    fprintf(stderr, "\rMigration: [%3d %%]", progress);
+}
+
 static int
 cmdMigrate (vshControl *ctl, const vshCmd *cmd)
 {
@@ -3524,6 +3547,9 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
     char retchar;
     struct sigaction sig_action;
     struct sigaction old_sig_action;
+    virDomainJobInfo jobinfo;
+    bool verbose = FALSE;
+    sigset_t sigmask, oldsigmask;
 
     struct {
         vshControl *ctl;
@@ -3534,6 +3560,9 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
     if (!(dom = vshCommandOptDomain (ctl, cmd, NULL)))
         return FALSE;
 
+    if (vshCommandOptBool (cmd, "verbose"))
+        verbose = TRUE;
+
     if (pipe(p) < 0)
         goto cleanup;
 
@@ -3556,25 +3585,42 @@ cmdMigrate (vshControl *ctl, const vshCmd *cmd)
     pollfd.fd = p[0];
     pollfd.events = POLLIN;
     pollfd.revents = 0;
+    sigemptyset(&sigmask);
+    sigaddset(&sigmask, SIGINT);
 
-    ret = poll(&pollfd, 1, -1);
-    if (ret > 0) {
-        if (saferead(p[0], &retchar, sizeof(retchar)) > 0) {
-            if (retchar == '0')
-                ret = TRUE;
-            else
+    while (1) {
+        ret = poll(&pollfd, 1, 500);
+        if (ret > 0) {
+            if (saferead(p[0], &retchar, sizeof(retchar)) > 0) {
+                if (retchar == '0') {
+                    ret = TRUE;
+                    if (verbose) {
+                        /* print [100 %] */
+                        print_job_progress(0, 1);
+                    }
+                } else
+                    ret = FALSE;
+            } else
                 ret = FALSE;
-        } else
-            ret = FALSE;
-    } else if (ret < 0) {
-        if (errno == EINTR && intCatched) {
-            virDomainAbortJob(dom);
-            ret = FALSE;
-            intCatched = FALSE;
+            break;
+        }
+
+        if (ret < 0) {
+            if (errno == EINTR && intCatched) {
+                virDomainAbortJob(dom);
+                ret = FALSE;
+                intCatched = FALSE;
+                break;
+            }
+        }
+
+        if (verbose) {
+            pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
+            ret = virDomainGetJobInfo(dom, &jobinfo);
+            pthread_sigmask(SIG_BLOCK, &oldsigmask, NULL);
+            if (ret == 0)
+                print_job_progress(jobinfo.dataRemaining, jobinfo.dataTotal);
         }
-    } else {
-        /* timed out */
-        ret = FALSE;
     }
 
     sigaction(SIGINT, &old_sig_action, NULL);
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 1f15fef..ce7e2e7 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -489,7 +489,8 @@ type attribute for the <domain> element of XML.
 
 =item B<migrate> optional I<--live> I<--p2p> I<--direct> I<--tunnelled>
 I<--persistent> I<--undefinesource> I<--suspend> I<--copy-storage-all>
-I<--copy-storage-inc> I<domain-id> I<desturi> I<migrateuri> I<dname>
+I<--copy-storage-inc> I<--verbose> I<domain-id> I<desturi> I<migrateuri>
+I<dname>
 
 Migrate domain to another host.  Add I<--live> for live migration; I<--p2p>
 for peer-2-peer migration; I<--direct> for direct migration; or I<--tunnelled>
@@ -499,6 +500,7 @@ and I<--suspend> leaves the domain paused on the destination host.
 I<--copy-storage-all> indicates migration with non-shared storage with full
 disk copy, I<--copy-storage-inc> indicates migration with non-shared storage
 with incremental copy (same base image shared between source and destination).
+I<--verbose> displays the progress of migration.
 
 The I<desturi> is the connection URI of the destination host, and
 I<migrateuri> is the migration URI, which usually can be omitted.
-- 
1.7.1


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]