From: Chun Feng Wu <wucf(a)linux.ibm.com>
* Add qemuBuildThrottleGroupCommandLine in qemuBuildCommandLine
* Add qemuBuildThrottleFiltersCommandLine in qemuBuildDiskCommandLine
* Make sure referenced throttle group exists
Signed-off-by: Chun Feng Wu <wucf(a)linux.ibm.com>
---
src/conf/domain_validate.c | 14 ++++++
src/qemu/qemu_command.c | 87 ++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_command.h | 3 ++
3 files changed, 104 insertions(+)
diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c
index 395e036e8f..fffe274afc 100644
--- a/src/conf/domain_validate.c
+++ b/src/conf/domain_validate.c
@@ -663,6 +663,7 @@ virDomainDiskDefValidate(const virDomainDef *def,
const virDomainDiskDef *disk)
{
virStorageSource *next;
+ size_t i;
/* disk target is used widely in other code so it must be validated first */
if (!disk->dst) {
@@ -942,6 +943,19 @@ virDomainDiskDefValidate(const virDomainDef *def,
return -1;
}
+ /* referenced group should be defined */
+ for (i = 0; i < disk->nthrottlefilters; i++) {
+ virDomainThrottleFilterDef *filter = disk->throttlefilters[i];
+ if (filter) {
+ if (!virDomainThrottleGroupFind(def, filter->group_name)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("throttle group '%1$s' not found"),
+ filter->group_name);
+ return -1;
+ }
+ }
+ }
+
return 0;
}
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 278b706616..e7cb20fd71 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1582,6 +1582,13 @@ qemuDiskConfigThrottleFilterChainEnabled(const virDomainDiskDef
*disk)
return disk->nthrottlefilters > 0;
}
+bool
+qemuDiskConfigThrottleFilterEnabled(const virDomainThrottleGroupDef *group)
+{
+ return !!group->group_name &&
+ virDomainBlockIoTuneInfoHasAny(group);
+}
+
/**
* qemuDiskBusIsSD:
@@ -2218,6 +2225,42 @@ qemuBuildBlockStorageSourceAttachDataCommandline(virCommand *cmd,
return 0;
}
+static int
+qemuBuildBlockThrottleFilterCommandline(virCommand *cmd,
+ qemuBlockThrottleFilterAttachData
*data)
+{
+ char *tmp;
+
+ if (data->filterProps) {
+ if (!(tmp = virJSONValueToString(data->filterProps, false)))
+ return -1;
+
+ virCommandAddArgList(cmd, "-blockdev", tmp, NULL);
+ VIR_FREE(tmp);
+ }
+
+ return 0;
+}
+
+static int
+qemuBuildThrottleFiltersCommandLine(virCommand *cmd,
+ virDomainDiskDef *disk)
+{
+ g_autoptr(qemuBlockThrottleFilterChainData) data = NULL;
+ size_t i;
+
+ if (!(data = qemuBuildThrottleFilterChainAttachPrepareBlockdev(disk))) {
+ return -1;
+ } else {
+ for (i = 0; i < data->nfilterdata; i++) {
+ if (qemuBuildBlockThrottleFilterCommandline(cmd,
+ data->filterdata[i]) < 0)
+ return -1;
+ }
+ }
+
+ return 0;
+}
static int
qemuBuildDiskSourceCommandLine(virCommand *cmd,
@@ -2276,6 +2319,9 @@ qemuBuildDiskCommandLine(virCommand *cmd,
if (qemuBuildDiskSourceCommandLine(cmd, disk, qemuCaps) < 0)
return -1;
+ if (qemuBuildThrottleFiltersCommandLine(cmd, disk) < 0)
+ return -1;
+
/* SD cards are currently instantiated via -drive if=sd, so the -device
* part must be skipped */
if (qemuDiskBusIsSD(disk->bus))
@@ -7448,6 +7494,44 @@ qemuBuildIOThreadCommandLine(virCommand *cmd,
return 0;
}
+/**
+ * qemuBuildThrottleGroupCommandLine:
+ * @cmd: the command to modify
+ * @def: domain definition
+ * @qemuCaps: qemu capabilities object
+ *
+ * build throttle group object in json format
+ * e.g. -object
'{"qom-type":"throttle-group","id":"limit0","limits":{"iops-total":200}}'
+ */
+static int
+qemuBuildThrottleGroupCommandLine(virCommand *cmd,
+ const virDomainDef *def,
+ virQEMUCaps *qemuCaps)
+{
+ size_t i;
+
+ for (i = 0; i < def->nthrottlegroups; i++) {
+ g_autoptr(virJSONValue) props = NULL;
+ g_autoptr(virJSONValue) limits = NULL;
+ virDomainThrottleGroupDef *group = def->throttlegroups[i];
+
+ if (!qemuDiskConfigThrottleFilterEnabled(group)) {
+ continue;
+ }
+
+ limits = qemuMonitorThrottleGroupLimits(group);
+
+ if (qemuMonitorCreateObjectProps(&props, "throttle-group",
group->group_name,
+ "a:limits", &limits,
+ NULL) < 0)
+ return -1;
+
+ if (qemuBuildObjectCommandlineFromJSON(cmd, props, qemuCaps) < 0)
+ return -1;
+ }
+
+ return 0;
+}
static int
qemuBuildNumaCellCache(virCommand *cmd,
@@ -10483,6 +10567,9 @@ qemuBuildCommandLine(virDomainObj *vm,
if (qemuBuildIOThreadCommandLine(cmd, def, qemuCaps) < 0)
return NULL;
+ if (qemuBuildThrottleGroupCommandLine(cmd, def, qemuCaps) < 0)
+ return NULL;
+
if (virDomainNumaGetNodeCount(def->numa) &&
qemuBuildNumaCommandLine(cfg, def, cmd, priv) < 0)
return NULL;
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index e2dee47906..9b8951d95f 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -122,6 +122,9 @@ qemuBuildThrottleFilterChainAttachPrepareBlockdev(virDomainDiskDef
*disk);
bool
qemuDiskConfigThrottleFilterChainEnabled(const virDomainDiskDef *disk);
+bool
+qemuDiskConfigThrottleFilterEnabled(const virDomainThrottleGroupDef *group);
+
virJSONValue *
qemuBuildDiskDeviceProps(const virDomainDef *def,
virDomainDiskDef *disk,
--
2.34.1