]> xenbits.xensource.com Git - libvirt.git/commitdiff
vsh: Introduce helper to parse --bandwidth
authorPeter Krempa <pkrempa@redhat.com>
Tue, 29 Mar 2016 13:47:40 +0000 (15:47 +0200)
committerPeter Krempa <pkrempa@redhat.com>
Tue, 29 Mar 2016 13:47:40 +0000 (15:47 +0200)
Historically we've used 'unsigned long' and allowed wrapping of negative
numbers for bandwidth values. Add a helper that will simplify adding
support for scaled integers and support for byte granularity while
keeping the compatibility with the older approach.

tools/vsh.c
tools/vsh.h

index cbe8189986827624f36961d710f3abd531e56f76..6bdc08296f45d1326f474e6e97c4d346836c8df3 100644 (file)
@@ -1201,6 +1201,58 @@ vshCommandOptArgv(vshControl *ctl ATTRIBUTE_UNUSED, const vshCmd *cmd,
 }
 
 
+/**
+ * vshBlockJobOptionBandwidth:
+ * @ctl: virsh control data
+ * @cmd: virsh command description
+ * @bytes: return bandwidth in bytes/s instead of MiB/s
+ * @bandwidth: return value
+ *
+ * Extracts the value of --bandwidth either as a wrap-able number without scale
+ * or as a scaled integer. The returned value is checked to fit into a unsigned
+ * long data type. This is a legacy compatibility function and it should not
+ * be used for things other the block job APIs.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+int
+vshBlockJobOptionBandwidth(vshControl *ctl,
+                           const vshCmd *cmd,
+                           bool bytes,
+                           unsigned long *bandwidth)
+{
+    vshCmdOpt *arg;
+    char *end;
+    unsigned long long bw;
+    int ret;
+
+    if ((ret = vshCommandOpt(cmd, "bandwidth", &arg, true)) <= 0)
+        return ret;
+
+    /* due to historical reasons we declare to parse negative numbers and wrap
+     * them to the unsigned data type. */
+    if (virStrToLong_ul(arg->data, NULL, 10, bandwidth) < 0) {
+        /* try to parse the number as scaled size in this case we don't accept
+         * wrapping since it would be ridiculous. In case of a 32 bit host,
+         * limit the value to ULONG_MAX */
+        if (virStrToLong_ullp(arg->data, &end, 10, &bw) < 0 ||
+            virScaleInteger(&bw, end, 1, ULONG_MAX) < 0) {
+            vshError(ctl,
+                     _("Scaled numeric value '%s' for <--bandwidth> option is "
+                       "malformed or out of range"), arg->data);
+            return -1;
+        }
+
+        if (!bytes)
+            bw >>= 20;
+
+        *bandwidth = bw;
+    }
+
+    return 0;
+}
+
+
 /*
  * Executes command(s) and returns return code from last command
  */
index f6e40e64e80e46f41a6193ec9197b3c31ceeb5f2..f738a6f1182081ac3a9090aab6cec541c1d0f61a 100644 (file)
@@ -291,6 +291,10 @@ int vshCommandOptScaledInt(vshControl *ctl, const vshCmd *cmd,
                            const char *name, unsigned long long *value,
                            int scale, unsigned long long max)
     ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
+int vshBlockJobOptionBandwidth(vshControl *ctl,
+                               const vshCmd *cmd,
+                               bool bytes,
+                               unsigned long *bandwidth);
 bool vshCommandOptBool(const vshCmd *cmd, const char *name);
 bool vshCommandRun(vshControl *ctl, const vshCmd *cmd);
 bool vshCommandStringParse(vshControl *ctl, char *cmdstr);