[libvirt] [PATCH RFC 1/2] viralloc: Report OOM error on failure

Michal Privoznik mprivozn at redhat.com
Fri Mar 22 11:44:56 UTC 2013


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




More information about the libvir-list mailing list