[libvirt] [PATCH 1/2] python: cleanup vcpu related binding APIs

Guannan Ren gren at redhat.com
Tue Apr 17 17:45:05 UTC 2012


    *libvirt_virDomainGetVcpus: add error handling, return -1 instead of None
    *libvirt_virDomainPinVcpu and libvirt_virDomainPinVcpuFlags:
         make use of libvirt_boolUnwrap

         set vcpus which are list in tuple pycpumap, trun off the rest
         in cpumap. The original way ignored the error info from PyTuple_GetItem
         if pos is out of bounds. "IndexError: tuple index out of range"
         The error message will only be raised on next command in interactive mode.
---
 python/libvirt-override.c |  173 +++++++++++++++++++++++++++++---------------
 1 files changed, 114 insertions(+), 59 deletions(-)

diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 56f96ba..2788546 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)
@@ -1388,54 +1394,80 @@ libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED,
         PyObject *info = PyTuple_New(4);
         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 (PyTuple_SetItem(info, 0, PyInt_FromLong((long)cpuinfo[i].number)) < 0)
+        {
+            Py_DECREF(info);
+            goto cleanup;
+        }
+
+        if (PyTuple_SetItem(info, 1, PyInt_FromLong((long)cpuinfo[i].state)) < 0)
+        {
+            Py_DECREF(info);
+            goto cleanup;
+        }
+
+        if (PyTuple_SetItem(info, 2, PyLong_FromLongLong((long long)cpuinfo[i].cpuTime)) < 0)
+        {
+            Py_DECREF(info);
+            goto cleanup;
+        }
+
+        if (PyTuple_SetItem(info, 3, PyInt_FromLong((long)cpuinfo[i].cpu)) < 0)
+        {
+            Py_DECREF(info);
+            goto cleanup;
+        }
+        if (PyList_SetItem(pycpuinfo, i, info) < 0)
+            goto cleanup;
     }
+
     for (i = 0 ; i < dominfo.nrVirtCpu ; i++) {
         PyObject *info = PyTuple_New(VIR_NODEINFO_MAXCPUS(nodeinfo));
-        int j;
         if (info == NULL)
             goto cleanup;
+
+        int j;
         for (j = 0 ; j < VIR_NODEINFO_MAXCPUS(nodeinfo) ; j++) {
-            PyTuple_SetItem(info, j, PyBool_FromLong(VIR_CPU_USABLE(cpumap, cpumaplen, i, j)));
+            if (PyTuple_SetItem(info, j, PyBool_FromLong(VIR_CPU_USABLE(cpumap, cpumaplen, i, j))) < 0)
+            {
+                Py_DECREF(info);
+                goto cleanup;
+            }
         }
-        PyList_SetItem(pycpumap, i, info);
+        if (PyList_SetItem(pycpumap, i, info) < 0)
+            goto cleanup;
     }
-    PyTuple_SetItem(pyretval, 0, pycpuinfo);
-    PyTuple_SetItem(pyretval, 1, pycpumap);
+
+    if (PyTuple_SetItem(pyretval, 0, pycpuinfo) < 0)
+        goto cleanup;
+
+    if (PyTuple_SetItem(pyretval, 1, pycpumap) < 0)
+        goto cleanup;
 
     VIR_FREE(cpuinfo);
     VIR_FREE(cpumap);
 
     return pyretval;
 
- cleanup:
+cleanup:
     VIR_FREE(cpuinfo);
     VIR_FREE(cpumap);
-    /* NB, Py_DECREF is a badly defined macro, so we require
-     * braces here to avoid 'ambiguous else' warnings from
-     * the compiler.
-     * NB. this comment is true at of time of writing wrt to
-     * at least python2.5.
-     */
-    if (pyretval) { Py_DECREF(pyretval); }
-    if (pycpuinfo) { Py_DECREF(pycpuinfo); }
-    if (pycpumap) { Py_DECREF(pycpumap); }
-    return VIR_PY_NONE;
+    Py_XDECREF(pyretval);
+    Py_XDECREF(pycpuinfo);
+    Py_XDECREF(pycpumap);
+    return error;
 }
 
-
 static PyObject *
 libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED,
