7a3408
From 399e5a89b2445523cd0628d07f5ada156725569e Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <399e5a89b2445523cd0628d07f5ada156725569e@dist-git>
7a3408
From: Peter Krempa <pkrempa@redhat.com>
7a3408
Date: Tue, 21 Jul 2015 16:18:35 +0200
7a3408
Subject: [PATCH] virsh: Refactor block job waiting in cmdBlockCopy
7a3408
7a3408
https://bugzilla.redhat.com/show_bug.cgi?id=1197592
7a3408
https://bugzilla.redhat.com/show_bug.cgi?id=1227551
7a3408
7a3408
Similarly to the refactor of cmdBlockCommit in a previous commit this
7a3408
does the same change for cmdBlockCopy.
7a3408
7a3408
(cherry picked from commit faa143912381aa48e33839b194b32cc14d574589)
7a3408
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 tools/virsh-domain.c | 119 ++++++++++++++-------------------------------------
7a3408
 1 file changed, 31 insertions(+), 88 deletions(-)
7a3408
7a3408
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
7a3408
index 8c5ef34..a61656f 100644
7a3408
--- a/tools/virsh-domain.c
7a3408
+++ b/tools/virsh-domain.c
7a3408
@@ -2263,20 +2263,13 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
7a3408
     bool blocking = vshCommandOptBool(cmd, "wait") || finish || pivot;
7a3408
     bool async = vshCommandOptBool(cmd, "async");
7a3408
     int timeout = 0;
7a3408
-    struct sigaction sig_action;
7a3408
-    struct sigaction old_sig_action;
7a3408
-    sigset_t sigmask, oldsigmask;
7a3408
-    struct timeval start;
7a3408
-    struct timeval curr;
7a3408
     const char *path = NULL;
7a3408
-    bool quit = false;
7a3408
     int abort_flags = 0;
7a3408
     const char *xml = NULL;
7a3408
     char *xmlstr = NULL;
7a3408
     virTypedParameterPtr params = NULL;
7a3408
+    vshBlockJobWaitDataPtr bjWait = NULL;
7a3408
     int nparams = 0;
7a3408
-    int status = -1;
7a3408
-    int cb_id = -1;
7a3408
 
7a3408
     if (vshCommandOptStringReq(ctl, cmd, "path", &path) < 0)
7a3408
         return false;
7a3408
@@ -2335,33 +2328,14 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
7a3408
         }
7a3408
     }
7a3408
 
