[libvirt] [PATCH v1 01/37] viralloc: Report OOM error on failure

Michal Privoznik mprivozn at redhat.com
Thu Jul 4 12:06:24 UTC 2013


Similarly to VIR_STRDUP, we want the OOM error to be reported in
VIR_ALLOC and friends.
---
 po/POTFILES.in                  |   1 +
 python/libvirt-override.c       | 102 +++++++++----------
 src/conf/domain_conf.c          |   9 +-
 src/conf/network_conf.c         |  34 ++-----
 src/conf/node_device_conf.c     |   2 +-
 src/esx/esx_vi.c                |   2 +-
 src/lxc/lxc_process.c           |   4 +-
 src/security/security_manager.c |   4 +-
 src/security/security_selinux.c |   4 +-
 src/util/viralloc.c             | 165 ++++++++++++++++++++++++++-----
 src/util/viralloc.h             | 213 ++++++++++++++++++++++++++++++++--------
 src/util/virbuffer.c            |   8 +-
 src/util/vircgroup.c            |   2 +-
 src/util/virerror.c             |   4 +-
 src/util/virpci.c               |   2 +-
 src/util/virthreadpthread.c     |   2 +-
 tests/commandhelper.c           |   1 +
 tests/networkxml2conftest.c     |   2 +
 tests/test_conf.c               |   2 +-
 tests/xmconfigtest.c            |   2 +
 20 files changed, 401 insertions(+), 164 deletions(-)

diff --git a/po/POTFILES.in b/po/POTFILES.in
index af7fd7f..0b65765 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -141,6 +141,7 @@ src/test/test_driver.c
 src/uml/uml_conf.c
 src/uml/uml_driver.c
 src/util/iohelper.c
+src/util/viralloc.c
 src/util/viraudit.c
 src/util/virauth.c
 src/util/virauthconfig.c
