In nearly all cases of calling VIR_ALLOC*, VIR_REALLOC_N, VIR_EXPAND_N, VIR_RESIZE_N, VIR_*_ELEMENT etc. we want to report OOM error, so our source code base is full of:
if (VIR_ALLOC(somePtr) < 0) { virReportOOMError(); goto cleanup; } or similar. Moreover, for those few cases where we don't want to report OOM error (e.g. virReportOOMError() itself) a new VIR_ALLOC_NOOOM macro is being introduced. --- src/util/viralloc.c | 23 ++++++++++++++++++----- src/util/viralloc.h | 13 ++++++++----- src/util/virerror.c | 2 +- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/util/viralloc.c b/src/util/viralloc.c index 342b0eb..60c33d2 100644 --- a/src/util/viralloc.c +++ b/src/util/viralloc.c @@ -24,8 +24,11 @@ #include <stdlib.h> #include "viralloc.h" +#include "virerror.h" #include "virlog.h" +#define VIR_FROM_THIS VIR_FROM_NONE + #if TEST_OOM static int testMallocNext = 0; static int testMallocFailFirst = 0; @@ -105,6 +108,7 @@ 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 error * * Allocate 'size' bytes of memory. Return the address of the * allocated memory in 'ptrptr'. The newly allocated memory is @@ -112,7 +116,7 @@ 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) { #if TEST_OOM if (virAllocTestFail()) { @@ -122,8 +126,11 @@ int virAlloc(void *ptrptr, size_t size) #endif *(void **)ptrptr = calloc(1, size); - if (*(void **)ptrptr == NULL) + if (*(void **)ptrptr == NULL) { + if (report) + virReportOOMError(); return -1; + } return 0; } @@ -150,8 +157,10 @@ int virAllocN(void *ptrptr, size_t size, size_t count) #endif *(void**)ptrptr = calloc(count, size); - if (*(void**)ptrptr == NULL) + if (*(void**)ptrptr == NULL) { + virReportOOMError(); return -1; + } return 0; } @@ -182,8 +191,10 @@ int virReallocN(void *ptrptr, size_t size, size_t count) return -1; } tmp = realloc(*(void**)ptrptr, size * count); - if (!tmp && (size * count)) + if (!tmp && (size * count)) { + virReportOOMError(); return -1; + } *(void**)ptrptr = tmp; return 0; } @@ -422,8 +433,10 @@ int virAllocVar(void *ptrptr, size_t struct_size, size_t element_size, size_t co alloc_size = struct_size + (element_size * count); *(void **)ptrptr = calloc(1, alloc_size); - if (*(void **)ptrptr == NULL) + if (*(void **)ptrptr == NULL) { + virReportOOMError(); return -1; + } return 0; } diff --git a/src/util/viralloc.h b/src/util/viralloc.h index 7be7f82..30ffe15 100644 --- a/src/util/viralloc.h +++ b/src/util/viralloc.h @@ -46,7 +46,7 @@ /* Don't call these directly - use the macros below */ -int virAlloc(void *ptrptr, size_t size) ATTRIBUTE_RETURN_CHECK +int virAlloc(void *ptrptr, size_t size, bool report) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); int virAllocN(void *ptrptr, size_t size, size_t count) ATTRIBUTE_RETURN_CHECK ATTRIBUTE_NONNULL(1); @@ -76,13 +76,16 @@ void virFree(void *ptrptr) ATTRIBUTE_NONNULL(1); * VIR_ALLOC: * @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. + * Allocate sizeof(*ptr) bytes of memory and store the + * address of allocated memory in 'ptr'. Fill the newly + * allocated memory with zeros. If there's a failure, + * OOM error is reported. The VIR_ALLOC_NOOOM macro + * behaves the same except the OOM error reporting. * * Returns -1 on failure, 0 on success */ -# define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr))) +# define VIR_ALLOC(ptr) virAlloc(&(ptr), sizeof(*(ptr)), true) +# define VIR_ALLOC_NOOOM(ptr) virAlloc(&(ptr), sizeof(*(ptr)), true) /** * VIR_ALLOC_N: diff --git a/src/util/virerror.c b/src/util/virerror.c index c30642a..c033129 100644 --- a/src/util/virerror.c +++ b/src/util/virerror.c @@ -204,7 +204,7 @@ virLastErrorObject(void) virErrorPtr err; err = virThreadLocalGet(&virLastErr); if (!err) { - if (VIR_ALLOC(err) < 0) + if (VIR_ALLOC_NOOOM(err) < 0) return NULL; if (virThreadLocalSet(&virLastErr, err) < 0) VIR_FREE(err); -- 1.8.1.5 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list