[libvirt] [PATCH RFCv2 0/5] LibSSH2 transport for libvirt
by Peter Krempa
This patchset proposes to use libssh2 as ssh transport option in libvirt
instead of the usual "spawn the client and connect pipes" approach.
For this to work, you'll need at least libssh2 v 1.3.0.
This is the second iteration of this functionality. I have completed nearly
all of the functionality and tested most of the common situations.
If you'd like to try this out, I've prepared for you a branch in my git repo:
git checkout -B libssh_transport 66ca7ce573a69858c5af60645984bb1f2f90b1e7
git pull git://aeon.pipo.sk/libvirt.git libssh_transport
(It should be up most of the time)
To test the connection use URI's in the following format:
qemu+libssh://USER@HOST:PORT/system?known_hosts=PATH_TO_KNOWN_HOSTS_FILE&keyfile=PATH_TO_PRIVATE_KEY
The parameters may be omitted and then they take a default value (root@localhost:22).
SSH Agent authentication is supported automaticaly. For public key to work
you need to specify the path to the key.
For host key verification to work, you'll need to specify the path
to a known_hosts file. (It may be empty and even don't exist).
I'd appreciate your feedback. Thanks for your comments and time.
Peter
Peter Krempa (5):
libssh2_transport: add main libssh2 transport implementation
libssh2_transport: add ssh context support to virNetSocket
libssh2_transport: Add libssh2 session support to net client code
libssh2_transport: Use libssh2 driver code in remote driver
virsh: Reconnect to daemon if remote netcat crashes while using
libssh
configure.ac | 40 ++-
include/libvirt/virterror.h | 4 +
po/POTFILES.in | 1 +
src/Makefile.am | 9 +
src/libvirt_private.syms | 1 +
src/remote/remote_driver.c | 116 +++--
src/rpc/virnetclient.c | 91 ++++-
src/rpc/virnetclient.h | 11 +
src/rpc/virnetlibsshcontext.c | 1132 +++++++++++++++++++++++++++++++++++++++++
src/rpc/virnetlibsshcontext.h | 76 +++
src/rpc/virnetsocket.c | 136 +++++-
src/rpc/virnetsocket.h | 12 +
src/util/virterror.c | 14 +
tools/virsh.c | 3 +-
14 files changed, 1606 insertions(+), 40 deletions(-)
create mode 100644 src/rpc/virnetlibsshcontext.c
create mode 100644 src/rpc/virnetlibsshcontext.h
--
1.7.3.4
12 years, 9 months
[libvirt] [PATCH] Add two NUMA tuning python bindings APIs
by Guannan Ren
*virDomainSetNumaParameters
*virDomainGetNumaParameters
---
python/libvirt-override-api.xml | 13 +++
python/libvirt-override.c | 186 +++++++++++++++++++++++++++++++++++++++
2 files changed, 199 insertions(+), 0 deletions(-)
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 704fee9..e09290c 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -248,6 +248,19 @@
<arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
<arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
</function>
+ <function name='virDomainSetNumaParameters' file='python'>
+ <info>Change the NUMA tunables</info>
+ <return type='int' info='-1 in case of error, 0 in case of success.'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='params' type='virTypedParameterPtr' info='pointer to memory tunable objects'/>
+ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
+ </function>
+ <function name='virDomainGetNumaParameters' file='python'>
+ <info>Get the NUMA parameters</info>
+ <return type='virTypedParameterPtr' info='the I/O tunables value or None in case of error'/>
+ <arg name='domain' type='virDomainPtr' info='pointer to domain object'/>
+ <arg name='flags' type='int' info='an OR'ed set of virDomainModificationImpact'/>
+ </function>
<function name='virConnectListStoragePools' file='python'>
<info>list the storage pools, stores the pointers to the names in @names</info>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index d2aad0f..27ad1d8 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -1000,6 +1000,190 @@ libvirt_virDomainGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
}
static PyObject *
+libvirt_virDomainSetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ int i_retval;
+ int nparams = 0, i;
+ unsigned int flags;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args,
+ (char *)"OOi:virDomainSetNumaParameters",
+ &pyobj_domain, &info, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_INT_FAIL;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_INT_FAIL;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 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(info, 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:
+ {
+ /* Hack - Python's definition of Py_True breaks strict
+ * aliasing rules, so can't directly compare
+ */
+ PyObject *hacktrue = PyBool_FromLong(1);
+ params[i].value.b = hacktrue == val ? 1: 0;
+ Py_DECREF(hacktrue);
+ }
+ break;
+
+ case VIR_TYPED_PARAM_STRING:
+ params[i].value.s = PyString_AsString(val);
+ break;
+
+ default:
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+ }
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainSetNumaParameters(domain, params, nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+
+ free(params);
+ return VIR_PY_INT_SUCCESS;
+}
+
+static PyObject *
+libvirt_virDomainGetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ int i_retval;
+ int nparams = 0, i;
+ unsigned int flags;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args, (char *)"Oi:virDomainGetNumaParameters",
+ &pyobj_domain, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_NONE;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_NONE;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetNumaParameters(domain, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_NONE;
+ }
+
+ /* convert to a Python tuple of long objects */
+ if ((info = 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((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;
+
+ case VIR_TYPED_PARAM_STRING:
+ val = libvirt_constcharPtrWrap(params[i].value.s);
+ break;
+
+ default:
+ free(params);
+ Py_DECREF(info);
+ return VIR_PY_NONE;
+ }
+
+ key = libvirt_constcharPtrWrap(params[i].field);
+ PyDict_SetItem(info, key, val);
+ }
+ free(params);
+ return(info);
+}
+
+static PyObject *
libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED,
PyObject *args) {
virDomainPtr domain;
@@ -5162,6 +5346,8 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainGetBlkioParameters", libvirt_virDomainGetBlkioParameters, METH_VARARGS, NULL},
{(char *) "virDomainSetMemoryParameters", libvirt_virDomainSetMemoryParameters, METH_VARARGS, NULL},
{(char *) "virDomainGetMemoryParameters", libvirt_virDomainGetMemoryParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainGetNumaParameters", libvirt_virDomainGetNumaParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainSetNumaParameters", libvirt_virDomainSetNumaParameters, METH_VARARGS, NULL},
{(char *) "virDomainGetVcpus", libvirt_virDomainGetVcpus, METH_VARARGS, NULL},
{(char *) "virDomainPinVcpu", libvirt_virDomainPinVcpu, METH_VARARGS, NULL},
{(char *) "virDomainPinVcpuFlags", libvirt_virDomainPinVcpuFlags, METH_VARARGS, NULL},
--
1.7.7.5
12 years, 9 months
[libvirt] [PATCH 0/8 v5] Summary on block IO throttle
by Lei Li
Changes since V3
- Use virTypedParameterPtr instead of specific struct in libvirt pulic API.
- Relevant changes to remote driver, qemu driver, python support and virsh.
Changes since V2
- Implement the Python binding support for setting blkio throttling.
- Implement --current --live --config options support to unify the libvirt API.
- Add changes in docs and tests.
- Some changes suggested by Adam Litke, Eric Blake, Daniel P. Berrange.
- Change the XML schema.
- API name to virDomain{Set, Get}BlockIoTune.
- Parameters changed to make them more self-explanatory.
- virsh command name to blkdeviotune.
- And other fixups.
Changes since V1
- Implement the support to get the block io throttling for
a device as read only connection - QMP/HMP.
- Split virDomainBlockIoThrottle into two separate functions
virDomainSetBlockIoThrottle - Set block I/O limits for a device
- Requires a connection in 'write' mode.
- Limits (info) structure passed as an input parameter
virDomainGetBlockIoThrottle - Get the current block I/O limits for a device
- Works on a read-only connection.
- Current limits are written to the output parameter (reply).
- And Other fixups suggested by Adam Litke, Daniel P. Berrange.
- For dynamically allocate the blkiothrottle struct, I will fix
it when implement --current --live --config options support.
Today libvirt supports the cgroups blkio-controller, which handles
proportional shares and throughput/iops limits on host block devices.
blkio-controller does not support network file systems (NFS) or other
QEMU remote block drivers (curl, Ceph/rbd, sheepdog) since they are
not host block devices. QEMU I/O throttling works with all types of
drive and can be applied independently to each drive attached to
a guest and supports throughput/iops limits.
To help add QEMU I/O throttling support to libvirt, we plan to complete
it with add new API virDomain{Set, Get}BlockIoThrottle(), new command 'blkdeviotune'
and Python bindings.
Notes: Now all the planed features were implemented (#1#2 were implemented by
Zhi Yong Wu), the previous comments were all fixed up too. And the qemu part patches
have been accepted upstream and are expected to be part of the QEMU 1.1
release, git tree from Zhi Yong:
http://repo.or.cz/w/qemu/kevin.git/shortlog/refs/heads/block
1) Enable the blkio throttling in xml when guest is starting up.
Add blkio throttling in xml as follows:
<disk type='file' device='disk'>
...
<iotune>
<total_bytes_sec>nnn</total_bytes_sec>
...
</iotune>
...
</disk>
2) Enable blkio throttling setting at guest running time.
virsh blkdeviotune <domain> <device> [--total_bytes_sec<number>] [--read_bytes_sec<number>] \
[--write_bytes_sec<number>] [--total_iops_sec<number>] [--read_iops_sec<number>]
[--write_iops_sec<number>]
3) The support to get the current block i/o throttling for a device - HMP/QMP.
virsh blkiothrottle <domain> <device>
total_bytes_sec:
read_bytes_sec:
write_bytes_sec:
total_iops_sec:
read_iops_sec:
write_iops_sec:
4) Python binding support for setting blkio throttling.
5) --current --live --config options support to unify the libvirt API.
virsh blkdeviotune <domain> <device> [--total_bytes_sec <number>] [--read_bytes_sec <number>]
[--write_bytes_sec <number>] [--total_iops_sec <number>] [--read_iops_sec <number>]
[--write_iops_sec <number>] [--config] [--live] [--current]
daemon/remote.c | 108 +++++++
docs/formatdomain.html.in | 31 ++
docs/schemas/domaincommon.rng | 24 ++
include/libvirt/libvirt.h.in | 70 ++++
python/generator.py | 2 +
python/libvirt-override-api.xml | 16 +
python/libvirt-override.c | 179 +++++++++++
src/conf/domain_conf.c | 101 ++++++-
src/conf/domain_conf.h | 12 +
src/driver.h | 20 ++
src/libvirt.c | 145 +++++++++
src/libvirt_public.syms | 2 +
src/qemu/qemu_command.c | 33 ++
src/qemu/qemu_driver.c | 338 ++++++++++++++++++++
src/qemu/qemu_monitor.c | 36 ++
src/qemu/qemu_monitor.h | 22 ++
src/qemu/qemu_monitor_json.c | 185 +++++++++++
src/qemu/qemu_monitor_json.h | 10 +
src/qemu/qemu_monitor_text.c | 164 ++++++++++
src/qemu/qemu_monitor_text.h | 10 +
src/remote/remote_driver.c | 96 ++++++
src/remote/remote_protocol.x | 26 ++-
src/remote_protocol-structs | 24 ++
src/util/xml.h | 2 +
.../qemuxml2argv-blkdeviotune.args | 4 +
.../qemuxml2argvdata/qemuxml2argv-blkdeviotune.xml | 37 +++
tests/qemuxml2argvtest.c | 1 +
tests/qemuxml2xmltest.c | 1 +
tools/virsh.c | 240 ++++++++++++++
tools/virsh.pod | 23 ++
30 files changed, 1958 insertions(+), 4 deletions(-)
--
Lei
12 years, 9 months
[libvirt] [PATCH v2] Added capability checking for block <iotune> setting.
by Martin Kletzander
There was missing capability for blkiotune and thus specifying these
settings caused libvirt to run qemu with invalid parameters and then
reporting qemu error instead of the standard libvirt one. The support
for blkiotune setting was added in upstream qemu repo under commit
0563e191516289c9d2f282a8c50f2eecef2fa773.
---
src/qemu/qemu_capabilities.c | 4 ++++
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_command.c | 13 +++++++++++++
tests/qemuxml2argvtest.c | 2 +-
4 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0a1c9aa..54757fc 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -150,6 +150,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"drive-copy-on-read",
"cpu-host",
"fsdev-writeout",
+
+ "drive-iotune", /* 85 */
);
struct qemu_feature_flags {
@@ -1031,6 +1033,8 @@ qemuCapsComputeCmdFlags(const char *help,
qemuCapsSet(flags, QEMU_CAPS_DRIVE_AIO);
if (strstr(help, "copy-on-read=on|off"))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_COPY_ON_READ);
+ if (strstr(help, "bps="))
+ qemuCapsSet(flags, QEMU_CAPS_DRIVE_IOTUNE);
}
if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
const char *nl = strstr(p, "\n");
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 1d4d10e..6a5389e 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -124,6 +124,8 @@ enum qemuCapsFlags {
QEMU_CAPS_CPU_HOST = 83, /* support for -cpu host */
QEMU_CAPS_FSDEV_WRITEOUT = 84, /* -fsdev writeout supported */
+ QEMU_CAPS_DRIVE_IOTUNE = 85, /* -drive bps= and friends ({b,io}ps{_rd,_wr,}) */
+
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3bbe9cf..aaccf62 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1987,6 +1987,19 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
}
/* block I/O throttling */
+ if ((disk->blkdeviotune.total_bytes_sec ||
+ disk->blkdeviotune.read_bytes_sec ||
+ disk->blkdeviotune.write_bytes_sec ||
+ disk->blkdeviotune.total_iops_sec ||
+ disk->blkdeviotune.read_iops_sec ||
+ disk->blkdeviotune.write_iops_sec) &&
+ !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("block I/O throttling not supported with this "
+ "QEMU binary"));
+ goto error;
+ }
+
if (disk->blkdeviotune.total_bytes_sec) {
virBufferAsprintf(&opt, ",bps=%llu",
disk->blkdeviotune.total_bytes_sec);
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 5cec86b..d40b37e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -705,7 +705,7 @@ mymain(void)
DO_TEST("cputune", false, QEMU_CAPS_NAME);
DO_TEST("numatune-memory", false, NONE);
DO_TEST("blkdeviotune", false, QEMU_CAPS_NAME, QEMU_CAPS_DEVICE,
- QEMU_CAPS_DRIVE);
+ QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_IOTUNE);
DO_TEST("multifunction-pci-device", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
--
1.7.3.4
12 years, 9 months
[libvirt] [PATCH] Added capability checking for block <iotune> setting.
by Martin Kletzander
There was missing capability for blkiotune and thus specifying these
settings caused libvirt to run qemu with invalid parameters and then
reporting qemu error instead of the standard libvirt one.
---
src/qemu/qemu_capabilities.c | 6 ++++++
src/qemu/qemu_capabilities.h | 2 ++
src/qemu/qemu_command.c | 13 +++++++++++++
tests/qemuxml2argvtest.c | 2 +-
4 files changed, 22 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0a1c9aa..f50e0b0 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -150,6 +150,8 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"drive-copy-on-read",
"cpu-host",
"fsdev-writeout",
+
+ "drive-iotune", /* 85 */
);
struct qemu_feature_flags {
@@ -1031,6 +1033,10 @@ qemuCapsComputeCmdFlags(const char *help,
qemuCapsSet(flags, QEMU_CAPS_DRIVE_AIO);
if (strstr(help, "copy-on-read=on|off"))
qemuCapsSet(flags, QEMU_CAPS_DRIVE_COPY_ON_READ);
+ if (strstr(help, "bps=") && strstr(help, "iops=") &&
+ strstr(help, "bps_rd=") && strstr(help, "bps_wr=") &&
+ strstr(help, "iops_rd=") && strstr(help, "iops_wr="))
+ qemuCapsSet(flags, QEMU_CAPS_DRIVE_IOTUNE);
}
if ((p = strstr(help, "-vga")) && !strstr(help, "-std-vga")) {
const char *nl = strstr(p, "\n");
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 1d4d10e..6a5389e 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -124,6 +124,8 @@ enum qemuCapsFlags {
QEMU_CAPS_CPU_HOST = 83, /* support for -cpu host */
QEMU_CAPS_FSDEV_WRITEOUT = 84, /* -fsdev writeout supported */
+ QEMU_CAPS_DRIVE_IOTUNE = 85, /* -drive bps= and friends ({b,io}ps{_rd,_wr,}) */
+
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 3bbe9cf..aaccf62 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1987,6 +1987,19 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
}
/* block I/O throttling */
+ if ((disk->blkdeviotune.total_bytes_sec ||
+ disk->blkdeviotune.read_bytes_sec ||
+ disk->blkdeviotune.write_bytes_sec ||
+ disk->blkdeviotune.total_iops_sec ||
+ disk->blkdeviotune.read_iops_sec ||
+ disk->blkdeviotune.write_iops_sec) &&
+ !qemuCapsGet(qemuCaps, QEMU_CAPS_DRIVE_IOTUNE)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("block I/O throttling not supported with this "
+ "QEMU binary"));
+ goto error;
+ }
+
if (disk->blkdeviotune.total_bytes_sec) {
virBufferAsprintf(&opt, ",bps=%llu",
disk->blkdeviotune.total_bytes_sec);
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 5cec86b..d40b37e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -705,7 +705,7 @@ mymain(void)
DO_TEST("cputune", false, QEMU_CAPS_NAME);
DO_TEST("numatune-memory", false, NONE);
DO_TEST("blkdeviotune", false, QEMU_CAPS_NAME, QEMU_CAPS_DEVICE,
- QEMU_CAPS_DRIVE);
+ QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_IOTUNE);
DO_TEST("multifunction-pci-device", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
--
1.7.3.4
12 years, 9 months
[libvirt] [libvirt-glib 1/3] API to get/set 'description' node in domain config
by Zeeshan Ali (Khattak)
From: "Zeeshan Ali (Khattak)" <zeeshanak(a)gnome.org>
---
libvirt-gconfig/libvirt-gconfig-domain.c | 28 ++++++++++++++++++++++++++++
libvirt-gconfig/libvirt-gconfig-domain.h | 2 ++
libvirt-gconfig/libvirt-gconfig.sym | 2 ++
3 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.c b/libvirt-gconfig/libvirt-gconfig-domain.c
index fba1ee2..c4027a3 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain.c
@@ -39,6 +39,7 @@ G_DEFINE_TYPE(GVirConfigDomain, gvir_config_domain, GVIR_CONFIG_TYPE_OBJECT);
enum {
PROP_0,
PROP_NAME,
+ PROP_DESCRIPTION,
PROP_MEMORY,
PROP_VCPU,
PROP_FEATURES
@@ -55,6 +56,9 @@ static void gvir_config_domain_get_property(GObject *object,
case PROP_NAME:
g_value_take_string(value, gvir_config_domain_get_name(domain));
break;
+ case PROP_DESCRIPTION:
+ g_value_take_string(value, gvir_config_domain_get_description(domain));
+ break;
case PROP_MEMORY:
g_value_set_uint64(value, gvir_config_domain_get_memory(domain));
break;
@@ -81,6 +85,9 @@ static void gvir_config_domain_set_property(GObject *object,
case PROP_NAME:
gvir_config_domain_set_name(domain, g_value_get_string(value));
break;
+ case PROP_DESCRIPTION:
+ gvir_config_domain_set_description(domain, g_value_get_string(value));
+ break;
case PROP_MEMORY:
gvir_config_domain_set_memory(domain, g_value_get_uint64(value));
break;
@@ -114,6 +121,14 @@ static void gvir_config_domain_class_init(GVirConfigDomainClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
g_object_class_install_property(object_class,
+ PROP_DESCRIPTION,
+ g_param_spec_string("description",
+ "Description",
+ "Description (could be anything).",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+ g_object_class_install_property(object_class,
PROP_MEMORY,
g_param_spec_uint64("memory",
"Memory",
@@ -196,6 +211,19 @@ void gvir_config_domain_set_name(GVirConfigDomain *domain, const char *name)
g_object_notify(G_OBJECT(domain), "name");
}
+char *gvir_config_domain_get_description(GVirConfigDomain *domain)
+{
+ return gvir_config_object_get_node_content(GVIR_CONFIG_OBJECT(domain),
+ "description");
+}
+
+void gvir_config_domain_set_description(GVirConfigDomain *domain, const char *description)
+{
+ gvir_config_object_set_node_content(GVIR_CONFIG_OBJECT(domain),
+ "description", description);
+ g_object_notify(G_OBJECT(domain), "description");
+}
+
/**
* gvir_config_domain_get_memory:
* @domain: A domain configuration object.
diff --git a/libvirt-gconfig/libvirt-gconfig-domain.h b/libvirt-gconfig/libvirt-gconfig-domain.h
index e68f1ac..6cdaec9 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain.h
@@ -102,6 +102,8 @@ GVirConfigDomain *gvir_config_domain_new(void);
void gvir_config_domain_set_virt_type(GVirConfigDomain *domain, GVirConfigDomainVirtType type);
char *gvir_config_domain_get_name(GVirConfigDomain *domain);
void gvir_config_domain_set_name(GVirConfigDomain *domain, const char *name);
+char *gvir_config_domain_get_description(GVirConfigDomain *domain);
+void gvir_config_domain_set_description(GVirConfigDomain *domain, const char *description);
guint64 gvir_config_domain_get_memory(GVirConfigDomain *domain);
void gvir_config_domain_set_memory(GVirConfigDomain *domain, guint64 memory);
guint64 gvir_config_domain_get_vcpus(GVirConfigDomain *domain);
diff --git a/libvirt-gconfig/libvirt-gconfig.sym b/libvirt-gconfig/libvirt-gconfig.sym
index 9bfe1d9..383acca 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -23,6 +23,8 @@ LIBVIRT_GCONFIG_0.0.4 {
gvir_config_domain_set_memory;
gvir_config_domain_get_name;
gvir_config_domain_set_name;
+ gvir_config_domain_get_description;
+ gvir_config_domain_set_description;
gvir_config_domain_set_os;
gvir_config_domain_set_seclabel;
gvir_config_domain_get_vcpus;
--
1.7.7.5
12 years, 9 months
[libvirt] [PATCH v2 0/6] Console coruption with two or more clients series
by Peter Krempa
This series fixes anoying console corruption if two clients try to connect
at same time to the console. The current state of this is, that two/more
of threads compete for the data from the PTY. This causes that each of the
consoles get scrambled and unusable.
These patches add mutual exclusion for opening consoles with two different
approaches and a option to terminate existing console streams.
A sample implementation is done using qemu driver, but i'll add more of them
if this will be OK. (They're basicaly the same as in qemu).
For convinience, to review these patches:
git checkout -b console_corruption 8d16201fe0e63afb5416a8eb7c6478f582ccccc0
git pull git://aeon.pipo.sk/libvirt.git console_dup
(The machine should be up most of time)
Peter
Peter Krempa (6):
Add flags for virDomainOpenConsole
virsh: add support for VIR_DOMAIN_CONSOLE_FORCE flag
fdstream: Emit stream abort callback even if poll() doesnt.
fdstream: Add internal callback on stream close
util: Add helpers for safe domain console operations
qemu: Add ability to abort existing console while creating new one
configure.ac | 37 +++-
include/libvirt/libvirt.h.in | 12 +-
src/Makefile.am | 5 +-
src/fdstream.c | 95 +++++++++-
src/fdstream.h | 11 +
src/libvirt_private.syms | 6 +
src/qemu/qemu_domain.c | 5 +
src/qemu/qemu_domain.h | 3 +
src/qemu/qemu_driver.c | 21 ++-
src/util/domain_safe_console.c | 399 ++++++++++++++++++++++++++++++++++++++++
src/util/domain_safe_console.h | 28 +++
tools/console.c | 5 +-
tools/console.h | 3 +-
tools/virsh.c | 18 ++-
14 files changed, 614 insertions(+), 34 deletions(-)
create mode 100644 src/util/domain_safe_console.c
create mode 100644 src/util/domain_safe_console.h
--
1.7.3.4
12 years, 9 months
[libvirt] [PATCH] python: Expose virDomain{G, S}etInterfaceParameters' APIs in python binding
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
An simple example to show how to use it:
#!/usr/bin/env python
import libvirt
conn = libvirt.open(None)
dom = conn.lookupByName('foo')
print dom.interfaceParameters('vnet0', 0)
params = {'outbound.peak': 20,
'inbound.peak': 20,
'inbound.burst': 10,
'inbound.average': 10,
'outbound.average': 30,
'outbound.burst': 30}
print dom.setInterfaceParameters('vnet0', params, 0)
print dom.interfaceParameters('vnet0', 0)
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=770971
https://bugzilla.redhat.com/show_bug.cgi?id=771015
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
python/libvirt-override-api.xml | 15 +++
python/libvirt-override.c | 179 +++++++++++++++++++++++++++++++++++++++
2 files changed, 194 insertions(+), 0 deletions(-)
diff --git a/python/libvirt-override-api.xml b/python/libvirt-override-api.xml
index 704fee9..b29c149 100644
--- a/python/libvirt-override-api.xml
+++ b/python/libvirt-override-api.xml
@@ -421,5 +421,20 @@
<arg name='flags' type='unsigned int' info='an OR'ed set of virDomainMemoryFlags'/>
<return type='char *' info='the returned buffer or None in case of error'/>
</function>
+ <function name='virDomainSetInterfaceParameters' file='python'>
+ <info>Change the bandwidth tunables for a interface device</info>
+ <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
+ <arg name='device' type='const char *' info='interface name'/>
+ <arg name='params' type='virTypedParameterPtr' info='Pointer to bandwidth tuning 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='virDomainGetInterfaceParameters' file='python'>
+ <info>Get the bandwidth tunables for a interface device</info>
+ <arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
+ <arg name='device' type='const char *' info='interface name'/>
+ <arg name='flags' type='unsigned int' info='an OR'ed set of virDomainModificationImpact'/>
+ <return type='virTypedParameterPtr' info='the bandwidth tunables value or None in case of error'/>
+ </function>
</symbols>
</api>
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index d2aad0f..ecd9355 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -5108,6 +5108,183 @@ cleanup:
return py_retval;
}
+static PyObject *
+libvirt_virDomainSetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ int i_retval;
+ int nparams = 0, i;
+ unsigned int flags;
+ const char *device;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args,
+ (char *)"OzOi:virDomainSetInterfaceParameters",
+ &pyobj_domain, &device, &info, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetInterfaceParameters(domain, device, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_INT_FAIL;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_INT_FAIL;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetInterfaceParameters(domain, device, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 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(info, 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:
+ {
+ /* Hack - Python's definition of Py_True breaks strict
+ * aliasing rules, so can't directly compare :-(
+ */
+ 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;
+ i_retval = virDomainSetInterfaceParameters(domain, device, params, nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_INT_FAIL;
+ }
+
+ free(params);
+ return VIR_PY_INT_SUCCESS;
+}
+
+static PyObject *
+libvirt_virDomainGetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED,
+ PyObject *args) {
+ virDomainPtr domain;
+ PyObject *pyobj_domain, *info;
+ int i_retval;
+ int nparams = 0, i;
+ unsigned int flags;
+ const char *device;
+ virTypedParameterPtr params;
+
+ if (!PyArg_ParseTuple(args, (char *)"Ozi:virDomainGetInterfaceParameters",
+ &pyobj_domain, &device, &flags))
+ return(NULL);
+ domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetInterfaceParameters(domain, device, NULL, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0)
+ return VIR_PY_NONE;
+
+ if ((params = malloc(sizeof(*params)*nparams)) == NULL)
+ return VIR_PY_NONE;
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ i_retval = virDomainGetInterfaceParameters(domain, device, params, &nparams, flags);
+ LIBVIRT_END_ALLOW_THREADS;
+
+ if (i_retval < 0) {
+ free(params);
+ return VIR_PY_NONE;
+ }
+
+ /* convert to a Python tuple of long objects */
+ if ((info = 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((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(info);
+ return VIR_PY_NONE;
+ }
+
+ key = libvirt_constcharPtrWrap(params[i].field);
+ PyDict_SetItem(info, key, val);
+ }
+ free(params);
+ return(info);
+}
+
/************************************************************************
* *
* The registration stuff *
@@ -5206,6 +5383,8 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainMigrateGetMaxSpeed", libvirt_virDomainMigrateGetMaxSpeed, METH_VARARGS, NULL},
{(char *) "virDomainBlockPeek", libvirt_virDomainBlockPeek, METH_VARARGS, NULL},
{(char *) "virDomainMemoryPeek", libvirt_virDomainMemoryPeek, METH_VARARGS, NULL},
+ {(char *) "virDomainSetInterfaceParameters", libvirt_virDomainSetInterfaceParameters, METH_VARARGS, NULL},
+ {(char *) "virDomainGetInterfaceParameters", libvirt_virDomainGetInterfaceParameters, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
--
1.7.1
12 years, 9 months