For cases where caller doesn't want to repor an OOM error, he should use VIR_ALLOC_QUIET or variants. --- HACKING | 4 ++ docs/hacking.html.in | 6 +++ po/POTFILES.in | 1 + python/libvirt-override.c | 102 ++++++++++++++++++++++---------------------- src/esx/esx_vi.c | 3 +- src/util/viralloc.c | 95 +++++++++++++++++++++++++++++++++++------ src/util/viralloc.h | 54 ++++++++++++++++------- src/util/virbuffer.c | 8 ++-- src/util/virerror.c | 4 +- src/util/virthreadpthread.c | 2 +- tests/networkxml2conftest.c | 2 + tests/test_conf.c | 2 +- tests/xmconfigtest.c | 2 + 13 files changed, 196 insertions(+), 89 deletions(-) diff --git a/HACKING b/HACKING index 0f681ce..b7b2798 100644 --- a/HACKING +++ b/HACKING @@ -595,6 +595,10 @@ size: +These memory allocation macros report out-of-memory error automatically. In +case, you want to suppress such behavior, use their _QUIET variant, e.g. +VIR_ALLOC_QUIET, VIR_REALLOC_N_QUIET etc. + File handling ============= diff --git a/docs/hacking.html.in b/docs/hacking.html.in index a9b78ba..2d9e1cd 100644 --- a/docs/hacking.html.in +++ b/docs/hacking.html.in @@ -712,6 +712,12 @@ </li> </ul> + <p> + These memory allocation macros report out-of-memory error automatically. + In case, you want to suppress such behavior, use their _QUIET variant, e.g. + VIR_ALLOC_QUIET, VIR_REALLOC_N_QUIET etc. + </p> + <h2><a name="file_handling">File handling</a></h2> <p> diff --git a/po/POTFILES.in b/po/POTFILES.in index bf5a864..7450642 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 856789a..df40ae3 100644 --- a/python/libvirt-override.c +++ b/python/libvirt-override.c @@ -167,7 +167,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; } @@ -353,7 +353,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; @@ -419,7 +419,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; } @@ -471,7 +471,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; } @@ -651,7 +651,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; @@ -699,7 +699,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; @@ -759,7 +759,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; @@ -835,7 +835,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; @@ -909,7 +909,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; @@ -969,7 +969,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; @@ -1029,7 +1029,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; @@ -1089,7 +1089,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; @@ -1149,7 +1149,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; @@ -1209,7 +1209,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; @@ -1270,7 +1270,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; @@ -1331,7 +1331,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; @@ -1377,12 +1377,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; } @@ -1504,7 +1504,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++) { @@ -1568,7 +1568,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++) { @@ -1628,7 +1628,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; @@ -1696,7 +1696,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++) { @@ -1755,7 +1755,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; @@ -2030,7 +2030,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; @@ -2158,7 +2158,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; @@ -2249,7 +2249,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); @@ -2296,7 +2296,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); @@ -2396,7 +2396,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, @@ -2728,7 +2728,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); @@ -2773,7 +2773,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); @@ -2981,7 +2981,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; @@ -3025,7 +3025,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; @@ -3088,7 +3088,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; @@ -3148,7 +3148,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); @@ -3201,7 +3201,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); @@ -3300,7 +3300,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); @@ -3561,7 +3561,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); @@ -3651,7 +3651,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); @@ -3770,7 +3770,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); @@ -3989,7 +3989,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); @@ -4080,7 +4080,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); @@ -4134,7 +4134,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); @@ -4234,7 +4234,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++) { @@ -4420,7 +4420,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; @@ -4481,7 +4481,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; @@ -4524,7 +4524,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; @@ -6345,7 +6345,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; @@ -6509,7 +6509,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; @@ -6546,7 +6546,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; @@ -6606,7 +6606,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; @@ -6666,7 +6666,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/esx/esx_vi.c b/src/esx/esx_vi.c index 7245fbb..cc247b4 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -1760,7 +1760,8 @@ esxVI_Alloc(void **ptrptr, size_t size) return -1; } - if (virAllocN(ptrptr, size, 1) < 0) { + if (virAllocN(ptrptr, size, 1, false, VIR_FROM_THIS, + __FILE__, __FUNCTION__, __LINE__) < 0) { virReportOOMError(); return -1; } diff --git a/src/util/viralloc.c b/src/util/viralloc.c index 8f219bf..a22d763 100644 --- a/src/util/viralloc.c +++ b/src/util/viralloc.c @@ -25,6 +25,7 @@ #include "viralloc.h" #include "virlog.h" +#include "virerror.h" #if TEST_OOM static int testMallocNext = 0; @@ -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,15 +240,21 @@ 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; if (*countptr + add < *countptr) { errno = ENOMEM; + if (report) + virReportSystemErrorFull(domcode, ENOMEM, filename, funcname, linenr, + _("Allocation would overflow: " + "countptr=%zu add=%zu"), *countptr, add); 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 +269,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 +285,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 +300,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 +320,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 +369,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 +446,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 +463,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 +476,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..f069b3b 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_ALLOC_QUIET(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_N_QUIET(ptr, count) virAllocN(&(ptr), sizeof(*(ptr)), (count), \ + false, VIR_FROM_NONE, NULL, NULL, 0) /** * VIR_REALLOC_N: @@ -108,7 +123,13 @@ 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_N_QUIET(ptr, count) virReallocN(&(ptr), sizeof(*(ptr)), (count), \ + false, VIR_FROM_NONE, NULL, NULL, 0) /** * VIR_EXPAND_N: @@ -124,7 +145,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 +169,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 +375,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..b25a659 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/virerror.c b/src/util/virerror.c index 2b3a910..f2d77bd 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -206,7 +206,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); @@ -306,7 +306,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/virthreadpthread.c b/src/util/virthreadpthread.c index b42b333..810ad9c 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/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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list