libvirt_virDomainGetVcpus: add error handling, return -1 instead of None
libvirt_virDomainPinVcpu and libvirt_virDomainPinVcpuFlags:
check the type of argument
make use of libvirt_boolUnwrap
Set bitmap according to these values which are contained in given
argument of vcpu tuple and turn off these bit corresponding to
missing vcpus in argument tuple
The original way ignored the error info from PyTuple_GetItem
if index is out of range.
"IndexError: tuple index out of range"
The error message will only be raised on next command in interactive mode.
---
python/libvirt-override.c | 163 ++
1 file changed, 121 insertions(+), 42 deletions(-)
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 25f9d3f..81099b1 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -1333,9 +1333,11 @@ cleanup:
static PyObject *
libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED,
- PyObject *args) {
+ PyObject *args)
+{
virDomainPtr domain;
PyObject *pyobj_domain, *pyretval = NULL, *pycpuinfo = NULL, *pycpumap =
NULL;
+PyObject *error = NULL;
virNodeInfo nodeinfo;
virDomainInfo dominfo;
virVcpuInfoPtr cpuinfo = NULL;
@@ -1352,29 +1354,33 @@ libvirt_virDomainGetVcpus(PyObject *self
ATTRIBUTE_UNUSED,
i_retval = virNodeGetInfo(virDomainGetConnect(domain), &nodeinfo);
LIBVIRT_END_ALLOW_THREADS;
if (i_retval < 0)
-return VIR_PY_NONE;
+return VIR_PY_INT_FAIL;
LIBVIRT_BEGIN_ALLOW_THREADS;
i_retval = virDomainGetInfo(domain, &dominfo);
LIBVIRT_END_ALLOW_THREADS;
if (i_retval < 0)
-return VIR_PY_NONE;
+return VIR_PY_INT_FAIL;
if (VIR_ALLOC_N(cpuinfo, dominfo.nrVirtCpu) < 0)
-return VIR_PY_NONE;
+return PyErr_NoMemory();
cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
if (xalloc_oversized(dominfo.nrVirtCpu, cpumaplen) ||
-VIR_ALLOC_N(cpumap, dominfo.nrVirtCpu * cpumaplen) < 0)
+VIR_ALLOC_N(cpumap, dominfo.nrVirtCpu * cpumaplen) < 0) {
+error = PyErr_NoMemory();
goto cleanup;
+}
LIBVIRT_BEGIN_ALLOW_THREADS;
i_retval = virDomainGetVcpus(domain,
cpuinfo, dominfo.nrVirtCpu,
cpumap, cpumaplen);
LIBVIRT_END_ALLOW_THREADS;
-if (i_retval < 0)
+if (i_retval < 0) {
+error = VIR_PY_INT_FAIL;
goto cleanup;
+}
/* convert to a Python tuple of long objects */
if ((pyretval = PyTuple_New(2)) == NULL)
@@ -1386,13 +1392,35 @@ libvirt_virDomainGetVcpus(PyObject *self
ATTRIBUTE_UNUSED,
for (i = 0 ; i < dominfo.nrVirtCpu ; i++) {
PyObject *info = PyTuple_New(4);
+PyObject *item = NULL;
+
if (info == NULL)
goto cleanup;
-PyTuple_SetItem(info, 0, PyInt_FromLong((long)cpuinfo[i].number));
-PyTuple_SetItem(info, 1, PyInt_FromLong((long)cpuinfo[i].state));
-PyTuple_SetItem(info, 2, PyLong_FromLongLong((long
long)cpuinfo[i].cpuTime));
-PyTuple_SetItem(info, 3, PyInt_FromLong((long)cpuinfo[i].cpu));
-PyList_SetItem(pycpuinfo, i, info);
+
+if ((item = PyInt_FromLong((long)cpuinfo[i].number)) == NULL ||
+PyTuple_SetItem(info, 0, item) < 0)
+goto itemError;
+
+if ((item = PyInt_FromLong((long)cpuinfo[i].state)) == NULL ||
+PyTuple_SetItem(info, 1, item) < 0)
+goto itemError;
+
+if ((item = PyLong_FromLongLong((long long)cpuinfo[i].cpuTime)) ==
NULL ||
+PyTuple_SetItem(info, 2, item) < 0)
+goto itemError;
+
+if ((item = PyInt_FromLong((long)cpuinfo[i].cpu)) == NULL ||
+PyTuple_SetItem(info, 3, item) < 0)
+goto itemError;
+
+if (PyList_SetItem(pycpuinfo, i, info) < 0)
+goto itemError;
+
+continue;
+itemError:
+Py_DECREF(info);
+Py_XDECREF(item);
+goto cleanup;
}
for (i = 0 ; i < dominfo.nrVirtCpu ; i++) {
PyObject *info = PyTuple_New(VIR_NODEINFO_MAXCPUS(nodeinfo));
@@ -1400,36 +1428,48 @@ libvirt_virDomainGetVcpus(PyObject *self
ATTRIBUTE_UNUSED,
if (info == NULL)
goto cleanup;
for (j = 0 ; j < VIR_NODEINFO_MAXCPUS(nodeinfo) ; j++) {
-PyTuple_SetItem(info, j, PyBool_FromLong(VIR_CPU_USABLE(cpumap,
cpumaplen, i, j)));
+PyObject *item = NULL;
+if ((item = PyBool_FromLong(VIR_CPU_USABLE(cpumap, cpumaplen, i,
j))) == NULL ||
+PyTuple_SetItem(info, j, item) < 0) {
+Py_DECREF(info);
+Py_XDECREF(item);
+goto cleanup;
+}
+}
+if (PyList_SetItem(pycpumap, i, info) < 0) {
+Py_DECREF(info);
+goto cleanup;
}
-PyList_