7a3408
From edf46d78c32b6cf6dc5a8d359603ac035b889610 Mon Sep 17 00:00:00 2001
7a3408
Message-Id: <edf46d78c32b6cf6dc5a8d359603ac035b889610@dist-git>
7a3408
From: Peter Krempa <pkrempa@redhat.com>
7a3408
Date: Tue, 21 Jul 2015 16:18:30 +0200
7a3408
Subject: [PATCH] virsh: Refactor argument handling in cmdBlockCopy
7a3408
7a3408
https://bugzilla.redhat.com/show_bug.cgi?id=1227551
7a3408
https://bugzilla.redhat.com/show_bug.cgi?id=1197592
7a3408
7a3408
Put all argument parsing together and refactor the argument checking
7a3408
code.
7a3408
7a3408
(cherry picked from commit 8e85f62826a7df46f16c4c9e9abca5ede27b5603)
7a3408
7a3408
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
7a3408
---
7a3408
 tools/virsh-domain.c | 133 ++++++++++++++++++++++++++++-----------------------
7a3408
 1 file changed, 72 insertions(+), 61 deletions(-)
7a3408
7a3408
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
7a3408
index 4560d32..c233eb7 100644
7a3408
--- a/tools/virsh-domain.c
7a3408
+++ b/tools/virsh-domain.c
7a3408
@@ -2088,11 +2088,12 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
7a3408
     unsigned long long buf_size = 0;
7a3408
     unsigned int flags = 0;
7a3408
     bool ret = false;
7a3408
-    bool blocking = vshCommandOptBool(cmd, "wait");
7a3408
     bool verbose = vshCommandOptBool(cmd, "verbose");
7a3408
     bool pivot = vshCommandOptBool(cmd, "pivot");
7a3408
     bool finish = vshCommandOptBool(cmd, "finish");
7a3408
     bool blockdev = vshCommandOptBool(cmd, "blockdev");
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
@@ -2117,78 +2118,88 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
7a3408
         return false;
7a3408
     if (vshCommandOptString(ctl, cmd, "format", &format) < 0)
7a3408
         return false;
7a3408
-
7a3408
-    VSH_EXCLUSIVE_OPTIONS_VAR(dest, xml);
7a3408
-    VSH_EXCLUSIVE_OPTIONS_VAR(format, xml);
7a3408
-    VSH_EXCLUSIVE_OPTIONS_VAR(blockdev, xml);
7a3408
-
7a3408
-    blocking |= vshCommandOptBool(cmd, "timeout") || pivot || finish;
7a3408
-    if (blocking) {
7a3408
-        if (pivot && finish) {
7a3408
-            vshError(ctl, "%s", _("cannot mix --pivot and --finish"));
7a3408
-            return false;
7a3408
-        }
7a3408
-        if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
7a3408
-            return false;
7a3408
-        if (vshCommandOptBool(cmd, "async"))
7a3408
-            abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC;
7a3408
-
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
-    } else if (verbose || vshCommandOptBool(cmd, "async")) {
7a3408
-        vshError(ctl, "%s", _("missing --wait option"));
7a3408
-        return false;
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
     /* XXX: Parse bandwidth as scaled input, rather than forcing
7a3408
      * MiB/s, and either reject negative input or treat it as 0 rather
7a3408
      * than trying to guess which value will work well across both
7a3408
      * APIs with their different sizes and scales.  */
7a3408
     if (vshCommandOptULWrap(ctl, cmd, "bandwidth", &bandwidth) < 0)
7a3408
-        goto cleanup;
7a3408
+        return false;
7a3408
     if (vshCommandOptUInt(ctl, cmd, "granularity", &granularity) < 0)
7a3408
-        goto cleanup;
7a3408
+        return false;
7a3408
     if (vshCommandOptULongLong(ctl, cmd, "buf-size", &buf_size) < 0)
7a3408
-        goto cleanup;
7a3408
-
7a3408
-    if (xml) {
7a3408
-        if (virFileReadAll(xml, VSH_MAX_XML_FILE, &xmlstr) < 0) {
7a3408
-            vshReportError(ctl);
7a3408
-            goto cleanup;
7a3408
-        }
7a3408
-    } else if (!dest) {
7a3408
-        vshError(ctl, "%s", _("need either --dest or --xml"));
7a3408
-        goto cleanup;
7a3408
-    }
7a3408
-
7a3408
+        return false;
7a3408
     /* Exploit that some VIR_DOMAIN_BLOCK_REBASE_* and
7a3408
      * VIR_DOMAIN_BLOCK_COPY_* flags have the same values.  */
7a3408
     if (vshCommandOptBool(cmd, "shallow"))
7a3408
         flags |= VIR_DOMAIN_BLOCK_REBASE_SHALLOW;
7a3408
     if (vshCommandOptBool(cmd, "reuse-external"))
7a3408
         flags |= VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
7a3408
+    if (vshCommandOptTimeoutToMs(ctl, cmd, &timeout) < 0)
7a3408
+        return false;
7a3408
+
7a3408
+    if (timeout)
7a3408
+        blocking = true;
7a3408
+
7a3408
+    if (async)
7a3408
+        abort_flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC;
7a3408
+
7a3408
+    VSH_EXCLUSIVE_OPTIONS_VAR(dest, xml);
7a3408
+    VSH_EXCLUSIVE_OPTIONS_VAR(format, xml);
7a3408
+    VSH_EXCLUSIVE_OPTIONS_VAR(blockdev, xml);
7a3408
+    VSH_EXCLUSIVE_OPTIONS_VAR(pivot, finish);
7a3408
+
7a3408
+    if (!dest && !xml) {
7a3408
+        vshError(ctl, "%s", _("need either --dest or --xml"));
7a3408
+        return false;
7a3408
+    }
7a3408
+
7a3408
+    if (!blocking) {
7a3408
+        if (verbose) {
7a3408
+            vshError(ctl, "%s", _("--verbose requires at least one of --timeout, "
7a3408
+                                  "--wait, --pivot, or --finish"));
7a3408
+            return false;
7a3408
+        }
7a3408
+
7a3408
+        if (async) {
7a3408
+            vshError(ctl, "%s", _("--async requires at least one of --timeout, "
7a3408
+                                  "--wait, --pivot, or --finish"));
7a3408
+            return false;
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 (xml) {
7a3408
+        if (virFileReadAll(xml, VSH_MAX_XML_FILE, &xmlstr) < 0) {
7a3408
+            vshReportError(ctl);
7a3408
+            goto cleanup;
7a3408
+        }
7a3408
+    }
7a3408
 
7a3408
     if (granularity || buf_size || (format && STRNEQ(format, "raw")) || xml) {
7a3408
         /* New API */
7a3408
@@ -2242,7 +2253,7 @@ cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
7a3408
     } else {
7a3408
         /* Old API */
7a3408
         flags |= VIR_DOMAIN_BLOCK_REBASE_COPY;
7a3408
-        if (vshCommandOptBool(cmd, "blockdev"))
7a3408
+        if (blockdev)
7a3408
             flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_DEV;
7a3408
         if (STREQ_NULLABLE(format, "raw"))
7a3408
             flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_RAW;
7a3408
-- 
7a3408
2.5.0
7a3408