Add a new 'virsh domblkthreshold' command to use the new API.
* tools/virsh.pod (domblkthreshold): Document it.
* tools/virsh-domain-monitor.c (cmdDomblkthreshold): New function.
(domMonitoringCmds): Register it.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
tools/virsh-domain-monitor.c | 81 ++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 24 +++++++++++++
2 files changed, 105 insertions(+)
diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 1d4dc25..66f7571 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -571,6 +571,81 @@ 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,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("new threshold, or 0 to disable"),
+ },
+ {.name = "percentage",
+ .type = VSH_OT_BOOL,
+ .help = N_("threshold is in units of .001% instead of bytes"),
+ },
+ {.name = NULL}
+};
+
+static bool
+cmdDomblkthreshold(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom;
+ bool ret = false;
+ const char *device = NULL;
+ unsigned long long threshold;
+ bool percentage = vshCommandOptBool(cmd, "percentage");
+ unsigned int flags = 0;
+
+ if (percentage)
+ flags |= VIR_DOMAIN_BLOCK_SET_WRITE_THRESHOLD_PERCENTAGE;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, NULL)))
+ return false;
+
+ if (vshCommandOptStringReq(ctl, cmd, "device", &device) < 0)
+ goto cleanup;
+ if (vshCommandOptULongLong(ctl, cmd, "threshold", &threshold) < 0)
+ goto cleanup;
+
+ if (virDomainBlockSetWriteThreshold(dom, device, threshold, flags) < 0)
+ goto cleanup;
+
+ if (percentage)
+ vshPrint(ctl, _("threshold of %s set to %llu.%03llu%%\n"),
+ device, threshold / 1000, threshold % 1000);
+ 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 +2433,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 84e8fc4..1c94651 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -843,6 +843,30 @@ 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<--percentage>]
+
+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<--percentage> is used, it is instead a
+thousandth of a percent of the disk size (80000 maps to an 80%
+threshold).
+
+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.2