Devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 28 participants
- 40117 discussions
[libvirt] [PATCH libvirt-java] Set source and target version to Java 1.6
by Wido den Hollander 18 Sep '13
by Wido den Hollander 18 Sep '13
18 Sep '13
On platforms with Java 1.7 it will still produce compatible code
with Java 1.6 platforms
Java 1.6 is still out there and widely used.
Signed-off-by: Wido den Hollander <wido(a)widodh.nl>
---
build.properties | 2 ++
build.xml | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/build.properties b/build.properties
index 679a271..7721f90 100644
--- a/build.properties
+++ b/build.properties
@@ -2,5 +2,7 @@ version=0.5.0
release=1
libvirt.required=0.9.12
java.required=1:1.5.0
+java.target=1.6
+java.source=1.6
rpm.topdir=/home/veillard/rpms
jar.dir=/usr/share/java
diff --git a/build.xml b/build.xml
index 61b15bb..acd9c92 100644
--- a/build.xml
+++ b/build.xml
@@ -52,7 +52,7 @@
destdir="target/testclasses"
cache="target/cache"
closure="true" />
- <javac srcdir="src/test/java" debug="${javac.debug}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" />
+ <javac srcdir="src/test/java" debug="${javac.debug}" source="${java.source}" target="${java.target}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" />
</target>
<target name="build" depends="init" description="builds the code">
@@ -60,7 +60,7 @@
destdir="target/classes"
cache="target/cache"
closure="true" />
- <javac srcdir="src/main/java" debug="${javac.debug}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" />
+ <javac srcdir="src/main/java" debug="${javac.debug}" source="${java.source}" target="${java.target}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" />
</target>
<target name="test" depends="buildtests" description="tests the code">
--
1.7.9.5
3
6
[libvirt] [PATCH 0/2] Add support for device blkio iops and bps throttle
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
The patches add support for setting/getting blkio read/write bps/iops
throttle per-device with blkio cgroup.
Guan Qiang (2):
blkiotune: add support for device iops and bps throttle
blkiotune: add virsh support for blkiotune.throttle.iops/bps
docs/formatdomain.html.in | 8 +
docs/schemas/domaincommon.rng | 28 +-
include/libvirt/libvirt.h.in | 40 ++
src/conf/domain_conf.c | 115 +++-
src/conf/domain_conf.h | 16 +-
src/libvirt_private.syms | 4 +-
src/lxc/lxc_cgroup.c | 9 +-
src/qemu/qemu_cgroup.c | 10 +-
src/qemu/qemu_driver.c | 579 ++++++++++++++++++--
src/util/vircgroup.c | 79 ++-
src/util/vircgroup.h | 8 +-
.../qemuxml2argv-blkiotune-device.xml | 4 +
tools/virsh-domain.c | 64 +++
tools/virsh.pod | 32 +-
14 files changed, 883 insertions(+), 113 deletions(-)
--
1.7.9.5
3
2
[libvirt] [PATCH 2/2] blkiotune: add virsh support for blkiotune.throttle.iops/bps
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
This adds four parameters --device-read-bps, --device-write-bps, --device-read-iops
and --device-write-iops to virsh command blkiotune for setting/getting
blkiotune.throttle.{read/write}_{iops/bps}_device.
---
tools/virsh-domain.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 32 +++++++++++++++++++++++--
2 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 49cd154..2830d6a 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1252,6 +1252,22 @@ static const vshCmdOptDef opts_blkiotune[] = {
.type = VSH_OT_STRING,
.help = N_("per-device IO Weights, in the form of /path/to/device,weight,...")
},
+ {.name = "device-read-bps",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device read throughput limit in bytes per second, in the form of /path/to/device,read_bps,...")
+ },
+ {.name = "device-write-bps",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device write throughput limit in bytes per second, in the form of /path/to/device,write_bps,...")
+ },
+ {.name = "device-read-iops",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device read I/O operations limit per second, in the form of /path/to/device,read_iops,...")
+ },
+ {.name = "device-write-iops",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device write I/O operations limit per second, in the form of /path/to/device,write_iops,...")
+ },
{.name = "config",
.type = VSH_OT_BOOL,
.help = N_("affect next boot")
@@ -1272,6 +1288,10 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
{
virDomainPtr dom;
const char *device_weight = NULL;
+ const char *device_read_bps = NULL;
+ const char *device_write_bps = NULL;
+ const char *device_read_iops = NULL;
+ const char *device_write_iops = NULL;
int weight = 0;
int nparams = 0;
int maxparams = 0;
@@ -1319,6 +1339,50 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
goto save_error;
}
+ rv = vshCommandOptString(cmd, "device-read-bps", &device_read_bps);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ device_read_bps) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-write-bps", &device_write_bps);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ device_write_bps) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-read-iops", &device_read_iops);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ device_read_iops) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-write-iops", &device_write_iops);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ device_write_iops) < 0)
+ goto save_error;
+ }
+
if (nparams == 0) {
/* get the number of blkio parameters */
if (virDomainGetBlkioParameters(dom, NULL, &nparams, flags) != 0) {
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 0ae5178..69829eb 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1611,8 +1611,12 @@ The guaranteed minimum memory allocation for the guest.
Specifying -1 as a value for these limits is interpreted as unlimited.
=item B<blkiotune> I<domain> [I<--weight> B<weight>]
-[I<--device-weights> B<device-weights>] [[I<--config>]
-[I<--live>] | [I<--current>]]
+[I<--device-weights> B<device-weights>]
+[I<--device-read-bps> B<device-read-bps>]
+[I<--device-write-bps> B<device-write-bps>]
+[I<--device-read-iops> B<device-read-iops>]
+[I<--device-write-iops> B<device-write-iops>]
+[[I<--config>] [I<--live>] | [I<--current>]]
Display or set the blkio parameters. QEMU/KVM supports I<--weight>.
I<--weight> is in range [100, 1000].
@@ -1624,6 +1628,30 @@ device from per-device listings. Only the devices listed in the string
are modified; any existing per-device weights for other devices remain
unchanged.
+B<device-read-bps> is a single string listing one or more device/read_bps
+pairs, in the format of /path/to/device,read_bps,/path/to/device,read_bps.
+Each read_bps is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device read_bps for other devices remain unchanged.
+
+B<device-write-bps> is a single string listing one or more device/write_bps
+pairs, in the format of /path/to/device,write_bps,/path/to/device,write_bps.
+Each write_bps is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device write_bps for other devices remain unchanged.
+
+B<device-read-iops> is a single string listing one or more device/read_iops
+pairs, in the format of /path/to/device,read_iops,/path/to/device,read_iops.
+Each read_iops is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device read_iops for other devices remain unchanged.
+
+B<device-write-iops> is a single string listing one or more device/write_iops
+pairs, in the format of /path/to/device,write_iops,/path/to/device,write_iops.
+Each write_iops is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device write_iops for other devices remain unchanged.
+
If I<--live> is specified, affect a running guest.
If I<--config> is specified, affect the next boot of a persistent guest.
If I<--current> is specified, affect the current guest state.
--
1.7.9.5
1
0
[libvirt] [PATCH 1/2] blkiotune: add support for device iops and bps throttle
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
This adds per-device iops and bps throttle to <blkiotune>. By
extending the existed 'domainSetBlkioParameters' interface,
read/write iops and bps throttle for per-device can be set
with blkio cgroup. The blkiotune xml entry is now looked like:
<domain ...>
<blkiotune>
<device>
<path>/path/to/block</path>
<weight>1000</weight>
<read_bps>100000</read_bps>
<write_bps>100000</write_bps>
<read_iops>100000</read_iops>
<write_iops>1000000</write_iops>
</device>
</blkiotune>
..
Elments <weight>,<read_bps>,<write_bps>,<read_iops>,<write_iops>
are all optional, but must have one.
---
docs/formatdomain.html.in | 8 +
docs/schemas/domaincommon.rng | 28 +-
include/libvirt/libvirt.h.in | 40 ++
src/conf/domain_conf.c | 115 +++-
src/conf/domain_conf.h | 16 +-
src/libvirt_private.syms | 4 +-
src/lxc/lxc_cgroup.c | 9 +-
src/qemu/qemu_cgroup.c | 10 +-
src/qemu/qemu_driver.c | 579 ++++++++++++++++++--
src/util/vircgroup.c | 79 ++-
src/util/vircgroup.h | 8 +-
.../qemuxml2argv-blkiotune-device.xml | 4 +
12 files changed, 789 insertions(+), 111 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a927643..daf4f7a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -753,10 +753,18 @@
<device>
<path>/dev/sda</path>
<weight>1000</weight>
+ <read_bps>20000000</read_bps>
+ <write_bps>30000000</write_bps>
+ <read_iops>4000</read_iops>
+ <write_iops>5000</write_iops>
</device>
<device>
<path>/dev/sdb</path>
<weight>500</weight>
+ <read_bps>30000000</read_bps>
+ <write_bps>30000000</write_bps>
+ <read_iops>4300</read_iops>
+ <write_iops>6000</write_iops>
</device>
</blkiotune>
...
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4d333a8..10553af 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -621,9 +621,31 @@
<element name="path">
<ref name="absFilePath"/>
</element>
- <element name="weight">
- <ref name="weight"/>
- </element>
+ <optional>
+ <element name="weight">
+ <ref name="weight"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="read_bps">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="write_bps">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="read_iops">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="write_iops">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
</interleave>
</element>
</zeroOrMore>
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a47e33c..fd4a2e5 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1780,6 +1780,46 @@ char * virDomainGetSchedulerType(virDomainPtr domain,
#define VIR_DOMAIN_BLKIO_DEVICE_WEIGHT "device_weight"
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS:
+ *
+ * Macro for the BLKIO tunable throttle.read_bps_device: it represents the read
+ * bytes per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,read_bps elements,
+ * separated by ',', with element read_bps as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS "device_read_bps"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS:
+ *
+ * Macro for the BLKIO tunable throttle.write_bps_device: it represents the write
+ * bytes per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,write_bps elements,
+ * separated by ',', with element write_bps as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS "device_write_bps"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS:
+ *
+ * Macro for the BLKIO tunable throttle.read_iops_device: it represents the read
+ * I/O operations per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,read_iops elements,
+ * separated by ',', with element read_iops as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS "device_read_iops"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS:
+ *
+ * Macro for the BLKIO tunable throttle.write_iops_device: it represents the write
+ * I/O operations per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,write_iops elements,
+ * separated by ',', with element write_iops as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS "device_write_iops"
+
/* Set Blkio tunables for the domain*/
int virDomainSetBlkioParameters(virDomainPtr domain,
virTypedParameterPtr params,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 05c1de4..f9df10f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -880,47 +880,100 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
void
-virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
+virBlkioDeviceIoTuneInfoArrayClear(virBlkioDeviceIoTuneInfoPtr devices,
int ndevices)
{
size_t i;
for (i = 0; i < ndevices; i++)
- VIR_FREE(deviceWeights[i].path);
+ VIR_FREE(devices[i].path);
}
/**
- * virDomainBlkioDeviceWeightParseXML
+ * virDomainBlkioDeviceIoTuneInfoParseXML
*
* this function parses a XML node:
*
* <device>
* <path>/fully/qualified/device/path</path>
* <weight>weight</weight>
+ * <read_bps>read_bps</read_bps>
+ * <write_bps>write_bps</write_bps>
+ * <read_iops>read_iops</read_iops>
+ * <write_iops>write_iops</write_iops>
* </device>
*
- * and fills a virBlkioDeviceWeight struct.
+ * and fills a virBlkioDeviceIoTuneInfo struct.
*/
static int
-virDomainBlkioDeviceWeightParseXML(xmlNodePtr root,
- virBlkioDeviceWeightPtr dw)
+virDomainBlkioDeviceIoTuneInfoParseXML(xmlNodePtr root,
+ virBlkioDeviceIoTuneInfoPtr dio)
{
char *c;
xmlNodePtr node;
+ dio->read_bps = 0;
+ dio->write_bps = 0;
+ dio->read_iops = 0;
+ dio->write_iops = 0;
+
node = root->children;
while (node) {
if (node->type == XML_ELEMENT_NODE) {
- if (xmlStrEqual(node->name, BAD_CAST "path") && !dw->path) {
- dw->path = (char *)xmlNodeGetContent(node);
+ if (xmlStrEqual(node->name, BAD_CAST "path") && !dio->path) {
+ dio->path = (char *)xmlNodeGetContent(node);
} else if (xmlStrEqual(node->name, BAD_CAST "weight")) {
c = (char *)xmlNodeGetContent(node);
- if (virStrToLong_ui(c, NULL, 10, &dw->weight) < 0) {
+ if (virStrToLong_ui(c, NULL, 10, &dio->weight) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not parse weight %s"),
c);
VIR_FREE(c);
- VIR_FREE(dw->path);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "read_bps")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->read_bps) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse read_bps %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "write_bps")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->write_bps) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse write_bps %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "read_iops")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->read_iops) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse read_iops %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "write_iops")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->write_iops) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse write_iops %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
return -1;
}
VIR_FREE(c);
@@ -928,7 +981,7 @@ virDomainBlkioDeviceWeightParseXML(xmlNodePtr root,
}
node = node->next;
}
- if (!dw->path) {
+ if (!dio->path) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("missing per-device path"));
return -1;
@@ -1988,8 +2041,8 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->description);
VIR_FREE(def->title);
- virBlkioDeviceWeightArrayClear(def->blkio.devices,
- def->blkio.ndevices);
+ virBlkioDeviceIoTuneInfoArrayClear(def->blkio.devices,
+ def->blkio.ndevices);
VIR_FREE(def->blkio.devices);
virDomainWatchdogDefFree(def->watchdog);
@@ -10962,15 +11015,15 @@ virDomainDefParseXML(xmlDocPtr xml,
for (i = 0; i < n; i++) {
size_t j;
- if (virDomainBlkioDeviceWeightParseXML(nodes[i],
- &def->blkio.devices[i]) < 0)
+ if (virDomainBlkioDeviceIoTuneInfoParseXML(nodes[i],
+ &def->blkio.devices[i]) < 0)
goto error;
def->blkio.ndevices++;
for (j = 0; j < i; j++) {
if (STREQ(def->blkio.devices[j].path,
def->blkio.devices[i].path)) {
virReportError(VIR_ERR_XML_ERROR,
- _("duplicate device weight path '%s'"),
+ _("duplicate blkio device path '%s'"),
def->blkio.devices[i].path);
goto error;
}
@@ -16349,7 +16402,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
blkio = true;
} else {
for (n = 0; n < def->blkio.ndevices; n++) {
- if (def->blkio.devices[n].weight) {
+ if (def->blkio.devices[n].weight || def->blkio.devices[n].read_bps ||
+ def->blkio.devices[n].write_bps || def->blkio.devices[n].read_iops ||
+ def->blkio.devices[n].write_iops) {
blkio = true;
break;
}
@@ -16364,13 +16419,33 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->blkio.weight);
for (n = 0; n < def->blkio.ndevices; n++) {
- if (def->blkio.devices[n].weight == 0)
+ if (def->blkio.devices[n].weight == 0 && def->blkio.devices[n].read_bps == 0 &&
+ def->blkio.devices[n].write_bps == 0 && def->blkio.devices[n].read_iops == 0 &&
+ def->blkio.devices[n].write_iops == 0)
continue;
virBufferAddLit(buf, " <device>\n");
virBufferEscapeString(buf, " <path>%s</path>\n",
def->blkio.devices[n].path);
- virBufferAsprintf(buf, " <weight>%u</weight>\n",
- def->blkio.devices[n].weight);
+ if (def->blkio.devices[n].weight) {
+ virBufferAsprintf(buf, " <weight>%u</weight>\n",
+ def->blkio.devices[n].weight);
+ }
+ if (def->blkio.devices[n].read_bps) {
+ virBufferAsprintf(buf, " <read_bps>%llu</read_bps>\n",
+ def->blkio.devices[n].read_bps);
+ }
+ if (def->blkio.devices[n].write_bps) {
+ virBufferAsprintf(buf, " <write_bps>%llu</write_bps>\n",
+ def->blkio.devices[n].write_bps);
+ }
+ if (def->blkio.devices[n].read_iops) {
+ virBufferAsprintf(buf, " <read_iops>%llu</read_iops>\n",
+ def->blkio.devices[n].read_iops);
+ }
+ if (def->blkio.devices[n].write_iops) {
+ virBufferAsprintf(buf, " <write_iops>%llu</write_iops>\n",
+ def->blkio.devices[n].write_iops);
+ }
virBufferAddLit(buf, " </device>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9414ebf..1f350ed 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1857,11 +1857,15 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
int nvcpupin,
int vcpu);
-typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
-typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
-struct _virBlkioDeviceWeight {
+typedef struct _virBlkioDeviceIoTuneInfo virBlkioDeviceIoTuneInfo;
+typedef virBlkioDeviceIoTuneInfo *virBlkioDeviceIoTuneInfoPtr;
+struct _virBlkioDeviceIoTuneInfo {
char *path;
unsigned int weight;
+ unsigned long long read_bps;
+ unsigned long long write_bps;
+ unsigned long long read_iops;
+ unsigned long long write_iops;
};
enum virDomainRNGModel {
@@ -1908,8 +1912,8 @@ struct _virDomainIdMapDef {
};
-void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
- int ndevices);
+void virBlkioDeviceIoTuneInfoArrayClear(virBlkioDeviceIoTuneInfoPtr devices,
+ int ndevices);
typedef struct _virDomainResourceDef virDomainResourceDef;
typedef virDomainResourceDef *virDomainResourceDefPtr;
@@ -1937,7 +1941,7 @@ struct _virDomainDef {
unsigned int weight;
size_t ndevices;
- virBlkioDeviceWeightPtr devices;
+ virBlkioDeviceIoTuneInfoPtr devices;
} blkio;
struct {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 50e2f48..e6259cf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -103,7 +103,7 @@ virDomainAuditVcpu;
# conf/domain_conf.h
-virBlkioDeviceWeightArrayClear;
+virBlkioDeviceIoTuneInfoArrayClear;
virDiskNameToBusDeviceIndex;
virDiskNameToIndex;
virDomainActualNetDefFree;
@@ -1207,7 +1207,7 @@ virCgroupNewVcpu;
virCgroupPathOfController;
virCgroupRemove;
virCgroupRemoveRecursively;
-virCgroupSetBlkioDeviceWeight;
+virCgroupSetBlkioDeviceIoTune;
virCgroupSetBlkioWeight;
virCgroupSetCpuCfsPeriod;
virCgroupSetCpuCfsQuota;
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 0b0ca02..f2c32e7 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -112,10 +112,13 @@ static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def,
if (def->blkio.ndevices) {
for (i = 0; i < def->blkio.ndevices; i++) {
- virBlkioDeviceWeightPtr dw = &def->blkio.devices[i];
- if (!dw->weight)
+ virBlkioDeviceIoTuneInfoPtr dio = &def->blkio.devices[i];
+ if (!dio->weight)
continue;
- if (virCgroupSetBlkioDeviceWeight(cgroup, dw->path, dw->weight) < 0)
+ if (virCgroupSetBlkioDeviceIoTune(cgroup,
+ dio->path, dio->weight,
+ dio->read_bps, dio->write_bps,
+ dio->read_iops, dio->write_iops) < 0)
return -1;
}
}
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f95c7f2..20e700f 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -399,11 +399,13 @@ qemuSetupBlkioCgroup(virDomainObjPtr vm)
if (vm->def->blkio.ndevices) {
for (i = 0; i < vm->def->blkio.ndevices; i++) {
- virBlkioDeviceWeightPtr dw = &vm->def->blkio.devices[i];
- if (!dw->weight)
+ virBlkioDeviceIoTuneInfoPtr dio = &vm->def->blkio.devices[i];
+ if (!dio->weight)
continue;
- if (virCgroupSetBlkioDeviceWeight(priv->cgroup, dw->path,
- dw->weight) < 0)
+ if (virCgroupSetBlkioDeviceIoTune(priv->cgroup,
+ dio->path, dio->weight,
+ dio->read_bps, dio->write_bps,
+ dio->read_iops, dio->write_iops) < 0)
return -1;
}
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0763f9b..ff0ae98 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -131,7 +131,7 @@
# define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */
#endif
-#define QEMU_NB_BLKIO_PARAM 2
+#define QEMU_NB_BLKIO_PARAM 6
#define QEMU_NB_BANDWIDTH_PARAM 6
@@ -7388,26 +7388,26 @@ cleanup:
return ret;
}
-/* deviceWeightStr in the form of /device/path,weight,/device/path,weight
+/* deviceIoTuneStr in the form of /device/path,ioTuneValue,/device/path,ioTuneValue or
* for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
+ * deviceIoTuneFiled represents the ioTune type to tune, including device weight,
+ * device read bps, device write bps, device read iops and device write iops.
*/
static int
-qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
- virBlkioDeviceWeightPtr *dw, size_t *size)
+qemuDomainParseDeviceIoTuneInfoStr(char *deviceIoTuneStr,
+ const char *deviceIoTuneFiled,
+ virBlkioDeviceIoTuneInfoPtr *dio, size_t *size)
{
char *temp;
int ndevices = 0;
int nsep = 0;
- size_t i;
- virBlkioDeviceWeightPtr result = NULL;
-
- *dw = NULL;
- *size = 0;
+ size_t i, j, k;
+ virBlkioDeviceIoTuneInfoPtr result = NULL;
- if (STREQ(deviceWeightStr, ""))
+ if (STREQ(deviceIoTuneStr, ""))
return 0;
- temp = deviceWeightStr;
+ temp = deviceIoTuneStr;
while (temp) {
temp = strchr(temp, ',');
if (temp) {
@@ -7426,8 +7426,11 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (VIR_ALLOC_N(result, ndevices) < 0)
return -1;
+ for (i = 0; i < ndevices; i++)
+ memset(&result[i], 0, sizeof(result[i]));
+
i = 0;
- temp = deviceWeightStr;
+ temp = deviceIoTuneStr;
while (temp) {
char *p = temp;
@@ -7439,11 +7442,25 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (VIR_STRNDUP(result[i].path, temp, p - temp) < 0)
goto cleanup;
- /* weight */
+ /* device ioTune value */
temp = p + 1;
- if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
- goto error;
+ if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
+ if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].read_bps) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].write_bps) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].read_iops) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].write_iops) < 0)
+ goto error;
+ }
i++;
@@ -7457,30 +7474,68 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (!i)
VIR_FREE(result);
- *dw = result;
- *size = i;
+ for (j = 0; j < i; j++) {
+ bool found = false;
+ virBlkioDeviceIoTuneInfoPtr old, new;
+
+ new = &result[j];
+ for (k = 0; k < *size; k++) {
+ old = &(*dio)[k];
+ if (STREQ(new->path, old->path)) {
+ found = true;
+ if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT))
+ old->weight = new->weight;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS))
+ old->read_bps = new->read_bps;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS))
+ old->write_bps = new->write_bps;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS))
+ old->read_iops = new->read_iops;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS))
+ old->write_iops = new->write_iops;
+ break;
+ }
+ }
+ if (!found) {
+ if (!new->weight && !new->read_bps && !new->write_bps &&
+ !new->read_iops && !new->write_iops)
+ continue;
+ if (VIR_EXPAND_N(*dio, *size, 1) < 0)
+ goto cleanup;
+ old = &(*dio)[*size -1];
+ if (VIR_STRDUP(old->path, new->path) < 0)
+ goto cleanup;
+ old->weight = new->weight;
+ old->read_bps = new->read_bps;
+ old->write_bps = new->write_bps;
+ old->read_iops = new->read_iops;
+ old->write_iops = new->write_iops;
+ }
+ }
+ virBlkioDeviceIoTuneInfoArrayClear(result, ndevices);
+ VIR_FREE(result);
return 0;
error:
virReportError(VIR_ERR_INVALID_ARG,
- _("unable to parse device weight '%s'"), deviceWeightStr);
+ _("unable to parse device ioTune '%s'"), deviceIoTuneStr);
cleanup:
- virBlkioDeviceWeightArrayClear(result, ndevices);
+ virBlkioDeviceIoTuneInfoArrayClear(result, ndevices);
VIR_FREE(result);
return -1;
}
-/* Modify dest_array to reflect all device weight changes described in
+/* Modify dest_array to reflect all device Iotune info changes described in
* src_array. */
static int
-qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *dest_array,
- size_t *dest_size,
- virBlkioDeviceWeightPtr src_array,
- size_t src_size)
+qemuDomainMergeDeviceIoTuneInfos(virBlkioDeviceIoTuneInfoPtr *dest_array,
+ size_t *dest_size,
+ virBlkioDeviceIoTuneInfoPtr src_array,
+ size_t src_size)
{
size_t i, j;
- virBlkioDeviceWeightPtr dest, src;
+ virBlkioDeviceIoTuneInfoPtr dest, src;
for (i = 0; i < src_size; i++) {
bool found = false;
@@ -7491,18 +7546,27 @@ qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *dest_array,
if (STREQ(src->path, dest->path)) {
found = true;
dest->weight = src->weight;
+ dest->read_bps = src->read_bps;
+ dest->write_bps = src->write_bps;
+ dest->read_iops = src->read_iops;
+ dest->write_iops = src->write_iops;
break;
}
}
if (!found) {
- if (!src->weight)
+ if (!src->weight && !src->read_bps && !src->write_bps &&
+ !src->read_iops && !src->write_iops)
continue;
if (VIR_EXPAND_N(*dest_array, *dest_size, 1) < 0)
return -1;
dest = &(*dest_array)[*dest_size - 1];
- dest->path = src->path;
+ if (VIR_STRDUP(dest->path, src->path) < 0)
+ return -1;
dest->weight = src->weight;
- src->path = NULL;
+ dest->read_bps = src->read_bps;
+ dest->write_bps = src->write_bps;
+ dest->read_iops = src->read_iops;
+ dest->write_iops = src->write_iops;
}
}
@@ -7531,6 +7595,14 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
VIR_TYPED_PARAM_UINT,
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ VIR_TYPED_PARAM_STRING,
NULL) < 0)
return -1;
@@ -7562,44 +7634,114 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
+ size_t ndevices = 0;
+ virBlkioDeviceIoTuneInfoPtr devices = NULL;
+ size_t j;
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&devices, &ndevices,
+ vm->def->blkio.devices,
+ vm->def->blkio.ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("out of blkio weight range."));
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
if (virCgroupSetBlkioWeight(priv->cgroup, params[i].value.ui) < 0)
ret = -1;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
- size_t ndevices;
- virBlkioDeviceWeightPtr devices = NULL;
- size_t j;
-
- if (qemuDomainParseDeviceWeightStr(params[i].value.s,
- &devices,
- &ndevices) < 0) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
- for (j = 0; j < ndevices; j++) {
- if (virCgroupSetBlkioDeviceWeight(priv->cgroup,
- devices[j].path,
- devices[j].weight) < 0) {
- ret = -1;
- break;
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
+ continue;
}
- if (j != ndevices ||
- qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
- &vm->def->blkio.ndevices,
- devices, ndevices) < 0)
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ }
+
+ for (j = 0; j < ndevices; j++) {
+ if (virCgroupSetBlkioDeviceIoTune(priv->cgroup,
+ devices[j].path, devices[j].weight,
+ devices[j].read_bps, devices[j].write_bps,
+ devices[j].read_iops, devices[j].write_iops) < 0) {
ret = -1;
- virBlkioDeviceWeightArrayClear(devices, ndevices);
- VIR_FREE(devices);
+ break;
+ }
}
+ if (j != ndevices ||
+ qemuDomainMergeDeviceIoTuneInfos(&vm->def->blkio.devices,
+ &vm->def->blkio.ndevices,
+ devices, ndevices) < 0)
+ ret = -1;
+
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
}
if (ret < 0)
@@ -7610,33 +7752,102 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
+ virBlkioDeviceIoTuneInfoPtr devices = NULL;
+ size_t ndevices = 0;
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&devices, &ndevices,
+ persistentDef->blkio.devices,
+ persistentDef->blkio.ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("out of blkio weight range."));
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
persistentDef->blkio.weight = params[i].value.ui;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
- virBlkioDeviceWeightPtr devices = NULL;
- size_t ndevices;
-
- if (qemuDomainParseDeviceWeightStr(params[i].value.s,
- &devices,
- &ndevices) < 0) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
- if (qemuDomainMergeDeviceWeights(&persistentDef->blkio.devices,
- &persistentDef->blkio.ndevices,
- devices, ndevices) < 0)
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
- virBlkioDeviceWeightArrayClear(devices, ndevices);
- VIR_FREE(devices);
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
}
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&persistentDef->blkio.devices,
+ &persistentDef->blkio.ndevices,
+ devices, ndevices) < 0)
+ ret = -1;
+
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
@@ -7747,6 +7958,122 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
goto cleanup;
break;
+ case 2: /* blkiotune.throttle.device_read_bps */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].read_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].read_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 3: /* blkiotune.throttle.device_write_bps */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].write_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].write_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 4: /* blkiotune.throttle.device_read_iops */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].read_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].read_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 5: /* blkiotune.throttle.device_write_iops */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].write_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].write_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
default:
break;
/* should not hit here */
@@ -7804,6 +8131,142 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
}
break;
+ case 2: /* blkiotune.device_read_bps */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].read_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].read_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS);
+ goto cleanup;
+ }
+ break;
+
+ case 3: /* blkiotune.device_write_bps */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].write_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].write_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS);
+ goto cleanup;
+ }
+ break;
+
+ case 4: /* blkiotune.device_read_iops */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].read_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].read_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS);
+ goto cleanup;
+ }
+ break;
+
+ case 5: /* blkiotune.device_write_iops */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].write_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].write_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS);
+ goto cleanup;
+ }
+ break;
+
default:
break;
/* should not hit here */
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index e99caf5..b506de5 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1825,23 +1825,36 @@ virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight)
/**
- * virCgroupSetBlkioDeviceWeight:
+ * virCgroupSetBlkioDeviceIoTune:
*
- * @group: The cgroup to change io device weight device for
+ * @group: The cgroup to change io device iotune device for
* @path: The device with a weight to alter
* @weight: The new device weight (100-1000), or 0 to clear
+ * @read_bps: The new read bps throttle, or 0 to clear
+ * @write_bps: The new write bps throttle, or 0 to clear
+ * @read_iops: The new read iops throttle, or 0 to clear
+ * @write_iops: The new write iops throttle, or 0 to clear
*
- * device_weight is treated as a write-only parameter, so
- * there isn't a getter counterpart.
+ * paramters like device_weight, device_read_bps, device_write_bps,
+ * device_read_iops and device_write_iops are treated as write-only,
+ * so there isn't a getter counterpart.
*
* Returns: 0 on success, -1 on error
*/
int
-virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
+virCgroupSetBlkioDeviceIoTune(virCgroupPtr group,
const char *path,
- unsigned int weight)
-{
- char *str;
+ unsigned int weight,
+ unsigned long long read_bps,
+ unsigned long long write_bps,
+ unsigned long long read_iops,
+ unsigned long long write_iops)
+{
+ char *weight_str;
+ char *read_bps_str;
+ char *write_bps_str;
+ char *read_iops_str;
+ char *write_iops_str;
struct stat sb;
int ret;
@@ -1866,15 +1879,51 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
return -1;
}
- if (virAsprintf(&str, "%d:%d %d", major(sb.st_rdev), minor(sb.st_rdev),
+ if (virAsprintf(&weight_str, "%d:%d %d", major(sb.st_rdev), minor(sb.st_rdev),
weight) < 0)
return -1;
+ if (virAsprintf(&read_bps_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ read_bps) < 0)
+ return -1;
+
+ if (virAsprintf(&write_bps_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ write_bps) < 0)
+ return -1;
+
+ if (virAsprintf(&read_iops_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ read_iops) < 0)
+ return -1;
+
+ if (virAsprintf(&write_iops_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ write_iops) < 0)
+ return -1;
+
ret = virCgroupSetValueStr(group,
VIR_CGROUP_CONTROLLER_BLKIO,
"blkio.weight_device",
- str);
- VIR_FREE(str);
+ weight_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.read_bps_device",
+ read_bps_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.write_bps_device",
+ write_bps_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.read_iops_device",
+ read_iops_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.write_iops_device",
+ write_iops_str);
+ VIR_FREE(weight_str);
+ VIR_FREE(read_bps_str);
+ VIR_FREE(write_bps_str);
+ VIR_FREE(read_iops_str);
+ VIR_FREE(write_iops_str);
return ret;
}
@@ -3287,9 +3336,13 @@ virCgroupGetBlkioWeight(virCgroupPtr group ATTRIBUTE_UNUSED,
int
-virCgroupSetBlkioDeviceWeight(virCgroupPtr group ATTRIBUTE_UNUSED,
+virCgroupSetBlkioDeviceIoTune(virCgroupPtr group ATTRIBUTE_UNUSED,
const char *path ATTRIBUTE_UNUSED,
- unsigned int weight ATTRIBUTE_UNUSED)
+ unsigned int weight ATTRIBUTE_UNUSED,
+ unsigned long long read_bps ATTRIBUTE_UNUSED,
+ unsigned long long write_bps ATTRIBUTE_UNUSED,
+ unsigned long long read_iops ATTRIBUTE_UNUSED,
+ unsigned long long write_iops ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Control groups not supported on this platform"));
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index 835eb30..21980da 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -122,9 +122,13 @@ int virCgroupMoveTask(virCgroupPtr src_group,
int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight);
int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight);
-int virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
+int virCgroupSetBlkioDeviceIoTune(virCgroupPtr group,
const char *path,
- unsigned int weight);
+ unsigned int weight,
+ unsigned long long read_bps,
+ unsigned long long write_bps,
+ unsigned long long read_iops,
+ unsigned long long write_iops);
int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb);
int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
index 743cf29..9bd97fe 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
@@ -8,6 +8,10 @@
<device>
<path>/dev/sda</path>
<weight>400</weight>
+ <read_bps>2000000000</read_bps>
+ <write_bps>1000000000</write_bps>
+ <read_iops>1000</read_iops>
+ <write_iops>2000</write_iops>
</device>
<device>
<path>/dev/sdb</path>
--
1.7.9.5
1
0
18 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
The https protocol is also accepted by qemu/KVM when specifying the cdrom ISO
image.
The xml should be as following:
<disk type='network' device='cdrom'>
<source protocol='https' name='/url/path'>
<host name='host.name' port='443'/>
</source>
</disk>
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
docs/formatdomain.html.in | 8 +++++
docs/schemas/domaincommon.rng | 1 +
src/conf/domain_conf.c | 1 +
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 6 ++++
.../qemuxml2argv-disk-cdrom-network-https.args | 8 +++++
.../qemuxml2argv-disk-cdrom-network-https.xml | 37 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
8 files changed, 64 insertions(+)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index f5a36d9..240571f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1511,6 +1511,14 @@
</disk>
<disk type='network' device='cdrom'>
<driver name='qemu' type='raw'/>
+ <source protocol="https" name="url_path">
+ <host name="hostname" port="443"/>
+ </source>
+ <target dev='hdc' bus='ide' tray='open'/>
+ <readonly/>
+ </disk>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
<source protocol="ftp" name="url_path">
<host name="hostname" port="21"/>
</source>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index ecd3a42..2f91f0f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1231,6 +1231,7 @@
<value>gluster</value>
<value>iscsi</value>
<value>http</value>
+ <value>https</value>
<value>ftp</value>
</choice>
</attribute>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e5fe900..04563f6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -265,6 +265,7 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"gluster",
"iscsi",
"http",
+ "https",
"ftp")
VIR_ENUM_IMPL(virDomainDiskProtocolTransport, VIR_DOMAIN_DISK_PROTO_TRANS_LAST,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index e4dfee9..d54b29e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -543,6 +543,7 @@ enum virDomainDiskProtocol {
VIR_DOMAIN_DISK_PROTOCOL_GLUSTER,
VIR_DOMAIN_DISK_PROTOCOL_ISCSI,
VIR_DOMAIN_DISK_PROTOCOL_HTTP,
+ VIR_DOMAIN_DISK_PROTOCOL_HTTPS,
VIR_DOMAIN_DISK_PROTOCOL_FTP,
VIR_DOMAIN_DISK_PROTOCOL_LAST
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1521431..883b513 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3905,6 +3905,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
disk->hosts->port ? disk->hosts->port : "80");
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
break;
+ case VIR_DOMAIN_DISK_PROTOCOL_HTTPS:
+ virBufferAsprintf(&opt, "file=https://%s:%s",
+ disk->hosts->name,
+ disk->hosts->port ? disk->hosts->port : "443");
+ virBufferEscape(&opt, ',', ",", "%s,", disk->src);
+ break;
case VIR_DOMAIN_DISK_PROTOCOL_FTP:
virBufferAsprintf(&opt, "file=ftp://%s:%s",
disk->hosts->name,
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.args
new file mode 100644
index 0000000..affa794
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.args
@@ -0,0 +1,8 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/kvm -S \
+-M pc-1.2 -m 1024 -smp 1 -nographic -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -boot d -usb \
+-drive \
+file=https://host.name:443/url/path/file.iso,if=none,media=cdrom,id=drive-ide0-1-0 \
+-device ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml
new file mode 100644
index 0000000..b8a60ed
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml
@@ -0,0 +1,37 @@
+<domain type='kvm'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='x86_64' machine='pc-1.2'>hvm</type>
+ <boot dev='cdrom'/>
+ </os>
+ <features>
+ <acpi/>
+ <apic/>
+ <pae/>
+ </features>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>restart</on_crash>
+ <devices>
+ <emulator>/usr/bin/kvm</emulator>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol='https' name='/url/path/file.iso'>
+ <host name='host.name' port='443'/>
+ </source>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <alias name='ide0-1-0'/>
+ <address type='drive' controller='0' bus='1' target='0' unit='0'/>
+ </disk>
+ <controller type='usb' index='0'/>
+ <controller type='pci' index='0' model='pci-root'/>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index fdf1d31..a11c9a8 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -445,6 +445,8 @@ mymain(void)
DO_TEST("disk-cdrom", NONE);
DO_TEST("disk-cdrom-network-http", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE);
+ DO_TEST("disk-cdrom-network-https", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
+ QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-network-ftp", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
--
1.7.9.5
4
5
[libvirt] [PATCH 2/2] blkiotune: add virsh support for blkiotune.throttle.iops/bps
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
This adds four parameters --device-read-bps, --device-write-bps, --device-read-iops
and --device-write-iops to virsh command blkiotune for setting/getting
blkiotune.throttle.{read/write}_{iops/bps}_device.
---
tools/virsh-domain.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 32 +++++++++++++++++++++++--
2 files changed, 94 insertions(+), 2 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 49cd154..2830d6a 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -1252,6 +1252,22 @@ static const vshCmdOptDef opts_blkiotune[] = {
.type = VSH_OT_STRING,
.help = N_("per-device IO Weights, in the form of /path/to/device,weight,...")
},
+ {.name = "device-read-bps",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device read throughput limit in bytes per second, in the form of /path/to/device,read_bps,...")
+ },
+ {.name = "device-write-bps",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device write throughput limit in bytes per second, in the form of /path/to/device,write_bps,...")
+ },
+ {.name = "device-read-iops",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device read I/O operations limit per second, in the form of /path/to/device,read_iops,...")
+ },
+ {.name = "device-write-iops",
+ .type = VSH_OT_STRING,
+ .help = N_("per-device write I/O operations limit per second, in the form of /path/to/device,write_iops,...")
+ },
{.name = "config",
.type = VSH_OT_BOOL,
.help = N_("affect next boot")
@@ -1272,6 +1288,10 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
{
virDomainPtr dom;
const char *device_weight = NULL;
+ const char *device_read_bps = NULL;
+ const char *device_write_bps = NULL;
+ const char *device_read_iops = NULL;
+ const char *device_write_iops = NULL;
int weight = 0;
int nparams = 0;
int maxparams = 0;
@@ -1319,6 +1339,50 @@ cmdBlkiotune(vshControl * ctl, const vshCmd * cmd)
goto save_error;
}
+ rv = vshCommandOptString(cmd, "device-read-bps", &device_read_bps);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ device_read_bps) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-write-bps", &device_write_bps);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ device_write_bps) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-read-iops", &device_read_iops);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ device_read_iops) < 0)
+ goto save_error;
+ }
+
+ rv = vshCommandOptString(cmd, "device-write-iops", &device_write_iops);
+ if (rv < 0) {
+ vshError(ctl, "%s", _("Unable to parse string parameter"));
+ goto cleanup;
+ } else if (rv > 0) {
+ if (virTypedParamsAddString(¶ms, &nparams, &maxparams,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ device_write_iops) < 0)
+ goto save_error;
+ }
+
if (nparams == 0) {
/* get the number of blkio parameters */
if (virDomainGetBlkioParameters(dom, NULL, &nparams, flags) != 0) {
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 0ae5178..69829eb 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1611,8 +1611,12 @@ The guaranteed minimum memory allocation for the guest.
Specifying -1 as a value for these limits is interpreted as unlimited.
=item B<blkiotune> I<domain> [I<--weight> B<weight>]
-[I<--device-weights> B<device-weights>] [[I<--config>]
-[I<--live>] | [I<--current>]]
+[I<--device-weights> B<device-weights>]
+[I<--device-read-bps> B<device-read-bps>]
+[I<--device-write-bps> B<device-write-bps>]
+[I<--device-read-iops> B<device-read-iops>]
+[I<--device-write-iops> B<device-write-iops>]
+[[I<--config>] [I<--live>] | [I<--current>]]
Display or set the blkio parameters. QEMU/KVM supports I<--weight>.
I<--weight> is in range [100, 1000].
@@ -1624,6 +1628,30 @@ device from per-device listings. Only the devices listed in the string
are modified; any existing per-device weights for other devices remain
unchanged.
+B<device-read-bps> is a single string listing one or more device/read_bps
+pairs, in the format of /path/to/device,read_bps,/path/to/device,read_bps.
+Each read_bps is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device read_bps for other devices remain unchanged.
+
+B<device-write-bps> is a single string listing one or more device/write_bps
+pairs, in the format of /path/to/device,write_bps,/path/to/device,write_bps.
+Each write_bps is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device write_bps for other devices remain unchanged.
+
+B<device-read-iops> is a single string listing one or more device/read_iops
+pairs, in the format of /path/to/device,read_iops,/path/to/device,read_iops.
+Each read_iops is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device read_iops for other devices remain unchanged.
+
+B<device-write-iops> is a single string listing one or more device/write_iops
+pairs, in the format of /path/to/device,write_iops,/path/to/device,write_iops.
+Each write_iops is a postive number, or the value 0 to remove that device from
+per-device listings. Only the devices listed in the string are modified;
+any existing per-device write_iops for other devices remain unchanged.
+
If I<--live> is specified, affect a running guest.
If I<--config> is specified, affect the next boot of a persistent guest.
If I<--current> is specified, affect the current guest state.
--
1.7.9.5
1
0
[libvirt] [PATCH 1/2] blkiotune: add support for device iops and bps throttle
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
This adds per-device iops and bps throttle to <blkiotune>. By
extending the existed 'domainSetBlkioParameters' interface,
read/write iops and bps throttle for per-device can be set
with blkio cgroup. The blkiotune xml entry is now looked like:
<domain ...>
<blkiotune>
<device>
<path>/path/to/block</path>
<weight>1000</weight>
<read_bps>100000</read_bps>
<write_bps>100000</write_bps>
<read_iops>100000</read_iops>
<write_iops>1000000</write_iops>
</device>
</blkiotune>
..
Elments <weight>,<read_bps>,<write_bps>,<read_iops>,<write_iops>
are all optional, but must have one.
---
docs/formatdomain.html.in | 8 +
docs/schemas/domaincommon.rng | 28 +-
include/libvirt/libvirt.h.in | 40 ++
src/conf/domain_conf.c | 115 +++-
src/conf/domain_conf.h | 16 +-
src/libvirt_private.syms | 4 +-
src/lxc/lxc_cgroup.c | 9 +-
src/qemu/qemu_cgroup.c | 10 +-
src/qemu/qemu_driver.c | 579 ++++++++++++++++++--
src/util/vircgroup.c | 79 ++-
src/util/vircgroup.h | 8 +-
.../qemuxml2argv-blkiotune-device.xml | 4 +
12 files changed, 789 insertions(+), 111 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index a927643..daf4f7a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -753,10 +753,18 @@
<device>
<path>/dev/sda</path>
<weight>1000</weight>
+ <read_bps>20000000</read_bps>
+ <write_bps>30000000</write_bps>
+ <read_iops>4000</read_iops>
+ <write_iops>5000</write_iops>
</device>
<device>
<path>/dev/sdb</path>
<weight>500</weight>
+ <read_bps>30000000</read_bps>
+ <write_bps>30000000</write_bps>
+ <read_iops>4300</read_iops>
+ <write_iops>6000</write_iops>
</device>
</blkiotune>
...
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 4d333a8..10553af 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -621,9 +621,31 @@
<element name="path">
<ref name="absFilePath"/>
</element>
- <element name="weight">
- <ref name="weight"/>
- </element>
+ <optional>
+ <element name="weight">
+ <ref name="weight"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="read_bps">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="write_bps">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="read_iops">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
+ <optional>
+ <element name="write_iops">
+ <data type="unsignedLong"/>
+ </element>
+ </optional>
</interleave>
</element>
</zeroOrMore>
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index a47e33c..fd4a2e5 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1780,6 +1780,46 @@ char * virDomainGetSchedulerType(virDomainPtr domain,
#define VIR_DOMAIN_BLKIO_DEVICE_WEIGHT "device_weight"
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS:
+ *
+ * Macro for the BLKIO tunable throttle.read_bps_device: it represents the read
+ * bytes per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,read_bps elements,
+ * separated by ',', with element read_bps as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS "device_read_bps"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS:
+ *
+ * Macro for the BLKIO tunable throttle.write_bps_device: it represents the write
+ * bytes per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,write_bps elements,
+ * separated by ',', with element write_bps as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS "device_write_bps"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS:
+ *
+ * Macro for the BLKIO tunable throttle.read_iops_device: it represents the read
+ * I/O operations per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,read_iops elements,
+ * separated by ',', with element read_iops as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS "device_read_iops"
+
+/**
+ * VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS:
+ *
+ * Macro for the BLKIO tunable throttle.write_iops_device: it represents the write
+ * I/O operations per second permitted through a block device, as a string.
+ * The string is parsed as a series of /path/to/device,write_iops elements,
+ * separated by ',', with element write_iops as a ullong.
+ */
+#define VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS "device_write_iops"
+
/* Set Blkio tunables for the domain*/
int virDomainSetBlkioParameters(virDomainPtr domain,
virTypedParameterPtr params,
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 05c1de4..f9df10f 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -880,47 +880,100 @@ virDomainXMLOptionGetNamespace(virDomainXMLOptionPtr xmlopt)
void
-virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
+virBlkioDeviceIoTuneInfoArrayClear(virBlkioDeviceIoTuneInfoPtr devices,
int ndevices)
{
size_t i;
for (i = 0; i < ndevices; i++)
- VIR_FREE(deviceWeights[i].path);
+ VIR_FREE(devices[i].path);
}
/**
- * virDomainBlkioDeviceWeightParseXML
+ * virDomainBlkioDeviceIoTuneInfoParseXML
*
* this function parses a XML node:
*
* <device>
* <path>/fully/qualified/device/path</path>
* <weight>weight</weight>
+ * <read_bps>read_bps</read_bps>
+ * <write_bps>write_bps</write_bps>
+ * <read_iops>read_iops</read_iops>
+ * <write_iops>write_iops</write_iops>
* </device>
*
- * and fills a virBlkioDeviceWeight struct.
+ * and fills a virBlkioDeviceIoTuneInfo struct.
*/
static int
-virDomainBlkioDeviceWeightParseXML(xmlNodePtr root,
- virBlkioDeviceWeightPtr dw)
+virDomainBlkioDeviceIoTuneInfoParseXML(xmlNodePtr root,
+ virBlkioDeviceIoTuneInfoPtr dio)
{
char *c;
xmlNodePtr node;
+ dio->read_bps = 0;
+ dio->write_bps = 0;
+ dio->read_iops = 0;
+ dio->write_iops = 0;
+
node = root->children;
while (node) {
if (node->type == XML_ELEMENT_NODE) {
- if (xmlStrEqual(node->name, BAD_CAST "path") && !dw->path) {
- dw->path = (char *)xmlNodeGetContent(node);
+ if (xmlStrEqual(node->name, BAD_CAST "path") && !dio->path) {
+ dio->path = (char *)xmlNodeGetContent(node);
} else if (xmlStrEqual(node->name, BAD_CAST "weight")) {
c = (char *)xmlNodeGetContent(node);
- if (virStrToLong_ui(c, NULL, 10, &dw->weight) < 0) {
+ if (virStrToLong_ui(c, NULL, 10, &dio->weight) < 0) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("could not parse weight %s"),
c);
VIR_FREE(c);
- VIR_FREE(dw->path);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "read_bps")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->read_bps) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse read_bps %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "write_bps")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->write_bps) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse write_bps %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "read_iops")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->read_iops) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse read_iops %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
+ return -1;
+ }
+ VIR_FREE(c);
+ } else if (xmlStrEqual(node->name, BAD_CAST "write_iops")) {
+ c = (char *)xmlNodeGetContent(node);
+ if (virStrToLong_ull(c, NULL, 10, &dio->write_iops) < 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("could not parse write_iops %s"),
+ c);
+ VIR_FREE(c);
+ VIR_FREE(dio->path);
return -1;
}
VIR_FREE(c);
@@ -928,7 +981,7 @@ virDomainBlkioDeviceWeightParseXML(xmlNodePtr root,
}
node = node->next;
}
- if (!dw->path) {
+ if (!dio->path) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("missing per-device path"));
return -1;
@@ -1988,8 +2041,8 @@ void virDomainDefFree(virDomainDefPtr def)
VIR_FREE(def->description);
VIR_FREE(def->title);
- virBlkioDeviceWeightArrayClear(def->blkio.devices,
- def->blkio.ndevices);
+ virBlkioDeviceIoTuneInfoArrayClear(def->blkio.devices,
+ def->blkio.ndevices);
VIR_FREE(def->blkio.devices);
virDomainWatchdogDefFree(def->watchdog);
@@ -10962,15 +11015,15 @@ virDomainDefParseXML(xmlDocPtr xml,
for (i = 0; i < n; i++) {
size_t j;
- if (virDomainBlkioDeviceWeightParseXML(nodes[i],
- &def->blkio.devices[i]) < 0)
+ if (virDomainBlkioDeviceIoTuneInfoParseXML(nodes[i],
+ &def->blkio.devices[i]) < 0)
goto error;
def->blkio.ndevices++;
for (j = 0; j < i; j++) {
if (STREQ(def->blkio.devices[j].path,
def->blkio.devices[i].path)) {
virReportError(VIR_ERR_XML_ERROR,
- _("duplicate device weight path '%s'"),
+ _("duplicate blkio device path '%s'"),
def->blkio.devices[i].path);
goto error;
}
@@ -16349,7 +16402,9 @@ virDomainDefFormatInternal(virDomainDefPtr def,
blkio = true;
} else {
for (n = 0; n < def->blkio.ndevices; n++) {
- if (def->blkio.devices[n].weight) {
+ if (def->blkio.devices[n].weight || def->blkio.devices[n].read_bps ||
+ def->blkio.devices[n].write_bps || def->blkio.devices[n].read_iops ||
+ def->blkio.devices[n].write_iops) {
blkio = true;
break;
}
@@ -16364,13 +16419,33 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->blkio.weight);
for (n = 0; n < def->blkio.ndevices; n++) {
- if (def->blkio.devices[n].weight == 0)
+ if (def->blkio.devices[n].weight == 0 && def->blkio.devices[n].read_bps == 0 &&
+ def->blkio.devices[n].write_bps == 0 && def->blkio.devices[n].read_iops == 0 &&
+ def->blkio.devices[n].write_iops == 0)
continue;
virBufferAddLit(buf, " <device>\n");
virBufferEscapeString(buf, " <path>%s</path>\n",
def->blkio.devices[n].path);
- virBufferAsprintf(buf, " <weight>%u</weight>\n",
- def->blkio.devices[n].weight);
+ if (def->blkio.devices[n].weight) {
+ virBufferAsprintf(buf, " <weight>%u</weight>\n",
+ def->blkio.devices[n].weight);
+ }
+ if (def->blkio.devices[n].read_bps) {
+ virBufferAsprintf(buf, " <read_bps>%llu</read_bps>\n",
+ def->blkio.devices[n].read_bps);
+ }
+ if (def->blkio.devices[n].write_bps) {
+ virBufferAsprintf(buf, " <write_bps>%llu</write_bps>\n",
+ def->blkio.devices[n].write_bps);
+ }
+ if (def->blkio.devices[n].read_iops) {
+ virBufferAsprintf(buf, " <read_iops>%llu</read_iops>\n",
+ def->blkio.devices[n].read_iops);
+ }
+ if (def->blkio.devices[n].write_iops) {
+ virBufferAsprintf(buf, " <write_iops>%llu</write_iops>\n",
+ def->blkio.devices[n].write_iops);
+ }
virBufferAddLit(buf, " </device>\n");
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9414ebf..1f350ed 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1857,11 +1857,15 @@ virDomainVcpuPinDefPtr virDomainVcpuPinFindByVcpu(virDomainVcpuPinDefPtr *def,
int nvcpupin,
int vcpu);
-typedef struct _virBlkioDeviceWeight virBlkioDeviceWeight;
-typedef virBlkioDeviceWeight *virBlkioDeviceWeightPtr;
-struct _virBlkioDeviceWeight {
+typedef struct _virBlkioDeviceIoTuneInfo virBlkioDeviceIoTuneInfo;
+typedef virBlkioDeviceIoTuneInfo *virBlkioDeviceIoTuneInfoPtr;
+struct _virBlkioDeviceIoTuneInfo {
char *path;
unsigned int weight;
+ unsigned long long read_bps;
+ unsigned long long write_bps;
+ unsigned long long read_iops;
+ unsigned long long write_iops;
};
enum virDomainRNGModel {
@@ -1908,8 +1912,8 @@ struct _virDomainIdMapDef {
};
-void virBlkioDeviceWeightArrayClear(virBlkioDeviceWeightPtr deviceWeights,
- int ndevices);
+void virBlkioDeviceIoTuneInfoArrayClear(virBlkioDeviceIoTuneInfoPtr devices,
+ int ndevices);
typedef struct _virDomainResourceDef virDomainResourceDef;
typedef virDomainResourceDef *virDomainResourceDefPtr;
@@ -1937,7 +1941,7 @@ struct _virDomainDef {
unsigned int weight;
size_t ndevices;
- virBlkioDeviceWeightPtr devices;
+ virBlkioDeviceIoTuneInfoPtr devices;
} blkio;
struct {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 50e2f48..e6259cf 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -103,7 +103,7 @@ virDomainAuditVcpu;
# conf/domain_conf.h
-virBlkioDeviceWeightArrayClear;
+virBlkioDeviceIoTuneInfoArrayClear;
virDiskNameToBusDeviceIndex;
virDiskNameToIndex;
virDomainActualNetDefFree;
@@ -1207,7 +1207,7 @@ virCgroupNewVcpu;
virCgroupPathOfController;
virCgroupRemove;
virCgroupRemoveRecursively;
-virCgroupSetBlkioDeviceWeight;
+virCgroupSetBlkioDeviceIoTune;
virCgroupSetBlkioWeight;
virCgroupSetCpuCfsPeriod;
virCgroupSetCpuCfsQuota;
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 0b0ca02..f2c32e7 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -112,10 +112,13 @@ static int virLXCCgroupSetupBlkioTune(virDomainDefPtr def,
if (def->blkio.ndevices) {
for (i = 0; i < def->blkio.ndevices; i++) {
- virBlkioDeviceWeightPtr dw = &def->blkio.devices[i];
- if (!dw->weight)
+ virBlkioDeviceIoTuneInfoPtr dio = &def->blkio.devices[i];
+ if (!dio->weight)
continue;
- if (virCgroupSetBlkioDeviceWeight(cgroup, dw->path, dw->weight) < 0)
+ if (virCgroupSetBlkioDeviceIoTune(cgroup,
+ dio->path, dio->weight,
+ dio->read_bps, dio->write_bps,
+ dio->read_iops, dio->write_iops) < 0)
return -1;
}
}
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f95c7f2..20e700f 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -399,11 +399,13 @@ qemuSetupBlkioCgroup(virDomainObjPtr vm)
if (vm->def->blkio.ndevices) {
for (i = 0; i < vm->def->blkio.ndevices; i++) {
- virBlkioDeviceWeightPtr dw = &vm->def->blkio.devices[i];
- if (!dw->weight)
+ virBlkioDeviceIoTuneInfoPtr dio = &vm->def->blkio.devices[i];
+ if (!dio->weight)
continue;
- if (virCgroupSetBlkioDeviceWeight(priv->cgroup, dw->path,
- dw->weight) < 0)
+ if (virCgroupSetBlkioDeviceIoTune(priv->cgroup,
+ dio->path, dio->weight,
+ dio->read_bps, dio->write_bps,
+ dio->read_iops, dio->write_iops) < 0)
return -1;
}
}
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0763f9b..ff0ae98 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -131,7 +131,7 @@
# define KVM_CAP_NR_VCPUS 9 /* returns max vcpus per vm */
#endif
-#define QEMU_NB_BLKIO_PARAM 2
+#define QEMU_NB_BLKIO_PARAM 6
#define QEMU_NB_BANDWIDTH_PARAM 6
@@ -7388,26 +7388,26 @@ cleanup:
return ret;
}
-/* deviceWeightStr in the form of /device/path,weight,/device/path,weight
+/* deviceIoTuneStr in the form of /device/path,ioTuneValue,/device/path,ioTuneValue or
* for example, /dev/disk/by-path/pci-0000:00:1f.2-scsi-0:0:0:0,800
+ * deviceIoTuneFiled represents the ioTune type to tune, including device weight,
+ * device read bps, device write bps, device read iops and device write iops.
*/
static int
-qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
- virBlkioDeviceWeightPtr *dw, size_t *size)
+qemuDomainParseDeviceIoTuneInfoStr(char *deviceIoTuneStr,
+ const char *deviceIoTuneFiled,
+ virBlkioDeviceIoTuneInfoPtr *dio, size_t *size)
{
char *temp;
int ndevices = 0;
int nsep = 0;
- size_t i;
- virBlkioDeviceWeightPtr result = NULL;
-
- *dw = NULL;
- *size = 0;
+ size_t i, j, k;
+ virBlkioDeviceIoTuneInfoPtr result = NULL;
- if (STREQ(deviceWeightStr, ""))
+ if (STREQ(deviceIoTuneStr, ""))
return 0;
- temp = deviceWeightStr;
+ temp = deviceIoTuneStr;
while (temp) {
temp = strchr(temp, ',');
if (temp) {
@@ -7426,8 +7426,11 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (VIR_ALLOC_N(result, ndevices) < 0)
return -1;
+ for (i = 0; i < ndevices; i++)
+ memset(&result[i], 0, sizeof(result[i]));
+
i = 0;
- temp = deviceWeightStr;
+ temp = deviceIoTuneStr;
while (temp) {
char *p = temp;
@@ -7439,11 +7442,25 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (VIR_STRNDUP(result[i].path, temp, p - temp) < 0)
goto cleanup;
- /* weight */
+ /* device ioTune value */
temp = p + 1;
- if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
- goto error;
+ if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
+ if (virStrToLong_ui(temp, &p, 10, &result[i].weight) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].read_bps) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].write_bps) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].read_iops) < 0)
+ goto error;
+ } else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (virStrToLong_ull(temp, &p, 10, &result[i].write_iops) < 0)
+ goto error;
+ }
i++;
@@ -7457,30 +7474,68 @@ qemuDomainParseDeviceWeightStr(char *deviceWeightStr,
if (!i)
VIR_FREE(result);
- *dw = result;
- *size = i;
+ for (j = 0; j < i; j++) {
+ bool found = false;
+ virBlkioDeviceIoTuneInfoPtr old, new;
+
+ new = &result[j];
+ for (k = 0; k < *size; k++) {
+ old = &(*dio)[k];
+ if (STREQ(new->path, old->path)) {
+ found = true;
+ if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT))
+ old->weight = new->weight;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS))
+ old->read_bps = new->read_bps;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS))
+ old->write_bps = new->write_bps;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS))
+ old->read_iops = new->read_iops;
+ else if (STREQ(deviceIoTuneFiled, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS))
+ old->write_iops = new->write_iops;
+ break;
+ }
+ }
+ if (!found) {
+ if (!new->weight && !new->read_bps && !new->write_bps &&
+ !new->read_iops && !new->write_iops)
+ continue;
+ if (VIR_EXPAND_N(*dio, *size, 1) < 0)
+ goto cleanup;
+ old = &(*dio)[*size -1];
+ if (VIR_STRDUP(old->path, new->path) < 0)
+ goto cleanup;
+ old->weight = new->weight;
+ old->read_bps = new->read_bps;
+ old->write_bps = new->write_bps;
+ old->read_iops = new->read_iops;
+ old->write_iops = new->write_iops;
+ }
+ }
+ virBlkioDeviceIoTuneInfoArrayClear(result, ndevices);
+ VIR_FREE(result);
return 0;
error:
virReportError(VIR_ERR_INVALID_ARG,
- _("unable to parse device weight '%s'"), deviceWeightStr);
+ _("unable to parse device ioTune '%s'"), deviceIoTuneStr);
cleanup:
- virBlkioDeviceWeightArrayClear(result, ndevices);
+ virBlkioDeviceIoTuneInfoArrayClear(result, ndevices);
VIR_FREE(result);
return -1;
}
-/* Modify dest_array to reflect all device weight changes described in
+/* Modify dest_array to reflect all device Iotune info changes described in
* src_array. */
static int
-qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *dest_array,
- size_t *dest_size,
- virBlkioDeviceWeightPtr src_array,
- size_t src_size)
+qemuDomainMergeDeviceIoTuneInfos(virBlkioDeviceIoTuneInfoPtr *dest_array,
+ size_t *dest_size,
+ virBlkioDeviceIoTuneInfoPtr src_array,
+ size_t src_size)
{
size_t i, j;
- virBlkioDeviceWeightPtr dest, src;
+ virBlkioDeviceIoTuneInfoPtr dest, src;
for (i = 0; i < src_size; i++) {
bool found = false;
@@ -7491,18 +7546,27 @@ qemuDomainMergeDeviceWeights(virBlkioDeviceWeightPtr *dest_array,
if (STREQ(src->path, dest->path)) {
found = true;
dest->weight = src->weight;
+ dest->read_bps = src->read_bps;
+ dest->write_bps = src->write_bps;
+ dest->read_iops = src->read_iops;
+ dest->write_iops = src->write_iops;
break;
}
}
if (!found) {
- if (!src->weight)
+ if (!src->weight && !src->read_bps && !src->write_bps &&
+ !src->read_iops && !src->write_iops)
continue;
if (VIR_EXPAND_N(*dest_array, *dest_size, 1) < 0)
return -1;
dest = &(*dest_array)[*dest_size - 1];
- dest->path = src->path;
+ if (VIR_STRDUP(dest->path, src->path) < 0)
+ return -1;
dest->weight = src->weight;
- src->path = NULL;
+ dest->read_bps = src->read_bps;
+ dest->write_bps = src->write_bps;
+ dest->read_iops = src->read_iops;
+ dest->write_iops = src->write_iops;
}
}
@@ -7531,6 +7595,14 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
VIR_TYPED_PARAM_UINT,
VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ VIR_TYPED_PARAM_STRING,
NULL) < 0)
return -1;
@@ -7562,44 +7634,114 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
if (flags & VIR_DOMAIN_AFFECT_LIVE) {
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
+ size_t ndevices = 0;
+ virBlkioDeviceIoTuneInfoPtr devices = NULL;
+ size_t j;
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&devices, &ndevices,
+ vm->def->blkio.devices,
+ vm->def->blkio.ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("out of blkio weight range."));
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
if (virCgroupSetBlkioWeight(priv->cgroup, params[i].value.ui) < 0)
ret = -1;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
- size_t ndevices;
- virBlkioDeviceWeightPtr devices = NULL;
- size_t j;
-
- if (qemuDomainParseDeviceWeightStr(params[i].value.s,
- &devices,
- &ndevices) < 0) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
- for (j = 0; j < ndevices; j++) {
- if (virCgroupSetBlkioDeviceWeight(priv->cgroup,
- devices[j].path,
- devices[j].weight) < 0) {
- ret = -1;
- break;
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
+ continue;
}
- if (j != ndevices ||
- qemuDomainMergeDeviceWeights(&vm->def->blkio.devices,
- &vm->def->blkio.ndevices,
- devices, ndevices) < 0)
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ }
+
+ for (j = 0; j < ndevices; j++) {
+ if (virCgroupSetBlkioDeviceIoTune(priv->cgroup,
+ devices[j].path, devices[j].weight,
+ devices[j].read_bps, devices[j].write_bps,
+ devices[j].read_iops, devices[j].write_iops) < 0) {
ret = -1;
- virBlkioDeviceWeightArrayClear(devices, ndevices);
- VIR_FREE(devices);
+ break;
+ }
}
+ if (j != ndevices ||
+ qemuDomainMergeDeviceIoTuneInfos(&vm->def->blkio.devices,
+ &vm->def->blkio.ndevices,
+ devices, ndevices) < 0)
+ ret = -1;
+
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
}
if (ret < 0)
@@ -7610,33 +7752,102 @@ qemuDomainSetBlkioParameters(virDomainPtr dom,
for (i = 0; i < nparams; i++) {
virTypedParameterPtr param = ¶ms[i];
+ virBlkioDeviceIoTuneInfoPtr devices = NULL;
+ size_t ndevices = 0;
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&devices, &ndevices,
+ persistentDef->blkio.devices,
+ persistentDef->blkio.ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
if (STREQ(param->field, VIR_DOMAIN_BLKIO_WEIGHT)) {
if (params[i].value.ui > 1000 || params[i].value.ui < 100) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("out of blkio weight range."));
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
persistentDef->blkio.weight = params[i].value.ui;
} else if (STREQ(param->field, VIR_DOMAIN_BLKIO_DEVICE_WEIGHT)) {
- virBlkioDeviceWeightPtr devices = NULL;
- size_t ndevices;
-
- if (qemuDomainParseDeviceWeightStr(params[i].value.s,
- &devices,
- &ndevices) < 0) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_DEVICE_WEIGHT,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
continue;
}
- if (qemuDomainMergeDeviceWeights(&persistentDef->blkio.devices,
- &persistentDef->blkio.ndevices,
- devices, ndevices) < 0)
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ &devices,
+ &ndevices) < 0) {
ret = -1;
- virBlkioDeviceWeightArrayClear(devices, ndevices);
- VIR_FREE(devices);
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
+ } else if (STREQ(param->field, VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS)) {
+ if (qemuDomainParseDeviceIoTuneInfoStr(params[i].value.s,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ &devices,
+ &ndevices) < 0) {
+ ret = -1;
+ if (ndevices) {
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
+ }
+ continue;
+ }
}
+
+ if (qemuDomainMergeDeviceIoTuneInfos(&persistentDef->blkio.devices,
+ &persistentDef->blkio.ndevices,
+ devices, ndevices) < 0)
+ ret = -1;
+
+ virBlkioDeviceIoTuneInfoArrayClear(devices, ndevices);
+ VIR_FREE(devices);
}
if (virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
@@ -7747,6 +7958,122 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
goto cleanup;
break;
+ case 2: /* blkiotune.throttle.device_read_bps */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].read_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].read_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 3: /* blkiotune.throttle.device_write_bps */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].write_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].write_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 4: /* blkiotune.throttle.device_read_iops */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].read_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].read_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
+ case 5: /* blkiotune.throttle.device_write_iops */
+ if (vm->def->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < vm->def->blkio.ndevices; j++) {
+ if (!vm->def->blkio.devices[j].write_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ vm->def->blkio.devices[j].path,
+ vm->def->blkio.devices[j].write_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (virTypedParameterAssign(param,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS,
+ VIR_TYPED_PARAM_STRING,
+ param->value.s) < 0)
+ goto cleanup;
+ break;
+
default:
break;
/* should not hit here */
@@ -7804,6 +8131,142 @@ qemuDomainGetBlkioParameters(virDomainPtr dom,
}
break;
+ case 2: /* blkiotune.device_read_bps */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].read_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].read_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_BPS);
+ goto cleanup;
+ }
+ break;
+
+ case 3: /* blkiotune.device_write_bps */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].write_bps)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].write_bps);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_BPS);
+ goto cleanup;
+ }
+ break;
+
+ case 4: /* blkiotune.device_read_iops */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].read_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].read_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_READ_IOPS);
+ goto cleanup;
+ }
+ break;
+
+ case 5: /* blkiotune.device_write_iops */
+ if (persistentDef->blkio.ndevices > 0) {
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ bool comma = false;
+
+ for (j = 0; j < persistentDef->blkio.ndevices; j++) {
+ if (!persistentDef->blkio.devices[j].write_iops)
+ continue;
+ if (comma)
+ virBufferAddChar(&buf, ',');
+ else
+ comma = true;
+ virBufferAsprintf(&buf, "%s,%llu",
+ persistentDef->blkio.devices[j].path,
+ persistentDef->blkio.devices[j].write_iops);
+ }
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ param->value.s = virBufferContentAndReset(&buf);
+ }
+ if (!param->value.s && VIR_STRDUP(param->value.s, "") < 0)
+ goto cleanup;
+ param->type = VIR_TYPED_PARAM_STRING;
+ if (virStrcpyStatic(param->field,
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS) == NULL) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Field name '%s' too long"),
+ VIR_DOMAIN_BLKIO_THROTTLE_DEVICE_WRITE_IOPS);
+ goto cleanup;
+ }
+ break;
+
default:
break;
/* should not hit here */
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index e99caf5..b506de5 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1825,23 +1825,36 @@ virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight)
/**
- * virCgroupSetBlkioDeviceWeight:
+ * virCgroupSetBlkioDeviceIoTune:
*
- * @group: The cgroup to change io device weight device for
+ * @group: The cgroup to change io device iotune device for
* @path: The device with a weight to alter
* @weight: The new device weight (100-1000), or 0 to clear
+ * @read_bps: The new read bps throttle, or 0 to clear
+ * @write_bps: The new write bps throttle, or 0 to clear
+ * @read_iops: The new read iops throttle, or 0 to clear
+ * @write_iops: The new write iops throttle, or 0 to clear
*
- * device_weight is treated as a write-only parameter, so
- * there isn't a getter counterpart.
+ * paramters like device_weight, device_read_bps, device_write_bps,
+ * device_read_iops and device_write_iops are treated as write-only,
+ * so there isn't a getter counterpart.
*
* Returns: 0 on success, -1 on error
*/
int
-virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
+virCgroupSetBlkioDeviceIoTune(virCgroupPtr group,
const char *path,
- unsigned int weight)
-{
- char *str;
+ unsigned int weight,
+ unsigned long long read_bps,
+ unsigned long long write_bps,
+ unsigned long long read_iops,
+ unsigned long long write_iops)
+{
+ char *weight_str;
+ char *read_bps_str;
+ char *write_bps_str;
+ char *read_iops_str;
+ char *write_iops_str;
struct stat sb;
int ret;
@@ -1866,15 +1879,51 @@ virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
return -1;
}
- if (virAsprintf(&str, "%d:%d %d", major(sb.st_rdev), minor(sb.st_rdev),
+ if (virAsprintf(&weight_str, "%d:%d %d", major(sb.st_rdev), minor(sb.st_rdev),
weight) < 0)
return -1;
+ if (virAsprintf(&read_bps_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ read_bps) < 0)
+ return -1;
+
+ if (virAsprintf(&write_bps_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ write_bps) < 0)
+ return -1;
+
+ if (virAsprintf(&read_iops_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ read_iops) < 0)
+ return -1;
+
+ if (virAsprintf(&write_iops_str, "%d:%d %llu", major(sb.st_rdev), minor(sb.st_rdev),
+ write_iops) < 0)
+ return -1;
+
ret = virCgroupSetValueStr(group,
VIR_CGROUP_CONTROLLER_BLKIO,
"blkio.weight_device",
- str);
- VIR_FREE(str);
+ weight_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.read_bps_device",
+ read_bps_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.write_bps_device",
+ write_bps_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.read_iops_device",
+ read_iops_str);
+ ret = virCgroupSetValueStr(group,
+ VIR_CGROUP_CONTROLLER_BLKIO,
+ "blkio.throttle.write_iops_device",
+ write_iops_str);
+ VIR_FREE(weight_str);
+ VIR_FREE(read_bps_str);
+ VIR_FREE(write_bps_str);
+ VIR_FREE(read_iops_str);
+ VIR_FREE(write_iops_str);
return ret;
}
@@ -3287,9 +3336,13 @@ virCgroupGetBlkioWeight(virCgroupPtr group ATTRIBUTE_UNUSED,
int
-virCgroupSetBlkioDeviceWeight(virCgroupPtr group ATTRIBUTE_UNUSED,
+virCgroupSetBlkioDeviceIoTune(virCgroupPtr group ATTRIBUTE_UNUSED,
const char *path ATTRIBUTE_UNUSED,
- unsigned int weight ATTRIBUTE_UNUSED)
+ unsigned int weight ATTRIBUTE_UNUSED,
+ unsigned long long read_bps ATTRIBUTE_UNUSED,
+ unsigned long long write_bps ATTRIBUTE_UNUSED,
+ unsigned long long read_iops ATTRIBUTE_UNUSED,
+ unsigned long long write_iops ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Control groups not supported on this platform"));
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index 835eb30..21980da 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -122,9 +122,13 @@ int virCgroupMoveTask(virCgroupPtr src_group,
int virCgroupSetBlkioWeight(virCgroupPtr group, unsigned int weight);
int virCgroupGetBlkioWeight(virCgroupPtr group, unsigned int *weight);
-int virCgroupSetBlkioDeviceWeight(virCgroupPtr group,
+int virCgroupSetBlkioDeviceIoTune(virCgroupPtr group,
const char *path,
- unsigned int weight);
+ unsigned int weight,
+ unsigned long long read_bps,
+ unsigned long long write_bps,
+ unsigned long long read_iops,
+ unsigned long long write_iops);
int virCgroupSetMemory(virCgroupPtr group, unsigned long long kb);
int virCgroupGetMemoryUsage(virCgroupPtr group, unsigned long *kb);
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
index 743cf29..9bd97fe 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-blkiotune-device.xml
@@ -8,6 +8,10 @@
<device>
<path>/dev/sda</path>
<weight>400</weight>
+ <read_bps>2000000000</read_bps>
+ <write_bps>1000000000</write_bps>
+ <read_iops>1000</read_iops>
+ <write_iops>2000</write_iops>
</device>
<device>
<path>/dev/sdb</path>
--
1.7.9.5
1
0
Peter Krempa (2):
test: Refactor setting of dummy error handlers
tests: metadatatest: Quiesce errors on expected paths
tests/esxutilstest.c | 12 +-----------
tests/metadatatest.c | 2 ++
tests/reconnect.c | 6 +-----
tests/sockettest.c | 9 +--------
tests/statstest.c | 9 +--------
tests/testutils.c | 13 ++++++++++---
tests/testutils.h | 2 ++
tests/utiltest.c | 12 +-----------
8 files changed, 19 insertions(+), 46 deletions(-)
--
1.8.3.2
2
5
[libvirt] [PATCH 0/5] Add support for device blkio iops and bps throttle
by hzguanqiang@gmail.com 18 Sep '13
by hzguanqiang@gmail.com 18 Sep '13
18 Sep '13
From: Guan Qiang <hzguanqiang(a)corp.netease.com>
The patches add support for setting/getting blkio read/write bps/iops
throttle per-device with blkio cgroup.
Aline Manera (3):
Add https protocol support for cdrom disk
Add ftps protocol support for cdrom disk
Add tftp protocol support for cdrom disk
Guan Qiang (2):
blkiotune: add support for device iops and bps throttle
blkiotune: add virsh support for blkiotune.throttle.iops/bps
docs/formatdomain.html.in | 32 ++
docs/schemas/domaincommon.rng | 31 +-
include/libvirt/libvirt.h.in | 40 ++
src/conf/domain_conf.c | 120 +++-
src/conf/domain_conf.h | 19 +-
src/libvirt_private.syms | 4 +-
src/lxc/lxc_cgroup.c | 9 +-
src/qemu/qemu_cgroup.c | 10 +-
src/qemu/qemu_command.c | 18 +
src/qemu/qemu_driver.c | 579 ++++++++++++++++++--
src/util/vircgroup.c | 79 ++-
src/util/vircgroup.h | 8 +-
.../qemuxml2argv-blkiotune-device.xml | 4 +
.../qemuxml2argv-disk-cdrom-network-ftps.args | 8 +
.../qemuxml2argv-disk-cdrom-network-ftps.xml | 37 ++
.../qemuxml2argv-disk-cdrom-network-https.args | 8 +
.../qemuxml2argv-disk-cdrom-network-https.xml | 37 ++
.../qemuxml2argv-disk-cdrom-network-tftp.args | 7 +
.../qemuxml2argv-disk-cdrom-network-tftp.xml | 37 ++
tests/qemuxml2argvtest.c | 6 +
tools/virsh-domain.c | 64 +++
tools/virsh.pod | 32 +-
22 files changed, 1075 insertions(+), 114 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-https.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
--
1.7.9.5
2
1
A user came into #virt the other day and was trying to get libvirtd
to work with VMware Fusion 5, which is basically the Mac OS X version of
VMware Workstation. In helping him out I noticed a few limitations of our
VMX parser so I've added support through this patchset. I don't personally
have access or own VMware's product.
v5:
* use virBufferEscapeString NULL handling instead of doing my own checks
* merge v4's patch 1 into master
* 2 & 3 of this series are unchanged and ACK'd from v4.
v4:
* Half the patchset has been merged at this point
* Add back 'auto detect' support via <source startupPolicy='optional'/>
* Made device='lun' match device='cdrom'
* Patch 1 & 2 are new to the series
v3:
* Dropped 'auto detect' support from series as it needs more work based on
feedback
* Added patch to combine virVMXFormatHardDisk and virVMXFormatCDROM into
one function.
* Converted to <disk type='block' device='lun'> instead of adding a
<driver> element to better match the behavior available via QEMU.
v2:
* Added additional test cases and fixed issues that arose from those
*** BLURB HERE ***
Doug Goldstein (3):
Allow <source> for type=block to have no dev
VMX: Add support for 'auto detect' fileNames
VMX: Add a VMWare Fusion 5 configuration for tests
docs/schemas/domaincommon.rng | 8 +-
src/conf/domain_conf.c | 4 +-
src/vmx/vmx.c | 28 +++++--
.../vmx2xml-cdrom-ide-raw-auto-detect.vmx | 5 ++
.../vmx2xml-cdrom-ide-raw-auto-detect.xml | 24 ++++++
.../vmx2xml-cdrom-scsi-raw-auto-detect.vmx | 6 ++
.../vmx2xml-cdrom-scsi-raw-auto-detect.xml | 24 ++++++
tests/vmx2xmldata/vmx2xml-fusion-in-the-wild-1.vmx | 88 ++++++++++++++++++++++
tests/vmx2xmldata/vmx2xml-fusion-in-the-wild-1.xml | 39 ++++++++++
tests/vmx2xmltest.c | 4 +
.../xml2vmx-cdrom-ide-raw-auto-detect.vmx | 14 ++++
.../xml2vmx-cdrom-ide-raw-auto-detect.xml | 14 ++++
.../xml2vmx-cdrom-scsi-raw-auto-detect.vmx | 15 ++++
.../xml2vmx-cdrom-scsi-raw-auto-detect.xml | 14 ++++
tests/xml2vmxdata/xml2vmx-fusion-in-the-wild-1.vmx | 30 ++++++++
tests/xml2vmxdata/xml2vmx-fusion-in-the-wild-1.xml | 41 ++++++++++
tests/xml2vmxtest.c | 4 +
17 files changed, 352 insertions(+), 10 deletions(-)
create mode 100644 tests/vmx2xmldata/vmx2xml-cdrom-ide-raw-auto-detect.vmx
create mode 100644 tests/vmx2xmldata/vmx2xml-cdrom-ide-raw-auto-detect.xml
create mode 100644 tests/vmx2xmldata/vmx2xml-cdrom-scsi-raw-auto-detect.vmx
create mode 100644 tests/vmx2xmldata/vmx2xml-cdrom-scsi-raw-auto-detect.xml
create mode 100644 tests/vmx2xmldata/vmx2xml-fusion-in-the-wild-1.vmx
create mode 100644 tests/vmx2xmldata/vmx2xml-fusion-in-the-wild-1.xml
create mode 100644 tests/xml2vmxdata/xml2vmx-cdrom-ide-raw-auto-detect.vmx
create mode 100644 tests/xml2vmxdata/xml2vmx-cdrom-ide-raw-auto-detect.xml
create mode 100644 tests/xml2vmxdata/xml2vmx-cdrom-scsi-raw-auto-detect.vmx
create mode 100644 tests/xml2vmxdata/xml2vmx-cdrom-scsi-raw-auto-detect.xml
create mode 100644 tests/xml2vmxdata/xml2vmx-fusion-in-the-wild-1.vmx
create mode 100644 tests/xml2vmxdata/xml2vmx-fusion-in-the-wild-1.xml
--
1.8.1.5
2
5