--- HACKING | 4 ++ docs/hacking.html.in | 4 ++ po/POTFILES.in | 1 + python/libvirt-override.c | 102 ++++++++++++++++++++++---------------------- src/esx/esx_vi.c | 5 +-- src/util/viralloc.c | 91 +++++++++++++++++++++++++++++++++------ src/util/viralloc.h | 52 +++++++++++++++------- src/util/virbuffer.c | 8 ++-- src/util/virerror.c | 4 +- src/util/virthreadpthread.c | 2 +- tests/commandhelper.c | 2 +- tests/networkxml2conftest.c | 2 +- tests/openvzutilstest.c | 2 +- tests/test_conf.c | 2 +- tests/xmconfigtest.c | 2 +- 15 files changed, 188 insertions(+), 95 deletions(-) diff --git a/HACKING b/HACKING index 6230ffd..c511cab 100644 --- a/HACKING +++ b/HACKING @@ -595,6 +595,10 @@ size: +These memory allocation macros report OOM error automatically. In case, you +want to suppress such behavior, use their NOOOM variant, e.g. VIR_ALLOCNOOM, +VIR_REALLOC_NNOOM etc. + File handling ============= diff --git a/docs/hacking.html.in b/docs/hacking.html.in index 0fbb500..531681b 100644 --- a/docs/hacking.html.in +++ b/docs/hacking.html.in @@ -712,6 +712,10 @@ </li> </ul> + <p>These memory allocation macros report OOM error automatically. In case, + you want to suppress such behavior, use their NOOOM variant, e.g. + VIR_ALLOCNOOM, VIR_REALLOC_NNOOM etc.</p> + <h2><a name="file_handling">File handling</a></h2> <p> diff --git a/po/POTFILES.in b/po/POTFILES.in index 91e5c02..78d6ffe 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -139,6 +139,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 5f9ae4b..08252ac 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -168,7 +168,7 @@ setPyVirTypedParameter(PyObject *info, return NULL; } - if (VIR_ALLOC_N(ret, size) < 0) { + if (VIR_ALLOC_NNOOM(ret, size) < 0) { PyErr_NoMemory(); return NULL; } @@ -354,7 +354,7 @@ libvirt_virDomainBlockStatsFlags(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -420,7 +420,7 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) sumparams = nparams * MIN(ncpus, 128); - if (VIR_ALLOC_N(params, sumparams) < 0) { + if (VIR_ALLOC_NNOOM(params, sumparams) < 0) { error = PyErr_NoMemory(); goto error; } @@ -472,7 +472,7 @@ libvirt_virDomainGetCPUStats(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) if (nparams) { sumparams = nparams; - if (VIR_ALLOC_N(params, nparams) < 0) { + if (VIR_ALLOC_NNOOM(params, nparams) < 0) { error = PyErr_NoMemory(); goto error; } @@ -652,7 +652,7 @@ libvirt_virDomainGetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -700,7 +700,7 @@ libvirt_virDomainGetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -760,7 +760,7 @@ libvirt_virDomainSetSchedulerParameters(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -836,7 +836,7 @@ libvirt_virDomainSetSchedulerParametersFlags(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -910,7 +910,7 @@ libvirt_virDomainSetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -970,7 +970,7 @@ libvirt_virDomainGetBlkioParameters(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1030,7 +1030,7 @@ libvirt_virDomainSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1090,7 +1090,7 @@ libvirt_virDomainGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1150,7 +1150,7 @@ libvirt_virDomainSetNumaParameters(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1210,7 +1210,7 @@ libvirt_virDomainGetNumaParameters(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1271,7 +1271,7 @@ libvirt_virDomainSetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1332,7 +1332,7 @@ libvirt_virDomainGetInterfaceParameters(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1378,12 +1378,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_NNOOM(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_NNOOM(cpumap, dominfo.nrVirtCpu * cpumaplen) < 0) { error = PyErr_NoMemory(); goto cleanup; } @@ -1505,7 +1505,7 @@ libvirt_virDomainPinVcpu(PyObject *self ATTRIBUTE_UNUSED, } cpumaplen = VIR_CPU_MAPLEN(cpunum); - if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) + if (VIR_ALLOC_NNOOM(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); for (i = 0; i < tuple_size; i++) { @@ -1569,7 +1569,7 @@ libvirt_virDomainPinVcpuFlags(PyObject *self ATTRIBUTE_UNUSED, } cpumaplen = VIR_CPU_MAPLEN(cpunum); - if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) + if (VIR_ALLOC_NNOOM(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); for (i = 0; i < tuple_size; i++) { @@ -1629,7 +1629,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_NNOOM(cpumaps, dominfo.nrVirtCpu * cpumaplen) < 0) goto cleanup; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -1697,7 +1697,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_NNOOM(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); for (i = 0; i < tuple_size; i++) { @@ -1756,7 +1756,7 @@ libvirt_virDomainGetEmulatorPinInfo(PyObject *self ATTRIBUTE_UNUSED, cpumaplen = VIR_CPU_MAPLEN(cpunum); - if (VIR_ALLOC_N(cpumap, cpumaplen) < 0) + if (VIR_ALLOC_NNOOM(cpumap, cpumaplen) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -2031,7 +2031,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_NNOOM(auth.credtype, auth.ncredtype) < 0) return VIR_PY_NONE; for (i = 0 ; i < auth.ncredtype ; i++) { PyObject *val; @@ -2159,7 +2159,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_NNOOM(ids, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -2250,7 +2250,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedDomains(conn, names, c_retval); @@ -2297,7 +2297,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_NNOOM(names, c_retval) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotListNames(dom, names, c_retval, flags); @@ -2397,7 +2397,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_NNOOM(names, c_retval) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virDomainSnapshotListChildrenNames(snap, names, c_retval, @@ -2729,7 +2729,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListNetworks(conn, names, c_retval); @@ -2774,7 +2774,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedNetworks(conn, names, c_retval); @@ -2982,7 +2982,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_NNOOM(freeMems, maxCells) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -3026,7 +3026,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_NNOOM(stats, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -3089,7 +3089,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_NNOOM(stats, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -3149,7 +3149,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListStoragePools(conn, names, c_retval); @@ -3202,7 +3202,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedStoragePools(conn, names, c_retval); @@ -3301,7 +3301,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virStoragePoolListVolumes(pool, names, c_retval); @@ -3562,7 +3562,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeListDevices(conn, cap, names, c_retval, flags); @@ -3652,7 +3652,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virNodeDeviceListCaps(dev, names, c_retval); @@ -3771,7 +3771,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_NNOOM(uuids, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListSecrets(conn, uuids, c_retval); @@ -3990,7 +3990,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_NNOOM(uuids, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListNWFilters(conn, uuids, c_retval); @@ -4081,7 +4081,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListInterfaces(conn, names, c_retval); @@ -4135,7 +4135,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_NNOOM(names, c_retval) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; c_retval = virConnectListDefinedInterfaces(conn, names, c_retval); @@ -4235,7 +4235,7 @@ libvirt_virConnectBaselineCPU(PyObject *self ATTRIBUTE_UNUSED, int i; ncpus = PyList_Size(list); - if (VIR_ALLOC_N(xmlcpus, ncpus) < 0) + if (VIR_ALLOC_NNOOM(xmlcpus, ncpus) < 0) return VIR_PY_INT_FAIL; for (i = 0; i < ncpus; i++) { @@ -4421,7 +4421,7 @@ libvirt_virDomainSetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -4482,7 +4482,7 @@ libvirt_virDomainGetBlockIoTune(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -4525,7 +4525,7 @@ libvirt_virDomainGetDiskErrors(PyObject *self ATTRIBUTE_UNUSED, ndisks = count; if (ndisks) { - if (VIR_ALLOC_N(disks, ndisks) < 0) + if (VIR_ALLOC_NNOOM(disks, ndisks) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -6346,7 +6346,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_NNOOM(buf, nbytes+1 > 0 ? nbytes+1 : 1) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -6510,7 +6510,7 @@ libvirt_virDomainBlockPeek(PyObject *self ATTRIBUTE_UNUSED, domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); - if (VIR_ALLOC_N(buf, size) < 0) + if (VIR_ALLOC_NNOOM(buf, size) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -6547,7 +6547,7 @@ libvirt_virDomainMemoryPeek(PyObject *self ATTRIBUTE_UNUSED, domain = (virDomainPtr) PyvirDomain_Get(pyobj_domain); - if (VIR_ALLOC_N(buf, size) < 0) + if (VIR_ALLOC_NNOOM(buf, size) < 0) return VIR_PY_NONE; LIBVIRT_BEGIN_ALLOW_THREADS; @@ -6607,7 +6607,7 @@ libvirt_virNodeSetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, return NULL; } - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; @@ -6667,7 +6667,7 @@ libvirt_virNodeGetMemoryParameters(PyObject *self ATTRIBUTE_UNUSED, if (!nparams) return PyDict_New(); - if (VIR_ALLOC_N(params, nparams) < 0) + if (VIR_ALLOC_NNOOM(params, nparams) < 0) return PyErr_NoMemory(); LIBVIRT_BEGIN_ALLOW_THREADS; diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 8f14fc5..042bbbc 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -1769,10 +1769,9 @@ esxVI_Alloc(void **ptrptr, size_t size) return -1; } - if (virAllocN(ptrptr, size, 1) < 0) { - virReportOOMError(); + if (virAllocN(ptrptr, size, 1, true, VIR_FROM_THIS, + __FILE__, __FUNCTION__, __LINE__) < 0) return -1; - } return 0; } diff --git a/src/util/viralloc.c b/src/util/viralloc.c index 8f219bf..750d34d 100644 --- a/src/util/viralloc.c +++ b/src/util/viralloc.c @@ -24,6 +24,7 @@ #include <stdlib.h> #include "viralloc.h" +#include "virerror.h" #include "virlog.h" #if TEST_OOM @@ -105,6 +106,11 @@ 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: report OOM + * @domcode: code of error domain + * @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 @@ -112,7 +118,8 @@ void virAllocTestHook(void (*func)(int, void*) ATTRIBUTE_UNUSED, * * 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 +129,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,6 +142,11 @@ 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: report OOM + * @domcode: code of error domain + * @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 @@ -140,7 +155,8 @@ int virAlloc(void *ptrptr, size_t size) * * 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 +166,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,6 +179,11 @@ 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: report OOM + * @domcode: code of error domain + * @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' @@ -169,7 +193,8 @@ int virAllocN(void *ptrptr, size_t size, size_t count) * * 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 @@ -179,11 +204,18 @@ int virReallocN(void *ptrptr, size_t size, size_t count) if (xalloc_oversized(count, size)) { errno = ENOMEM; + if (report) + virReportSystemErrorFull(domcode, ENOMEM, filename, funcname, linenr, + _("Allocation would overflow: " + "count=%zu size=%zu"), count, size); 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,6 +226,11 @@ 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: report OOM + * @domcode: code of error domain + * @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. @@ -203,7 +240,8 @@ int virReallocN(void *ptrptr, size_t size, size_t count) * * 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; @@ -211,7 +249,8 @@ int virExpandN(void *ptrptr, size_t size, size_t *countptr, size_t add) 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,6 +265,11 @@ 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: report OOM + * @domcode: code of error domain + * @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' + @@ -237,7 +281,8 @@ int virExpandN(void *ptrptr, size_t size, size_t *countptr, size_t add) * 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) + size_t add, bool report, int domcode, const char *filename, + const char *funcname, size_t linenr) { size_t delta; @@ -251,7 +296,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 +316,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; @@ -318,7 +365,8 @@ virInsertElementsN(void *ptrptr, size_t size, size_t at, if (inPlace) { *countptr += add; - } else if (virExpandN(ptrptr, size, countptr, add) < 0) { + } else if (virExpandN(ptrptr, size, countptr, add, + false, 0, NULL, NULL, 0) < 0) { return -1; } @@ -394,6 +442,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: report OOM + * @domcode: code of error domain + * @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 @@ -406,7 +459,9 @@ virDeleteElementsN(void *ptrptr, size_t size, size_t at, * * 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; @@ -417,13 +472,21 @@ int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, size_t co if (VIR_ALLOC_VAR_OVERSIZED(struct_size, count, element_size)) { errno = ENOMEM; + if (report) + virReportSystemErrorFull(domcode, ENOMEM, filename, funcname, linenr, + _("Allocation would overflow: struct_size=%zu " + "count=%zu element_size=%zu"), + struct_size, count, element_size); 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 7be7f82..f3c8a56 100644 --- a/src/util/viralloc.h +++ b/src/util/viralloc.h @@ -46,16 +46,21 @@ /* 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) + 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); @@ -69,7 +74,10 @@ int virDeleteElementsN(void *ptrptr, size_t size, size_t at, size_t *countptr, int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, - size_t count) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); + 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,7 +90,9 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * * Returns -1 on failure, 0 on success */ -# define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr))) +# define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr)), true, VIR_FROM_THIS, \ + __FILE__, __FUNCTION__, __LINE__) +# define VIR_ALLOCNOOM(ptr) virAlloc(&(ptr), sizeof(*(ptr)), false, 0, NULL, NULL, 0) /** * VIR_ALLOC_N: @@ -95,7 +105,12 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * * Returns -1 on failure, 0 on success */ -# define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count)) +# define VIR_ALLOC_N(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count), \ + true, VIR_FROM_THIS, __FILE__, \ + __FUNCTION__, __LINE__) + +# define VIR_ALLOC_NNOOM(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count), \ + false, VIR_FROM_NONE, NULL, NULL, 0) /** * VIR_REALLOC_N: @@ -108,8 +123,12 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * * Returns -1 on failure, 0 on success */ -# define VIR_REALLOC_N(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count)) +# define VIR_REALLOC_N(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count), \ + true, VIR_FROM_THIS, __FILE__, \ + __FUNCTION__, __LINE__) +# define VIR_REALLOC_NNOOM(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count), \ + false, VIR_FROM_NONE, NULL, NULL, 0) /** * VIR_EXPAND_N: * @ptr: pointer to hold address of allocated memory @@ -124,7 +143,8 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * Returns -1 on failure, 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_RESIZE_N: @@ -147,7 +167,8 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * Returns -1 on failure, 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_SHRINK_N: @@ -352,7 +373,8 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * Returns -1 on failure, 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_FREE: diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c index 693e4b2..977ed50 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_NNOOM(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_NNOOM(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_NNOOM(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_NNOOM(escaped, 4 * len + 3) < 0) { virBufferSetError(buf, errno); return; } diff --git a/src/util/virerror.c b/src/util/virerror.c index d89f505..6ba875b 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -205,7 +205,7 @@ virLastErrorObject(void) virErrorPtr err; err = virThreadLocalGet(&virLastErr); if (!err) { - if (VIR_ALLOC(err) < 0) + if (VIR_ALLOCNOOM(err) < 0) return NULL; if (virThreadLocalSet(&virLastErr, err) < 0) VIR_FREE(err); @@ -305,7 +305,7 @@ virSaveLastError(void) virErrorPtr to; int saved_errno = errno; - if (VIR_ALLOC(to) < 0) + if (VIR_ALLOCNOOM(to) < 0) return NULL; virCopyLastError(to); diff --git a/src/util/virthreadpthread.c b/src/util/virthreadpthread.c index b42b333..8ac29b4 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_ALLOCNOOM(args) < 0) { err = ENOMEM; goto cleanup; } diff --git a/tests/commandhelper.c b/tests/commandhelper.c index 747bec2..14c9f4d 100644 --- a/tests/commandhelper.c +++ b/tests/commandhelper.c @@ -71,7 +71,7 @@ int main(int argc, char **argv) { origenv++; } - if (VIR_ALLOC_N(newenv, n) < 0) + if (VIR_ALLOC_NNOOM(newenv, n) < 0) return EXIT_FAILURE; origenv = environ; diff --git a/tests/networkxml2conftest.c b/tests/networkxml2conftest.c index f393c4b..2d7141e 100644 --- a/tests/networkxml2conftest.c +++ b/tests/networkxml2conftest.c @@ -38,7 +38,7 @@ testCompareXMLToConfFiles(const char *inxml, const char *outconf, dnsmasqCapsPtr if (!(dev = virNetworkDefParseString(inXmlData))) goto fail; - if (VIR_ALLOC(obj) < 0) + if (VIR_ALLOCNOOM(obj) < 0) goto fail; obj->def = dev; diff --git a/tests/openvzutilstest.c b/tests/openvzutilstest.c index 8044389..4e65dbd 100644 --- a/tests/openvzutilstest.c +++ b/tests/openvzutilstest.c @@ -101,7 +101,7 @@ testReadNetworkConf(const void *data ATTRIBUTE_UNUSED) " </devices>\n" "</domain>\n"; - if (VIR_ALLOC(def) < 0 || + if (VIR_ALLOCNOOM(def) < 0 || !(def->os.type = strdup("exe")) || !(def->os.init = strdup("/sbin/init"))) goto cleanup; diff --git a/tests/test_conf.c b/tests/test_conf.c index d5467e8..81e620f 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_NNOOM(buffer, len) < 0) { fprintf(stderr, "out of memory\n"); goto cleanup; } diff --git a/tests/xmconfigtest.c b/tests/xmconfigtest.c index 176f318..71f5166 100644 --- a/tests/xmconfigtest.c +++ b/tests/xmconfigtest.c @@ -53,7 +53,7 @@ testCompareParseXML(const char *xmcfg, const char *xml, int xendConfigVersion) struct _xenUnifiedPrivate priv; virDomainDefPtr def = NULL; - if (VIR_ALLOC_N(gotxmcfgData, wrote) < 0) + if (VIR_ALLOC_NNOOM(gotxmcfgData, wrote) < 0) goto fail; conn = virGetConnect(); -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list