From: Chun Feng Wu <wucf(a)linux.ibm.com>
* Update "attach_disk" to support new option: throttle-groups to
form filter chain in QEMU for specific disk
Signed-off-by: Chun Feng Wu <wucf(a)linux.ibm.com>
---
tools/virsh-completer-domain.c | 64 ++++++++++++++++++++++++++++++++++
tools/virsh-completer-domain.h | 5 +++
tools/virsh-domain.c | 25 ++++++++++++-
3 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/tools/virsh-completer-domain.c b/tools/virsh-completer-domain.c
index 61362224a3..000cf65c99 100644
--- a/tools/virsh-completer-domain.c
+++ b/tools/virsh-completer-domain.c
@@ -248,6 +248,70 @@ virshDomainMigrateDisksCompleter(vshControl *ctl,
}
+static char **
+virshDomainThrottleGroupCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ unsigned int flags)
+{
+ virshControl *priv = ctl->privData;
+ g_autoptr(xmlDoc) xmldoc = NULL;
+ g_autoptr(xmlXPathContext) ctxt = NULL;
+ g_autofree xmlNodePtr *groups = NULL;
+ int ngroups;
+ size_t i;
+ g_auto(GStrv) tmp = NULL;
+
+ virCheckFlags(0, NULL);
+
+ if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
+ return NULL;
+
+ if (virshDomainGetXML(ctl, cmd, 0, &xmldoc, &ctxt) < 0)
+ return NULL;
+
+ ngroups = virXPathNodeSet("./throttlegroups/throttlegroup", ctxt,
&groups);
+ if (ngroups < 0)
+ return NULL;
+
+ tmp = g_new0(char *, ngroups + 1);
+
+ for (i = 0; i < ngroups; i++) {
+ ctxt->node = groups[i];
+ if (!(tmp[i] = virXPathString("string(./group_name)", ctxt)))
+ return NULL;
+ }
+
+ return g_steal_pointer(&tmp);
+}
+
+
+static char **
+virshDomainThrottleGroupListCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ const char *argname)
+{
+ const char *curval = NULL;
+ g_auto(GStrv) groups = virshDomainThrottleGroupCompleter(ctl, cmd, 0);
+
+ if (vshCommandOptStringQuiet(ctl, cmd, argname, &curval) < 0)
+ return NULL;
+
+ if (!groups)
+ return NULL;
+
+ return virshCommaStringListComplete(curval, (const char **) groups);
+}
+
+
+char **
+virshDomainThrottleGroupsCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ unsigned int completeflags G_GNUC_UNUSED)
+{
+ return virshDomainThrottleGroupListCompleter(ctl, cmd, "throttle-groups");
+}
+
+
char **
virshDomainUndefineStorageDisksCompleter(vshControl *ctl,
const vshCmd *cmd,
diff --git a/tools/virsh-completer-domain.h b/tools/virsh-completer-domain.h
index 27cf963912..95ec3e28df 100644
--- a/tools/virsh-completer-domain.h
+++ b/tools/virsh-completer-domain.h
@@ -41,6 +41,11 @@ virshDomainDiskTargetCompleter(vshControl *ctl,
const vshCmd *cmd,
unsigned int flags);
+char **
+virshDomainThrottleGroupsCompleter(vshControl *ctl,
+ const vshCmd *cmd,
+ unsigned int completeflags);
+
char **
virshDomainInterfaceStateCompleter(vshControl *ctl,
const vshCmd *cmd,
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index f84a65451a..ec2330c8dd 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -522,6 +522,11 @@ static const vshCmdOptDef opts_attach_disk[] = {
.type = VSH_OT_STRING,
.help = N_("host socket for source of disk device")
},
+ {.name = "throttle-groups",
+ .type = VSH_OT_STRING,
+ .completer = virshDomainThrottleGroupsCompleter,
+ .help = N_("comma separated list of throttle groups to be applied")
+ },
VIRSH_COMMON_OPT_DOMAIN_PERSISTENT,
VIRSH_COMMON_OPT_DOMAIN_CONFIG,
VIRSH_COMMON_OPT_DOMAIN_LIVE,
@@ -611,6 +616,8 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
const char *host_name = NULL;
const char *host_transport = NULL;
const char *host_socket = NULL;
+ const char *throttle_groups_str = NULL;
+ g_autofree char **throttle_groups = NULL;
int ret;
unsigned int flags = VIR_DOMAIN_AFFECT_CURRENT;
const char *stype = NULL;
@@ -622,6 +629,7 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
g_auto(virBuffer) sourceAttrBuf = VIR_BUFFER_INITIALIZER;
g_auto(virBuffer) sourceChildBuf = VIR_BUFFER_INIT_CHILD(&diskChildBuf);
g_auto(virBuffer) hostAttrBuf = VIR_BUFFER_INITIALIZER;
+ g_auto(virBuffer) throttleChildBuf = VIR_BUFFER_INITIALIZER;
g_autofree char *xml = NULL;
struct stat st;
bool current = vshCommandOptBool(cmd, "current");
@@ -665,9 +673,14 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
vshCommandOptString(ctl, cmd, "source-protocol", &source_protocol)
< 0 ||
vshCommandOptString(ctl, cmd, "source-host-name", &host_name) <
0 ||
vshCommandOptString(ctl, cmd, "source-host-transport",
&host_transport) < 0 ||
- vshCommandOptString(ctl, cmd, "source-host-socket", &host_socket)
< 0)
+ vshCommandOptString(ctl, cmd, "source-host-socket", &host_socket)
< 0 ||
+ vshCommandOptString(ctl, cmd, "throttle-groups",
&throttle_groups_str) < 0)
return false;
+ if (throttle_groups_str) {
+ throttle_groups = g_strsplit(throttle_groups_str, ",", 0);
+ }
+
if (stype &&
(type = virshAttachDiskSourceTypeFromString(stype)) < 0) {
vshError(ctl, _("Unknown source type: '%1$s'"), stype);
@@ -714,6 +727,16 @@ cmdAttachDisk(vshControl *ctl, const vshCmd *cmd)
virXMLFormatElement(&diskChildBuf, "driver", &driverAttrBuf,
NULL);
+ if (throttle_groups) {
+ char **iter;
+ for (iter = throttle_groups; *iter != NULL; iter++) {
+ g_auto(virBuffer) throttleAttrBuf = VIR_BUFFER_INITIALIZER;
+ virBufferAsprintf(&throttleAttrBuf, " group='%s'",
*iter);
+ virXMLFormatElement(&throttleChildBuf, "throttlefilter",
&throttleAttrBuf, NULL);
+ }
+ virXMLFormatElement(&diskChildBuf, "throttlefilters", NULL,
&throttleChildBuf);
+ }
+
switch ((enum virshAttachDiskSourceType) type) {
case VIRSH_ATTACH_DISK_SOURCE_TYPE_FILE:
virBufferEscapeString(&sourceAttrBuf, " file='%s'",
source);
--
2.34.1