diff --git a/python/libvirt-override.c b/python/libvirt-override.c
index 5c5586d..6b6e77b 100644
--- a/python/libvirt-override.c
+++ b/python/libvirt-override.c
@@ -171,7 +171,7 @@ setPyVirTypedParameter(PyObject *info,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(ret, size) < 0) {
+    if (VIR_ALLOC_N_QUIET(ret, size) < 0) {
         PyErr_NoMemory();
         return NULL;
     }
@@ -511,7 +511,7 @@ libvirt_virDomainBlockStatsFlags(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -577,7 +577,7 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
 
         sumparams = nparams * MIN(ncpus, 128);
 
-        if (VIR_ALLOC_N(params, sumparams) < 0) {
+        if (VIR_ALLOC_N_QUIET(params, sumparams) < 0) {
             error = PyErr_NoMemory();
             goto error;
         }
@@ -629,7 +629,7 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
         if (nparams) {
             sumparams = nparams;
 
-            if (VIR_ALLOC_N(params, nparams) < 0) {
+            if (VIR_ALLOC_N_QUIET(params, nparams) < 0) {
                 error = PyErr_NoMemory();
                 goto error;
             }
@@ -809,7 +809,7 @@ libvirt_virDomainGetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -857,7 +857,7 @@ libvirt_virDomainGetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -917,7 +917,7 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -993,7 +993,7 @@ libvirt_virDomainSetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1067,7 +1067,7 @@ libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1127,7 +1127,7 @@ libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1187,7 +1187,7 @@ libvirt_virDomainSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1247,7 +1247,7 @@ libvirt_virDomainGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1307,7 +1307,7 @@ libvirt_virDomainSetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1367,7 +1367,7 @@ libvirt_virDomainGetNumaParameters(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1428,7 +1428,7 @@ libvirt_virDomainSetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1489,7 +1489,7 @@ libvirt_virDomainGetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1535,12 +1535,12 @@ libvirt_virDomainGetVcpus(PyObject *self ATTRIBUTE_UNUSED,
     if (i_retval < 0)
         return VIR_PY_INT_FAIL;
 
-    if (VIR_ALLOC_N(cpuinfo, dominfo.nrVirtCpu) < 0)
+    if (VIR_ALLOC_N_QUIET(cpuinfo, dominfo.nrVirtCpu) < 0)
         return PyErr_NoMemory();
 
     cpumaplen = VIR_CPU_MAPLEN(cpunum);
     if (xalloc_oversized(dominfo.nrVirtCpu, cpumaplen) ||
-        VIR_ALLOC_N(cpumap, dominfo.nrVirtCpu * cpumaplen) < 0) {
+        VIR_ALLOC_N_QUIET(cpumap, dominfo.nrVirtCpu * cpumaplen) < 0) {
         error = PyErr_NoMemory();
         goto cleanup;
     }
@@ -1662,7 +1662,7 @@ libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED,
     }
 
     cpumaplen = VIR_CPU_MAPLEN(cpunum);
-    if (VIR_ALLOC_N(cpumap, cpumaplen) < 0)
+    if (VIR_ALLOC_N_QUIET(cpumap, cpumaplen) < 0)
         return PyErr_NoMemory();
 
     for (i = 0; i < tuple_size; i++) {
@@ -1726,7 +1726,7 @@ libvirt_virDomainPinVcpuFlags(PyObject *self ATTRIBUTE_UNUSED,
     }
 
     cpumaplen = VIR_CPU_MAPLEN(cpunum);
-    if (VIR_ALLOC_N(cpumap, cpumaplen) < 0)
+    if (VIR_ALLOC_N_QUIET(cpumap, cpumaplen) < 0)
         return PyErr_NoMemory();
 
     for (i = 0; i < tuple_size; i++) {
@@ -1786,7 +1786,7 @@ libvirt_virDomainGetVcpuPinInfo(PyObject *self ATTRIBUTE_UNUSED,
 
     cpumaplen = VIR_CPU_MAPLEN(cpunum);
     if (xalloc_oversized(dominfo.nrVirtCpu, cpumaplen) ||
-        VIR_ALLOC_N(cpumaps, dominfo.nrVirtCpu * cpumaplen) < 0)
+        VIR_ALLOC_N_QUIET(cpumaps, dominfo.nrVirtCpu * cpumaplen) < 0)
         goto cleanup;
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -1854,7 +1854,7 @@ libvirt_virDomainPinEmulator(PyObject *self ATTRIBUTE_UNUSED,
     if ((tuple_size = PyTuple_Size(pycpumap)) == -1)
         return NULL;
 
-    if (VIR_ALLOC_N(cpumap, cpumaplen) < 0)
+    if (VIR_ALLOC_N_QUIET(cpumap, cpumaplen) < 0)
         return PyErr_NoMemory();
 
     for (i = 0; i < tuple_size; i++) {
@@ -1913,7 +1913,7 @@ libvirt_virDomainGetEmulatorPinInfo(PyObject *self ATTRIBUTE_UNUSED,
 
     cpumaplen = VIR_CPU_MAPLEN(cpunum);
 
-    if (VIR_ALLOC_N(cpumap, cpumaplen) < 0)
+    if (VIR_ALLOC_N_QUIET(cpumap, cpumaplen) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -2188,7 +2188,7 @@ libvirt_virConnectOpenAuth(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) {
     auth.ncredtype = PyList_Size(pycredtype);
     if (auth.ncredtype) {
         int i;
-        if (VIR_ALLOC_N(auth.credtype, auth.ncredtype) < 0)
+        if (VIR_ALLOC_N_QUIET(auth.credtype, auth.ncredtype) < 0)
             return VIR_PY_NONE;
         for (i = 0; i < auth.ncredtype; i++) {
             PyObject *val;
@@ -2316,7 +2316,7 @@ libvirt_virConnectListDomainsID(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(ids, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(ids, c_retval) < 0)
             return VIR_PY_NONE;
 
         LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -2407,7 +2407,7 @@ libvirt_virConnectListDefinedDomains(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListDefinedDomains(conn, names, c_retval);
@@ -2454,7 +2454,7 @@ libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return PyErr_NoMemory();
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virDomainSnapshotListNames(dom, names, c_retval, flags);
@@ -2554,7 +2554,7 @@ libvirt_virDomainSnapshotListChildrenNames(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return PyErr_NoMemory();
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virDomainSnapshotListChildrenNames(snap, names, c_retval,
@@ -2886,7 +2886,7 @@ libvirt_virConnectListNetworks(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListNetworks(conn, names, c_retval);
@@ -2931,7 +2931,7 @@ libvirt_virConnectListDefinedNetworks(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListDefinedNetworks(conn, names, c_retval);
@@ -3139,7 +3139,7 @@ libvirt_virNodeGetCellsFreeMemory(PyObject *self ATTRIBUTE_UNUSED, PyObject *arg
         return VIR_PY_NONE;
 
     conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn);
-    if (VIR_ALLOC_N(freeMems, maxCells) < 0)
+    if (VIR_ALLOC_N_QUIET(freeMems, maxCells) < 0)
         return VIR_PY_NONE;
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -3183,7 +3183,7 @@ libvirt_virNodeGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
         return VIR_PY_NONE;
 
     if (nparams) {
-        if (VIR_ALLOC_N(stats, nparams) < 0)
+        if (VIR_ALLOC_N_QUIET(stats, nparams) < 0)
             return PyErr_NoMemory();
 
         LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -3246,7 +3246,7 @@ libvirt_virNodeGetMemoryStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)
         return VIR_PY_NONE;
 
     if (nparams) {
-        if (VIR_ALLOC_N(stats, nparams) < 0)
+        if (VIR_ALLOC_N_QUIET(stats, nparams) < 0)
             return PyErr_NoMemory();
 
         LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -3306,7 +3306,7 @@ libvirt_virConnectListStoragePools(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListStoragePools(conn, names, c_retval);
@@ -3359,7 +3359,7 @@ libvirt_virConnectListDefinedStoragePools(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListDefinedStoragePools(conn, names, c_retval);
@@ -3458,7 +3458,7 @@ libvirt_virStoragePoolListVolumes(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virStoragePoolListVolumes(pool, names, c_retval);
@@ -3719,7 +3719,7 @@ libvirt_virNodeListDevices(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virNodeListDevices(conn, cap, names, c_retval, flags);
@@ -3809,7 +3809,7 @@ libvirt_virNodeDeviceListCaps(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virNodeDeviceListCaps(dev, names, c_retval);
@@ -3928,7 +3928,7 @@ libvirt_virConnectListSecrets(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(uuids, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(uuids, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListSecrets(conn, uuids, c_retval);
@@ -4147,7 +4147,7 @@ libvirt_virConnectListNWFilters(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(uuids, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(uuids, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListNWFilters(conn, uuids, c_retval);
@@ -4238,7 +4238,7 @@ libvirt_virConnectListInterfaces(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListInterfaces(conn, names, c_retval);
@@ -4292,7 +4292,7 @@ libvirt_virConnectListDefinedInterfaces(PyObject *self ATTRIBUTE_UNUSED,
         return VIR_PY_NONE;
 
     if (c_retval) {
-        if (VIR_ALLOC_N(names, c_retval) < 0)
+        if (VIR_ALLOC_N_QUIET(names, c_retval) < 0)
             return VIR_PY_NONE;
         LIBVIRT_BEGIN_ALLOW_THREADS;
         c_retval = virConnectListDefinedInterfaces(conn, names, c_retval);
@@ -4392,7 +4392,7 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED,
         int i;
 
         ncpus = PyList_Size(list);
-        if (VIR_ALLOC_N(xmlcpus, ncpus) < 0)
+        if (VIR_ALLOC_N_QUIET(xmlcpus, ncpus) < 0)
             return VIR_PY_INT_FAIL;
 
         for (i = 0; i < ncpus; i++) {
@@ -4578,7 +4578,7 @@ libvirt_virDomainSetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -4639,7 +4639,7 @@ libvirt_virDomainGetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -4682,7 +4682,7 @@ libvirt_virDomainGetDiskErrors(PyObject *self ATTRIBUTE_UNUSED,
     ndisks = count;
 
     if (ndisks) {
-        if (VIR_ALLOC_N(disks, ndisks) < 0)
+        if (VIR_ALLOC_N_QUIET(disks, ndisks) < 0)
             return VIR_PY_NONE;
 
         LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -6503,7 +6503,7 @@ libvirt_virStreamRecv(PyObject *self ATTRIBUTE_UNUSED,
     }
     stream = PyvirStream_Get(pyobj_stream);
 
-    if (VIR_ALLOC_N(buf, nbytes+1 > 0 ? nbytes+1 : 1) < 0)
+    if (VIR_ALLOC_N_QUIET(buf, nbytes+1 > 0 ? nbytes+1 : 1) < 0)
         return VIR_PY_NONE;
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -6729,7 +6729,7 @@ libvirt_virDomainBlockPeek(PyObject *self ATTRIBUTE_UNUSED,
 
     domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
 
-    if (VIR_ALLOC_N(buf, size) < 0)
+    if (VIR_ALLOC_N_QUIET(buf, size) < 0)
         return VIR_PY_NONE;
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -6766,7 +6766,7 @@ libvirt_virDomainMemoryPeek(PyObject *self ATTRIBUTE_UNUSED,
 
     domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain);
 
-    if (VIR_ALLOC_N(buf, size) < 0)
+    if (VIR_ALLOC_N_QUIET(buf, size) < 0)
         return VIR_PY_NONE;
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -6826,7 +6826,7 @@ libvirt_virNodeSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
         return NULL;
     }
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
@@ -6886,7 +6886,7 @@ libvirt_virNodeGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED,
     if (!nparams)
         return PyDict_New();
 
-    if (VIR_ALLOC_N(params, nparams) < 0)
+    if (VIR_ALLOC_N_QUIET(params, nparams) < 0)
         return PyErr_NoMemory();
 
     LIBVIRT_BEGIN_ALLOW_THREADS;
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index f80b690..921a4f6 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2750,8 +2750,8 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
         /* create the serial port definition from the console definition */
         if (def->nserials == 0) {
             if (VIR_APPEND_ELEMENT(def->serials, def->nserials,
-                                   def->consoles[0]) < 0)
-                goto no_memory;
+                                   def->consoles[0], true) < 0)
+                return -1;
 
             /* modify it to be a serial port */
             def->serials[0]->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
@@ -10435,9 +10435,8 @@ virDomainDefMaybeAddController(virDomainDefPtr def,
         cont->opts.vioserial.vectors = -1;
     }
 
-    if (VIR_APPEND_ELEMENT(def->controllers, def->ncontrollers, cont) < 0) {
+    if (VIR_APPEND_ELEMENT(def->controllers, def->ncontrollers, cont, true) < 0) {
         VIR_FREE(cont);
-        virReportOOMError();
         return -1;
     }
 
@@ -11907,7 +11906,7 @@ virDomainDefParseXML(xmlDocPtr xml,
         if (VIR_INSERT_ELEMENT_INPLACE(def->videos,
                                        ii,
                                        def->nvideos,
-                                       video) < 0) {
+                                       video, false) < 0) {
             virDomainVideoDefFree(video);
             goto error;
         }
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 64fd581..d6799d2 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -3414,10 +3414,8 @@ virNetworkDefUpdateIPDHCPHost(virNetworkDefPtr def,
         if (VIR_INSERT_ELEMENT(ipdef->hosts,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
                                ? 0 : ipdef->nhosts,
-                               ipdef->nhosts, host) < 0) {
-            virReportOOMError();
+                               ipdef->nhosts, host, true) < 0)
             goto cleanup;
-        }
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         if (virNetworkDHCPHostDefParseXML(def->name, ipdef,
@@ -3520,11 +3518,8 @@ virNetworkDefUpdateIPDHCPRange(virNetworkDefPtr def,
         if (VIR_INSERT_ELEMENT(ipdef->ranges,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
                                ? 0 : ipdef->nranges,
-                               ipdef->nranges, range) < 0) {
-            virReportOOMError();
+                               ipdef->nranges, range, true) < 0)
             goto cleanup;
-        }
-
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         if (ii == ipdef->nranges) {
@@ -3615,11 +3610,8 @@ virNetworkDefUpdateForwardInterface(virNetworkDefPtr def,
         if (VIR_INSERT_ELEMENT(def->forward.ifs,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
                                ? 0 : def->forward.nifs,
-                               def->forward.nifs, iface) < 0) {
-            virReportOOMError();
+                               def->forward.nifs, iface, true) < 0)
             goto cleanup;
-        }
-
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         if (ii == def->forward.nifs) {
@@ -3742,11 +3734,8 @@ virNetworkDefUpdatePortGroup(virNetworkDefPtr def,
         if (VIR_INSERT_ELEMENT(def->portGroups,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
                                ? 0 : def->nPortGroups,
-                               def->nPortGroups, portgroup) < 0) {
-            virReportOOMError();
+                               def->nPortGroups, portgroup, true) < 0)
             goto cleanup;
-        }
-
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         /* remove it */
@@ -3825,11 +3814,8 @@ virNetworkDefUpdateDNSHost(virNetworkDefPtr def,
         /* add to beginning/end of list */
         if (VIR_INSERT_ELEMENT(dns->hosts,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
-                               ? 0 : dns->nhosts, dns->nhosts, host) < 0) {
-            virReportOOMError();
+                               ? 0 : dns->nhosts, dns->nhosts, host, true) < 0)
             goto cleanup;
-        }
-
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         if (foundCt == 0) {
@@ -3913,11 +3899,8 @@ virNetworkDefUpdateDNSSrv(virNetworkDefPtr def,
         /* add to beginning/end of list */
         if (VIR_INSERT_ELEMENT(dns->srvs,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
-                               ? 0 : dns->nsrvs, dns->nsrvs, srv) < 0) {
-            virReportOOMError();
+                               ? 0 : dns->nsrvs, dns->nsrvs, srv, true) < 0)
             goto cleanup;
-        }
-
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         if (foundCt == 0) {
@@ -3995,11 +3978,8 @@ virNetworkDefUpdateDNSTxt(virNetworkDefPtr def,
         /* add to beginning/end of list */
         if (VIR_INSERT_ELEMENT(dns->txts,
                                command == VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST
-                               ? 0 : dns->ntxts, dns->ntxts, txt) < 0) {
-            virReportOOMError();
+                               ? 0 : dns->ntxts, dns->ntxts, txt, true) < 0)
             goto cleanup;
-        }
-
     } else if (command == VIR_NETWORK_UPDATE_COMMAND_DELETE) {
 
         if (foundIdx == dns->ntxts) {
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index 3209604..7406652 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -1025,7 +1025,7 @@ virNodeDevCapPciDevIommuGroupParseXML(xmlXPathContextPtr ctxt,
         pciAddr->function = addr.function;
         if (VIR_APPEND_ELEMENT(data->pci_dev.iommuGroupDevices,
                                data->pci_dev.nIommuGroupDevices,
-                               pciAddr) < 0) {
+                               pciAddr, false) < 0) {
             virReportOOMError();
             goto cleanup;
         }
diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 8dc2592..39420b6 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -1750,7 +1750,7 @@ esxVI_Alloc(void **ptrptr, size_t size)
         return -1;
     }
 
-    if (virAllocN(ptrptr, size, 1) < 0) {
+    if (virAllocN(ptrptr, size, 1, false, 0, NULL, NULL, 0) < 0) {
         virReportOOMError();
         return -1;
     }
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 990decb..01e35c4 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -1003,8 +1003,8 @@ virLXCProcessEnsureRootFS(virDomainObjPtr vm)
     if (VIR_INSERT_ELEMENT(vm->def->fss,
                            0,
                            vm->def->nfss,
-                           root) < 0)
-        goto no_memory;
+                           root, true) < 0)
+        goto error;
 
     return 0;
 
diff --git a/src/security/security_manager.c b/src/security/security_manager.c
index f7c5c2e..f5ea73a 100644
--- a/src/security/security_manager.c
+++ b/src/security/security_manager.c
@@ -487,10 +487,8 @@ int virSecurityManagerGenLabel(virSecurityManagerPtr mgr,
             /* The seclabel must be added to @vm prior calling domainGenSecurityLabel
              * which may require seclabel to be presented already */
             if (generated &&
-                VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel) < 0) {
-                virReportOOMError();
+                VIR_APPEND_ELEMENT(vm->seclabels, vm->nseclabels, seclabel, true) < 0)
                 goto cleanup;
-            }
 
             if (sec_managers[i]->drv->domainGenSecurityLabel(sec_managers[i], vm) < 0) {
                 if (VIR_DELETE_ELEMENT(vm->seclabels,
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 7802dda..8842d85 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1227,8 +1227,8 @@ virSecuritySELinuxSetSecurityFileLabel(virDomainDiskDefPtr disk,
         if (!disk_seclabel)
             return -1;
         disk_seclabel->norelabel = true;
-        if (VIR_APPEND_ELEMENT(disk->seclabels, disk->nseclabels, disk_seclabel) < 0) {
-            virReportOOMError();
+        if (VIR_APPEND_ELEMENT(disk->seclabels, disk->nseclabels,
+                               disk_seclabel, true) < 0) {
             virSecurityDeviceLabelDefFree(disk_seclabel);
             return -1;
         }
diff --git a/src/util/viralloc.c b/src/util/viralloc.c
index 8d6a7e6..16afac7 100644
--- a/src/util/viralloc.c
+++ b/src/util/viralloc.c
@@ -25,6 +25,9 @@
 
 #include "viralloc.h"
 #include "virlog.h"
+#include "virerror.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
 
 #if TEST_OOM
 static int testMallocNext = 0;
@@ -105,14 +108,26 @@ void virAllocTestHook(void (*func)(int, void*) ATTRIBUTE_UNUSED,
  * virAlloc:
  * @ptrptr: pointer to pointer for address of allocated memory
  * @size: number of bytes to allocate
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
  *
  * Allocate  'size' bytes of memory. Return the address of the
  * allocated memory in 'ptrptr'. The newly allocated memory is
- * filled with zeros.
+ * filled with zeros. In case of OOM error and @report is true,
+ * the error is reported.
  *
  * Returns -1 on failure to allocate, zero on success
  */
-int virAlloc(void *ptrptr, size_t size)
+int virAlloc(void *ptrptr,
+             size_t size,
+             bool report,
+             int domcode,
+             const char *filename,
+             const char *funcname,
+             size_t linenr)
 {
 #if TEST_OOM
     if (virAllocTestFail()) {
@@ -122,8 +137,11 @@ int virAlloc(void *ptrptr, size_t size)
 #endif
 
     *(void **)ptrptr = calloc(1, size);
-    if (*(void **)ptrptr == NULL)
+    if (*(void **)ptrptr == NULL) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         return -1;
+    }
     return 0;
 }
 
@@ -132,15 +150,28 @@ int virAlloc(void *ptrptr, size_t size)
  * @ptrptr: pointer to pointer for address of allocated memory
  * @size: number of bytes to allocate
  * @count: number of elements to allocate
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
  *
  * Allocate an array of memory 'count' elements long,
  * each with 'size' bytes. Return the address of the
  * allocated memory in 'ptrptr'.  The newly allocated
- * memory is filled with zeros.
+ * memory is filled with zeros. In case of OOM error
+ * and @report is true, the error is reported.
  *
  * Returns -1 on failure to allocate, zero on success
  */
-int virAllocN(void *ptrptr, size_t size, size_t count)
+int virAllocN(void *ptrptr,
+              size_t size,
+              size_t count,
+              bool report,
+              int domcode,
+              const char *filename,
+              const char *funcname,
+              size_t linenr)
 {
 #if TEST_OOM
     if (virAllocTestFail()) {
@@ -150,8 +181,11 @@ int virAllocN(void *ptrptr, size_t size, size_t count)
 #endif
 
     *(void**)ptrptr = calloc(count, size);
-    if (*(void**)ptrptr == NULL)
+    if (*(void**)ptrptr == NULL) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         return -1;
+    }
     return 0;
 }
 
@@ -160,16 +194,29 @@ int virAllocN(void *ptrptr, size_t size, size_t count)
  * @ptrptr: pointer to pointer for address of allocated memory
  * @size: number of bytes to allocate
  * @count: number of elements in array
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
  *
  * Resize the block of memory in 'ptrptr' to be an array of
  * 'count' elements, each 'size' bytes in length. Update 'ptrptr'
  * with the address of the newly allocated memory. On failure,
  * 'ptrptr' is not changed and still points to the original memory
  * block. Any newly allocated memory in 'ptrptr' is uninitialized.
+ * In case of OOM error and @report is true, the error is reported.
  *
  * Returns -1 on failure to allocate, zero on success
  */
-int virReallocN(void *ptrptr, size_t size, size_t count)
+int virReallocN(void *ptrptr,
+                size_t size,
+                size_t count,
+                bool report,
+                int domcode,
+                const char *filename,
+                const char *funcname,
+                size_t linenr)
 {
     void *tmp;
 #if TEST_OOM
@@ -178,12 +225,17 @@ int virReallocN(void *ptrptr, size_t size, size_t count)
 #endif
 
     if (xalloc_oversized(count, size)) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         errno = ENOMEM;
         return -1;
     }
     tmp = realloc(*(void**)ptrptr, size * count);
-    if (!tmp && (size * count))
+    if (!tmp && (size * count)) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         return -1;
+    }
     *(void**)ptrptr = tmp;
     return 0;
 }
@@ -194,24 +246,41 @@ int virReallocN(void *ptrptr, size_t size, size_t count)
  * @size: number of bytes per element
  * @countptr: pointer to number of elements in array
  * @add: number of elements to add
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
  *
  * Resize the block of memory in 'ptrptr' to be an array of
  * '*countptr' + 'add' elements, each 'size' bytes in length.
  * Update 'ptrptr' and 'countptr'  with the details of the newly
  * allocated memory. On failure, 'ptrptr' and 'countptr' are not
  * changed. Any newly allocated memory in 'ptrptr' is zero-filled.
+ * In case of OOM error and @report is true, the error is reported.
  *
  * Returns -1 on failure to allocate, zero on success
  */
-int virExpandN(void *ptrptr, size_t size, size_t *countptr, size_t add)
+int virExpandN(void *ptrptr,
+               size_t size,
+               size_t *countptr,
+               size_t add,
+               bool report,
+               int domcode,
+               const char *filename,
+               const char *funcname,
+               size_t linenr)
 {
     int ret;
 
     if (*countptr + add < *countptr) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         errno = ENOMEM;
         return -1;
     }
-    ret = virReallocN(ptrptr, size, *countptr + add);
+    ret = virReallocN(ptrptr, size, *countptr + add, report,
+                      domcode, filename, funcname, linenr);
     if (ret == 0) {
         memset(*(char **)ptrptr + (size * *countptr), 0, size * add);
         *countptr += add;
@@ -226,22 +295,38 @@ int virExpandN(void *ptrptr, size_t size, size_t *countptr, size_t add)
  * @allocptr: pointer to number of elements allocated in array
  * @count: number of elements currently used in array
  * @add: minimum number of additional elements to support in array
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
  *
  * If 'count' + 'add' is larger than '*allocptr', then resize the
  * block of memory in 'ptrptr' to be an array of at least 'count' +
  * 'add' elements, each 'size' bytes in length. Update 'ptrptr' and
  * 'allocptr' with the details of the newly allocated memory. On
  * failure, 'ptrptr' and 'allocptr' are not changed. Any newly
- * allocated memory in 'ptrptr' is zero-filled.
+ * allocated memory in 'ptrptr' is zero-filled. In case of OOM error
+ * and @report is true, the error is reported.
  *
  * Returns -1 on failure to allocate, zero on success
  */
-int virResizeN(void *ptrptr, size_t size, size_t *allocptr, size_t count,
-               size_t add)
+int virResizeN(void *ptrptr,
+               size_t size,
+               size_t *allocptr,
+               size_t count,
+               size_t add,
+               bool report,
+               int domcode,
+               const char *filename,
+               const char *funcname,
+               size_t linenr)
 {
     size_t delta;
 
     if (count + add < count) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         errno = ENOMEM;
         return -1;
     }
@@ -251,7 +336,8 @@ int virResizeN(void *ptrptr, size_t size, size_t *allocptr, size_t count,
     delta = count + add - *allocptr;
     if (delta < *allocptr / 2)
         delta = *allocptr / 2;
-    return virExpandN(ptrptr, size, allocptr, delta);
+    return virExpandN(ptrptr, size, allocptr, delta, report,
+                      domcode, filename, funcname, linenr);
 }
 
 /**
@@ -270,7 +356,8 @@ int virResizeN(void *ptrptr, size_t size, size_t *allocptr, size_t count,
 void virShrinkN(void *ptrptr, size_t size, size_t *countptr, size_t toremove)
 {
     if (toremove < *countptr)
-        ignore_value(virReallocN(ptrptr, size, *countptr -= toremove));
+        ignore_value(virReallocN(ptrptr, size, *countptr -= toremove,
+                                 false, 0, NULL, NULL, 0));
     else {
         virFree(ptrptr);
         *countptr = 0;
@@ -293,6 +380,11 @@ void virShrinkN(void *ptrptr, size_t size, size_t *countptr, size_t toremove)
  * @inPlace:  false if we should expand the allocated memory before
  *            moving, true if we should assume someone else *has
  *            already* done that.
+ * @report:   whether to report OOM error, if there is one
+ * @domcode:  error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr:   caller's line number
  *
  * Re-allocate an array of *countptr elements, each sizeof(*ptrptr) bytes
  * long, to be *countptr+add elements long, then appropriately move
@@ -301,7 +393,8 @@ void virShrinkN(void *ptrptr, size_t size, size_t *countptr, size_t toremove)
  * allocated memory in *ptrptr and the new size in *countptr.  If
  * newelems is NULL, the new elements at ptrptr[at] are instead filled
  * with zero.  at must be between [0,*countptr], except that -1 is
- * treated the same as *countptr for convenience.
+ * treated the same as *countptr for convenience. In case of OOM error
+ * and @report is true, the error is reported.
  *
  * Returns -1 on failure, 0 on success
  */
@@ -309,19 +402,26 @@ int
 virInsertElementsN(void *ptrptr, size_t size, size_t at,
                    size_t *countptr,
                    size_t add, void *newelems,
-                   bool clearOriginal, bool inPlace)
+                   bool clearOriginal, bool inPlace,
+                   bool report,
+                   int domcode,
+                   const char *filename,
+                   const char *funcname,
+                   size_t linenr)
 {
     if (at == -1) {
         at = *countptr;
     } else if (at > *countptr) {
-        VIR_WARN("out of bounds index - count %zu at %zu add %zu",
-                 *countptr, at, add);
+        virReportError(VIR_ERR_INTERNAL_ERROR,
+                       _("out of bounds index - count %zu at %zu add %zu"),
+                       *countptr, at, add);
         return -1;
     }
 
     if (inPlace) {
         *countptr += add;
-    } else if (virExpandN(ptrptr, size, countptr, add) < 0) {
+    } else if (virExpandN(ptrptr, size, countptr, add, report,
+                          domcode, filename, funcname, linenr) < 0) {
         return -1;
     }
 
@@ -397,6 +497,11 @@ virDeleteElementsN(void *ptrptr, size_t size, size_t at,
  * @struct_size: size of initial struct
  * @element_size: size of array elements
  * @count: number of array elements to allocate
+ * @report: whether to report OOM error, if there is one
+ * @domcode: error domain code
+ * @filename: caller's filename
+ * @funcname: caller's funcname
+ * @linenr: caller's line number
  *
  * Allocate struct_size bytes plus an array of 'count' elements, each
  * of size element_size.  This sort of allocation is useful for
@@ -405,11 +510,20 @@ virDeleteElementsN(void *ptrptr, size_t size, size_t at,
  * The caller of this type of API is expected to know the length of
  * the array that will be returned and allocate a suitable buffer to
  * contain the returned data.  C99 refers to these variable length
- * objects as structs containing flexible array members.
+ * objects as structs containing flexible array members. In case of
+ * OOM error and @report is true, the error is reported.
  *
  * Returns -1 on failure, 0 on success
  */
-int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, size_t count)
+int virAllocVar(void *ptrptr,
+                size_t struct_size,
+                size_t element_size,
+                size_t count,
+                bool report,
+                int domcode,
+                const char *filename,
+                const char *funcname,
+                size_t linenr)
 {
     size_t alloc_size = 0;
 
@@ -419,14 +533,19 @@ int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, size_t co
 #endif
 
     if (VIR_ALLOC_VAR_OVERSIZED(struct_size, count, element_size)) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         errno = ENOMEM;
         return -1;
     }
 
     alloc_size = struct_size + (element_size * count);
     *(void **)ptrptr = calloc(1, alloc_size);
-    if (*(void **)ptrptr == NULL)
+    if (*(void **)ptrptr == NULL) {
+        if (report)
+            virReportOOMErrorFull(domcode, filename, funcname, linenr);
         return -1;
+    }
     return 0;
 }
 
diff --git a/src/util/viralloc.h b/src/util/viralloc.h
index 35d3a37..f0dba49 100644
--- a/src/util/viralloc.h
+++ b/src/util/viralloc.h
@@ -46,30 +46,36 @@
 
 
 /* Don't call these directly - use the macros below */
-int virAlloc(void *ptrptr, size_t size) ATTRIBUTE_RETURN_CHECK
-    ATTRIBUTE_NONNULL(1);
-int virAllocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK
-    ATTRIBUTE_NONNULL(1);
-int virReallocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK
-    ATTRIBUTE_NONNULL(1);
-int virExpandN(void *ptrptr, size_t size, size_t *count, size_t add)
+int virAlloc(void *ptrptr, size_t size, bool report, int domcode,
+             const char *filename, const char *funcname, size_t linenr)
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+int virAllocN(void *ptrptr, size_t size, size_t count, bool report, int domcode,
+              const char *filename, const char *funcname, size_t linenr)
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+int virReallocN(void *ptrptr, size_t size, size_t count, bool report, int domcode,
+                const char *filename, const char *funcname, size_t linenr)
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+int virExpandN(void *ptrptr, size_t size, size_t *count, size_t add, bool report,
+               int domcode, const char *filename, const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
-int virResizeN(void *ptrptr, size_t size, size_t *alloc, size_t count,
-               size_t desired)
+int virResizeN(void *ptrptr, size_t size, size_t *alloc, size_t count, size_t desired,
+               bool report, int domcode, const char *filename,
+               const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
 void virShrinkN(void *ptrptr, size_t size, size_t *count, size_t toremove)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3);
 int virInsertElementsN(void *ptrptr, size_t size, size_t at, size_t *countptr,
                        size_t add, void *newelem,
-                       bool clearOriginal, bool inPlace)
+                       bool clearOriginal, bool inPlace, bool report, int domcode,
+                       const char *filename, const char *funcname, size_t linenr)
     ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
 int virDeleteElementsN(void *ptrptr, size_t size, size_t at, size_t *countptr,
                        size_t toremove, bool inPlace)
     ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4);
-int virAllocVar(void *ptrptr,
-                size_t struct_size,
-                size_t element_size,
-                size_t count) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
+int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, size_t count,
+                bool report, int domcode, const char *filename,
+                const char *funcname, size_t linenr)
+    ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1);
 void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
 
 /**
@@ -82,9 +88,24 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * This macro is safe to use on arguments with side effects.
  *
+ * Returns -1 on failure (with OOM error reported), 0 on success
+ */
+# define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr)), true, VIR_FROM_THIS, \
+                                 __FILE__, __FUNCTION__, __LINE__)
+
+/**
+ * VIR_ALLOC_QUIET:
+ * @ptr: pointer to hold address of allocated memory
+ *
+ * Allocate sizeof(*ptr) bytes of memory and store
+ * the address of allocated memory in 'ptr'. Fill the
+ * newly allocated memory with zeros.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
  * Returns -1 on failure, 0 on success
  */
-# define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr)))
+# define VIR_ALLOC_QUIET(ptr) virAlloc(&(ptr), sizeof(*(ptr)), false, 0, NULL, NULL, 0)
 
 /**
  * VIR_ALLOC_N:
@@ -97,9 +118,26 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * This macro is safe to use on arguments with side effects.
  *
+ * Returns -1 on failure (with OOM error reported), 0 on success
+ */
+# define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count), true, \
+                                           VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+
+/**
+ * VIR_ALLOC_N_QUIET:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: number of elements to allocate
+ *
+ * Allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long and store the address of allocated memory in
+ * 'ptr'. Fill the newly allocated memory with zeros.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
  * Returns -1 on failure, 0 on success
  */
-# define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count))
+# define VIR_ALLOC_N_QUIET(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count), \
+                                                 false, 0, NULL, NULL, 0)
 
 /**
  * VIR_REALLOC_N:
@@ -112,9 +150,27 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * This macro is safe to use on arguments with side effects.
  *
+ * Returns -1 on failure (with OOM error reported), 0 on success
+ */
+# define VIR_REALLOC_N(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count), \
+                                               true, VIR_FROM_THIS, __FILE__, \
+                                               __FUNCTION__, __LINE__)
+
+/**
+ * VIR_REALLOC_N_QUIET:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: number of elements to allocate
+ *
+ * Re-allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long and store the address of allocated memory in
+ * 'ptr'. If 'ptr' grew, the added memory is uninitialized.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
  * Returns -1 on failure, 0 on success
  */
-# define VIR_REALLOC_N(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count))
+# define VIR_REALLOC_N_QUIET(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count), \
+                                                     false, 0, NULL, NULL, 0)
 
 /**
  * VIR_EXPAND_N:
@@ -129,10 +185,29 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * This macro is safe to use on arguments with side effects.
  *
- * Returns -1 on failure, 0 on success
+ * Returns -1 on failure (with OOM error reported), 0 on success
  */
 # define VIR_EXPAND_N(ptr, count, add) \
-    virExpandN(&(ptr), sizeof(*(ptr)), &(count), add)
+    virExpandN(&(ptr), sizeof(*(ptr)), &(count), add, true, VIR_FROM_THIS, \
+               __FILE__, __FUNCTION__, __LINE__)
+
+/**
+ * VIR_EXPAND_N_QUIET:
+ * @ptr: pointer to hold address of allocated memory
+ * @count: variable tracking number of elements currently allocated
+ * @add: number of elements to add
+ *
+ * Re-allocate an array of 'count' elements, each sizeof(*ptr)
+ * bytes long, to be 'count' + 'add' elements long, then store the
+ * address of allocated memory in 'ptr' and the new size in 'count'.
+ * The new elements are filled with zero.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+# define VIR_EXPAND_N_QUIET(ptr, count, add) \
+    virExpandN(&(ptr), sizeof(*(ptr)), &(count), add, false, 0, NULL, NULL, 0)
 
 /**
  * VIR_RESIZE_N:
@@ -154,10 +229,37 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * This macro is safe to use on arguments with side effects.
  *
- * Returns -1 on failure, 0 on success
+ * Returns -1 on failure (with OOM error reported), 0 on success
  */
 # define VIR_RESIZE_N(ptr, alloc, count, add) \
-    virResizeN(&(ptr), sizeof(*(ptr)), &(alloc), count, add)
+    virResizeN(&(ptr), sizeof(*(ptr)), &(alloc), count, add, true, \
+               VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+
+/**
+ * VIR_RESIZE_N_QUIET:
+ * @ptr: pointer to hold address of allocated memory
+ * @alloc: variable tracking number of elements currently allocated
+ * @count: number of elements currently in use
+ * @add: minimum number of elements to additionally support
+ *
+ * Blindly using VIR_EXPAND_N(array, alloc, 1) in a loop scales
+ * quadratically, because every iteration must copy contents from
+ * all prior iterations.  But amortized linear scaling can be achieved
+ * by tracking allocation size separately from the number of used
+ * elements, and growing geometrically only as needed.
+ *
+ * If 'count' + 'add' is larger than 'alloc', then geometrically reallocate
+ * the array of 'alloc' elements, each sizeof(*ptr) bytes long, and store
+ * the address of allocated memory in 'ptr' and the new size in 'alloc'.
+ * The new elements are filled with zero.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+# define VIR_RESIZE_N_QUIET(ptr, alloc, count, add) \
+    virResizeN(&(ptr), sizeof(*(ptr)), &(alloc), count, add, \
+               false, 0, NULL, NULL, 0)
 
 /**
  * VIR_SHRINK_N:
@@ -224,6 +326,7 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  * @newelem: the new element to move into place (*not* a pointer to
  *           the element, but the element itself).
  *           (the original will be zeroed out if successful)
+ * @report:  whether report OOM error on failure
  *
  * Re-allocate an array of 'count' elements, each sizeof(*ptr) bytes
  * long, to be 'count' + 1 elements long, then appropriately move
@@ -252,18 +355,22 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * Returns -1 on failure, 0 on success
  */
-# define VIR_INSERT_ELEMENT(ptr, at, count, newelem) \
+# define VIR_INSERT_ELEMENT(ptr, at, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), at, &(count),    \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, false)
-# define VIR_INSERT_ELEMENT_COPY(ptr, at, count, newelem) \
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, false, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+# define VIR_INSERT_ELEMENT_COPY(ptr, at, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), at, &(count), \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, false)
-# define VIR_INSERT_ELEMENT_INPLACE(ptr, at, count, newelem) \
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, false, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+# define VIR_INSERT_ELEMENT_INPLACE(ptr, at, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), at, &(count), \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, true)
-# define VIR_INSERT_ELEMENT_COPY_INPLACE(ptr, at, count, newelem) \
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, true, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+# define VIR_INSERT_ELEMENT_COPY_INPLACE(ptr, at, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), at, &(count), \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, true)
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, true, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
 
 /**
  * VIR_APPEND_ELEMENT:
@@ -272,6 +379,7 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  * @newelem: the new element to move into place (*not* a pointer to
  *           the element, but the element itself).
  *           (the original will be zeroed out if successful)
+ * @report:  whether report OOM error on failure
  *
  * Re-allocate an array of 'count' elements, each sizeof(*ptr) bytes
  * long, to be 'count' + 1 elements long, then copy the item from
@@ -300,18 +408,22 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * Returns -1 on failure, 0 on success
  */
-# define VIR_APPEND_ELEMENT(ptr, count, newelem) \
+# define VIR_APPEND_ELEMENT(ptr, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), -1, &(count),  \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, false)
-# define VIR_APPEND_ELEMENT_COPY(ptr, count, newelem) \
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, false, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+# define VIR_APPEND_ELEMENT_COPY(ptr, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), -1, &(count),  \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, false)
-# define VIR_APPEND_ELEMENT_INPLACE(ptr, count, newelem) \
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, false, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+# define VIR_APPEND_ELEMENT_INPLACE(ptr, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), -1, &(count),  \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, true)
-# define VIR_APPEND_ELEMENT_COPY_INPLACE(ptr, count, newelem) \
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), true, true, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+# define VIR_APPEND_ELEMENT_COPY_INPLACE(ptr, count, newelem, report) \
     virInsertElementsN(&(ptr), sizeof(*(ptr)), -1, &(count),  \
-                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, true)
+                       VIR_TYPEMATCH(ptr, &(newelem)), &(newelem), false, true, \
+                       report, VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
 
 /**
  * VIR_DELETE_ELEMENT:
@@ -365,10 +477,33 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1);
  *
  * This macro is safe to use on arguments with side effects.
  *
- * Returns -1 on failure, 0 on success
+ * Returns -1 on failure (with OOM error reported), 0 on success
  */
 # define VIR_ALLOC_VAR(ptr, type, count) \
-    virAllocVar(&(ptr), sizeof(*(ptr)), sizeof(type), (count))
+    virAllocVar(&(ptr), sizeof(*(ptr)), sizeof(type), (count), true, \
+                VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
+
+/**
+ * VIR_ALLOC_VAR_QUIET:
+ * @ptr: pointer to hold address of allocated memory
+ * @type: element type of trailing array
+ * @count: number of array elements to allocate
+ *
+ * Allocate sizeof(*ptr) bytes plus an array of 'count' elements, each
+ * sizeof('type').  This sort of allocation is useful for receiving
+ * the data of certain ioctls and other APIs which return a struct in
+ * which the last element is an array of undefined length.  The caller
+ * of this type of API is expected to know the length of the array
+ * that will be returned and allocate a suitable buffer to contain the
+ * returned data.  C99 refers to these variable length objects as
+ * structs containing flexible array members.
+ *
+ * This macro is safe to use on arguments with side effects.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+# define VIR_ALLOC_VAR_QUIET(ptr, type, count) \
+    virAllocVar(&(ptr), sizeof(*(ptr)), sizeof(type), (count), false, 0, NULL, NULL, 0)
 
 /**
  * VIR_FREE:
diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c
index 4969497..ee0be6c 100644
--- a/src/util/virbuffer.c
+++ b/src/util/virbuffer.c
@@ -126,7 +126,7 @@ virBufferGrow(virBufferPtr buf, unsigned int len)
 
     size = buf->use + len + 1000;
 
-    if (VIR_REALLOC_N(buf->content, size) < 0) {
+    if (VIR_REALLOC_N_QUIET(buf->content, size) < 0) {
         virBufferSetError(buf, errno);
         return -1;
     }
@@ -382,7 +382,7 @@ virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
     }
 
     if (xalloc_oversized(6, len) ||
-        VIR_ALLOC_N(escaped, 6 * len + 1) < 0) {
+        VIR_ALLOC_N_QUIET(escaped, 6 * len + 1) < 0) {
         virBufferSetError(buf, errno);
         return;
     }
@@ -499,7 +499,7 @@ virBufferEscape(virBufferPtr buf, char escape, const char *toescape,
     }
 
     if (xalloc_oversized(2, len) ||
-        VIR_ALLOC_N(escaped, 2 * len + 1) < 0) {
+        VIR_ALLOC_N_QUIET(escaped, 2 * len + 1) < 0) {
         virBufferSetError(buf, errno);
         return;
     }
@@ -597,7 +597,7 @@ virBufferEscapeShell(virBufferPtr buf, const char *str)
     if (*str) {
         len = strlen(str);
         if (xalloc_oversized(4, len) ||
-            VIR_ALLOC_N(escaped, 4 * len + 3) < 0) {
+            VIR_ALLOC_N_QUIET(escaped, 4 * len + 3) < 0) {
             virBufferSetError(buf, errno);
             return;
         }
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index e0b25ed..13fd162 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1171,7 +1171,7 @@ static int virCgroupPartitionEscape(char **path)
     if ((rc = virCgroupPartitionNeedsEscaping(*path)) <= 0)
         return rc;
 
-    if (VIR_INSERT_ELEMENT(*path, 0, len, escape) < 0)
+    if (VIR_INSERT_ELEMENT(*path, 0, len, escape, false) < 0)
         return -ENOMEM;
 
     return 0;
diff --git a/src/util/virerror.c b/src/util/virerror.c
index 4789bae..e238dce 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -209,7 +209,7 @@ virLastErrorObject(void)
     virErrorPtr err;
     err = virThreadLocalGet(&virLastErr);
     if (!err) {
-        if (VIR_ALLOC(err) < 0)
+        if (VIR_ALLOC_QUIET(err) < 0)
             return NULL;
         if (virThreadLocalSet(&virLastErr, err) < 0)
             VIR_FREE(err);
@@ -330,7 +330,7 @@ virSaveLastError(void)
     virErrorPtr to;
     int saved_errno = errno;
 
-    if (VIR_ALLOC(to) < 0)
+    if (VIR_ALLOC_QUIET(to) < 0)
         return NULL;
 
     virCopyLastError(to);
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 54f7715..9ed257e 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2009,7 +2009,7 @@ virPCIGetIOMMUGroupAddressesAddOne(virPCIDeviceAddressPtr newDevAddr, void *opaq
     *copyAddr = *newDevAddr;
 
     if (VIR_APPEND_ELEMENT(*addrList->iommuGroupDevices,
-                           *addrList->nIommuGroupDevices, copyAddr) < 0) {
+                           *addrList->nIommuGroupDevices, copyAddr, false) < 0) {
         virReportOOMError();
         goto cleanup;
     }
diff --git a/src/util/virthreadpthread.c b/src/util/virthreadpthread.c
index 75b5fd6..ca841e4 100644
--- a/src/util/virthreadpthread.c
+++ b/src/util/virthreadpthread.c
@@ -174,7 +174,7 @@ int virThreadCreate(virThreadPtr thread,
 
     if ((err = pthread_attr_init(&attr)) != 0)
         goto cleanup;
-    if (VIR_ALLOC(args) < 0) {
+    if (VIR_ALLOC_QUIET(args) < 0) {
         err = ENOMEM;
         goto cleanup;
     }
diff --git a/tests/commandhelper.c b/tests/commandhelper.c
index e4cc5d2..d492c70 100644
--- a/tests/commandhelper.c
+++ b/tests/commandhelper.c
@@ -35,6 +35,7 @@
 
 #ifndef WIN32
 
+# define VIR_FROM_THIS VIR_FROM_NONE
 
 static int envsort(const void *a, const void *b) {
     const char *const*astrptr = a;
diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c
index 520feba..b234b30 100644
--- a/tests/networkxml2conftest.c
+++ b/tests/networkxml2conftest.c
@@ -16,6 +16,8 @@
 #include "network/bridge_driver.h"
 #include "virstring.h"
 
+#define VIR_FROM_THIS VIR_FROM_NONE
+
 static int
 testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr caps)
 {
diff --git a/tests/test_conf.c b/tests/test_conf.c
index d5467e8..acf41c6 100644
--- a/tests/test_conf.c
+++ b/tests/test_conf.c
@@ -20,7 +20,7 @@ int main(int argc, char **argv)
         goto cleanup;
     }
 
-    if (VIR_ALLOC_N(buffer, len) < 0) {
+    if (VIR_ALLOC_N_QUIET(buffer, len) < 0) {
         fprintf(stderr, "out of memory\n");
         goto cleanup;
     }
diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c
index 8e0c59e..73e4a2d 100644
--- a/tests/xmconfigtest.c
+++ b/tests/xmconfigtest.c
@@ -37,6 +37,8 @@
 #include "viralloc.h"
 #include "virstring.h"
 
+#define VIR_FROM_THIS VIR_FROM_NONE
+
 static virCapsPtr caps;
 static virDomainXMLOptionPtr xmlopt;
 
-- 
1.8.1.5




More information about the libvir-list mailing list