-                         PyObject *args) {
+                         PyObject *args)
+{
     virDomainPtr domain;
-    PyObject *pyobj_domain, *pycpumap, *truth;
+    PyObject *pyobj_domain, *pycpumap;
+    PyObject *ret = NULL;
     virNodeInfo nodeinfo;
     unsigned char *cpumap;
-    int cpumaplen, i, vcpu;
+    int cpumaplen, i, j, vcpu, tuple_size;
     int i_retval;
 
     if (!PyArg_ParseTuple(args, (char *)"OiO:virDomainPinVcpu",
@@ -1451,37 +1483,50 @@ libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED,
 
     cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
     if (VIR_ALLOC_N(cpumap, cpumaplen) < 0)
-        return VIR_PY_INT_FAIL;
+        return PyErr_NoMemory();
 
-    truth = PyBool_FromLong(1);
-    for (i = 0 ; i < VIR_NODEINFO_MAXCPUS(nodeinfo) ; i++) {
+    tuple_size = PyTuple_Size(pycpumap);
+    if (tuple_size == -1)
+        goto cleanup;
+
+    for (i = 0; i < tuple_size; i++) {
         PyObject *flag = PyTuple_GetItem(pycpumap, i);
-        if (flag == truth)
-            VIR_USE_CPU(cpumap, i);
-        else
-            VIR_UNUSE_CPU(cpumap, i);
+        bool b;
+
+        if ((!flag) || (libvirt_boolUnwrap(flag, &b) < 0))
+            goto cleanup;
+
+        (b) ? VIR_USE_CPU(cpumap, i) : VIR_UNUSE_CPU(cpumap, i);
     }
 
+    for (j = 0; j < VIR_NODEINFO_MAXCPUS(nodeinfo) - i; j++)
+        VIR_UNUSE_CPU(cpumap, i + j);
+
     LIBVIRT_BEGIN_ALLOW_THREADS;
     i_retval = virDomainPinVcpu(domain, vcpu, cpumap, cpumaplen);
     LIBVIRT_END_ALLOW_THREADS;
-    Py_DECREF(truth);
-    VIR_FREE(cpumap);
 
-    if (i_retval < 0)
-        return VIR_PY_INT_FAIL;
+    if (i_retval < 0) {
+        ret = VIR_PY_INT_FAIL;
+        goto cleanup;
+    }
+    ret = VIR_PY_INT_SUCCESS;
 
-    return VIR_PY_INT_SUCCESS;
+cleanup:
+    VIR_FREE(cpumap);
+    return ret;
 }
 
 static PyObject *
 libvirt_virDomainPinVcpuFlags(PyObject *self ATTRIBUTE_UNUSED,
-                              PyObject *args) {
+                              PyObject *args)
+{
     virDomainPtr domain;
-    PyObject *pyobj_domain, *pycpumap, *truth;
+    PyObject *pyobj_domain, *pycpumap;
+    PyObject *ret = NULL;
     virNodeInfo nodeinfo;
     unsigned char *cpumap;
-    int cpumaplen, i, vcpu;
+    int cpumaplen, i, j, vcpu, tuple_size;
     unsigned int flags;
     int i_retval;
 
@@ -1498,27 +1543,37 @@ libvirt_virDomainPinVcpuFlags(PyObject *self ATTRIBUTE_UNUSED,
 
     cpumaplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(nodeinfo));
     if (VIR_ALLOC_N(cpumap, cpumaplen) < 0)
-        return VIR_PY_INT_FAIL;
+        return PyErr_NoMemory();
+
+    tuple_size = PyTuple_Size(pycpumap);
+    if (tuple_size == -1)
+        goto cleanup;
 
-    truth = PyBool_FromLong(1);
-    for (i = 0 ; i < VIR_NODEINFO_MAXCPUS(nodeinfo) ; i++) {
+    for (i = 0; i < tuple_size; i++) {
         PyObject *flag = PyTuple_GetItem(pycpumap, i);
-        if (flag == truth)
-            VIR_USE_CPU(cpumap, i);
-        else
-            VIR_UNUSE_CPU(cpumap, i);
+        bool b;
+
+        if ((!flag) || (libvirt_boolUnwrap(flag, &b) < 0))
+            goto cleanup;
+
+        (b) ? VIR_USE_CPU(cpumap, i) : VIR_UNUSE_CPU(cpumap, i);
     }
 
+    for (j = 0; j < VIR_NODEINFO_MAXCPUS(nodeinfo) - i; j++)
+        VIR_UNUSE_CPU(cpumap, i + j);
+
     LIBVIRT_BEGIN_ALLOW_THREADS;
     i_retval = virDomainPinVcpuFlags(domain, vcpu, cpumap, cpumaplen, flags);
     LIBVIRT_END_ALLOW_THREADS;
-    Py_DECREF(truth);
-    VIR_FREE(cpumap);
-
-    if (i_retval < 0)
-        return VIR_PY_INT_FAIL;
+    if (i_retval < 0) {
+        ret = VIR_PY_INT_FAIL;
+        goto cleanup;
+    }
+    ret = VIR_PY_INT_SUCCESS;
 
-    return VIR_PY_INT_SUCCESS;
+cleanup:
+    VIR_FREE(cpumap);
+    return ret;
 }
 
 static PyObject *
-- 
1.7.7.5




More information about the libvir-list mailing list