[libvirt] [PATCH 6/8] Docs: Add description and validation for blkdeviotune
by Lei Li
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
---
docs/formatdomain.html.in | 31 +++++++++++++++++++++++++++++++
docs/schemas/domaincommon.rng | 24 ++++++++++++++++++++++++
2 files changed, 55 insertions(+), 0 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index cbad196..733062d 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -893,6 +893,14 @@
<driver name="tap" type="aio" cache="default"/>
<source file='/var/lib/xen/images/fv0'/ startupPolicy='optional'>
<target dev='hda' bus='ide'/>
+ <iotune>
+ <total_bytes_sec>n</total_bytes_sec>
+ <read_bytes_sec>n</read_bytes_sec>
+ <write_bytes_sec>n</write_bytes_sec>
+ <total_iops_sec>n</total_iops_sec>
+ <read_bytes_sec>n</read_bytes_sec>
+ <write_bytes_sec>n</write_bytes_sec>
+ </iotune>
<boot order='2'/>
<encryption type='...'>
...
@@ -1010,6 +1018,29 @@
<span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3;
"usb" attribute value since after 0.4.4; "sata" attribute value since
0.9.7</span></dd>
+ <dt><code>iotune</code></dt>
+ <dd>The optional <code>iotune</code> element provides the ability
+ to set or get block I/O throttling for the device. Block I/O
+ throtting be implemented by qemu, is specified per-disk and can
+ vary across multiple disks.</dd>
+ <dt><code>total_bytes_sec</code></dt>
+ <dd>The optinal <code>total_bytes_sec</code> element is the total throughput
+ limit in bytes per second.</dd>
+ <dt><code>read_bytes_sec</code></dt>
+ <dd>The optinal <code>read_bytes_sec</code> element is the read throughput
+ limit in bytes per second.</dd>
+ <dt><code>write_bytes_sec</code</dt>
+ <dd>The optinal <code>write_bytes_sec</code> element is the write throughput
+ limit in bytes per second.</dd>
+ <dt><code>total_iops_sec</code></dt>
+ <dd>The optional <code>total_iops_sec</code> element is the total I/O operations
+ per second.</dd>
+ <dt><code>read_iops_sec</code></dt>
+ <dd>The optional <code>read_iops_sec</code> element is the read I/O operations
+ per second.</dd>
+ <dt><code>write_iops_sec</code></dt>
+ <dd>The optional <code>write_iops_sec</code> element is the write I/O operations
+ per second.</dd>
<dt><code>driver</code></dt>
<dd>
The optional driver element allows specifying further details
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index b6f858e..c6873a0 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -698,6 +698,30 @@
<optional>
<ref name="snapshot"/>
</optional>
+ <optional>
+ <element name="iotune">
+ <choice>
+ <element name="total_bytes_sec">
+ <ref name="unsignedLongLong">
+ </element>
+ <element name="read_bytes_sec">
+ <ref name="unsignedLongLong">
+ </element>
+ <element name="write_bytes_sec">
+ <ref name="unsignedLongLong">
+ </element>
+ <element name="total_iops_sec">
+ <ref name="unsignedLongLong">
+ </element>
+ <element name="read_iops_sec">
+ <ref name="unsignedLongLong">
+ </element>
+ <element name="write_iopw_sec">
+ <ref name="unsignedLongLong">
+ </emement>
+ </choice>
+ </element>
+ </optional>
<choice>
<group>
<attribute name="type">
--
1.7.1
13 years
[libvirt] [PATCH] nwfilter: Fix return value of virNWFilterHashTablePut
by Michal Privoznik
In libvirt it is common to return value <0 on error not vice versa.
---
src/conf/nwfilter_params.c | 16 ++++++++--------
src/nwfilter/nwfilter_gentech_driver.c | 4 ++--
src/nwfilter/nwfilter_learnipaddr.c | 2 +-
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/conf/nwfilter_params.c b/src/conf/nwfilter_params.c
index 12c6524..ba41972 100644
--- a/src/conf/nwfilter_params.c
+++ b/src/conf/nwfilter_params.c
@@ -490,7 +490,7 @@ hashDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
* @val: The value associated with the key
* @freeName: Whether the name must be freed on table destruction
*
- * Returns 0 on success, 1 on failure.
+ * Returns 0 on success, -1 on failure.
*
* Put an entry into the hashmap replacing and freeing an existing entry
* if one existed.
@@ -505,11 +505,11 @@ virNWFilterHashTablePut(virNWFilterHashTablePtr table,
if (copyName) {
name = strdup(name);
if (!name)
- return 1;
+ return -1;
if (VIR_REALLOC_N(table->names, table->nNames + 1) < 0) {
VIR_FREE(name);
- return 1;
+ return -1;
}
table->names[table->nNames++] = (char *)name;
}
@@ -519,11 +519,11 @@ virNWFilterHashTablePut(virNWFilterHashTablePtr table,
VIR_FREE(name);
table->nNames--;
}
- return 1;
+ return -1;
}
} else {
if (virHashUpdateEntry(table->hashTable, name, val) != 0) {
- return 1;
+ return -1;
}
}
return 0;
@@ -614,7 +614,7 @@ addToTable(void *payload, const void *name, void *data)
return;
}
- if (virNWFilterHashTablePut(atts->target, (const char *)name, val, 1) != 0) {
+ if (virNWFilterHashTablePut(atts->target, (const char *)name, val, 1) < 0) {
virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not put variable '%s' into hashmap"),
(const char *)name);
@@ -640,7 +640,7 @@ virNWFilterHashTablePutAll(virNWFilterHashTablePtr src,
return 0;
err_exit:
- return 1;
+ return -1;
}
@@ -700,7 +700,7 @@ virNWFilterParseParamAttributes(xmlNodePtr cur)
value = virNWFilterParseVarValue(val);
if (!value)
goto skip_entry;
- if (virNWFilterHashTablePut(table, nam, value, 1))
+ if (virNWFilterHashTablePut(table, nam, value, 1) < 0)
goto err_exit;
}
value = NULL;
diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c
index 84a959b..946ed14 100644
--- a/src/nwfilter/nwfilter_gentech_driver.c
+++ b/src/nwfilter/nwfilter_gentech_driver.c
@@ -343,10 +343,10 @@ virNWFilterCreateVarsFrom(virNWFilterHashTablePtr vars1,
return NULL;
}
- if (virNWFilterHashTablePutAll(vars1, res))
+ if (virNWFilterHashTablePutAll(vars1, res) < 0)
goto err_exit;
- if (virNWFilterHashTablePutAll(vars2, res))
+ if (virNWFilterHashTablePutAll(vars2, res) < 0)
goto err_exit;
return res;
diff --git a/src/nwfilter/nwfilter_learnipaddr.c b/src/nwfilter/nwfilter_learnipaddr.c
index 2e373a6..425e8a2 100644
--- a/src/nwfilter/nwfilter_learnipaddr.c
+++ b/src/nwfilter/nwfilter_learnipaddr.c
@@ -800,7 +800,7 @@ virNWFilterLearnIPAddress(virNWFilterTechDriverPtr techdriver,
goto err_free_req;
}
- if (virNWFilterHashTablePutAll(filterparams, ht))
+ if (virNWFilterHashTablePutAll(filterparams, ht) < 0)
goto err_free_ht;
req->filtername = strdup(filtername);
--
1.7.3.4
13 years
[libvirt] [PATCH 8/8] Add tests for blkdeviotune
by Lei Li
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
---
.../qemuxml2argv-blkdeviotune.args | 4 ++
.../qemuxml2argvdata/qemuxml2argv-blkdeviotune.xml | 36 ++++++++++++++++++++
tests/qemuxml2argvtest.c | 1 +
tests/qemuxml2xmltest.c | 1 +
4 files changed, 42 insertions(+), 0 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.xml
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.args b/tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.args
new file mode 100644
index 0000000..6f34698
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -name QEMUGuest1 -nographic -monitor unix:/tmp/test-monitor, \
+server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial \
+none -parallel none -usb
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.xml b/tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.xml
new file mode 100644
index 0000000..1fceef8
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-blkdeviotune.xml
@@ -0,0 +1,36 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219100</memory>
+ <currentMemory>219100</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk' snapshot='internal'>
+ <driver name='qemu' type='qcow2' cache='none'/>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <iotune>
+ <total_bytes_sec>5000</total_bytes_sec>
+ <total_iops_sec>6000</total_iops_sec>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <disk type='block' device='cdrom' snapshot='no'>
+ <driver name='qemu' type='raw'/>
+ <source dev='/dev/HostVG/QEMUGuest2'/>
+ <target dev='hdc' bus='ide'/>
+ <readonly/>
+ <address type='drive' controller='0' bus='1' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index d9a6e8d..1ebb950 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -585,6 +585,7 @@ mymain(void)
DO_TEST("blkiotune", false, QEMU_CAPS_NAME);
DO_TEST("cputune", false, QEMU_CAPS_NAME);
DO_TEST("numatune-memory", false, NONE);
+ DO_TEST("blkdeviotune", false, QEMU_CAPS_NAME);
DO_TEST("multifunction-pci-device", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 3f37520..2e6b5c7 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -191,6 +191,7 @@ mymain(void)
DO_TEST("event_idx");
DO_TEST("usb-redir");
+ DO_TEST("blkdeviotune");
/* These tests generate different XML */
DO_TEST_DIFFERENT("balloon-device-auto");
--
1.7.1
13 years
[libvirt] [PATCH 7/8] Support virDomain{Set, Get}BlockIoTune in the python API
by Lei Li
Python support for both setting and getting block I/O throttle.
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
---
python/generator.py | 2 +
python/libvirt-override-api.xml | 16 ++++
python/libvirt-override.c | 178 +++++++++++++++++++++++++++++++++++++++
3 files changed, 196 insertions(+), 0 deletions(-)
diff --git a/python/generator.py b/python/generator.py
index 71afdb7..88c52b9 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -414,6 +414,8 @@ skip_impl = (
'virDomainGetBlockJobInfo',
'virDomainMigrateGetMaxSpeed',
'virDomainBlockStatsFlags',
+ 'virDomainSetBlockIoTune',
+ 'virDomainGetBlockIoTune',
)
qemu_skip_impl = (
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index ef02f34..a05da3c 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -375,5 +375,21 @@
<arg name='flags' type='unsigned int' info='flags, currently unused, pass 0.'/>
<return type='unsigned long' info='current max migration speed, or None in case of error'/>
</function>
+ <function name='virDomainSetBlockIoTune' file='python'>
+ <info>Change the I/O throttle for a block device</info>
+ <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
+ <arg name='disk' type='const char *' info='disk name'/>
+ <arg name='params' type='virTypedParameterPtr' info='Pointer to blkio throttle params object'/>
+ <arg name='flags' type='unsigned int' info='an OR'ed set of virDomainModificationImpact'/>
+ <return type='int' info='0 in case of success, -1 in case of failure'/>
+ </function>
+ <function name='virDomainGetBlockIoTune' file='python'>
+ <info>Get the I/O throttle a block device</info>
+ <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
+ <arg name='disk' type='const char *' info='disk name'/>
+ <arg name='params' type='virTypedParameterPtr' info='Pointer to blkio throttle params object'/>
+ <arg name='flags' type='unsigned int' info='an OR'ed set of virDomainModificationImpact'/>
+ <return type='int' info='0 in case of success, -1 in case of failure'/>
+ </function>
</symbols>
</api>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 1759bae..be76d87 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -3195,6 +3195,182 @@ LIBVIRT_END_ALLOW_THREADS;
return ret;
}
+static PyObject *
+libvirt_virDomainSetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args)
+{
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *pyinfo;
+ const char *disk;
+ unsigned int flags;
+ virTypedParameterPtr params;
+ int nparams = 0, i;
+ int c_ret;
+
+ if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainSetBlockIoTune",
+ &pyobj_domain, &disk, &pyinfo, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_ret = virDomainGetBlockIoTune(domain, disk, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (c_ret < 0)
+ return VIR_PY_INT_FAIL;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_INT_FAIL;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_ret = virDomainGetBlockIoTune(domain, disk, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (c_ret < 0) {
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+
+ /* convert to a Python tuple of long objects */
+ for (i = 0; i < nparams; i++) {
+ PyObject *key, *val;
+ key = libvirt_constcharPtrWrap(params[i].field);
+ val = PyDict_GetItem(pyinfo, key);
+ Py_DECREF(key);
+
+ if (val == NULL)
+ continue;
+
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ params[i].value.i = (int)PyInt_AS_LONG(val);
+ break;
+
+ case VIR_TYPED_PARAM_UINT:
+ params[i].value.ui = (unsigned int)PyInt_AS_LONG(val);
+ break;
+
+ case VIR_TYPED_PARAM_LLONG:
+ params[i].value.l = (long long)PyLong_AsLongLong(val);
+ break;
+
+ case VIR_TYPED_PARAM_ULLONG:
+ params[i].value.ul = (unsigned long long)PyLong_AsLongLong(val);
+ break;
+
+ case VIR_TYPED_PARAM_DOUBLE:
+ params[i].value.d = (double)PyFloat_AsDouble(val);
+ break;
+
+ case VIR_TYPED_PARAM_BOOLEAN:
+ {
+ PyObject *hacktrue = PyBool_FromLong(1);
+ params[i].value.b = hacktrue == val ? 1: 0;
+ Py_DECREF(hacktrue);
+ }
+ break;
+
+ default:
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+ }
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_ret = virDomainSetMemoryParameters(domain, params, nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (c_ret < 0) {
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+
+ free(params);
+ return VIR_PY_INT_SUCCESS;
+}
+
+static PyObject *
+libvirt_virDomainGetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args)
+{
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *pyreply;
+ const char *disk;
+ int nparams = 0, i;
+ unsigned int flags;
+ virTypedParameterPtr params;
+ int c_ret;
+
+ if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetBlockIoTune",
+ &pyobj_domain, &disk, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_ret = virDomainGetBlockIoTune(domain, disk, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (c_ret < 0)
+ return VIR_PY_NONE;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_NONE;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_ret = virDomainGetBlockIoTune(domain, disk, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (c_ret < 0) {
+ free(params);
+ return VIR_PY_NONE;
+ }
+
+ /* convert to a Python tuple of long objects */
+ if ((pyreply = PyDict_New()) == NULL) {
+ free(params);
+ return VIR_PY_NONE;
+ }
+ for (i = 0 ; i < nparams ; i++) {
+ PyObject *key, *val;
+
+ switch (params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ val = PyInt_FromLong((long)params[i].value.i);
+ break;
+
+ case VIR_TYPED_PARAM_UINT:
+ val = PyInt_FromLong((long)params[i].value.ui);
+ break;
+
+ case VIR_TYPED_PARAM_LLONG:
+ val = PyLong_FromLongLong((long long)params[i].value.l);
+ break;
+
+ case VIR_TYPED_PARAM_ULLONG:
+ val = PyLong_FromLongLong((unsigned long long)params[i].value.ul);
+ break;
+
+ case VIR_TYPED_PARAM_DOUBLE:
+ val = PyFloat_FromDouble((double)params[i].value.d);
+ break;
+
+ case VIR_TYPED_PARAM_BOOLEAN:
+ val = PyBool_FromLong((long)params[i].value.b);
+ break;
+
+ default:
+ free(params);
+ Py_DECREF(pyreply);
+ return VIR_PY_NONE;
+ }
+
+ key = libvirt_constcharPtrWrap(params[i].field);
+ PyDict_SetItem(pyreply, key, val);
+ }
+ free(params);
+ return(pyreply);
+}
+
/*******************************************
* Helper functions to avoid importing modules
* for every callback
@@ -4837,6 +5013,8 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainSnapshotListNames", libvirt_virDomainSnapshotListNames, METH_VARARGS, NULL},
{(char *) "virDomainRevertToSnapshot", libvirt_virDomainRevertToSnapshot, METH_VARARGS, NULL},
{(char *) "virDomainGetBlockJobInfo", libvirt_virDomainGetBlockJobInfo, METH_VARARGS, NULL},
+ {(char *) "virDomainSetBlockIoTune", libvirt_virDomainSetBlockIoTune, METH_VARARGS, NULL},
+ {(char *) "virDomainGetBlockIoTune", libvirt_virDomainGetBlockIoTune, METH_VARARGS, NULL},
{(char *) "virDomainSendKey", libvirt_virDomainSendKey, METH_VARARGS, NULL},
{(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
--
1.7.1
13 years
[libvirt] [PATCH 5/8] Enable the blkdeviotune command in virsh
by Lei Li
Support virsh command blkdeviotune. Can set or query a block disk
I/O throttle setting.
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
---
tools/virsh.c | 240 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 23 +++++
2 files changed, 263 insertions(+), 0 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 83dc3c7..9eec68e 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -6074,6 +6074,245 @@ cmdNetworkAutostart(vshControl *ctl, const vshCmd *cmd)
}
/*
+ * "blkdeviotune" command
+ */
+static const vshCmdInfo info_blkdeviotune[] = {
+ {"help", N_("Set or query a block disk I/O throttle setting.")},
+ {"desc", N_("Set or query a block disk I/O throttle setting.\n" \
+ " To query the block disk I/O throttle setting use the following" \
+ " command: \n\n" \
+ " virsh # blkdeviotune <domain> <device>")},
+ {NULL, NULL}
+};
+
+static const vshCmdOptDef opts_blkdeviotune[] = {
+ {"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
+ {"device", VSH_OT_DATA, VSH_OFLAG_REQ, N_("block device")},
+ {"total_bytes_sec", VSH_OT_INT, VSH_OFLAG_NONE, N_("total throughput limit in bytes per second")},
+ {"read_bytes_sec", VSH_OT_INT, VSH_OFLAG_NONE, N_("read throughput limit in bytes per second")},
+ {"write_bytes_sec", VSH_OT_INT, VSH_OFLAG_NONE, N_("write throughput limit in bytes per second")},
+ {"total_iops_sec", VSH_OT_INT, VSH_OFLAG_NONE, N_("total I/O operations limit per second")},
+ {"read_iops_sec", VSH_OT_INT, VSH_OFLAG_NONE, N_("read I/O operations limit per second")},
+ {"write_iops_sec", VSH_OT_INT, VSH_OFLAG_NONE, N_("write I/O operations limit per second")},
+ {"config", VSH_OT_BOOL, 0, N_("affect next boot")},
+ {"live", VSH_OT_BOOL, 0, N_("affect running domain")},
+ {"current", VSH_OT_BOOL, 0, N_("affect current domain")},
+ {NULL, 0, 0, NULL}
+};
+
+static bool
+cmdBlkdeviotune(vshControl *ctl, const vshCmd *cmd)
+{
+ virDomainPtr dom = NULL;
+ const char *name, *disk;
+ unsigned long long total_bytes_sec = 0, read_bytes_sec = 0, write_bytes_sec = 0;
+ unsigned long long total_iops_sec = 0, read_iops_sec = 0, write_iops_sec = 0;
+ int nparams = 0;
+ virTypedParameterPtr params = NULL, temp = NULL;
+ unsigned int flags = 0, i = 0;
+ int rv = 0;
+ int current = vshCommandOptBool(cmd, "current");
+ int config = vshCommandOptBool(cmd, "config");
+ int live = vshCommandOptBool(cmd, "live");
+
+ if (current) {
+ if (live || config) {
+ vshError(ctl, "%s", _("--current must be specified exclusively"));
+ return false;
+ }
+ flags = VIR_DOMAIN_AFFECT_CURRENT;
+ } else {
+ if (config)
+ flags |= VIR_DOMAIN_AFFECT_CONFIG;
+ if (live)
+ flags |= VIR_DOMAIN_AFFECT_LIVE;
+ }
+
+ if (!vshConnectionUsability(ctl, ctl->conn))
+ goto out;
+
+ if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
+ goto out;
+
+ if (vshCommandOptString(cmd, "device", &disk) < 0)
+ goto out;
+
+ if ((rv = vshCommandOptULongLong(cmd, "total_bytes_sec", &total_bytes_sec)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter"));
+ goto out;
+ } else if (rv > 0) {
+ nparams++;
+ }
+
+ if ((rv = vshCommandOptULongLong(cmd, "read_bytes_sec", &read_bytes_sec)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter"));
+ goto out;
+ } else if (rv > 0) {
+ nparams++;
+ }
+
+ if ((rv = vshCommandOptULongLong(cmd, "write_bytes_sec", &write_bytes_sec)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter"));
+ goto out;
+ } else if (rv > 0) {
+ nparams++;
+ }
+
+ if ((rv = vshCommandOptULongLong(cmd, "total_iops_sec", &total_iops_sec)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter"));
+ goto out;
+ } else if (rv > 0) {
+ nparams++;
+ }
+
+ if ((rv = vshCommandOptULongLong(cmd, "read_iops_sec", &read_iops_sec)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter"));
+ goto out;
+ } else if (rv > 0) {
+ nparams++;
+ }
+
+ if ((rv = vshCommandOptULongLong(cmd, "write_iops_sec", &write_iops_sec)) < 0) {
+ vshError(ctl, "%s",
+ _("Unable to parse integer parameter"));
+ goto out;
+ } else if (rv > 0) {
+ nparams++;
+ }
+
+ if (nparams == 0) {
+
+ if ((virDomainGetBlockIoTune(dom, disk, NULL, &nparams, flags)) != 0) {
+ vshError(ctl, "%s",
+ _("Unable to get number of block I/O throttle parameters"));
+ goto out;
+ }
+
+ if (nparams == 0) {
+ virDomainFree(dom);
+ return true;
+ }
+
+ params = vshCalloc(ctl, nparams, sizeof(*params));
+
+ if ((virDomainGetBlockIoTune(dom, disk, params, &nparams, flags)) != 0) {
+ vshError(ctl, "%s",
+ _("Unable to get block I/O throttle parameters"));
+ goto out;
+ }
+
+ for (i = 0; i < nparams; i++) {
+ switch(params[i].type) {
+ case VIR_TYPED_PARAM_INT:
+ vshPrint(ctl, "%-15s: %d\n", params[i].field,
+ params[i].value.i);
+ break;
+ case VIR_TYPED_PARAM_UINT:
+ vshPrint(ctl, "%-15s: %u\n", params[i].field,
+ params[i].value.ui);
+ break;
+ case VIR_TYPED_PARAM_LLONG:
+ vshPrint(ctl, "%-15s: %lld\n", params[i].field,
+ params[i].value.l);
+ break;
+ case VIR_TYPED_PARAM_ULLONG:
+ vshPrint(ctl, "%-15s: %llu\n", params[i].field,
+ params[i].value.ul);
+ break;
+ case VIR_TYPED_PARAM_DOUBLE:
+ vshPrint(ctl, "%-15s: %f\n", params[i].field,
+ params[i].value.d);
+ break;
+ case VIR_TYPED_PARAM_BOOLEAN:
+ vshPrint(ctl, "%-15s: %d\n", params[i].field,
+ params[i].value.b);
+ break;
+ default:
+ vshPrint(ctl, "unimplemented block I/O throttle parameter type\n");
+ }
+ }
+
+ virDomainFree(dom);
+ return true;
+ } else {
+ /* Set the block I/O throttle, match by opt since parameters can be 0 */
+ params = vshCalloc(ctl, nparams, sizeof(*params));
+ i = 0;
+
+ if ((i < nparams) && (vshCommandOptBool(cmd, "total_bytes_sec"))) {
+ temp = ¶ms[i];
+ temp->type = VIR_TYPED_PARAM_ULLONG;
+ strncpy(temp->field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_BYTES_SEC,
+ sizeof(temp->field));
+ temp->value.ul = total_bytes_sec;
+ i++;
+ }
+
+ if ((i < nparams) && (vshCommandOptBool(cmd, "read_bytes_sec"))) {
+ temp = ¶ms[i];
+ temp->type = VIR_TYPED_PARAM_ULLONG;
+ strncpy(temp->field, VIR_DOMAIN_BLOCK_IOTUNE_READ_BYTES_SEC,
+ sizeof(temp->field));
+ temp->value.ul = read_bytes_sec;
+ i++;
+ }
+
+ if ((i < nparams) && (vshCommandOptBool(cmd, "write_bytes_sec"))) {
+ temp = ¶ms[i];
+ temp->type = VIR_TYPED_PARAM_ULLONG;
+ strncpy(temp->field, VIR_DOMAIN_BLOCK_IOTUNE_WRITE_BYTES_SEC,
+ sizeof(temp->field));
+ temp->value.ul = write_bytes_sec;
+ i++;
+ }
+
+ if ((i < nparams) && (vshCommandOptBool(cmd, "total_iops_sec"))) {
+ temp = ¶ms[i];
+ temp->type = VIR_TYPED_PARAM_ULLONG;
+ strncpy(temp->field, VIR_DOMAIN_BLOCK_IOTUNE_TOTAL_IOPS_SEC,
+ sizeof(temp->field));
+ temp->value.ul = total_iops_sec;
+ i++;
+ }
+
+ if ((i < nparams) && (vshCommandOptBool(cmd, "read_iops_sec"))) {
+ temp = ¶ms[i];
+ temp->type = VIR_TYPED_PARAM_ULLONG;
+ strncpy(temp->field, VIR_DOMAIN_BLOCK_IOTUNE_READ_IOPS_SEC,
+ sizeof(temp->field));
+ temp->value.ul = read_iops_sec;
+ i++;
+ }
+
+ if ((i < nparams) && (vshCommandOptBool(cmd, "write_iops_sec"))) {
+ temp = ¶ms[i];
+ temp->type = VIR_TYPED_PARAM_ULLONG;
+ strncpy(temp->field, VIR_DOMAIN_BLOCK_IOTUNE_WRITE_IOPS_SEC,
+ sizeof(temp->field));
+ temp->value.ul = write_iops_sec;
+ }
+
+ if ((virDomainSetBlockIoTune(dom, disk, params, nparams, flags)) != 0) {
+ vshError(ctl, "%s",
+ _("Unable to change block I/O throttle"));
+ goto out;
+ } else {
+ virDomainFree(dom);
+ return true;
+ }
+ }
+
+out:
+ virDomainFree(dom);
+ return false;
+}
+
+/*
* "net-create" command
*/
static const vshCmdInfo info_network_create[] = {
@@ -14023,6 +14262,7 @@ static const vshCmdDef domManagementCmds[] = {
{"blkiotune", cmdBlkiotune, opts_blkiotune, info_blkiotune, 0},
{"blockpull", cmdBlockPull, opts_block_pull, info_block_pull, 0},
{"blockjob", cmdBlockJob, opts_block_job, info_block_job, 0},
+ {"blkdeviotune", cmdBlkdeviotune, opts_blkdeviotune, info_blkdeviotune, 0},
#ifndef WIN32
{"console", cmdConsole, opts_console, info_console, 0},
#endif
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 775d302..85927d5 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -572,6 +572,29 @@ operation can be checked with B<blockjob>.
I<path> specifies fully-qualified path of the disk.
I<bandwidth> specifies copying bandwidth limit in Mbps.
+=item B<blkdeviotune> I<domain> I<device> [[I<--total_bytes_sec> B<total_bytes_sec>]
+| [[I<--read_bytes_sec> B<read_bytes_sec>] [I<--write_bytes_sec> B<write_bytes_sec>]]
+[[I<--total_iops_sec> B<total_iops_sec>] | [[I<--read_iops_sec> B<read_iops_sec>]
+[I<--write_iops_sec> B<write_iops_sec>]] [[I<--config>] [I<--live>] | [I<--current>]]
+
+Set or query the block disk io limits settting.
+I<path> specifies block disk name.
+I<--total_bytes_sec> specifies total throughput limit in bytes per second.
+I<--read_bytes_sec> specifies read throughput limit in bytes per second.
+I<--write_bytes_sec> specifies write throughput limit in bytes per second.
+I<--total_iops_sec> specifies total I/O operations limit per second.
+I<--read_iops_sec> specifies read I/O operations limit per second.
+I<--write_iops_sec> specifies write I/O operations limit per second.
+
+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.
+Both I<--live> and I<--current> flags may be given, but I<--current> is
+exclusive. If no flag is specified, behavior is different depending
+on hypervisor.
+
+If no limit is specified, it will query current I/O limits setting.
+
=item B<blockjob> I<domain> I<path> [I<--abort>] [I<--info>] [I<bandwidth>]
Manage active block operations.
--
1.7.1
13 years
[libvirt] [PATCH] qemu: Avoid dereference of NULL pointer
by Peter Krempa
If something fails while initializing qemu job object in
qemuDomainObjPrivateAlloc(), memory to the private pointer is freed, but
after that, the pointer is still dereferenced, which may result in a
segfault.
* qemuDomainObjPrivateAlloc() - Don't dereference NULL pointer.
---
I added the label and jump with future expansions in mind, as I've
found this bug while modifying said function.
src/qemu/qemu_domain.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3e755d7..d33d1d9 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -214,11 +214,15 @@ static void *qemuDomainObjPrivateAlloc(void)
return NULL;
if (qemuDomainObjInitJob(priv) < 0)
- VIR_FREE(priv);
+ goto error;
priv->migMaxBandwidth = QEMU_DOMAIN_DEFAULT_MIG_BANDWIDTH_MAX;
return priv;
+
+error:
+ VIR_FREE(priv);
+ return NULL;
}
static void qemuDomainObjPrivateFree(void *data)
--
1.7.3.4
13 years
[libvirt] libvirt-gconfig patches
by Christophe Fergeau
Here is the 3rd version of my libvirt-gconfig patches, I did the renaming
to put all the new classes it introduces in the GVirConfigDomain namespace.
GVirConfigDomainSnapshot looks a bit out of place now though...
Apart from this, I fixed the other issues that were reported, and
rearranged a bit the patches introducing GVirConfigDomainInterfaceNetwork.
I've also pushed the first 5 patches that were in v2 since they've already
been ack'ed
Christophe
13 years
[libvirt] [PATCH] qemu: fix a const-correctness issue
by Eric Blake
Generally, functions which return malloc'd strings should be typed
as 'char *', not 'const char *', to make it obvious that the caller
is responsible to free things. free(const char *) fails to compile,
and although we have a cast embedded in VIR_FREE to work around poor
code that frees const char *, it's better to not rely on that hack.
* src/qemu/qemu_driver.c (qemuDiskPathToAlias): Change return type.
(qemuDomainBlockJobImpl): Update callers.
---
Pushing under the trivial rule.
src/qemu/qemu_driver.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 98ce695..94fbe94 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10565,8 +10565,9 @@ cleanup:
return ret;
}
-static const char *
-qemuDiskPathToAlias(virDomainObjPtr vm, const char *path) {
+static char *
+qemuDiskPathToAlias(virDomainObjPtr vm, const char *path)
+{
int i;
char *ret = NULL;
virDomainDiskDefPtr disk;
@@ -10605,7 +10606,7 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char *path,
virDomainObjPtr vm = NULL;
qemuDomainObjPrivatePtr priv;
char uuidstr[VIR_UUID_STRING_BUFLEN];
- const char *device = NULL;
+ char *device = NULL;
int ret = -1;
qemuDriverLock(driver);
--
1.7.7.3
13 years
[libvirt] [PATCH 4/8] Support block I/O throtte in XML
by Lei Li
Enable block I/O throttle for per-disk in XML.
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
---
src/conf/domain_conf.c | 101 +++++++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 12 ++++++
src/qemu/qemu_command.c | 33 +++++++++++++++
src/util/xml.h | 2 +
4 files changed, 145 insertions(+), 3 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 58f4d0f..a157b80 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2318,7 +2318,8 @@ static virDomainDiskDefPtr
virDomainDiskDefParseXML(virCapsPtr caps,
xmlNodePtr node,
virBitmapPtr bootMap,
- unsigned int flags)
+ unsigned int flags,
+ xmlXPathContextPtr ctxt)
{
virDomainDiskDefPtr def;
xmlNodePtr cur, child;
@@ -2517,6 +2518,62 @@ virDomainDiskDefParseXML(virCapsPtr caps,
}
child = child->next;
}
+ } else if (xmlStrEqual(cur->name, BAD_CAST "iotune")) {
+ if (virXPathULongLong("string(./devices/disk/iotune/total_bytes_sec)",
+ ctxt, &def->blkdeviotune.total_bytes_sec) < 0) {
+ def->blkdeviotune.total_bytes_sec = 0;
+ } else {
+ def->blkdeviotune.mark = 1;
+ }
+
+ if (virXPathULongLong("string(./devices/disk/iotune/read_bytes_sec)",
+ ctxt, &def->blkdeviotune.read_bytes_sec) < 0) {
+ def->blkdeviotune.read_bytes_sec = 0;
+ } else {
+ def->blkdeviotune.mark = 1;
+ }
+
+ if (virXPathULongLong("string(./devices/disk/iotune/write_bytes_sec)",
+ ctxt, &def->blkdeviotune.write_bytes_sec) < 0) {
+ def->blkdeviotune.write_bytes_sec = 0;
+ } else {
+ def->blkdeviotune.mark = 1;
+ }
+
+ if (virXPathULongLong("string(./devices/disk/iotune/total_iops_sec)",
+ ctxt, &def->blkdeviotune.total_iops_sec) < 0) {
+ def->blkdeviotune.total_iops_sec = 0;
+ } else {
+ def->blkdeviotune.mark = 1;
+ }
+
+ if (virXPathULongLong("string(./devices/disk/iotune/read_iops_sec)",
+ ctxt, &def->blkdeviotune.read_iops_sec) < 0) {
+ def->blkdeviotune.read_iops_sec = 0;
+ } else {
+ def->blkdeviotune.mark = 1;
+ }
+
+ if (virXPathULongLong("string(./devices/disk/iotune/write_iops_sec)",
+ ctxt, &def->blkdeviotune.write_iops_sec) < 0) {
+ def->blkdeviotune.write_iops_sec = 0;
+ } else {
+ def->blkdeviotune.mark = 1;
+ }
+
+ if ((def->blkdeviotune.total_bytes_sec && def->blkdeviotune.read_bytes_sec)
+ || (def->blkdeviotune.total_bytes_sec && def->blkdeviotune.write_bytes_sec)) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("total and read/write bytes_sec cannot be set at the same time"));
+ goto error;
+ }
+
+ if ((def->blkdeviotune.total_iops_sec && def->blkdeviotune.read_iops_sec)
+ || (def->blkdeviotune.total_iops_sec && def->blkdeviotune.write_iops_sec)) {
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("total and read/write iops_sec cannot be set at the same time"));
+ goto error;
+ }
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@@ -6003,7 +6060,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
if (xmlStrEqual(node->name, BAD_CAST "disk")) {
dev->type = VIR_DOMAIN_DEVICE_DISK;
if (!(dev->data.disk = virDomainDiskDefParseXML(caps, node,
- NULL, flags)))
+ NULL, flags, NULL)))
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "lease")) {
dev->type = VIR_DOMAIN_DEVICE_LEASE;
@@ -7076,7 +7133,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps,
nodes[i],
bootMap,
- flags);
+ flags,
+ ctxt);
if (!disk)
goto error;
@@ -9511,6 +9569,43 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " <target dev='%s' bus='%s'/>\n",
def->dst, bus);
+ /*disk I/O throttling*/
+ if (def->blkdeviotune.mark) {
+ virBufferAddLit(buf, " <iotune>\n");
+ if (def->blkdeviotune.total_bytes_sec) {
+ virBufferAsprintf(buf, " <total_bytes_sec>%llu</total_bytes_sec>\n",
+ def->blkdeviotune.total_bytes_sec);
+ }
+
+ if (def->blkdeviotune.read_bytes_sec) {
+ virBufferAsprintf(buf, " <read_bytes_sec>%llu</read_bytes_sec>\n",
+ def->blkdeviotune.read_bytes_sec);
+
+ }
+
+ if (def->blkdeviotune.write_bytes_sec) {
+ virBufferAsprintf(buf, " <write_bytes_sec>%llu</write_bytes_sec>\n",
+ def->blkdeviotune.write_bytes_sec);
+ }
+
+ if (def->blkdeviotune.total_iops_sec) {
+ virBufferAsprintf(buf, " <total_iops_sec>%llu</total_iops_sec>\n",
+ def->blkdeviotune.total_iops_sec);
+ }
+
+ if (def->blkdeviotune.read_iops_sec) {
+ virBufferAsprintf(buf, " <read_iops_sec>%llu</read_iops_sec>",
+ def->blkdeviotune.read_iops_sec);
+ }
+
+ if (def->blkdeviotune.write_iops_sec) {
+ virBufferAsprintf(buf, " <write_iops_sec>%llu</write_iops_sec>",
+ def->blkdeviotune.write_iops_sec);
+ }
+
+ virBufferAddLit(buf, " </iotune>\n");
+ }
+
if (def->bootIndex)
virBufferAsprintf(buf, " <boot order='%d'/>\n", def->bootIndex);
if (def->readonly)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index a3cb834..d95e239 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -333,6 +333,18 @@ struct _virDomainDiskDef {
} auth;
char *driverName;
char *driverType;
+
+ /*disk I/O throttling*/
+ struct {
+ unsigned long long total_bytes_sec;
+ unsigned long long read_bytes_sec;
+ unsigned long long write_bytes_sec;
+ unsigned long long total_iops_sec;
+ unsigned long long read_iops_sec;
+ unsigned long long write_iops_sec;
+ unsigned int mark;
+ } blkdeviotune;
+
char *serial;
int cachemode;
int error_policy; /* enum virDomainDiskErrorPolicy */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2fbf691..91c6508 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1690,6 +1690,39 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
}
}
+ /*block I/O throttling*/
+ if (disk->blkdeviotune.mark) {
+ if (disk->blkdeviotune.total_bytes_sec) {
+ virBufferAsprintf(&opt, ",bps=%llu",
+ disk->blkdeviotune.total_bytes_sec);
+ }
+
+ if (disk->blkdeviotune.read_bytes_sec) {
+ virBufferAsprintf(&opt, ",bps_rd=%llu",
+ disk->blkdeviotune.read_bytes_sec);
+ }
+
+ if (disk->blkdeviotune.write_bytes_sec) {
+ virBufferAsprintf(&opt, ",bps_wr=%llu",
+ disk->blkdeviotune.write_bytes_sec);
+ }
+
+ if (disk->blkdeviotune.total_iops_sec) {
+ virBufferAsprintf(&opt, ",iops=%llu",
+ disk->blkdeviotune.total_iops_sec);
+ }
+
+ if (disk->blkdeviotune.read_iops_sec) {
+ virBufferAsprintf(&opt, ",iops_rd=%llu",
+ disk->blkdeviotune.read_iops_sec);
+ }
+
+ if (disk->blkdeviotune.write_iops_sec) {
+ virBufferAsprintf(&opt, ",iops_wr=%llu",
+ disk->blkdeviotune.write_iops_sec);
+ }
+ }
+
if (virBufferError(&opt)) {
virReportOOMError();
goto error;
diff --git a/src/util/xml.h b/src/util/xml.h
index c492063..5742f19 100644
--- a/src/util/xml.h
+++ b/src/util/xml.h
@@ -50,6 +50,8 @@ xmlNodePtr virXPathNode(const char *xpath,
int virXPathNodeSet(const char *xpath,
xmlXPathContextPtr ctxt,
xmlNodePtr **list);
+int virXMLStringToULongLong (const char *stringval,
+ unsigned long long *value);
char * virXMLPropString(xmlNodePtr node,
const char *name);
--
1.7.1
13 years
[libvirt] [PATCH] nwfilter: remove virConnectPtr from internal API calls
by Stefan Berger
Remove the virConnectPtr from the nwfilter's internal API calls as
far as possible.
---
src/conf/nwfilter_conf.h | 18 ++-----
src/nwfilter/nwfilter_ebiptables_driver.c | 34 ++++----------
src/nwfilter/nwfilter_gentech_driver.c | 72 ++++++++++--------------------
src/nwfilter/nwfilter_gentech_driver.h | 9 +--
src/nwfilter/nwfilter_learnipaddr.c | 3 -
5 files changed, 45 insertions(+), 91 deletions(-)
Index: libvirt-acl/src/conf/nwfilter_conf.h
===================================================================
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -592,27 +592,22 @@ typedef void (*virNWFilterTechDrvShutdow
enum virDomainNetType;
-typedef int (*virNWFilterRuleCreateInstance)(virConnectPtr conn,
- enum virDomainNetType nettype,
+typedef int (*virNWFilterRuleCreateInstance)(enum virDomainNetType nettype,
virNWFilterDefPtr filter,
virNWFilterRuleDefPtr rule,
const char *ifname,
virNWFilterHashTablePtr vars,
virNWFilterRuleInstPtr res);
-typedef int (*virNWFilterRuleApplyNewRules)(virConnectPtr conn,
- const char *ifname,
+typedef int (*virNWFilterRuleApplyNewRules)(const char *ifname,
int nruleInstances,
void **_inst);
-typedef int (*virNWFilterRuleTeardownNewRules)(virConnectPtr conn,
- const char *ifname);
+typedef int (*virNWFilterRuleTeardownNewRules)(const char *ifname);
-typedef int (*virNWFilterRuleTeardownOldRules)(virConnectPtr conn,
- const char *ifname);
+typedef int (*virNWFilterRuleTeardownOldRules)(const char *ifname);
-typedef int (*virNWFilterRuleRemoveRules)(virConnectPtr conn,
- const char *ifname,
+typedef int (*virNWFilterRuleRemoveRules)(const char *ifname,
int nruleInstances,
void **_inst);
@@ -620,8 +615,7 @@ typedef int (*virNWFilterRuleAllTeardown
typedef int (*virNWFilterRuleFreeInstanceData)(void * _inst);
-typedef int (*virNWFilterRuleDisplayInstanceData)(virConnectPtr conn,
- void *_inst);
+typedef int (*virNWFilterRuleDisplayInstanceData)(void *_inst);
typedef int (*virNWFilterCanApplyBasicRules)(void);
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -1188,8 +1188,7 @@ iptablesEnforceDirection(int directionIn
* Convert a single rule into its representation for later instantiation
*
* Returns 0 in case of success with the result stored in the data structure
- * pointed to by res, != 0 otherwise with the error message stored in the
- * virConnect object.
+ * pointed to by res, != 0 otherwise.
*/
static int
_iptablesCreateRuleInstance(int directionIn,
@@ -1917,8 +1916,7 @@ iptablesCreateRuleInstance(virNWFilterDe
* Convert a single rule into its representation for later instantiation
*
* Returns 0 in case of success with the result stored in the data structure
- * pointed to by res, != 0 otherwise with the error message stored in the
- * virConnect object.
+ * pointed to by res, != 0 otherwise.
*/
static int
ebtablesCreateRuleInstance(char chainPrefix,
@@ -2503,7 +2501,6 @@ err_exit:
/*
* ebiptablesCreateRuleInstance:
- * @conn : Pointer to a virConnect object
* @nwfilter : The filter
* @rule: The rule of the filter to convert
* @ifname : The name of the interface to apply the rule to
@@ -2513,12 +2510,10 @@ err_exit:
* Convert a single rule into its representation for later instantiation
*
* Returns 0 in case of success with the result stored in the data structure
- * pointed to by res, != 0 otherwise with the error message stored in the
- * virConnect object.
+ * pointed to by res, != 0 otherwise.
*/
static int
-ebiptablesCreateRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
- enum virDomainNetType nettype ATTRIBUTE_UNUSED,
+ebiptablesCreateRuleInstance(enum virDomainNetType nettype ATTRIBUTE_UNUSED,
virNWFilterDefPtr nwfilter,
virNWFilterRuleDefPtr rule,
const char *ifname,
@@ -2610,7 +2605,6 @@ ebiptablesCreateRuleInstance(virConnectP
static int
ebiptablesCreateRuleInstanceIterate(
- virConnectPtr conn ATTRIBUTE_UNUSED,
enum virDomainNetType nettype ATTRIBUTE_UNUSED,
virNWFilterDefPtr nwfilter,
virNWFilterRuleDefPtr rule,
@@ -2630,8 +2624,7 @@ ebiptablesCreateRuleInstanceIterate(
return 1;
do {
- rc = ebiptablesCreateRuleInstance(conn,
- nettype,
+ rc = ebiptablesCreateRuleInstance(nettype,
nwfilter,
rule,
ifname,
@@ -2656,8 +2649,7 @@ ebiptablesFreeRuleInstance(void *_inst)
static int
-ebiptablesDisplayRuleInstance(virConnectPtr conn ATTRIBUTE_UNUSED,
- void *_inst)
+ebiptablesDisplayRuleInstance(void *_inst)
{
ebiptablesRuleInstPtr inst = (ebiptablesRuleInstPtr)_inst;
VIR_INFO("Command Template: '%s', Needed protocol: '%s'",
@@ -3096,7 +3088,6 @@ ebiptablesCanApplyBasicRules(void) {
/**
* ebtablesApplyBasicRules
*
- * @conn: virConnect object
* @ifname: name of the backend-interface to which to apply the rules
* @macaddr: MAC address the VM is using in packets sent through the
* interface
@@ -3552,8 +3543,7 @@ ebtablesCreateTmpRootAndSubChains(virBuf
}
static int
-ebiptablesApplyNewRules(virConnectPtr conn ATTRIBUTE_UNUSED,
- const char *ifname,
+ebiptablesApplyNewRules(const char *ifname,
int nruleInstances,
void **_inst)
{
@@ -3824,8 +3814,7 @@ exit_free_sets:
static int
-ebiptablesTearNewRules(virConnectPtr conn ATTRIBUTE_UNUSED,
- const char *ifname)
+ebiptablesTearNewRules(const char *ifname)
{
int cli_status;
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -3862,8 +3851,7 @@ ebiptablesTearNewRules(virConnectPtr con
static int
-ebiptablesTearOldRules(virConnectPtr conn ATTRIBUTE_UNUSED,
- const char *ifname)
+ebiptablesTearOldRules(const char *ifname)
{
int cli_status;
virBuffer buf = VIR_BUFFER_INITIALIZER;
@@ -3911,7 +3899,6 @@ ebiptablesTearOldRules(virConnectPtr con
/**
* ebiptablesRemoveRules:
- * @conn : pointer to virConnect object
* @ifname : the name of the interface to which the rules apply
* @nRuleInstance : the number of given rules
* @_inst : array of rule instantiation data
@@ -3922,8 +3909,7 @@ ebiptablesTearOldRules(virConnectPtr con
* commands failed.
*/
static int
-ebiptablesRemoveRules(virConnectPtr conn ATTRIBUTE_UNUSED,
- const char *ifname ATTRIBUTE_UNUSED,
+ebiptablesRemoveRules(const char *ifname ATTRIBUTE_UNUSED,
int nruleInstances,
void **_inst)
{
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
@@ -98,8 +98,7 @@ virNWFilterTechDriverForName(const char
* for bidirectional traffic and data needs to be added to the incoming
* and outgoing chains.
*
- * Returns 0 in case of success, 1 in case of an error with the error
- * message attached to the virConnect object.
+ * Returns 0 in case of success, 1 in case of an error.
*/
int
virNWFilterRuleInstAddData(virNWFilterRuleInstPtr res,
@@ -190,8 +189,7 @@ virNWFilterVarHashmapAddStdValues(virNWF
* Create a hashmap used for evaluating the firewall rules. Initializes
* it with the standard variable 'MAC' and 'IP' if provided.
*
- * Returns pointer to hashmap, NULL if an error occcurred and error message
- * is attached to the virConnect object.
+ * Returns pointer to hashmap, NULL if an error occcurred.
*/
virNWFilterHashTablePtr
virNWFilterCreateVarHashmap(char *macaddr,
@@ -274,7 +272,6 @@ virNWFilterPrintVars(virHashTablePtr var
/**
* virNWFilterRuleInstantiate:
- * @conn: pointer to virConnect object
* @techdriver: the driver to use for instantiation
* @filter: The filter the rule is part of
* @rule : The rule that is to be instantiated
@@ -289,8 +286,7 @@ virNWFilterPrintVars(virHashTablePtr var
* from the instantiation. Returns NULL on error with error reported.
*/
static virNWFilterRuleInstPtr
-virNWFilterRuleInstantiate(virConnectPtr conn,
- virNWFilterTechDriverPtr techdriver,
+virNWFilterRuleInstantiate(virNWFilterTechDriverPtr techdriver,
enum virDomainNetType nettype,
virNWFilterDefPtr filter,
virNWFilterRuleDefPtr rule,
@@ -308,7 +304,7 @@ virNWFilterRuleInstantiate(virConnectPtr
ret->techdriver = techdriver;
- rc = techdriver->createRuleInstance(conn, nettype, filter,
+ rc = techdriver->createRuleInstance(nettype, filter,
rule, ifname, vars, ret);
if (rc) {
@@ -359,7 +355,6 @@ err_exit:
/**
* _virNWFilterInstantiateRec:
- * @conn: pointer to virConnect object
* @techdriver: The driver to use for instantiation
* @filter: The filter to instantiate
* @ifname: The name of the interface to apply the rules to
@@ -382,8 +377,7 @@ err_exit:
* resolved -- among other reasons.
*/
static int
-_virNWFilterInstantiateRec(virConnectPtr conn,
- virNWFilterTechDriverPtr techdriver,
+_virNWFilterInstantiateRec(virNWFilterTechDriverPtr techdriver,
enum virDomainNetType nettype,
virNWFilterDefPtr filter,
const char *ifname,
@@ -403,8 +397,7 @@ _virNWFilterInstantiateRec(virConnectPtr
virNWFilterRuleDefPtr rule = filter->filterEntries[i]->rule;
virNWFilterIncludeDefPtr inc = filter->filterEntries[i]->include;
if (rule) {
- inst = virNWFilterRuleInstantiate(conn,
- techdriver,
+ inst = virNWFilterRuleInstantiate(techdriver,
nettype,
filter,
rule,
@@ -461,8 +454,7 @@ _virNWFilterInstantiateRec(virConnectPtr
break;
}
- rc = _virNWFilterInstantiateRec(conn,
- techdriver,
+ rc = _virNWFilterInstantiateRec(techdriver,
nettype,
next_filter,
ifname,
@@ -491,8 +483,7 @@ _virNWFilterInstantiateRec(virConnectPtr
static int
-virNWFilterDetermineMissingVarsRec(virConnectPtr conn,
- virNWFilterDefPtr filter,
+virNWFilterDetermineMissingVarsRec(virNWFilterDefPtr filter,
virNWFilterHashTablePtr vars,
virNWFilterHashTablePtr missing_vars,
int useNewFilter,
@@ -559,8 +550,7 @@ virNWFilterDetermineMissingVarsRec(virCo
break;
}
- rc = virNWFilterDetermineMissingVarsRec(conn,
- next_filter,
+ rc = virNWFilterDetermineMissingVarsRec(next_filter,
tmpvars,
missing_vars,
useNewFilter,
@@ -617,7 +607,6 @@ virNWFilterRuleInstancesToArray(int nEnt
/**
* virNWFilterInstantiate:
- * @conn: pointer to virConnect object
* @techdriver: The driver to use for instantiation
* @filter: The filter to instantiate
* @ifname: The name of the interface to apply the rules to
@@ -636,8 +625,7 @@ virNWFilterRuleInstancesToArray(int nEnt
* Call this function while holding the NWFilter filter update lock
*/
static int
-virNWFilterInstantiate(virConnectPtr conn,
- virNWFilterTechDriverPtr techdriver,
+virNWFilterInstantiate(virNWFilterTechDriverPtr techdriver,
enum virDomainNetType nettype,
virNWFilterDefPtr filter,
const char *ifname,
@@ -665,8 +653,7 @@ virNWFilterInstantiate(virConnectPtr con
goto err_exit;
}
- rc = virNWFilterDetermineMissingVarsRec(conn,
- filter,
+ rc = virNWFilterDetermineMissingVarsRec(filter,
vars,
missing_vars,
useNewFilter,
@@ -697,8 +684,7 @@ virNWFilterInstantiate(virConnectPtr con
goto err_exit;
}
- rc = _virNWFilterInstantiateRec(conn,
- techdriver,
+ rc = _virNWFilterInstantiateRec(techdriver,
nettype,
filter,
ifname,
@@ -729,10 +715,10 @@ virNWFilterInstantiate(virConnectPtr con
if (virNWFilterLockIface(ifname))
goto err_exit;
- rc = techdriver->applyNewRules(conn, ifname, nptrs, ptrs);
+ rc = techdriver->applyNewRules(ifname, nptrs, ptrs);
if (teardownOld && rc == 0)
- techdriver->tearOldRules(conn, ifname);
+ techdriver->tearOldRules(ifname);
if (rc == 0 && (virNetDevValidateConfig(ifname, NULL, ifindex) <= 0)) {
virResetLastError();
@@ -775,8 +761,7 @@ err_unresolvable_vars:
* Call this function while holding the NWFilter filter update lock
*/
static int
-__virNWFilterInstantiateFilter(virConnectPtr conn,
- bool teardownOld,
+__virNWFilterInstantiateFilter(bool teardownOld,
const char *ifname,
int ifindex,
const char *linkdev,
@@ -868,8 +853,7 @@ __virNWFilterInstantiateFilter(virConnec
break;
}
- rc = virNWFilterInstantiate(conn,
- techdriver,
+ rc = virNWFilterInstantiate(techdriver,
nettype,
filter,
ifname,
@@ -924,8 +908,7 @@ _virNWFilterInstantiateFilter(virConnect
goto cleanup;
}
- rc = __virNWFilterInstantiateFilter(conn,
- teardownOld,
+ rc = __virNWFilterInstantiateFilter(teardownOld,
net->ifname,
ifindex,
linkdev,
@@ -946,8 +929,7 @@ cleanup:
int
-virNWFilterInstantiateFilterLate(virConnectPtr conn,
- const char *ifname,
+virNWFilterInstantiateFilterLate(const char *ifname,
int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
@@ -961,8 +943,7 @@ virNWFilterInstantiateFilterLate(virConn
virNWFilterLockFilterUpdates();
- rc = __virNWFilterInstantiateFilter(conn,
- 1,
+ rc = __virNWFilterInstantiateFilter(true,
ifname,
ifindex,
linkdev,
@@ -1019,8 +1000,7 @@ virNWFilterUpdateInstantiateFilter(virCo
return rc;
}
-int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
- const virDomainNetDefPtr net)
+int virNWFilterRollbackUpdateFilter(const virDomainNetDefPtr net)
{
const char *drvname = EBIPTABLES_DRIVER_ID;
int ifindex;
@@ -1041,13 +1021,12 @@ int virNWFilterRollbackUpdateFilter(virC
else if (virNWFilterLookupLearnReq(ifindex) != NULL)
return 0;
- return techdriver->tearNewRules(conn, net->ifname);
+ return techdriver->tearNewRules(net->ifname);
}
int
-virNWFilterTearOldFilter(virConnectPtr conn,
- virDomainNetDefPtr net)
+virNWFilterTearOldFilter(virDomainNetDefPtr net)
{
const char *drvname = EBIPTABLES_DRIVER_ID;
int ifindex;
@@ -1068,7 +1047,7 @@ virNWFilterTearOldFilter(virConnectPtr c
else if (virNWFilterLookupLearnReq(ifindex) != NULL)
return 0;
- return techdriver->tearOldRules(conn, net->ifname);
+ return techdriver->tearOldRules(net->ifname);
}
@@ -1141,14 +1120,13 @@ virNWFilterDomainFWUpdateCB(void *payloa
case STEP_TEAR_NEW:
if ( !virHashLookup(cb->skipInterfaces, net->ifname)) {
- cb->err = virNWFilterRollbackUpdateFilter(cb->conn,
- net);
+ cb->err = virNWFilterRollbackUpdateFilter(net);
}
break;
case STEP_TEAR_OLD:
if ( !virHashLookup(cb->skipInterfaces, net->ifname)) {
- cb->err = virNWFilterTearOldFilter(cb->conn, net);
+ cb->err = virNWFilterTearOldFilter(net);
}
break;
}
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.h
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.h
@@ -42,14 +42,11 @@ int virNWFilterInstantiateFilter(virConn
int virNWFilterUpdateInstantiateFilter(virConnectPtr conn,
const virDomainNetDefPtr net,
bool *skipIface);
-int virNWFilterRollbackUpdateFilter(virConnectPtr conn,
- const virDomainNetDefPtr net);
+int virNWFilterRollbackUpdateFilter(const virDomainNetDefPtr net);
-int virNWFilterTearOldFilter(virConnectPtr conn,
- const virDomainNetDefPtr net);
+int virNWFilterTearOldFilter(const virDomainNetDefPtr net);
-int virNWFilterInstantiateFilterLate(virConnectPtr conn,
- const char *ifname,
+int virNWFilterInstantiateFilterLate(const char *ifname,
int ifindex,
const char *linkdev,
enum virDomainNetType nettype,
Index: libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
===================================================================
--- libvirt-acl.orig/src/nwfilter/nwfilter_learnipaddr.c
+++ libvirt-acl/src/nwfilter/nwfilter_learnipaddr.c
@@ -702,8 +702,7 @@ learnIPAddressThread(void *arg)
"cache for interface %s"), inetaddr, req->ifname);
}
- ret = virNWFilterInstantiateFilterLate(NULL,
- req->ifname,
+ ret = virNWFilterInstantiateFilterLate(req->ifname,
req->ifindex,
req->linkdev,
req->nettype,
13 years