Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- 38 participants
- 40204 discussions
[libvirt] [PATCH] virsh-domain: Remove unnecessary check and tune code in cmdDesc()
by Hongwei Bi 18 Sep '13
by Hongwei Bi 18 Sep '13
18 Sep '13
Since there is a check on buf through virBufferError(),
it is not necessary to check desc again.
---
tools/virsh-domain.c | 62 +++++++++++++++++++++----------------------------
1 files changed, 27 insertions(+), 35 deletions(-)
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index e47877b..a8a0105 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -6724,45 +6724,37 @@ cmdDesc(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
}
desc = virBufferContentAndReset(&buf);
- if (edit || desc) {
- if (!desc) {
- desc = vshGetDomainDescription(ctl, dom, title,
- config?VIR_DOMAIN_XML_INACTIVE:0);
- if (!desc)
- goto cleanup;
- }
-
- if (edit) {
- /* Create and open the temporary file. */
- if (!(tmp = vshEditWriteToTempFile(ctl, desc)))
- goto cleanup;
+ if (edit) {
+ /* Create and open the temporary file. */
+ if (!(tmp = vshEditWriteToTempFile(ctl, desc)))
+ goto cleanup;
- /* Start the editor. */
- if (vshEditFile(ctl, tmp) == -1)
- goto cleanup;
+ /* Start the editor. */
+ if (vshEditFile(ctl, tmp) == -1)
+ goto cleanup;
- /* Read back the edited file. */
- if (!(desc_edited = vshEditReadBackFile(ctl, tmp)))
- goto cleanup;
+ /* Read back the edited file. */
+ if (!(desc_edited = vshEditReadBackFile(ctl, tmp)))
+ goto cleanup;
- /* strip a possible newline at the end of file; some
- * editors enforce a newline, this makes editing the title
- * more convenient */
- if (title &&
- (tmpstr = strrchr(desc_edited, '\n')) &&
- *(tmpstr+1) == '\0')
- *tmpstr = '\0';
-
- /* Compare original XML with edited. Has it changed at all? */
- if (STREQ(desc, desc_edited)) {
- vshPrint(ctl, _("Domain description not changed.\n"));
- ret = true;
- goto cleanup;
- }
+ /* strip a possible newline at the end of file; some
+ * editors enforce a newline, this makes editing the title
+ * more convenient */
+ if (title &&
+ (tmpstr = strrchr(desc_edited, '\n')) &&
+ *(tmpstr+1) == '\0')
+ *tmpstr = '\0';
+
+ /* Compare original XML with edited. Has it changed at all? */
+ if (STREQ(desc, desc_edited)) {
+ vshPrint(ctl, _("Domain description not changed.\n"));
+ ret = true;
+ goto cleanup;
+ }
- VIR_FREE(desc);
- desc = desc_edited;
- desc_edited = NULL;
+ VIR_FREE(desc);
+ desc = desc_edited;
+ desc_edited = NULL;
}
if (virDomainSetMetadata(dom, type, desc, NULL, NULL, flags) < 0) {
--
1.7.1
2
2
17 Sep '13
Useful to set custom forwarders instead of using the contents of
/etc/resolv.conf. It helps me to setup dnsmasq as local nameserver to resolv VM
domain names from domain 0, when domain option is used.
Signed-off-by: Diego Woitasen <diego.woitasen(a)vhgroup.net>
---
docs/formatnetwork.html.in | 8 ++++
docs/schemas/network.rng | 5 +++
src/conf/network_conf.c | 43 ++++++++++++++++++++--
src/conf/network_conf.h | 2 +
src/network/bridge_driver.c | 8 ++++
.../nat-network-dns-forwarders.conf | 16 ++++++++
.../nat-network-dns-forwarders.xml | 12 ++++++
tests/networkxml2conftest.c | 1 +
8 files changed, 92 insertions(+), 3 deletions(-)
create mode 100644 tests/networkxml2confdata/nat-network-dns-forwarders.conf
create mode 100644 tests/networkxml2confdata/nat-network-dns-forwarders.xml
diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
index e1482db..9fdc3cf 100644
--- a/docs/formatnetwork.html.in
+++ b/docs/formatnetwork.html.in
@@ -631,6 +631,8 @@
<domain name="example.com"/>
<dns>
<txt name="example" value="example value" />
+ <forwarder addr="8.8.8.8"/>
+ <forwarder addr="8.8.4.4"/>
<srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10'/>
<host ip='192.168.122.2'>
<hostname>myhost</hostname>
@@ -685,6 +687,12 @@
Currently supported sub-elements of <code><dns></code> are:
<dl>
+ <dt><code>forwarder</code></dt>
+ <dd>A <code>dns</code> element can have 0 or more <code>forwarder</code> elements.
+ Each forwarder element defines an IP address to be used as forwarder
+ in DNS server configuration. The addr attribute is required and defines the
+ IP address of every forwarder. <span class="since">Since N/A</span>
+ </dd>
<dt><code>txt</code></dt>
<dd>A <code>dns</code> element can have 0 or more <code>txt</code> elements.
Each txt element defines a DNS TXT record and has two attributes, both
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index ab183f1..95db5c2 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -217,6 +217,11 @@
</attribute>
</optional>
<zeroOrMore>
+ <element name="forwarder">
+ <attribute name="addr"><ref name="ipAddr"/></attribute>
+ </element>
+ </zeroOrMore>
+ <zeroOrMore>
<element name="txt">
<attribute name="name"><ref name="dnsName"/></attribute>
<attribute name="value"><text/></attribute>
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index d54f2aa..c9b90e7 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -175,6 +175,11 @@ virNetworkDNSSrvDefClear(virNetworkDNSSrvDefPtr def)
static void
virNetworkDNSDefClear(virNetworkDNSDefPtr def)
{
+ if (def->forwarders) {
+ while (def->nfwds)
+ VIR_FREE(def->forwarders[--def->nfwds]);
+ VIR_FREE(def->forwarders);
+ }
if (def->txts) {
while (def->ntxts)
virNetworkDNSTxtDefClear(&def->txts[--def->ntxts]);
@@ -1037,8 +1042,9 @@ virNetworkDNSDefParseXML(const char *networkName,
xmlNodePtr *hostNodes = NULL;
xmlNodePtr *srvNodes = NULL;
xmlNodePtr *txtNodes = NULL;
+ xmlNodePtr *fwdNodes = NULL;
char *forwardPlainNames = NULL;
- int nhosts, nsrvs, ntxts;
+ int nfwds, nhosts, nsrvs, ntxts;
size_t i;
int ret = -1;
xmlNodePtr save = ctxt->node;
@@ -1058,6 +1064,30 @@ virNetworkDNSDefParseXML(const char *networkName,
}
}
+ nfwds = virXPathNodeSet("./forwarder", ctxt, &fwdNodes);
+ if (nfwds < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("invalid <forwarder> element found in <dns> of network %s"),
+ networkName);
+ goto cleanup;
+ }
+ if (nfwds > 0) {
+ if (VIR_ALLOC_N(def->forwarders, nfwds) < 0)
+ goto cleanup;
+
+ for (i = 0; i < nfwds; i++) {
+ def->forwarders[i] = virXMLPropString(fwdNodes[i], "addr");
+ if (virSocketAddrParse(NULL, def->forwarders[i], AF_UNSPEC) < 0) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Invalid forwarder IP address '%s' "
+ "in network '%s'"),
+ def->forwarders[i], networkName);
+ goto cleanup;
+ }
+ def->nfwds++;
+ }
+ }
+
nhosts = virXPathNodeSet("./host", ctxt, &hostNodes);
if (nhosts < 0) {
virReportError(VIR_ERR_XML_ERROR,
@@ -1121,6 +1151,7 @@ virNetworkDNSDefParseXML(const char *networkName,
ret = 0;
cleanup:
VIR_FREE(forwardPlainNames);
+ VIR_FREE(fwdNodes);
VIR_FREE(hostNodes);
VIR_FREE(srvNodes);
VIR_FREE(txtNodes);
@@ -2267,13 +2298,14 @@ virNetworkDNSDefFormat(virBufferPtr buf,
int result = 0;
size_t i, j;
- if (!(def->forwardPlainNames || def->nhosts || def->nsrvs || def->ntxts))
+ if (!(def->forwardPlainNames || def->forwarders || def->nhosts ||
+ def->nsrvs || def->ntxts))
goto out;
virBufferAddLit(buf, "<dns");
if (def->forwardPlainNames) {
virBufferAddLit(buf, " forwardPlainNames='yes'");
- if (!(def->nhosts || def->nsrvs || def->ntxts)) {
+ if (!(def->forwarders || def->nhosts || def->nsrvs || def->ntxts)) {
virBufferAddLit(buf, "/>\n");
goto out;
}
@@ -2282,6 +2314,11 @@ virNetworkDNSDefFormat(virBufferPtr buf,
virBufferAddLit(buf, ">\n");
virBufferAdjustIndent(buf, 2);
+ for (i = 0; i < def->nfwds; i++) {
+ virBufferAsprintf(buf, "<forwarders addr='%s' />\n",
+ def->forwarders[i]);
+ }
+
for (i = 0; i < def->ntxts; i++) {
virBufferAsprintf(buf, "<txt name='%s' value='%s'/>\n",
def->txts[i].name,
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index c28bfae..b425986 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -122,6 +122,8 @@ struct _virNetworkDNSDef {
virNetworkDNSHostDefPtr hosts;
size_t nsrvs;
virNetworkDNSSrvDefPtr srvs;
+ size_t nfwds;
+ char **forwarders;
};
typedef struct _virNetworkIpDef virNetworkIpDef;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 3a8be90..a2cfb35 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -708,6 +708,14 @@ networkDnsmasqConfContents(virNetworkObjPtr network,
if (!network->def->dns.forwardPlainNames)
virBufferAddLit(&configbuf, "domain-needed\n");
+ if (network->def->dns.forwarders) {
+ virBufferAddLit(&configbuf, "no-resolv\n");
+ for (i=0; i < network->def->dns.nfwds; i++) {
+ virBufferAsprintf(&configbuf, "server=%s\n",
+ network->def->dns.forwarders[i]);
+ }
+ }
+
if (network->def->domain) {
virBufferAsprintf(&configbuf,
"domain=%s\n"
diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.conf b/tests/networkxml2confdata/nat-network-dns-forwarders.conf
new file mode 100644
index 0000000..ebca289
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-forwarders.conf
@@ -0,0 +1,16 @@
+##WARNING: THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
+##OVERWRITTEN AND LOST. Changes to this configuration should be made using:
+## virsh net-edit default
+## or other application using the libvirt API.
+##
+## dnsmasq conf file created by libvirt
+strict-order
+domain-needed
+no-resolv
+server=8.8.8.8
+server=8.8.4.4
+local=//
+except-interface=lo
+bind-dynamic
+interface=virbr0
+addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts
diff --git a/tests/networkxml2confdata/nat-network-dns-forwarders.xml b/tests/networkxml2confdata/nat-network-dns-forwarders.xml
new file mode 100644
index 0000000..eebec97
--- /dev/null
+++ b/tests/networkxml2confdata/nat-network-dns-forwarders.xml
@@ -0,0 +1,12 @@
+<network>
+ <name>default</name>
+ <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9c</uuid>
+ <forward dev='eth0' mode='nat'/>
+ <bridge name='virbr0' stp='on' delay='0' />
+ <dns>
+ <forwarder addr='8.8.8.8' />
+ <forwarder addr='8.8.4.4' />
+ </dns>
+ <ip address='192.168.122.1' netmask='255.255.255.0'>
+ </ip>
+</network>
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 5825af3..ad50e88 100644
--- a/tests/networkxml2conftest.c
+++ b/tests/networkxml2conftest.c
@@ -145,6 +145,7 @@ mymain(void)
DO_TEST("nat-network-dns-srv-record", full);
DO_TEST("nat-network-dns-hosts", full);
DO_TEST("nat-network-dns-forward-plain", full);
+ DO_TEST("nat-network-dns-forwarders", full);
DO_TEST("dhcp6-network", dhcpv6);
DO_TEST("dhcp6-nat-network", dhcpv6);
DO_TEST("dhcp6host-routed-network", dhcpv6);
--
1.8.1.2
2
1
On 08/29/2013 11:38 AM, Erik van Pienbroek wrote:
>
> This mass rebuild was done using winpthreads instead of the old
> pthreads-w32 implementation. In Fedora itself winpthreads isn't
> used by default yet, but it will be introduced in Fedora 20 once
> all build failures which are caused by it are resolved (if this
> takes too long the introduction of winpthreads in Fedora will
> have to be postponed until Fedora 21 which is scheduled for
> release in Q2 2014). The gcc package is still being built without
> --enable-threads=posix (thus support for C++11 std::thread
> is not enabled yet)
>
>> mingw-libvirt-1.1.1-1
>> Package owner: berrange
>> Time to build: 6 minutes, 39 seconds
>> Build logs: http://build1.vanpienbroek.nl/fedora-mingw-rebuild/20130829/mingw-libvirt-1…
>
>
> Also caused by winpthreads:
>
> CCLD libvirt.la
> ./.libs/libvirt_driver_remote.a(libvirt_net_rpc_client_la-virnetclient.o): In function `virNetClientIOEventLoop':
> /builddir/build/BUILD/libvirt-1.1.1/build_win32/src/../../src/rpc/virnetclient.c:1517: undefined reference to `pthread_sigmask'
> /builddir/build/BUILD/libvirt-1.1.1/build_win32/src/../../src/rpc/virnetclient.c:1524: undefined reference to `pthread_sigmask'
> /builddir/build/BUILD/libvirt-1.1.1/build_win32/src/../../src/rpc/virnetclient.c:1524: undefined reference to `pthread_sigmask'
> ./.libs/libvirt_driver_remote.a(libvirt_net_rpc_client_la-virnetclient.o): In function `virNetClientSetTLSSession':
> /builddir/build/BUILD/libvirt-1.1.1/build_win32/src/../../src/rpc/virnetclient.c:785: undefined reference to `pthread_sigmask'
> /builddir/build/BUILD/libvirt-1.1.1/build_win32/src/../../src/rpc/virnetclient.c:792: undefined reference to `pthread_sigmask'
> ./.libs/libvirt_driver_remote.a(libvirt_net_rpc_client_la-virnetclient.o):/builddir/build/BUILD/libvirt-1.1.1/build_win32/src/../../src/rpc/virnetclient.c:809: more undefined references to `pthread_sigmask' follow
> collect2: error: ld returned 1 exit status
Hmm. The libvirt build for mingw explicitly wants to avoid pthread_*,
and use native threading instead (at least we wanted to explicitly avoid
the old pthreads-w32, and since we already have native thread support,
we might as well use it instead of dragging in winpthreads). Probably a
case of our configure checks not detecting the right situation once
winpthreads are turned on. I'll see if we can get this fixed up for
libvirt 1.1.2 (due real soon now), or if it will have to wait for 1.1.3
(a month out, but probably still in time to make it into F20). Is there
an easy environment to set up (such as rawhide + a repo) for testing a
mingw cross-build with winpthreads?
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
2
3
[libvirt] [PATCH] build: hoist system-specific checks before library checks
by Eric Blake 17 Sep '13
by Eric Blake 17 Sep '13
17 Sep '13
Commit f92c7e3 fixed a regression for native builds, but introduced
a regression for cross-compilation builds; in particular,
./autobuild.sh on a Fedora system with mingw cross-compiler fails
with:
checking for qemu-kvm... /usr/bin/qemu-kvm
checking for yajl_parse_complete in -lyajl... no
checking for yajl_tree_parse in -lyajl... no
configure: error: You must install the libyajl library & headers to compile libvirt
Since we default $with_qemu to 'yes' rather than 'check', and then
flip that default based on platform-specific checks, those platform
specifics need to come prior to any library checks that depend on
the value of $with_qemu.
* configure.ac: Ensure system defaults are sane before checking
for things that make decisions based on system default.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
I'm tempted to push this under the build-breaker rule, so that
I can get a successful ./autobuild.sh run.
configure.ac | 85 +++++++++++++++++++++++++++++++-----------------------------
1 file changed, 44 insertions(+), 41 deletions(-)
diff --git a/configure.ac b/configure.ac
index 39b5fd5..69a01ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -160,6 +160,50 @@ VERSION_SCRIPT_FLAGS=-Wl,--version-script=
VERSION_SCRIPT_FLAGS="-Wl,-M -Wl,"
AC_MSG_RESULT([$VERSION_SCRIPT_FLAGS])
+dnl Specify if we rely on ifconfig instead of iproute2 (e.g. in case
+dnl we're working on BSD)
+want_ifconfig=no
+
+dnl Make some notes about which OS we're compiling for, as the lxc and qemu
+dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter
+dnl are also linux specific. The "network" and storage_fs drivers are known
+dnl to not work on MacOS X presently, so we also make a note if compiling
+dnl for that
+
+with_linux=no with_osx=no with_freebsd=no
+case $host in
+ *-*-linux*) with_linux=yes ;;
+ *-*-darwin*) with_osx=yes ;;
+ *-*-freebsd*) with_freebsd=yes ;;
+esac
+
+if test $with_linux = no; then
+ if test "x$with_lxc" != xyes
+ then
+ with_lxc=no
+ fi
+ with_dtrace=no
+fi
+
+if test $with_freebsd = yes; then
+ want_ifconfig=yes
+
+ with_firewalld=no
+fi
+
+if test $with_osx = yes; then
+ with_qemu=no
+fi
+
+AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
+AM_CONDITIONAL([WITH_FREEBSD], [test "$with_freebsd" = "yes"])
+
+if test "$with_libvirtd" = "no" ; then
+ with_qemu=no
+fi
+
+# Check for compiler and library settings.
+
LIBVIRT_COMPILE_WARNINGS
LIBVIRT_COMPILE_PIE
LIBVIRT_LINKER_RELRO
@@ -391,44 +435,6 @@ if test "$prefix" = "/usr" && test "$sysconfdir" = '${prefix}/etc' ; then
sysconfdir='/etc'
fi
-dnl Specify if we rely on ifconfig instead of iproute2 (e.g. in case
-dnl we're working on BSD)
-want_ifconfig=no
-
-dnl Make some notes about which OS we're compiling for, as the lxc and qemu
-dnl drivers require linux headers, and storage_mpath, dtrace, and nwfilter
-dnl are also linux specific. The "network" and storage_fs drivers are known
-dnl to not work on MacOS X presently, so we also make a note if compiling
-dnl for that
-
-with_linux=no with_osx=no with_freebsd=no
-case $host in
- *-*-linux*) with_linux=yes ;;
- *-*-darwin*) with_osx=yes ;;
- *-*-freebsd*) with_freebsd=yes ;;
-esac
-
-if test $with_linux = no; then
- if test "x$with_lxc" != xyes
- then
- with_lxc=no
- fi
- with_dtrace=no
-fi
-
-if test $with_freebsd = yes; then
- want_ifconfig=yes
-
- with_firewalld=no
-fi
-
-if test $with_osx = yes; then
- with_qemu=no
-fi
-
-AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
-AM_CONDITIONAL([WITH_FREEBSD], [test "$with_freebsd" = "yes"])
-
dnl Allow to build without Xen, QEMU/KVM, test or remote driver
AC_ARG_WITH([xen],
[AS_HELP_STRING([--with-xen],
@@ -721,9 +727,6 @@ if test "x$with_vbox" = "xyes"; then
fi
AM_CONDITIONAL([WITH_VBOX], [test "$with_vbox" = "yes"])
-if test "$with_libvirtd" = "no" ; then
- with_qemu=no
-fi
if test "$with_qemu" = "yes" ; then
AC_DEFINE_UNQUOTED([WITH_QEMU], 1, [whether QEMU driver is enabled])
fi
--
1.8.3.1
1
1
17 Sep '13
A cross build to mingw fails with:
CC virsystemdtest-virsystemdtest.o
../../tests/virsystemdtest.c: In function 'testCreateNoSystemd':
../../tests/virsystemdtest.c:97:9: error: implicit declaration of function 'unsetenv' [-Werror=implicit-function-declaration]
unsetenv("FAIL_NO_SERVICE");
^
../../tests/virsystemdtest.c:97:9: error: nested extern declaration of 'unsetenv' [-Werror=nested-externs]
We could cop out and pull in the gnulib unsetenv module. But when
you stop and think about it, this test requires LD_PRELOAD to work,
and systemd is a Linux-only concept anyways, both of which mean
the test could never work on mingw in the first place. Simpler is
to just fix the test to behave like our other LD_PRELOAD tests.
* tests/virsystemdtest.c: Provide non-Linux implementation.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule.
tests/virsystemdtest.c | 23 +++++++++++++++++------
1 file changed, 17 insertions(+), 6 deletions(-)
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index 7dc7520..e68b3ac 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -20,13 +20,16 @@
#include <config.h>
-#include <stdlib.h>
-
-#include "virsystemd.h"
-#include "virlog.h"
#include "testutils.h"
-#define VIR_FROM_THIS VIR_FROM_NONE
+#ifdef __linux__
+
+# include <stdlib.h>
+
+# include "virsystemd.h"
+# include "virlog.h"
+
+# define VIR_FROM_THIS VIR_FROM_NONE
static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
{
@@ -188,7 +191,7 @@ mymain(void)
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
ret = -1;
-#define TEST_SCOPE(name, partition, unitname) \
+# define TEST_SCOPE(name, partition, unitname) \
do { \
struct testScopeData data = { \
name, partition, unitname \
@@ -209,3 +212,11 @@ mymain(void)
}
VIRT_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/virsystemdmock.so")
+
+#else
+int
+main(void)
+{
+ return EXIT_AM_SKIP;
+}
+#endif
--
1.8.3.1
1
0
17 Sep '13
Thank you Laine, for your prompt reply. Adding the dev list to broaden the
audience.
On Mon, Sep 16, 2013 at 9:21 AM, Laine Stump <laine(a)laine.org> wrote:
On 09/16/2013 07:32 AM, Ajith Antony wrote:
>> Hi, I'm not sure what the best way to pursue this is, but since it
>> appears you authored the relevant code, you could advise of a good
>> next step.
>
> Kind of. I think I wrote code for hostdev networks, but the original was
> (if I remember correctly) written by Kyle Mestery with support only for
> openvswitch.
>
>> I'm trying to use libvirt to set up openvswitch vlans, but ran into a
>> problem where the libvirt code is precluding using vlans if the
>> network is not "Forwarded."[1] I don't think there is any technical
>> reason not to support vlans for non-forwarded networks. I verified
>> this by manually adding vlan tags to the ephemeral ports created by
>> the libvirt network definition. The tags worked as expected.
>> [1] http://libvirt.org/git/?p=libvirt.git;a=blob;f=src/network/bridge_driver.c;…
>
> You're misunderstanding the intent (at least) of that if condition. The
> way that you configure a libvirt network to use openvswitch is with the
> following:
>
> <forward mode='bridge'/>
> <virtualport type='openvswitch'>
> <some other stuff I forget/>
> </virtualport>
>
> That condition is only checking if:
>
> vlanAllowed = ((def->forward.type == VIR_NETWORK_FORWARD_BRIDGE &&
>
>
> 1) forward mode is 'bridge' (this doesn't necessarily mean that anything
> will be forwarded beyond the bridge that the guest's network device is
> connected to, only that it is connected to a bridge, i.e. as far as
> libvirt is concerned any forwarding that *is* done will be L2
> forwarding. The specifics of how that happens are left up to the bridge.)
Yes, I think this the test that interests me. The key fact in my scenario is
that I'm not preconfiguring a bridge. I wouldn't be able to set the forward
mode as 'bridge' unless I already prepared a bridge. I recongize that if I
prepared a bridge that I could add more portgroups to it with thier unique vlan
tags and not expect anything to actually cross the physical interface. I think
this is what is is reccomended among the blogs when one searches for
"openvswitch fake bridge."
> You'll need to post a copy of your network config for me to understand
> for sure, but I'm guessing that you're missing one of the two items in
> your config, possibly indicating that you've misunderstood how to
> configure a libvirt network that uses an openvswitch bridge.
>
> So can you send a copy of your network XML?
The network that I'm trying to define is described as the following. Note
there there is no <forward> element as I'm not expcting there to be a *real*
bridge and I don't expect that I need to preconfigre explicit bridges. I
expect an ephemeral virtual bridge to be created.
<network>
<name>ajith-net1</name>
<virtualport type='openvswitch'/>
<portgroup name='client_lan'>
<vlan>
<tag id='1'/>
</vlan>
</portgroup>
<portgroup name='client_wan'>
<vlan>
<tag id='2'/>
</vlan>
</portgroup>
</network>
When I include the VLAN tags I get the error:
error: unsupported configuration: <vlan> element specified for network
ajith-net1, whose type doesn't support vlan configuration
When I omit the VLAN tags as follows I am able to create the network:
<network>
<name>ajith-net1</name>
<virtualport type='openvswitch'/>
<portgroup name='client_lan'>
</portgroup>
<portgroup name='client_wan'>
</portgroup>
</network>
In my domain configs I specify the network like so:
<interface type='network'>
<source network='ajith-net1' portgroup='client_lan'/>
<virtualport type='openvswitch'/>
<model type='virtio'/>
</interface>
The resulting ephemeral bridge(virbr1) looks like the following when my
network(w/o vlans) and two domains are started. I don't know if the portgroup
was meaningful, but it was accepted in the definition:
$ sudo ovs-vsctl show
<...>
Bridge "virbr1"
Port "vnet23"
Interface "vnet23"
Port "vnet25"
Interface "vnet25"
Port "virbr1"
Interface "virbr1"
type: internal
Port "virbr1-nic"
Interface "virbr1-nic"
ovs_version: "1.9.3"
My goal is assign unique vlan tags to the two portgroups. While the network
and the domains are started, I can manually add tags to the ports:
$ sudo ovs-vsctl set port vnet25 tag=2
$ sudo ovs-vsctl set port vnet23 tag=1
$ sudo ovs-vsctl show
Bridge "virbr1"
Port "vnet23"
tag: 1
Interface "vnet23"
Port "vnet25"
tag: 2
Interface "vnet25"
Port "virbr1"
Interface "virbr1"
type: internal
Port "virbr1-nic"
Interface "virbr1-nic"
ovs_version: "1.9.3"
This configuration behaves exactly as I want. I'm interested to learn how to
prepare this without the manual step of tagging the ports outside of the
libvirt operations.
Ultimately my goal is to prepare isolated test environments that consist of
several VM's attached to a similar qty of vlans. I intend to create many of
these environments per host. I also recongnize that instead of portgroups, I
could use separate networks altogether. From an administrative standpoint, I'd
prefer to have one "network" per test environment, with several portgroups,
instead of *many* networks.
FWIW, I'm doing something similar on ESX, where I create a "vSwitch" and then
create several "portgroups", each with its own vlan tag. These vSwitches are
not attached to any physical interfaces. (My esx work is directly against the
vsphere API, so I'm not sure if the same could be configured via libvirt) I'm
looking to port this work to KVM. It seems like a pretty natural thing to
support.
2
2
* .gitignore: Ignore metadatatest.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the trivial rule.
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 2b8652f..d70d0dd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -166,6 +166,7 @@
/tests/hashtest
/tests/jsontest
/tests/libvirtdconftest
+/tests/metadatatest
/tests/networkxml2argvtest
/tests/nodeinfotest
/tests/nwfilterxml2xmltest
--
1.8.3.1
1
0
[libvirt] [PATCH libvirt-java] Set source and target version to Java 1.6
by Wido den Hollander 17 Sep '13
by Wido den Hollander 17 Sep '13
17 Sep '13
On platforms with Java 1.7 it will still produce compatible code
with Java 1.6 platforms
Java 1.6 is still out there and widely used.
Signed-off-by: Wido den Hollander <wido(a)widodh.nl>
---
build.properties | 2 ++
build.xml | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/build.properties b/build.properties
index 679a271..7721f90 100644
--- a/build.properties
+++ b/build.properties
@@ -2,5 +2,7 @@ version=0.5.0
release=1
libvirt.required=0.9.12
java.required=1:1.5.0
+java.target=1.6
+java.source=1.6
rpm.topdir=/home/veillard/rpms
jar.dir=/usr/share/java
diff --git a/build.xml b/build.xml
index 61b15bb..acd9c92 100644
--- a/build.xml
+++ b/build.xml
@@ -52,7 +52,7 @@
destdir="target/testclasses"
cache="target/cache"
closure="true" />
- <javac srcdir="src/test/java" debug="${javac.debug}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" />
+ <javac srcdir="src/test/java" debug="${javac.debug}" source="${java.source}" target="${java.target}" includes="**/*.java" classpathref="test.classpath" destdir="target/testclasses" includeAntRuntime="false" />
</target>
<target name="build" depends="init" description="builds the code">
@@ -60,7 +60,7 @@
destdir="target/classes"
cache="target/cache"
closure="true" />
- <javac srcdir="src/main/java" debug="${javac.debug}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" />
+ <javac srcdir="src/main/java" debug="${javac.debug}" source="${java.source}" target="${java.target}" includes="**/*.java" classpathref="compile.classpath" destdir="target/classes" includeAntRuntime="false" />
</target>
<target name="test" depends="buildtests" description="tests the code">
--
1.7.9.5
3
6
[libvirt] [PATCH 0/2] Add support for device blkio iops and bps throttle
by hzguanqiangï¼ gmail.com 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.
Guan Qiang (2):
blkiotune: add support for device iops and bps throttle
blkiotune: add virsh support for blkiotune.throttle.iops/bps
docs/formatdomain.html.in | 8 +
docs/schemas/domaincommon.rng | 28 +-
include/libvirt/libvirt.h.in | 40 ++
src/conf/domain_conf.c | 115 +++-
src/conf/domain_conf.h | 16 +-
src/libvirt_private.syms | 4 +-
src/lxc/lxc_cgroup.c | 9 +-
src/qemu/qemu_cgroup.c | 10 +-
src/qemu/qemu_driver.c | 579 ++++++++++++++++++--
src/util/vircgroup.c | 79 ++-
src/util/vircgroup.h | 8 +-
.../qemuxml2argv-blkiotune-device.xml | 4 +
tools/virsh-domain.c | 64 +++
tools/virsh.pod | 32 +-
14 files changed, 883 insertions(+), 113 deletions(-)
--
1.7.9.5
3
2
[libvirt] [PATCH 2/2] blkiotune: add virsh support for blkiotune.throttle.iops/bps
by hzguanqiangï¼ gmail.com 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
[libvirt] [PATCH 1/5] Add https protocol support for cdrom disk
by hzguanqiangï¼ gmail.com 17 Sep '13
by hzguanqiangï¼ gmail.com 17 Sep '13
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
[libvirt] [PATCH 3/5] Add tftp protocol support for cdrom disk
by hzguanqiangï¼ gmail.com 17 Sep '13
by hzguanqiangï¼ gmail.com 17 Sep '13
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
[libvirt] [PATCH 2/5] Add ftps protocol support for cdrom disk
by hzguanqiangï¼ gmail.com 17 Sep '13
by hzguanqiangï¼ gmail.com 17 Sep '13
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
Hello,
In the recent months various new methods were added to libvirt-java
which we (Apache CloudStack) would like to use in our KVM code.
For example resizing storage volumes, right now we have to do this with
Bash scripting since although libvirt supports resizing volumes, the
current release (0.4.9) of libvirt-java doesn't.
I don't know if there are any objections, but if possible I'd like to
see 0.5.0 released so we get this new functionality for CloudStack.
We use maven for building CloudStack and it fetches libvirt-java from
libvirt.org/maven2
Thank you,
Wido den Hollander
2
14
17 Sep '13
From: Aline Manera <alinefm(a)br.ibm.com>
qemu/KVM also supports https, ftps and tftp URL for cdrom definition.
With this patchset we will support all the protocols supported by qemu/KVM.
Aline Manera (3):
Add https protocol support for cdrom disk
Add ftps protocol support for cdrom disk
Add tftp protocol support for cdrom disk
docs/formatdomain.html.in | 24 +++++++++++++
docs/schemas/domaincommon.rng | 3 ++
src/conf/domain_conf.c | 5 ++-
src/conf/domain_conf.h | 3 ++
src/qemu/qemu_command.c | 18 ++++++++++
.../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 ++++
12 files changed, 192 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
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.10.4
2
4
hi friends,
I need some help for finding python APIs of libvirt. I have already find the Java APIs doc at here:http://libvirt.org/sources/java/javadoc/, is there any doc just like this to make me to find APIs more easy. many thanks!!
tony gong
2
1
[libvirt] [PATCH 00/14] Add ability to handle the <metadata> element using the API
by Peter Krempa 17 Sep '13
by Peter Krempa 17 Sep '13
17 Sep '13
This series adds the initialy omitted functionality of changing the <metadata>
element using the virDomain[Get|Set]Metadata API.
First few patches are cleanup of some code noticed during implementation of the
other stuff.
Peter Krempa (14):
virsh-domain: Remove spurious ATTRIBUTE_UNUSED from cmdDesc
virsh-domain: Line up signal names array
qemu: Factor out body of qemuDomainGetMetadata for universal use
qemu: Factor out body of qemuDomainSetMetadata for universal use
conf: Factor out setting of metadata to simplify code
util: Add helper to convert libxml2 nodes to a string
virsh-domain: use virXMLNodeDump instead of xmlNodeDump
virsh-domain: Add command to allow modifications of XML metadata
conf: Add support for requesting of XML metadata via the API
conf: allow to add XML metadata using the virDomainSetMetadata api
lib: Don't force the key argument when deleting metadata
lxc: Add metadata modification APIs
test: Add <metadata> support into the test driver
tests: Add metadata tests
src/conf/domain_conf.c | 171 ++++++++++++++++++++++++++
src/conf/domain_conf.h | 17 +++
src/libvirt.c | 3 +-
src/libvirt_private.syms | 4 +
src/lxc/lxc_driver.c | 70 +++++++++++
src/qemu/qemu_driver.c | 122 ++-----------------
src/test/test_driver.c | 68 +++++++++++
src/util/virxml.c | 187 +++++++++++++++++++++++++++++
src/util/virxml.h | 13 ++
tests/Makefile.am | 7 ++
tests/metadatatest.c | 245 ++++++++++++++++++++++++++++++++++++++
tools/virsh-domain.c | 304 ++++++++++++++++++++++++++++++++---------------
12 files changed, 1001 insertions(+), 210 deletions(-)
create mode 100644 tests/metadatatest.c
--
1.8.3.2
2
32