mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-30 18:50:18 +03:00
virsh: Add support for throttle group operations
Implement new throttle cmds * Add new virsh cmds: domthrottlegroupset, domthrottlegrouplist, domthrottlegroupinfo, domthrottlegroupdel * Add doc for new cmds at docs/manpages/virsh.rst * Add cmd helper "virshDomainThrottleGroupCompleter", which is used by domthrottlegroupset, domthrottlegroupinfo, domthrottlegroupdel Signed-off-by: Chun Feng Wu <danielwuwy@163.com> * Update of code documentation comments. * Reimplement Get throttle group from XML. Signed-off-by: Harikumar Rajkumar <harirajkumar230@gmail.com>a * Fixed memleaks * Rewrote getter to avoid extra copies * Simplified name extractor Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
This commit is contained in:
parent
f839ff5887
commit
180d41934c
@ -1164,6 +1164,140 @@ given, but *--current* is exclusive. For querying only one of *--live*,
|
||||
is different depending on hypervisor.
|
||||
|
||||
|
||||
domthrottlegroupset
|
||||
-------------------
|
||||
|
||||
**Syntax:**
|
||||
|
||||
::
|
||||
|
||||
domthrottlegroupset domain group-name [[--config] [--live] | [--current]]
|
||||
[[total-bytes-sec] | [read-bytes-sec] [write-bytes-sec]]
|
||||
[[total-iops-sec] | [read-iops-sec] [write-iops-sec]]
|
||||
[[total-bytes-sec-max] | [read-bytes-sec-max] [write-bytes-sec-max]]
|
||||
[[total-iops-sec-max] | [read-iops-sec-max] [write-iops-sec-max]]
|
||||
[[total-bytes-sec-max-length] |
|
||||
[read-bytes-sec-max-length] [write-bytes-sec-max-length]]
|
||||
[[total-iops-sec-max-length] |
|
||||
[read-iops-sec-max-length] [write-iops-sec-max-length]]
|
||||
[size-iops-sec]
|
||||
|
||||
Add or update a throttle group against specific *domain*.
|
||||
*group-name* specifies a unique throttle group name, which defines limit, and
|
||||
will be referenced by drives.
|
||||
|
||||
If no limit is specified, default them as all zeros, which will fail,
|
||||
Otherwise, set limits with these flags:
|
||||
*--total-bytes-sec* specifies total throughput limit as a scaled integer, the
|
||||
default being bytes per second if no suffix is specified.
|
||||
*--read-bytes-sec* specifies read throughput limit as a scaled integer, the
|
||||
default being bytes per second if no suffix is specified.
|
||||
*--write-bytes-sec* specifies write throughput limit as a scaled integer, the
|
||||
default being bytes per second if no suffix is specified.
|
||||
*--total-iops-sec* specifies total I/O operations limit per second.
|
||||
*--read-iops-sec* specifies read I/O operations limit per second.
|
||||
*--write-iops-sec* specifies write I/O operations limit per second.
|
||||
*--total-bytes-sec-max* specifies maximum total throughput limit as a scaled
|
||||
integer, the default being bytes per second if no suffix is specified
|
||||
*--read-bytes-sec-max* specifies maximum read throughput limit as a scaled
|
||||
integer, the default being bytes per second if no suffix is specified.
|
||||
*--write-bytes-sec-max* specifies maximum write throughput limit as a scaled
|
||||
integer, the default being bytes per second if no suffix is specified.
|
||||
*--total-iops-sec-max* specifies maximum total I/O operations limit per second.
|
||||
*--read-iops-sec-max* specifies maximum read I/O operations limit per second.
|
||||
*--write-iops-sec-max* specifies maximum write I/O operations limit per second.
|
||||
*--total-bytes-sec-max-length* specifies duration in seconds to allow maximum
|
||||
total throughput limit.
|
||||
*--read-bytes-sec-max-length* specifies duration in seconds to allow maximum
|
||||
read throughput limit.
|
||||
*--write-bytes-sec-max-length* specifies duration in seconds to allow maximum
|
||||
write throughput limit.
|
||||
*--total-iops-sec-max-length* specifies duration in seconds to allow maximum
|
||||
total I/O operations limit.
|
||||
*--read-iops-sec-max-length* specifies duration in seconds to allow maximum
|
||||
read I/O operations limit.
|
||||
*--write-iops-sec-max-length* specifies duration in seconds to allow maximum
|
||||
write I/O operations limit.
|
||||
*--size-iops-sec* specifies size I/O operations limit per second.
|
||||
|
||||
Bytes and iops values are independent, but setting only one value (such
|
||||
as --read-bytes-sec) resets the other two in that category to unlimited.
|
||||
An explicit 0 also clears any limit. A non-zero value for a given total
|
||||
cannot be mixed with non-zero values for read or write.
|
||||
|
||||
It is up to the hypervisor to determine how to handle the length values.
|
||||
For the QEMU hypervisor, if an I/O limit value or maximum value is set,
|
||||
then the default value of 1 second will be displayed. Supplying a 0 will
|
||||
reset the value back to the default.
|
||||
|
||||
If *--live* is specified, affect a running guest.
|
||||
If *--config* is specified, affect the next start of a persistent guest.
|
||||
If *--current* is specified, it is equivalent to either *--live* or
|
||||
*--config*, depending on the current state of the guest.
|
||||
When setting the disk io parameters both *--live* and *--config*
|
||||
are specified, both live configuration and config are updated while setting
|
||||
the description, but *--current* is exclusive. If no flag is specified, behavior
|
||||
is different depending on hypervisor.
|
||||
|
||||
|
||||
domthrottlegroupdel
|
||||
-------------------
|
||||
|
||||
**Syntax:**
|
||||
|
||||
::
|
||||
|
||||
domthrottlegroupdel domain group-name [[--config] [--live] | [--current]]
|
||||
|
||||
Delete a Throttlegroup from the domain using the specified *group-name*.
|
||||
If an Throttlegroup is currently referenced by a disk resource, then the attempt
|
||||
to remove the Throttlegroup will fail.
|
||||
If the *group-name* does not exist an error will occur.
|
||||
|
||||
If *--live* is specified, affect a running guest. If the guest is not
|
||||
running an error is returned.
|
||||
If *--config* is specified, affect the next start of a persistent guest.
|
||||
If *--current* is specified, it is equivalent to either *--live* or
|
||||
*--config*, depending on the current state of the guest.
|
||||
|
||||
|
||||
domthrottlegroupinfo
|
||||
--------------------
|
||||
|
||||
**Syntax:**
|
||||
|
||||
::
|
||||
|
||||
domthrottlegroupinfo domain group-name [[--config] [--live] | [--current]]
|
||||
|
||||
Display domain Throttlegroup information including I/O limits setting.
|
||||
|
||||
If *--live* is specified, get the Throttlegroup data from the running guest. If
|
||||
the guest is not running, an error is returned.
|
||||
If *--config* is specified, get the Throttlegroup data from the next start of
|
||||
a persistent guest.
|
||||
If *--current* is specified or *--live* and *--config* are not specified,
|
||||
then get the Throttlegroup data based on the current guest state, which can
|
||||
either be live or offline.
|
||||
If both *--live* and *--config* are specified, the *--config* option takes
|
||||
precedence on getting the current description.
|
||||
|
||||
|
||||
domthrottlegrouplist
|
||||
--------------------
|
||||
|
||||
**Syntax:**
|
||||
|
||||
::
|
||||
|
||||
domthrottlegrouplist domain [--inactive]
|
||||
|
||||
Print a table showing names of all throttle groups
|
||||
associated with *domain*. If *--inactive* is specified, query the
|
||||
Throttlegroup data that will be used on the next boot, rather than those
|
||||
currently in use by a running domain.
|
||||
|
||||
|
||||
blkiotune
|
||||
---------
|
||||
|
||||
|
@ -248,6 +248,51 @@ virshDomainMigrateDisksCompleter(vshControl *ctl,
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshGetThrottleGroupNames(xmlXPathContext *ctxt)
|
||||
{
|
||||
g_auto(GStrv) groupNames = NULL;
|
||||
g_autofree xmlNodePtr *groups = NULL;
|
||||
int ngroups;
|
||||
size_t i;
|
||||
|
||||
if ((ngroups = virXPathNodeSet("./throttlegroups/throttlegroup", ctxt, &groups)) < 0)
|
||||
return NULL;
|
||||
|
||||
groupNames = g_new0(char *, ngroups + 1);
|
||||
|
||||
for (i = 0; i < ngroups; i++) {
|
||||
ctxt->node = groups[i];
|
||||
|
||||
if (!(groupNames[i] = virXPathString("string(./group_name)", ctxt)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_steal_pointer(&groupNames);
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshDomainThrottleGroupCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags)
|
||||
{
|
||||
virshControl *priv = ctl->privData;
|
||||
g_autoptr(xmlDoc) xmldoc = NULL;
|
||||
g_autoptr(xmlXPathContext) ctxt = NULL;
|
||||
|
||||
virCheckFlags(0, NULL);
|
||||
|
||||
if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
|
||||
return NULL;
|
||||
|
||||
if (virshDomainGetXML(ctl, cmd, 0, &xmldoc, &ctxt) < 0)
|
||||
return NULL;
|
||||
|
||||
return virshGetThrottleGroupNames(ctxt);
|
||||
}
|
||||
|
||||
|
||||
char **
|
||||
virshDomainUndefineStorageDisksCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
|
@ -21,6 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "vsh.h"
|
||||
#include <libxml/xpath.h>
|
||||
|
||||
char **
|
||||
virshDomainNameCompleter(vshControl *ctl,
|
||||
@ -41,6 +42,14 @@ virshDomainDiskTargetCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
||||
char **
|
||||
virshGetThrottleGroupNames(xmlXPathContext *ctxt);
|
||||
|
||||
char **
|
||||
virshDomainThrottleGroupCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
unsigned int flags);
|
||||
|
||||
char **
|
||||
virshDomainInterfaceStateCompleter(vshControl *ctl,
|
||||
const vshCmd *cmd,
|
||||
|
@ -1395,7 +1395,7 @@ static const vshCmdOptDef opts_blkdeviotune[] = {
|
||||
VIRSH_COMMON_OPT_DOMAIN_CURRENT,
|
||||
{.name = NULL}
|
||||
};
|
||||
#undef VSH_OPTS_IOTUNE
|
||||
|
||||
|
||||
static bool
|
||||
cmdBlkdeviotune(vshControl *ctl, const vshCmd *cmd)
|
||||
@ -1533,6 +1533,348 @@ cmdBlkdeviotune(vshControl *ctl, const vshCmd *cmd)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "domthrottlegrouplist" command
|
||||
*/
|
||||
static const vshCmdInfo info_domthrottlegrouplist = {
|
||||
.help = N_("list all domain throttlegroups."),
|
||||
.desc = N_("Get the summary of throttle groups for a domain."),
|
||||
};
|
||||
|
||||
|
||||
static const vshCmdOptDef opts_domthrottlegrouplist[] = {
|
||||
VIRSH_COMMON_OPT_DOMAIN_FULL(0),
|
||||
{.name = "inactive",
|
||||
.type = VSH_OT_BOOL,
|
||||
.help = N_("get inactive rather than running configuration")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
|
||||
static bool
|
||||
cmdThrottleGroupList(vshControl *ctl,
|
||||
const vshCmd *cmd)
|
||||
{
|
||||
unsigned int flags = 0;
|
||||
g_autoptr(xmlDoc) xml = NULL;
|
||||
g_autoptr(xmlXPathContext) ctxt = NULL;
|
||||
g_auto(GStrv) groupNames = NULL;
|
||||
char **n;
|
||||
g_autoptr(vshTable) table = NULL;
|
||||
|
||||
if (vshCommandOptBool(cmd, "inactive"))
|
||||
flags |= VIR_DOMAIN_XML_INACTIVE;
|
||||
|
||||
if (virshDomainGetXML(ctl, cmd, flags, &xml, &ctxt) < 0)
|
||||
return false;
|
||||
|
||||
if (!(table = vshTableNew(_("Name"), NULL)))
|
||||
return false;
|
||||
|
||||
if (!(groupNames = virshGetThrottleGroupNames(ctxt)))
|
||||
return false;
|
||||
|
||||
for (n = groupNames; *n; n++) {
|
||||
if (vshTableRowAppend(table, *n, NULL) < 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
vshTablePrintToStdout(table, ctl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "domthrottlegroupset" command
|
||||
*/
|
||||
static const vshCmdInfo info_domthrottlegroupset = {
|
||||
.help = N_("Add or update a throttling group."),
|
||||
.desc = N_("Add or updte a throttling group."),
|
||||
};
|
||||
|
||||
|
||||
static const vshCmdOptDef opts_domthrottlegroupset[] = {
|
||||
VIRSH_COMMON_OPT_DOMAIN_FULL(0),
|
||||
{.name = "group-name",
|
||||
.type = VSH_OT_STRING,
|
||||
.positional = true,
|
||||
.required = true,
|
||||
.completer = virshDomainThrottleGroupCompleter,
|
||||
.help = N_("throttle group name")
|
||||
},
|
||||
VSH_OPTS_IOTUNE,
|
||||
VIRSH_COMMON_OPT_DOMAIN_CONFIG,
|
||||
VIRSH_COMMON_OPT_DOMAIN_LIVE,
|
||||
VIRSH_COMMON_OPT_DOMAIN_CURRENT,
|
||||
{.name = NULL}
|
||||
};
|
||||
#undef VSH_OPTS_IOTUNE
|
||||
|
||||
|
||||
static bool
|
||||
cmdThrottleGroupSet(vshControl *ctl,
|
||||
const vshCmd *cmd)
|
||||
{
|
||||
g_autoptr(virshDomain) dom = NULL;
|
||||
const char *group_name = NULL;
|
||||
unsigned long long value;
|
||||
int nparams = 0;
|
||||
int maxparams = 0;
|
||||
virTypedParameterPtr params = NULL;
|
||||
unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
|
||||
int rv = 0;
|
||||
bool current = vshCommandOptBool(cmd, "current");
|
||||
bool config = vshCommandOptBool(cmd, "config");
|
||||
bool live = vshCommandOptBool(cmd, "live");
|
||||
bool ret = false;
|
||||
|
||||
VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
|
||||
VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
|
||||
|
||||
if (config)
|
||||
flags |= VIR_DOMAIN_AFFECT_CONFIG;
|
||||
if (live)
|
||||
flags |= VIR_DOMAIN_AFFECT_LIVE;
|
||||
|
||||
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
||||
goto cleanup;
|
||||
|
||||
|
||||
#define VSH_SET_THROTTLE_GROUP_SCALED(PARAM, CONST) \
|
||||
if ((rv = vshCommandOptScaledInt(ctl, cmd, #PARAM, &value, \
|
||||
1, ULLONG_MAX)) < 0) { \
|
||||
goto interror; \
|
||||
} else if (rv > 0) { \
|
||||
if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, \
|
||||
VIR_DOMAIN_BLOCK_IOTUNE_##CONST, \
|
||||
value) < 0) \
|
||||
goto save_error; \
|
||||
}
|
||||
|
||||
VSH_SET_THROTTLE_GROUP_SCALED(total-bytes-sec, TOTAL_BYTES_SEC);
|
||||
VSH_SET_THROTTLE_GROUP_SCALED(read-bytes-sec, READ_BYTES_SEC);
|
||||
VSH_SET_THROTTLE_GROUP_SCALED(write-bytes-sec, WRITE_BYTES_SEC);
|
||||
VSH_SET_THROTTLE_GROUP_SCALED(total-bytes-sec-max, TOTAL_BYTES_SEC_MAX);
|
||||
VSH_SET_THROTTLE_GROUP_SCALED(read-bytes-sec-max, READ_BYTES_SEC_MAX);
|
||||
VSH_SET_THROTTLE_GROUP_SCALED(write-bytes-sec-max, WRITE_BYTES_SEC_MAX);
|
||||
#undef VSH_SET_THROTTLE_GROUP_SCALED
|
||||
|
||||
#define VSH_SET_THROTTLE_GROUP(PARAM, CONST) \
|
||||
if ((rv = vshCommandOptULongLong(ctl, cmd, #PARAM, &value)) < 0) { \
|
||||
goto interror; \
|
||||
} else if (rv > 0) { \
|
||||
if (virTypedParamsAddULLong(¶ms, &nparams, &maxparams, \
|
||||
VIR_DOMAIN_BLOCK_IOTUNE_##CONST, \
|
||||
value) < 0) \
|
||||
goto save_error; \
|
||||
}
|
||||
|
||||
VSH_SET_THROTTLE_GROUP(total-iops-sec, TOTAL_IOPS_SEC);
|
||||
VSH_SET_THROTTLE_GROUP(read-iops-sec, READ_IOPS_SEC);
|
||||
VSH_SET_THROTTLE_GROUP(write-iops-sec, WRITE_IOPS_SEC);
|
||||
VSH_SET_THROTTLE_GROUP(total-iops-sec-max, TOTAL_IOPS_SEC_MAX);
|
||||
VSH_SET_THROTTLE_GROUP(read-iops-sec-max, READ_IOPS_SEC_MAX);
|
||||
VSH_SET_THROTTLE_GROUP(write-iops-sec-max, WRITE_IOPS_SEC_MAX);
|
||||
VSH_SET_THROTTLE_GROUP(size-iops-sec, SIZE_IOPS_SEC);
|
||||
|
||||
VSH_SET_THROTTLE_GROUP(total-bytes-sec-max-length, TOTAL_BYTES_SEC_MAX_LENGTH);
|
||||
VSH_SET_THROTTLE_GROUP(read-bytes-sec-max-length, READ_BYTES_SEC_MAX_LENGTH);
|
||||
VSH_SET_THROTTLE_GROUP(write-bytes-sec-max-length, WRITE_BYTES_SEC_MAX_LENGTH);
|
||||
VSH_SET_THROTTLE_GROUP(total-iops-sec-max-length, TOTAL_IOPS_SEC_MAX_LENGTH);
|
||||
VSH_SET_THROTTLE_GROUP(read-iops-sec-max-length, READ_IOPS_SEC_MAX_LENGTH);
|
||||
VSH_SET_THROTTLE_GROUP(write-iops-sec-max-length, WRITE_IOPS_SEC_MAX_LENGTH);
|
||||
#undef VSH_SET_THROTTLE_GROUP
|
||||
|
||||
if (vshCommandOptString(ctl, cmd, "group-name", &group_name) < 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (group_name) {
|
||||
if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
|
||||
VIR_DOMAIN_BLOCK_IOTUNE_GROUP_NAME,
|
||||
group_name) < 0)
|
||||
goto save_error;
|
||||
}
|
||||
|
||||
if (virDomainSetThrottleGroup(dom, group_name, params, nparams, flags) < 0)
|
||||
goto error;
|
||||
vshPrintExtra(ctl, "%s", _("Throttle group set successfully\n"));
|
||||
|
||||
ret = true;
|
||||
|
||||
cleanup:
|
||||
virTypedParamsFree(params, nparams);
|
||||
return ret;
|
||||
|
||||
save_error:
|
||||
vshSaveLibvirtError();
|
||||
error:
|
||||
vshError(ctl, "%s", _("Unable to set throttle group"));
|
||||
goto cleanup;
|
||||
|
||||
interror:
|
||||
vshError(ctl, "%s", _("Unable to parse integer parameter"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "domthrottlegroupdel" command
|
||||
*/
|
||||
static const vshCmdInfo info_domthrottlegroupdel = {
|
||||
.help = N_("Delete a throttling group."),
|
||||
.desc = N_("Delete a throttling group."),
|
||||
};
|
||||
|
||||
|
||||
static const vshCmdOptDef opts_domthrottlegroupdel[] = {
|
||||
VIRSH_COMMON_OPT_DOMAIN_FULL(0),
|
||||
{.name = "group-name",
|
||||
.type = VSH_OT_STRING,
|
||||
.positional = true,
|
||||
.required = true,
|
||||
.completer = virshDomainThrottleGroupCompleter,
|
||||
.help = N_("throttle group name")
|
||||
},
|
||||
VIRSH_COMMON_OPT_DOMAIN_CONFIG,
|
||||
VIRSH_COMMON_OPT_DOMAIN_LIVE,
|
||||
VIRSH_COMMON_OPT_DOMAIN_CURRENT,
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
|
||||
static bool
|
||||
cmdThrottleGroupDel(vshControl *ctl,
|
||||
const vshCmd *cmd)
|
||||
{
|
||||
g_autoptr(virshDomain) dom = NULL;
|
||||
const char *group_name = NULL;
|
||||
bool config = vshCommandOptBool(cmd, "config");
|
||||
bool live = vshCommandOptBool(cmd, "live");
|
||||
bool current = vshCommandOptBool(cmd, "current");
|
||||
unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
|
||||
|
||||
VSH_EXCLUSIVE_OPTIONS_VAR(current, live);
|
||||
VSH_EXCLUSIVE_OPTIONS_VAR(current, config);
|
||||
|
||||
if (config)
|
||||
flags |= VIR_DOMAIN_AFFECT_CONFIG;
|
||||
if (live)
|
||||
flags |= VIR_DOMAIN_AFFECT_LIVE;
|
||||
|
||||
if (!(dom = virshCommandOptDomain(ctl, cmd, NULL)))
|
||||
return false;
|
||||
|
||||
if (vshCommandOptString(ctl, cmd, "group-name", &group_name) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (virDomainDelThrottleGroup(dom, group_name, flags) < 0)
|
||||
return false;
|
||||
vshPrintExtra(ctl, "%s", _("Throttle group deleted successfully\n"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* "domthrottlegroupinfo" command
|
||||
*/
|
||||
static const vshCmdInfo info_domthrottlegroupinfo = {
|
||||
.help = N_("Get a throttling group."),
|
||||
.desc = N_("Get a throttling group."),
|
||||
};
|
||||
|
||||
|
||||
static const vshCmdOptDef opts_domthrottlegroupinfo[] = {
|
||||
VIRSH_COMMON_OPT_DOMAIN_FULL(0),
|
||||
{.name = "group-name",
|
||||
.type = VSH_OT_STRING,
|
||||
.positional = true,
|
||||
.required = true,
|
||||
.completer = virshDomainThrottleGroupCompleter,
|
||||
.help = N_("throttle group name")
|
||||
},
|
||||
{.name = "inactive",
|
||||
.type = VSH_OT_BOOL,
|
||||
.help = N_("get inactive rather than running configuration")
|
||||
},
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
|
||||
#define PARSE_THROTTLE_GROUP(val) \
|
||||
do { \
|
||||
g_autofree char *str = virXPathString("string(./" #val ")", ctxt); \
|
||||
if (str) \
|
||||
vshPrint(ctl, "%-15s: %s\n", #val, str); \
|
||||
} while (false)
|
||||
|
||||
static bool
|
||||
cmdThrottleGroupInfo(vshControl *ctl,
|
||||
const vshCmd *cmd)
|
||||
{
|
||||
const char *group_name = NULL;
|
||||
unsigned int flags = 0;
|
||||
g_autoptr(xmlDoc) xml = NULL;
|
||||
g_autoptr(xmlXPathContext) ctxt = NULL;
|
||||
g_autofree xmlNodePtr *node = NULL;
|
||||
int n = 0;
|
||||
size_t i;
|
||||
|
||||
if (vshCommandOptBool(cmd, "inactive"))
|
||||
flags |= VIR_DOMAIN_XML_INACTIVE;
|
||||
|
||||
if (vshCommandOptString(ctl, cmd, "group-name", &group_name) < 0)
|
||||
return false;
|
||||
|
||||
if (virshDomainGetXML(ctl, cmd, flags, &xml, &ctxt) < 0)
|
||||
return false;
|
||||
|
||||
if ((n = virXPathNodeSet("/domain/throttlegroups/throttlegroup", ctxt, &node)) < 0)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
g_autofree char *name = NULL;
|
||||
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
||||
ctxt->node = node[i];
|
||||
|
||||
name = virXPathString("string(./group_name)", ctxt);
|
||||
|
||||
if (STRNEQ_NULLABLE(group_name, name))
|
||||
continue;
|
||||
|
||||
PARSE_THROTTLE_GROUP(total_bytes_sec);
|
||||
PARSE_THROTTLE_GROUP(read_bytes_sec);
|
||||
PARSE_THROTTLE_GROUP(write_bytes_sec);
|
||||
PARSE_THROTTLE_GROUP(total_iops_sec);
|
||||
PARSE_THROTTLE_GROUP(read_iops_sec);
|
||||
PARSE_THROTTLE_GROUP(write_iops_sec);
|
||||
|
||||
PARSE_THROTTLE_GROUP(total_bytes_sec_max);
|
||||
PARSE_THROTTLE_GROUP(read_bytes_sec_max);
|
||||
PARSE_THROTTLE_GROUP(write_bytes_sec_max);
|
||||
PARSE_THROTTLE_GROUP(total_iops_sec_max);
|
||||
PARSE_THROTTLE_GROUP(read_iops_sec_max);
|
||||
PARSE_THROTTLE_GROUP(write_iops_sec_max);
|
||||
|
||||
PARSE_THROTTLE_GROUP(size_iops_sec);
|
||||
|
||||
PARSE_THROTTLE_GROUP(total_bytes_sec_max_length);
|
||||
PARSE_THROTTLE_GROUP(read_bytes_sec_max_length);
|
||||
PARSE_THROTTLE_GROUP(write_bytes_sec_max_length);
|
||||
PARSE_THROTTLE_GROUP(total_iops_sec_max_length);
|
||||
PARSE_THROTTLE_GROUP(read_iops_sec_max_length);
|
||||
PARSE_THROTTLE_GROUP(write_iops_sec_max_length);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#undef PARSE_THROTTLE_GROUP
|
||||
|
||||
/*
|
||||
* "blkiotune" command
|
||||
*/
|
||||
@ -13463,6 +13805,30 @@ const vshCmdDef domManagementCmds[] = {
|
||||
.info = &info_blkdeviotune,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "domthrottlegroupset",
|
||||
.handler = cmdThrottleGroupSet,
|
||||
.opts = opts_domthrottlegroupset,
|
||||
.info = &info_domthrottlegroupset,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "domthrottlegroupdel",
|
||||
.handler = cmdThrottleGroupDel,
|
||||
.opts = opts_domthrottlegroupdel,
|
||||
.info = &info_domthrottlegroupdel,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "domthrottlegroupinfo",
|
||||
.handler = cmdThrottleGroupInfo,
|
||||
.opts = opts_domthrottlegroupinfo,
|
||||
.info = &info_domthrottlegroupinfo,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "domthrottlegrouplist",
|
||||
.handler = cmdThrottleGroupList,
|
||||
.opts = opts_domthrottlegrouplist,
|
||||
.info = &info_domthrottlegrouplist,
|
||||
.flags = 0
|
||||
},
|
||||
{.name = "blkiotune",
|
||||
.handler = cmdBlkiotune,
|
||||
.opts = opts_blkiotune,
|
||||
|
Loading…
x
Reference in New Issue
Block a user