[libvirt] [PATCH] Memory Leak Fix: Check def->info->alias before assigning
by Nehal J Wani
On running the command make -C tests valgrind, there used to be a bunch of
memory leaks shown by valgrind. Specifically, one can check it by running:
libtool --mode=execute valgrind --quiet --leak-check=full --suppressions=./.valgrind.supp qemuhotplugtest
The issue was that def->info->alias was already malloc'ed by xmlStrndup in
virDomainDeviceInfoParseXML (domain_conf.c:3439). The new alias was being
assigned again without freeing the old one in qemuAssignDeviceAliases().
This patch checks if the entity exists, and frees accordingly, hence making
valgrind cry lesser.
---
src/qemu/qemu_command.c | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 763417f..bbec1d4 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -979,6 +979,8 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
size_t i;
for (i = 0; i < def->ndisks; i++) {
+ if (def->disks[i]->info.alias)
+ VIR_FREE(def->disks[i]->info.alias);
if (qemuAssignDeviceDiskAlias(def, def->disks[i], qemuCaps) < 0)
return -1;
}
@@ -988,6 +990,9 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
/* type='hostdev' interfaces are also on the hostdevs list,
* and will have their alias assigned with other hostdevs.
*/
+ if (def->nets[i]->info.alias)
+ VIR_FREE(def->nets[i]->info.alias);
+
if (virDomainNetGetActualType(def->nets[i])
!= VIR_DOMAIN_NET_TYPE_HOSTDEV &&
qemuAssignDeviceNetAlias(def, def->nets[i], i) < 0) {
@@ -1000,70 +1005,104 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
return 0;
for (i = 0; i < def->nfss; i++) {
+ if (def->fss[i]->info.alias)
+ VIR_FREE(def->fss[i]->info.alias);
if (virAsprintf(&def->fss[i]->info.alias, "fs%zu", i) < 0)
return -1;
}
for (i = 0; i < def->nsounds; i++) {
+ if (def->sounds[i]->info.alias)
+ VIR_FREE(def->sounds[i]->info.alias);
if (virAsprintf(&def->sounds[i]->info.alias, "sound%zu", i) < 0)
return -1;
}
for (i = 0; i < def->nhostdevs; i++) {
+ if (def->hostdevs[i]->info->alias)
+ VIR_FREE(def->hostdevs[i]->info->alias);
if (qemuAssignDeviceHostdevAlias(def, def->hostdevs[i], i) < 0)
return -1;
}
for (i = 0; i < def->nredirdevs; i++) {
+ if (def->redirdevs[i]->info.alias)
+ VIR_FREE(def->redirdevs[i]->info.alias);
if (qemuAssignDeviceRedirdevAlias(def, def->redirdevs[i], i) < 0)
return -1;
}
for (i = 0; i < def->nvideos; i++) {
+ if (def->videos[i]->info.alias)
+ VIR_FREE(def->videos[i]->info.alias);
if (virAsprintf(&def->videos[i]->info.alias, "video%zu", i) < 0)
return -1;
}
for (i = 0; i < def->ncontrollers; i++) {
+ if (def->controllers[i]->info.alias)
+ VIR_FREE(def->controllers[i]->info.alias);
if (qemuAssignDeviceControllerAlias(def->controllers[i]) < 0)
return -1;
}
for (i = 0; i < def->ninputs; i++) {
+ if (def->inputs[i]->info.alias)
+ VIR_FREE(def->inputs[i]->info.alias);
if (virAsprintf(&def->inputs[i]->info.alias, "input%zu", i) < 0)
return -1;
}
for (i = 0; i < def->nparallels; i++) {
+ if (def->parallels[i]->info.alias)
+ VIR_FREE(def->parallels[i]->info.alias);
if (qemuAssignDeviceChrAlias(def, def->parallels[i], i) < 0)
return -1;
}
for (i = 0; i < def->nserials; i++) {
+ if (def->serials[i]->info.alias)
+ VIR_FREE(def->serials[i]->info.alias);
if (qemuAssignDeviceChrAlias(def, def->serials[i], i) < 0)
return -1;
}
for (i = 0; i < def->nchannels; i++) {
+ if (def->channels[i]->info.alias)
+ VIR_FREE(def->channels[i]->info.alias);
if (qemuAssignDeviceChrAlias(def, def->channels[i], i) < 0)
return -1;
}
for (i = 0; i < def->nconsoles; i++) {
+ if (def->consoles[i]->info.alias)
+ VIR_FREE(def->consoles[i]->info.alias);
if (qemuAssignDeviceChrAlias(def, def->consoles[i], i) < 0)
return -1;
}
for (i = 0; i < def->nhubs; i++) {
+ if (def->hubs[i]->info.alias)
+ VIR_FREE(def->hubs[i]->info.alias);
if (virAsprintf(&def->hubs[i]->info.alias, "hub%zu", i) < 0)
return -1;
}
for (i = 0; i < def->nsmartcards; i++) {
+ if (def->smartcards[i]->info.alias)
+ VIR_FREE(def->smartcards[i]->info.alias);
if (virAsprintf(&def->smartcards[i]->info.alias, "smartcard%zu", i) < 0)
return -1;
}
if (def->watchdog) {
+ if (def->watchdog->info.alias)
+ VIR_FREE(def->watchdog->info.alias);
if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0)
return -1;
}
if (def->memballoon) {
+ if (def->memballoon->info.alias)
+ VIR_FREE(def->memballoon->info.alias);
if (virAsprintf(&def->memballoon->info.alias, "balloon%d", 0) < 0)
return -1;
}
if (def->rng) {
+ if (def->rng->info.alias)
+ VIR_FREE(def->rng->info.alias);
if (virAsprintf(&def->rng->info.alias, "rng%d", 0) < 0)
return -1;
}
if (def->tpm) {
+ if (def->tpm->info.alias)
+ VIR_FREE(def->tpm->info.alias);
if (virAsprintf(&def->tpm->info.alias, "tpm%d", 0) < 0)
return -1;
}
--
1.8.1.4
11 years
[libvirt] [PATCH python] Deal with old filenames for events/error functions
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Older libvirt has files named 'events' and 'virterror'
rather than 'virevent' and 'virerror'. This is visible
in the API XML files. We must look for both names to
ensure we don't loose generation of methods with older
versions of libvirt.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
generator.py | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/generator.py b/generator.py
index 273efbd..cd857b4 100755
--- a/generator.py
+++ b/generator.py
@@ -113,7 +113,8 @@ class docParser(xml.sax.handler.ContentHandler):
elif tag == 'enum':
# enums come from header files, hence virterror.h
if (attrs['file'] == "libvirt" or
- attrs['file'] == "virterror"):
+ attrs['file'] == "virterror" or
+ attrs['file'] == "virerror"):
enum(attrs['type'],attrs['name'],attrs['value'])
elif attrs['file'] == "libvirt-lxc":
lxc_enum(attrs['type'],attrs['name'],attrs['value'])
@@ -127,8 +128,10 @@ class docParser(xml.sax.handler.ContentHandler):
# fuctions come from source files, hence 'virerror.c'
if self.function is not None:
if (self.function_module == "libvirt" or
+ self.function_module == "event" or
self.function_module == "virevent" or
- self.function_module == "virerror"):
+ self.function_module == "virerror" or
+ self.function_module == "virterror"):
function(self.function, self.function_descr,
self.function_return, self.function_args,
self.function_file, self.function_module,
--
1.8.3.1
11 years
[libvirt] [PATCH] storage: skip selinux cleanup when fd not available
by Eric Blake
When attempting to backport gluster pools to an older version
where there is no VIR_STRDUP, I got a crash from calling
strdup(,NULL). Rather than relying on the current else branch
safely doing nothing when there is no fd, it is easier to just
skip it. While at it, there's no need to explicitly set
perms.label to NULL after a VIR_FREE().
* src/storage/storage_backend.c
(virStorageBackendUpdateVolTargetInfoFD): Minor optimization.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
src/storage/storage_backend.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/src/storage/storage_backend.c b/src/storage/storage_backend.c
index bde39d6..b08d646 100644
--- a/src/storage/storage_backend.c
+++ b/src/storage/storage_backend.c
@@ -1383,28 +1383,26 @@ virStorageBackendUpdateVolTargetInfoFD(virStorageVolTargetPtr target,
VIR_FREE(target->perms.label);
#if WITH_SELINUX
/* XXX: make this a security driver call */
- if (fd >= 0 && fgetfilecon_raw(fd, &filecon) == -1) {
- if (errno != ENODATA && errno != ENOTSUP) {
- virReportSystemError(errno,
- _("cannot get file context of '%s'"),
- target->path);
- return -1;
+ if (fd >= 0) {
+ if (fgetfilecon_raw(fd, &filecon) == -1) {
+ if (errno != ENODATA && errno != ENOTSUP) {
+ virReportSystemError(errno,
+ _("cannot get file context of '%s'"),
+ target->path);
+ return -1;
+ }
} else {
- target->perms.label = NULL;
- }
- } else {
- if (VIR_STRDUP(target->perms.label, filecon) < 0) {
+ if (VIR_STRDUP(target->perms.label, filecon) < 0) {
+ freecon(filecon);
+ return -1;
+ }
freecon(filecon);
- return -1;
}
- freecon(filecon);
}
-#else
- target->perms.label = NULL;
#endif
return 0;
}
--
1.8.3.1
11 years
[libvirt] [PATCH python] Fix misc RPM specfile flaws
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Fix the RPM summary line, add placeholder %changelog tag,
make %setup quiet, add Url: tag and filter out bogus
provides and add example programs as docs.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
libvirt-python.spec.in | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/libvirt-python.spec.in b/libvirt-python.spec.in
index e6c229f..7c6257e 100644
--- a/libvirt-python.spec.in
+++ b/libvirt-python.spec.in
@@ -1,14 +1,19 @@
-Summary: The libvirt virtualization API
+Summary: The libvirt virtualization API python binding
Name: libvirt-python
Version: @PY_VERSION@
Release: 1%{?dist}%{?extra_release}
Source0: http://libvirt.org/sources/python/%{name}-%{version}.tar.gz
+Url: http://libvirt.org
License: LGPLv2+
Group: Development/Libraries
BuildRequires: libvirt-devel >= @C_VERSION@
BuildRequires: python-devel
+# Don't want provides for python shared objects
+%{?filter_provides_in: %filter_provides_in %{python_sitearch}/.*\.so}
+%{?filter_setup}
+
%description
The libvirt-python package contains a module that permits applications
written in the Python programming language to use the interface
@@ -16,7 +21,7 @@ supplied by the libvirt library to use the virtualization capabilities
of recent versions of Linux (and other OSes).
%prep
-%setup
+%setup -q
%build
CFLAGS="$RPM_OPT_FLAGS" %{__python} setup.py build
@@ -27,8 +32,10 @@ rm -f %{buildroot}%{_libdir}/python*/site-packages/*egg-info
%files
%defattr(-,root,root)
-%doc ChangeLog AUTHORS NEWS README COPYING COPYING.LESSER
+%doc ChangeLog AUTHORS NEWS README COPYING COPYING.LESSER examples/
%{_libdir}/python*/site-packages/libvirt.py*
%{_libdir}/python*/site-packages/libvirt_qemu.py*
%{_libdir}/python*/site-packages/libvirt_lxc.py*
%{_libdir}/python*/site-packages/libvirtmod*
+
+%changelog
--
1.8.3.1
11 years
[libvirt] [PATCH python] Fix code for avoiding overrides of non-existant functions
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
When reading/writing a global variable from inside a method
it must be declared as a global, otherwise a local variable
by the same name will be used.
Special case the virConnectListDomainsID method which is
bizarrely renamed for no obvious reason.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
generator.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/generator.py b/generator.py
index cd857b4..e8d8ea9 100755
--- a/generator.py
+++ b/generator.py
@@ -187,16 +187,21 @@ class docParser(xml.sax.handler.ContentHandler):
def function(name, desc, ret, args, file, module, cond):
+ global onlyOverrides
if onlyOverrides and name not in functions:
return
+ if name == "virConnectListDomains":
+ name = "virConnectListDomainsID"
functions[name] = (desc, ret, args, file, module, cond)
def qemu_function(name, desc, ret, args, file, module, cond):
+ global onlyOverrides
if onlyOverrides and name not in qemu_functions:
return
qemu_functions[name] = (desc, ret, args, file, module, cond)
def lxc_function(name, desc, ret, args, file, module, cond):
+ global onlyOverrides
if onlyOverrides and name not in lxc_functions:
return
lxc_functions[name] = (desc, ret, args, file, module, cond)
@@ -786,6 +791,7 @@ def buildStubs(module, api_xml):
global py_types
global py_return_types
global unknown_types
+ global onlyOverrides
if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
print "ERROR: Unknown module type: %s" % module
--
1.8.3.1
11 years
[libvirt] [PATCH] Make virsh command 'domxml-to-native' copy the MAC addr parsed from XML
by mars@linux.vnet.ibm.com
From: Bing Bu Cao <mars(a)linux.vnet.ibm.com>
virsh command 'domxml-to-native' did not copy the
MAC address which parsed from a domain xml, in the commandline
the MAC addr of network device always was 00:00:00:00:00:00.
This patch fix it.
Signed-off-by: Bing Bu Cao <mars(a)linux.vnet.ibm.com>
---
src/qemu/qemu_driver.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8a1eefd..4693dad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -5821,6 +5821,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
virDomainNetDefPtr net = def->nets[i];
int bootIndex = net->info.bootIndex;
char *model = net->model;
+ virMacAddr mac = net->mac;
if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
int actualType = virDomainNetGetActualType(net);
@@ -5843,6 +5844,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
net->script = NULL;
net->data.ethernet.dev = brnamecopy;
net->data.ethernet.ipaddr = NULL;
+ net->mac = mac;
} else {
/* actualType is either NETWORK or DIRECT. In either
* case, the best we can do is NULL everything out.
@@ -5854,6 +5856,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
net->script = NULL;
net->data.ethernet.dev = NULL;
net->data.ethernet.ipaddr = NULL;
+ net->mac = mac;
}
} else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) {
VIR_FREE(net->data.direct.linkdev);
@@ -5864,6 +5867,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
net->script = NULL;
net->data.ethernet.dev = NULL;
net->data.ethernet.ipaddr = NULL;
+ net->mac = mac;
} else if (net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) {
char *script = net->script;
char *brname = net->data.bridge.brname;
@@ -5875,6 +5879,7 @@ static char *qemuConnectDomainXMLToNative(virConnectPtr conn,
net->script = script;
net->data.ethernet.dev = brname;
net->data.ethernet.ipaddr = ipaddr;
+ net->mac = mac;
}
VIR_FREE(net->virtPortProfile);
--
1.7.7.6
11 years
[libvirt] [PATCH python] Add missing binding of security model/label APIs
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The virNodeGetSecurityModel, virDomainGetSecurityLabel and
virDomainGetSecurityLabelList methods were disabled in the
python binding for inexplicable reasons.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
generator.py | 6 ++--
libvirt-override-api.xml | 15 +++++++++
libvirt-override.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++
typewrappers.c | 9 ++++++
typewrappers.h | 1 +
5 files changed, 110 insertions(+), 3 deletions(-)
diff --git a/generator.py b/generator.py
index ab2a97f..273efbd 100755
--- a/generator.py
+++ b/generator.py
@@ -381,6 +381,9 @@ skip_impl = (
'virDomainGetJobInfo',
'virDomainGetJobStats',
'virNodeGetInfo',
+ 'virNodeGetSecurityModel',
+ 'virDomainGetSecurityLabel',
+ 'virDomainGetSecurityLabelList',
'virDomainGetUUID',
'virDomainGetUUIDString',
'virDomainLookupByUUID',
@@ -476,9 +479,6 @@ skip_function = (
'virCopyLastError', # Python API is called virGetLastError instead
'virConnectOpenAuth', # Python C code is manually written
'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
- 'virDomainGetSecurityLabel', # Needs investigation...
- 'virDomainGetSecurityLabelList', # Needs investigation...
- 'virNodeGetSecurityModel', # Needs investigation...
'virConnectDomainEventRegister', # overridden in virConnect.py
'virConnectDomainEventDeregister', # overridden in virConnect.py
'virConnectDomainEventRegisterAny', # overridden in virConnect.py
diff --git a/libvirt-override-api.xml b/libvirt-override-api.xml
index 337d0a0..d5b25b5 100644
--- a/libvirt-override-api.xml
+++ b/libvirt-override-api.xml
@@ -104,6 +104,21 @@
<return type='char *' info='the list of information or None in case of error'/>
<arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
</function>
+ <function name='virNodeGetSecurityModel' file='python'>
+ <info>Extract information about the host security model</info>
+ <return type='char *' info='the list of information or None in case of error'/>
+ <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/>
+ </function>
+ <function name='virDomainGetSecurityLabel' file='python'>
+ <info>Extract information about the domain security label. Only the first label will be returned.</info>
+ <return type='char *' info='the list of information or None in case of error'/>
+ <arg name='domain' type='virDomainPtr' info='a domain object'/>
+ </function>
+ <function name='virDomainGetSecurityLabelList' file='python'>
+ <info>Extract information about the domain security label. A list of all labels will be returned.</info>
+ <return type='char *' info='the list of information or None in case of error'/>
+ <arg name='domain' type='virDomainPtr' info='a domain object'/>
+ </function>
<function name='virNodeGetCPUStats' file='python'>
<info>Extract node's CPU statistics.</info>
<return type='char *' info='dictionary mapping field names to values or None in case of error'/>
diff --git a/libvirt-override.c b/libvirt-override.c
index d3802de..42e253e 100644
--- a/libvirt-override.c
+++ b/libvirt-override.c
@@ -2865,6 +2865,83 @@ libvirt_virNodeGetInfo(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
}
static PyObject *
+libvirt_virNodeGetSecurityModel(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+ PyObject *py_retval;
+ int c_retval;
+ virConnectPtr conn;
+ PyObject *pyobj_conn;
+ virSecurityModel model;
+
+ if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetSecurityModel", &pyobj_conn))
+ return NULL;
+ conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_retval = virNodeGetSecurityModel(conn, &model);
+ LIBVIRT_END_ALLOW_THREADS;
+ if (c_retval < 0)
+ return VIR_PY_NONE;
+ py_retval = PyList_New(2);
+ PyList_SetItem(py_retval, 0, libvirt_constcharPtrWrap(&model.model[0]));
+ PyList_SetItem(py_retval, 1, libvirt_constcharPtrWrap(&model.doi[0]));
+ return py_retval;
+}
+
+static PyObject *
+libvirt_virDomainGetSecurityLabel(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+ PyObject *py_retval;
+ int c_retval;
+ virDomainPtr dom;
+ PyObject *pyobj_dom;
+ virSecurityLabel label;
+
+ if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetSecurityLabel", &pyobj_dom))
+ return NULL;
+ dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_retval = virDomainGetSecurityLabel(dom, &label);
+ LIBVIRT_END_ALLOW_THREADS;
+ if (c_retval < 0)
+ return VIR_PY_NONE;
+ py_retval = PyList_New(2);
+ PyList_SetItem(py_retval, 0, libvirt_constcharPtrWrap(&label.label[0]));
+ PyList_SetItem(py_retval, 1, libvirt_boolWrap(label.enforcing));
+ return py_retval;
+}
+
+#if LIBVIR_CHECK_VERSION(0, 9, 13)
+static PyObject *
+libvirt_virDomainGetSecurityLabelList(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
+ PyObject *py_retval;
+ int c_retval;
+ virDomainPtr dom;
+ PyObject *pyobj_dom;
+ virSecurityLabel *labels;
+ size_t i;
+
+ if (!PyArg_ParseTuple(args, (char *)"O:virDomainGetSecurityLabel", &pyobj_dom))
+ return NULL;
+ dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom);
+
+ LIBVIRT_BEGIN_ALLOW_THREADS;
+ c_retval = virDomainGetSecurityLabelList(dom, &labels);
+ LIBVIRT_END_ALLOW_THREADS;
+ if (c_retval < 0)
+ return VIR_PY_NONE;
+ py_retval = PyList_New(0);
+ for (i = 0 ; i < c_retval ; i++) {
+ PyObject *entry = PyList_New(2);
+ PyList_SetItem(entry, 0, libvirt_constcharPtrWrap(&labels[i].label[0]));
+ PyList_SetItem(entry, 1, libvirt_boolWrap(labels[i].enforcing));
+ PyList_Append(py_retval, entry);
+ }
+ free(labels);
+ return py_retval;
+}
+#endif
+
+static PyObject *
libvirt_virDomainGetUUID(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
PyObject *py_retval;
unsigned char uuid[VIR_UUID_BUFLEN];
@@ -7304,6 +7381,11 @@ static PyMethodDef libvirtMethods[] = {
{(char *) "virDomainGetControlInfo", libvirt_virDomainGetControlInfo, METH_VARARGS, NULL},
{(char *) "virDomainGetBlockInfo", libvirt_virDomainGetBlockInfo, METH_VARARGS, NULL},
{(char *) "virNodeGetInfo", libvirt_virNodeGetInfo, METH_VARARGS, NULL},
+ {(char *) "virNodeGetSecurityModel", libvirt_virNodeGetSecurityModel, METH_VARARGS, NULL},
+ {(char *) "virDomainGetSecurityLabel", libvirt_virDomainGetSecurityLabel, METH_VARARGS, NULL},
+#if LIBVIR_CHECK_VERSION(0, 9, 13)
+ {(char *) "virDomainGetSecurityLabelList", libvirt_virDomainGetSecurityLabelList, METH_VARARGS, NULL},
+#endif /* LIBVIR_CHECK_VERSION(0, 9, 13) */
{(char *) "virNodeGetCPUStats", libvirt_virNodeGetCPUStats, METH_VARARGS, NULL},
{(char *) "virNodeGetMemoryStats", libvirt_virNodeGetMemoryStats, METH_VARARGS, NULL},
{(char *) "virDomainGetUUID", libvirt_virDomainGetUUID, METH_VARARGS, NULL},
diff --git a/typewrappers.c b/typewrappers.c
index d6cbbf1..1622986 100644
--- a/typewrappers.c
+++ b/typewrappers.c
@@ -116,6 +116,15 @@ libvirt_constcharPtrWrap(const char *str)
return ret;
}
+PyObject *
+libvirt_boolWrap(int val)
+{
+ if (val)
+ Py_RETURN_TRUE;
+ else
+ Py_RETURN_FALSE;
+}
+
int
libvirt_intUnwrap(PyObject *obj, int *val)
{
diff --git a/typewrappers.h b/typewrappers.h
index d871d3f..04e364f 100644
--- a/typewrappers.h
+++ b/typewrappers.h
@@ -164,6 +164,7 @@ PyObject * libvirt_ulonglongWrap(unsigned long long val);
PyObject * libvirt_charPtrWrap(char *str);
PyObject * libvirt_charPtrSizeWrap(char *str, Py_ssize_t size);
PyObject * libvirt_constcharPtrWrap(const char *str);
+PyObject * libvirt_boolWrap(int val);
int libvirt_intUnwrap(PyObject *obj, int *val);
int libvirt_uintUnwrap(PyObject *obj, unsigned int *val);
int libvirt_longUnwrap(PyObject *obj, long *val);
--
1.8.3.1
11 years
[libvirt] [PATCH python] Avoid generating the migrate methods in multiple classes
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The python code generator tries to figure out what class a
method should be in by looking at the list of arguments for
any which are object types. Unfortunately missing break
statements meant that methods which have multiple object
arguments (eg migrate as a virDomainPtr followed by a
virConnectPtr) got added to multiple classes. The migrate
methods should only be visible in the virDomain class, and
the versions in the virConnect class have fubar arguments.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
generator.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/generator.py b/generator.py
index c769ed0..ab2a97f 100755
--- a/generator.py
+++ b/generator.py
@@ -1264,12 +1264,14 @@ def buildWrappers(module):
func = nameFixup(name, classe, type, file)
info = (0, func, name, ret, args, file, mod)
function_classes[classe].append(info)
+ break
elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \
and file != "python_accessor" and not name in function_skip_index_one:
found = 1
func = nameFixup(name, classe, type, file)
info = (1, func, name, ret, args, file, mod)
function_classes[classe].append(info)
+ break
if found == 1:
continue
func = nameFixup(name, "None", file, file)
--
1.8.3.1
11 years
[libvirt] virDomain{Attach, Detach, Update}DeviceFlags filesystem support for qemu driver
by Jesse Cook
It does not currently appear to be possible to attach/detach a filesystem
with kvm through the C API or virsh. Looking at
src/qemu/qemu_driver.c:qemuDomain{Attach,Detach,Update}Config,
VIR_DOMAIN_DEVICE_FS is not a case within the switch statement for
dev->type.
Is support for this planned for the near future or in progress? If not, how
much would have to be implemented outside these functions to add support
for attaching, detaching, and modifying filesystems? I would like to gauge
whether I should carve out time to add support, or work around it by using
disks in place of filesystems. Thanks!
--
Jesse J. Cook
Camber Corporation
Lead Software Developer
11 years
[libvirt] [libvirt-test-API][PATCH] Fix utils.exec_cmd output problem
by Jincheng Miao
The 'out' returned from exec_cmds is not 'None' type if stderr occurs, it is
because utils pass 'subprocess.PIPE' to stdout to open this subprocess.
"Similarly, to get anything other than None in the result tuple, you need to
give stdout=PIPE and/or stderr=PIPE too."
(see http://docs.python.org/2/library/subprocess.html#module-subprocess)
Finally, make out equals to err when stderr happened.
---
utils/utils.py | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/utils/utils.py b/utils/utils.py
index 147c1ef..2248ce1 100644
--- a/utils/utils.py
+++ b/utils/utils.py
@@ -404,14 +404,12 @@ def exec_cmd(command, sudo=False, cwd=None, infile=None, outfile=None, shell=Fal
command = ["sudo"] + command
if infile == None:
infile = subprocess.PIPE
- if outfile == None:
- outfile = subprocess.PIPE
p = subprocess.Popen(command, shell=shell, close_fds=True, cwd=cwd,
stdin=infile, stdout=outfile, stderr=subprocess.PIPE)
(out, err) = p.communicate(data)
if out == None:
- # Prevent splitlines() from barfing later on
- out = ""
+ # Because stderr is PIPE, err will not be None, and can be splitlines.
+ out = err
return (p.returncode, out.splitlines())
def remote_exec_pexpect(hostname, username, password, cmd):
--
1.8.3.1
11 years