[PATCHv3 02/10] threshold: expose new API in virsh

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

 



Add a new 'virsh domblkthreshold' command to use the new API.

The main use is an obvious mapping to the new API:
 virsh domblkthreshold $dom $disk 10000000 # 10M bytes
or
 virsh domblkthreshold $dom $disk 101000 --proportion # 10.1%
but I also wanted to be lazy at computing parts per million,
so I allow:
 virsh domblkthreshold $dom $disk --percentage 10.1% # as before

* tools/virsh.pod (domblkthreshold): Document it.
* tools/virsh-domain-monitor.c (cmdDomblkthreshold): New function.
(domMonitoringCmds): Register it.

Signed-off-by: Eric Blake <eblake@xxxxxxxxxx>
---
 tools/virsh-domain-monitor.c | 108 +++++++++++++++++++++++++++++++++++++++++++
 tools/virsh.pod              |  25 ++++++++++
 2 files changed, 133 insertions(+)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 1d4dc25..5a0287f 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -571,6 +571,108 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 }

 /*
+ * "domblkthreshold" command
+ */
+static const vshCmdInfo info_domblkthreshold[] = {
+    {.name = "help",
+     .data = N_("set domain block device write thresholds")
+    },
+    {.name = "desc",
+     .data = N_("Set a threshold to get a one-shot event if block "
+                "allocation exceeds that size")
+    },
+    {.name = NULL}
+};
+
+static const vshCmdOptDef opts_domblkthreshold[] = {
+    {.name = "domain",
+     .type = VSH_OT_DATA,
+     .flags = VSH_OFLAG_REQ,
+     .help = N_("domain name, id or uuid"),
+    },
+    {.name = "device",
+     .type = VSH_OT_DATA,
+     .flags = VSH_OFLAG_REQ,
+     .help = N_("block device"),
+    },
+    {.name = "threshold",
+     .type = VSH_OT_INT,
+     .help = N_("new threshold, or 0 to disable"),
+    },
+    {.name = "proportion",
+     .type = VSH_OT_BOOL,
+     .help = N_("threshold is in parts-per-million instead of bytes"),
+    },
+    {.name = "percentage",
+     .type = VSH_OT_STRING, /* floating point doesn't have an option type */
+     .flags = VSH_OFLAG_REQ_OPT,
+     .help = N_("determine threshold from a percentage"),
+    },
+    {.name = NULL}
+};
+
+static bool
+cmdDomblkthreshold(vshControl *ctl, const vshCmd *cmd)
+{
+    virDomainPtr dom;
+    bool ret = false;
+    const char *device = NULL;
+    unsigned long long threshold;
+    bool proportion = vshCommandOptBool(cmd, "proportion");
+    unsigned int flags = 0;
+    const char *percentage = NULL;
+
+    VSH_EXCLUSIVE_OPTIONS("threshold", "percentage");
+    VSH_EXCLUSIVE_OPTIONS("proportion", "percentage");
+
+    if (vshCommandOptStringReq(ctl, cmd, "percentage", &percentage) < 0)
+        return false;
+    if (percentage) {
+        char *end;
+        double raw;
+
+        if (virStrToDouble(percentage, &end, &raw) < 0 ||
+            end[*end == '%'] || raw < 0.0 || raw > 100.0) {
+            vshError(ctl, _("unable to parse '%s' as percentage"), percentage);
+            return false;
+        }
+        threshold = raw * 10000;
+        proportion = true;
+    } else if (!vshCommandOptBool(cmd, "threshold")) {
+        vshError(ctl, "%s",
+                 _("either --threshold or --percentage is required"));
+        return false;
+    } else if (vshCommandOptULongLong(ctl, cmd, "threshold", &threshold) < 0) {
+        return false;
+    }
+
+    if (proportion)
+        flags |= VIR_DOMAIN_BLOCK_SET_WRITE_THRESHOLD_PROPORTION;
+
+    if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+        return false;
+
+    if (vshCommandOptStringReq(ctl, cmd, "device", &device) < 0)
+        goto cleanup;
+
+    if (virDomainBlockSetWriteThreshold(dom, device, threshold, flags) < 0)
+        goto cleanup;
+
+    if (proportion)
+        vshPrint(ctl, _("threshold of %s set to %llu.%04llu%%\n"),
+                 device, threshold / 10000, threshold % 10000);
+    else
+        vshPrint(ctl, _("threshold of %s set to %llu bytes\n"),
+                 device, threshold);
+
+    ret = true;
+
+ cleanup:
+    virDomainFree(dom);
+    return ret;
+}
+
+/*
  * "domiflist" command
  */
 static const vshCmdInfo info_domiflist[] = {
@@ -2358,6 +2460,12 @@ const vshCmdDef domMonitoringCmds[] = {
      .info = info_domblkstat,
      .flags = 0
     },
+    {.name = "domblkthreshold",
+     .handler = cmdDomblkthreshold,
+     .opts = opts_domblkthreshold,
+     .info = info_domblkthreshold,
+     .flags = 0
+    },
     {.name = "domcontrol",
      .handler = cmdDomControl,
      .opts = opts_domcontrol,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 600ea42..1b67a72 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -843,6 +843,31 @@ that require a block device name (such as I<domblkinfo> or
 I<snapshot-create> for disk snapshots) will accept either target
 or unique source names printed by this command.

+=item B<domblkthreshold> I<domain> I<block-device> { I<threshold>
+[I<--proportion>] | I<--percentage> I<value> }
+
+Set the write threshold for a block device of a domain.  A
+I<block-device> corresponds to a unique target name (<target
+dev='name'/>) or source file (<source file='name'/>) for one of the
+disk devices attached to I<domain> (see also B<domblklist> for listing
+these names).  Some hypervisors also allow "vda[1]" to set a threshold
+on the first backing file of the target "vda", useful when doing a
+block commit.
+
+By default, I<threshold> is the byte offset within the host that will
+trigger an event; but if I<--proportion> is used, the threshold is
+instead a parts-per-million relative to the disk size (800000 maps to
+an 80% threshold).  It is also possible to use I<--percentage=80.00>
+as shorthand for I<--proportion --threshold=800000>.
+
+Setting a write threshold causes an event to be delivered if the
+allocation of I<block-device> passes that point, allowing a user to
+resize the underlying storage before the guest would be forcefully
+paused due to an ENOSPC scenario.  The B<event> command can be used to
+listen for such events.  If the hypervisor does not support event
+notification, then B<domblkinfo> must instead be polled to track
+allocation over time.  The current threshold is listed in B<domstats>.
+
 =item B<domstats> [I<--raw>] [I<--enforce>] [I<--backing>] [I<--state>]
 [I<--cpu-total>] [I<--balloon>] [I<--vcpu>] [I<--interface>] [I<--block>]
 [[I<--list-active>] [I<--list-inactive>] [I<--list-persistent>]
-- 
2.4.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]