Devel
Threads by month
- ----- 2026 -----
- 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
September 2013
- 112 participants
- 389 discussions
17 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 17 Sep '13
by hzguanqiang@gmail.com 17 Sep '13
17 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 17 Sep '13
by hzguanqiang@gmail.com 17 Sep '13
17 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 17 Sep '13
by hzguanqiang@gmail.com 17 Sep '13
17 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
[libvirt] [PATCH 5/5] blkiotune: add virsh support for blkiotune.throttle.iops/bps
by hzguanqiang@gmail.com 17 Sep '13
by hzguanqiang@gmail.com 17 Sep '13
17 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 4/5] blkiotune: add support for device iops and bps throttle
by hzguanqiang@gmail.com 17 Sep '13
by hzguanqiang@gmail.com 17 Sep '13
17 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
17 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
qemu/KVM also supports a tftp URL while specifying the cdrom ISO image.
The xml should be as following:
<disk type='network' device='cdrom'>
<source protocol='tftp' name='/url/path'>
<host name='host.name' port='69'/>
</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 | 3 +-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 6 ++++
.../qemuxml2argv-disk-cdrom-network-tftp.args | 7 ++++
.../qemuxml2argv-disk-cdrom-network-tftp.xml | 37 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
8 files changed, 64 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0b6cd45..a927643 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1533,6 +1533,14 @@
<target dev='hdc' bus='ide' tray='open'/>
<readonly/>
</disk>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol="tftp" name="url_path">
+ <host name="hostname" port="69"/>
+ </source>
+ <target dev='hdc' bus='ide' tray='open'/>
+ <readonly/>
+ </disk>
<disk type='block' device='lun'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sda'/>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2da3669..4d333a8 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1234,6 +1234,7 @@
<value>https</value>
<value>ftp</value>
<value>ftps</value>
+ <value>tftp</value>
</choice>
</attribute>
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ff3da7a..05c1de4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -267,7 +267,8 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"http",
"https",
"ftp",
- "ftps")
+ "ftps",
+ "tftp")
VIR_ENUM_IMPL(virDomainDiskProtocolTransport, VIR_DOMAIN_DISK_PROTO_TRANS_LAST,
"tcp",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ab1290b..9414ebf 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -546,6 +546,7 @@ enum virDomainDiskProtocol {
VIR_DOMAIN_DISK_PROTOCOL_HTTPS,
VIR_DOMAIN_DISK_PROTOCOL_FTP,
VIR_DOMAIN_DISK_PROTOCOL_FTPS,
+ VIR_DOMAIN_DISK_PROTOCOL_TFTP,
VIR_DOMAIN_DISK_PROTOCOL_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 1bde013..4628dac 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3923,6 +3923,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
disk->hosts->port ? disk->hosts->port : "990");
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
break;
+ case VIR_DOMAIN_DISK_PROTOCOL_TFTP:
+ virBufferAsprintf(&opt, "file=tftp://%s:%s",
+ disk->hosts->name,
+ disk->hosts->port ? disk->hosts->port : "69");
+ virBufferEscape(&opt, ',', ",", "%s,", disk->src);
+ break;
}
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME) {
if (qemuBuildVolumeString(conn, disk, &opt) < 0)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
new file mode 100644
index 0000000..bc0cb92
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.args
@@ -0,0 +1,7 @@
+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=tftp://host.name:69/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-tftp.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.xml
new file mode 100644
index 0000000..b311237
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-tftp.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='tftp' name='/url/path/file.iso'>
+ <host name='host.name' port='69'/>
+ </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 5daee82..ec4a6e5 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -451,6 +451,8 @@ mymain(void)
QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-network-ftps", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE);
+ DO_TEST("disk-cdrom-network-tftp", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
+ QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-tray",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_TX_ALG);
--
1.7.9.5
1
0
17 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
The ftps protocol is another protocol supported by qemu/KVM while specifying
the cdrom ISO image.
The xml should be as following:
<disk type='network' device='cdrom'>
<source protocol='ftps' name='/url/path'>
<host name='host.name' port='990'/>
</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 | 3 +-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 6 ++++
.../qemuxml2argv-disk-cdrom-network-ftps.args | 8 +++++
.../qemuxml2argv-disk-cdrom-network-ftps.xml | 37 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 2 ++
8 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 240571f..0b6cd45 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1525,6 +1525,14 @@
<target dev='hdc' bus='ide' tray='open'/>
<readonly/>
</disk>
+ <disk type='network' device='cdrom'>
+ <driver name='qemu' type='raw'/>
+ <source protocol="ftps" name="url_path">
+ <host name="hostname" port="990"/>
+ </source>
+ <target dev='hdc' bus='ide' tray='open'/>
+ <readonly/>
+ </disk>
<disk type='block' device='lun'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sda'/>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 2f91f0f..2da3669 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1233,6 +1233,7 @@
<value>http</value>
<value>https</value>
<value>ftp</value>
+ <value>ftps</value>
</choice>
</attribute>
<optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 04563f6..ff3da7a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -266,7 +266,8 @@ VIR_ENUM_IMPL(virDomainDiskProtocol, VIR_DOMAIN_DISK_PROTOCOL_LAST,
"iscsi",
"http",
"https",
- "ftp")
+ "ftp",
+ "ftps")
VIR_ENUM_IMPL(virDomainDiskProtocolTransport, VIR_DOMAIN_DISK_PROTO_TRANS_LAST,
"tcp",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d54b29e..ab1290b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -545,6 +545,7 @@ enum virDomainDiskProtocol {
VIR_DOMAIN_DISK_PROTOCOL_HTTP,
VIR_DOMAIN_DISK_PROTOCOL_HTTPS,
VIR_DOMAIN_DISK_PROTOCOL_FTP,
+ VIR_DOMAIN_DISK_PROTOCOL_FTPS,
VIR_DOMAIN_DISK_PROTOCOL_LAST
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 883b513..1bde013 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3917,6 +3917,12 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
disk->hosts->port ? disk->hosts->port : "21");
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
break;
+ case VIR_DOMAIN_DISK_PROTOCOL_FTPS:
+ virBufferAsprintf(&opt, "file=ftps://%s:%s",
+ disk->hosts->name,
+ disk->hosts->port ? disk->hosts->port : "990");
+ virBufferEscape(&opt, ',', ",", "%s,", disk->src);
+ break;
}
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME) {
if (qemuBuildVolumeString(conn, disk, &opt) < 0)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.args
new file mode 100644
index 0000000..78dbff2
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.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=ftps://host.name:990/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-ftps.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.xml
new file mode 100644
index 0000000..b4a0f52
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-network-ftps.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='ftps' name='/url/path/file.iso'>
+ <host name='host.name' port='990'/>
+ </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 a11c9a8..5daee82 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -449,6 +449,8 @@ mymain(void)
QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-network-ftp", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
QEMU_CAPS_DRIVE);
+ DO_TEST("disk-cdrom-network-ftps", QEMU_CAPS_KVM, QEMU_CAPS_DEVICE,
+ QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-tray",
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_VIRTIO_TX_ALG);
--
1.7.9.5
1
0