7a3408
-    if (blocking) {
7a3408
-        sigemptyset(&sigmask);
7a3408
-        sigaddset(&sigmask, SIGINT);
7a3408
-
7a3408
-        intCaught = 0;
7a3408
-        sig_action.sa_sigaction = vshCatchInt;
7a3408
-        sig_action.sa_flags = SA_SIGINFO;
7a3408
-        sigemptyset(&sig_action.sa_mask);
7a3408
-        sigaction(SIGINT, &sig_action, &old_sig_action);
7a3408
-
7a3408
-        GETTIMEOFDAY(&start;;
7a3408
-    }
7a3408
-
7a3408
-    virConnectDomainEventGenericCallback cb =
7a3408
-        VIR_DOMAIN_EVENT_CALLBACK(vshBlockJobStatusHandler);
7a3408
-
7a3408
-    if ((cb_id = virConnectDomainEventRegisterAny(ctl->conn,
7a3408
-                                                  dom,
7a3408
-                                                  VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
7a3408
-                                                  cb,
7a3408
-                                                  &status,
7a3408
-                                                  NULL)) < 0)
7a3408
-        vshResetLibvirtError();
7a3408
-
7a3408
     if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
7a3408
         goto cleanup;
7a3408
 
7a3408
+    if (blocking &&
7a3408
+        !(bjWait = vshBlockJobWaitInit(ctl, dom, path, _("Block Copy"), verbose,
7a3408
+                                       timeout, async)))
7a3408
+        goto cleanup;
7a3408
+
7a3408
     if (xml) {
7a3408
         if (virFileReadAll(xml, VSH_MAX_XML_FILE, &xmlstr) < 0) {
7a3408
             vshReportError(ctl);
7a3408
@@ -2436,83 +2410,52 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
7a3408
         goto cleanup;
7a3408
     }
7a3408
 
7a3408
-    while (blocking) {
7a3408
-        virDomainBlockJobInfo info;
7a3408
-        int result;
7a3408
-
7a3408
-        pthread_sigmask(SIG_BLOCK, &sigmask, &oldsigmask);
7a3408
-        result = virDomainGetBlockJobInfo(dom, path, &info, 0);
7a3408
-        pthread_sigmask(SIG_SETMASK, &oldsigmask, NULL);
7a3408
-
7a3408
-        if (result < 0) {
7a3408
-            vshError(ctl, _("failed to query job for disk %s"), path);
7a3408
+    /* Execution continues here only if --wait or friends were specified */
7a3408
+    switch (vshBlockJobWait(bjWait)) {
7a3408
+        case -1:
7a3408
             goto cleanup;
7a3408
-        }
7a3408
 
7a3408
-        if (result == 0) {
7a3408
-            vshError(ctl, _("Block Copy unexpectedly failed"));
7a3408
+        case VIR_DOMAIN_BLOCK_JOB_CANCELED:
7a3408
+            vshPrint(ctl, "\n%s", _("Copy aborted"));
7a3408
             goto cleanup;
7a3408
-        }
7a3408
+            break;
7a3408
 
7a3408
-        if (verbose)
7a3408
-            vshPrintJobProgress(_("Block Copy"), info.end - info.cur, info.end);
7a3408
-        if (info.cur == info.end)
7a3408
+        case VIR_DOMAIN_BLOCK_JOB_FAILED:
7a3408
+            vshPrint(ctl, "\n%s", _("Copy failed"));
7a3408
+            goto cleanup;
7a3408
             break;
7a3408
 
7a3408
-        GETTIMEOFDAY(&curr);
7a3408
-        if (intCaught || (timeout &&
7a3408
-                          (((int)(curr.tv_sec - start.tv_sec)  * 1000 +
7a3408
-                            (int)(curr.tv_usec - start.tv_usec) / 1000) >
7a3408
-                           timeout))) {
7a3408
-            vshDebug(ctl, VSH_ERR_DEBUG,
7a3408
-                     intCaught ? "interrupted" : "timeout");
7a3408
-            intCaught = 0;
7a3408
-            timeout = 0;
7a3408
-            status = VIR_DOMAIN_BLOCK_JOB_CANCELED;
7a3408
-            if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
7a3408
-                vshError(ctl, _("failed to abort job for disk %s"), path);
7a3408
-                goto cleanup;
7a3408
-            }
7a3408
-            if (abort_flags & VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC)
7a3408
-                break;
7a3408
-        } else {
7a3408
-            usleep(500 * 1000);
7a3408
-        }
7a3408
+        case VIR_DOMAIN_BLOCK_JOB_READY:
7a3408
+        case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
7a3408
+            break;
7a3408
     }
7a3408
 
7a3408
-    if (status == VIR_DOMAIN_BLOCK_JOB_CANCELED)
7a3408
-        quit = true;
7a3408
-
7a3408
-    if (!quit && pivot) {
7a3408
+    if (pivot) {
7a3408
         abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT;
7a3408
         if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
7a3408
             vshError(ctl, _("failed to pivot job for disk %s"), path);
7a3408
             goto cleanup;
7a3408
         }
7a3408
-    } else if (finish && !quit &&
7a3408
-               virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
7a3408
-        vshError(ctl, _("failed to finish job for disk %s"), path);
7a3408
-        goto cleanup;
7a3408
-    }
7a3408
-    if (quit)
7a3408
-        vshPrint(ctl, "\n%s", _("Copy aborted"));
7a3408
-    else if (pivot)
7a3408
+
7a3408
         vshPrint(ctl, "\n%s", _("Successfully pivoted"));
7a3408
-    else if (finish)
7a3408
+    } else if (finish) {
7a3408
+        if (virDomainBlockJobAbort(dom, path, abort_flags) < 0) {
7a3408
+            vshError(ctl, _("failed to finish job for disk %s"), path);
7a3408
+            goto cleanup;
7a3408
+        }
7a3408
+
7a3408
         vshPrint(ctl, "\n%s", _("Successfully copied"));
7a3408
-    else
7a3408
+    } else {
7a3408
         vshPrint(ctl, "\n%s", _("Now in mirroring phase"));
7a3408
+    }
7a3408
 
7a3408
     ret = true;
7a3408
+
7a3408
  cleanup:
7a3408
     VIR_FREE(xmlstr);
7a3408
     virTypedParamsFree(params, nparams);
7a3408
-    if (dom)
7a3408
-        virDomainFree(dom);
7a3408
-    if (blocking)
7a3408
-        sigaction(SIGINT, &old_sig_action, NULL);
7a3408
-    if (cb_id >= 0)
7a3408
-        virConnectDomainEventDeregisterAny(ctl->conn, cb_id);
7a3408
+    virDomainFree(dom);
7a3408
+    vshBlockJobWaitFree(bjWait);
7a3408
     return ret;
7a3408
 }
7a3408
 
7a3408
-- 
7a3408
2.5.0
7a3408