[Libvir] PATCH: Make the virBuffer API harder to misuse

Daniel P. Berrange berrange at redhat.com
Mon Apr 28 13:59:06 UTC 2008


On Mon, Apr 28, 2008 at 08:19:20AM -0400, Daniel Veillard wrote:
> On Mon, Apr 28, 2008 at 01:13:00PM +0100, Daniel P. Berrange wrote:
> > On Mon, Apr 28, 2008 at 03:17:33AM -0400, Daniel Veillard wrote:
> > > I would prefer to relax the 'non-public' point and let the compiler 
> > > compute the size in some ways rather than hardcode based on a word size
> > > indication which may not take into account specific alignment problems
> > > on some platforms.
> > 
> > One other option I considered is to just define the struct in the public 
> > header with meaningless field names
> > 
> >   struct _virBuffer {
> >      char a;
> 
>        char *a;
> 
> >      unsigned int b;
> >      unsinged int c;
> >   };
> > 
> > The real version is re-declared with proper names in buf.c, so this will
> > at least discourage its use which is probably good enough.
> 
>   Fine by me.

Here's the updated patch...

 src/buf.c               |  241 ++++++++++++++++-------------
 src/buf.h               |   35 ++--
 src/capabilities.c      |  187 ++++++++--------------
 src/conf.c              |   77 ++++-----
 src/libvirt_sym.version |    2 
 src/lxc_conf.c          |  104 +++---------
 src/qemu_conf.c         |  391 ++++++++++++++++++------------------------------
 src/qparams.c           |   15 +
 src/storage_conf.c      |  227 ++++++++++-----------------
 src/test.c              |   74 ++++-----
 src/virsh.c             |  158 ++++++++-----------
 src/xend_internal.c     |  126 ++++++---------
 src/xm_internal.c       |  184 ++++++++++------------
 src/xml.c               |  101 +++++-------
 src/xmlrpc.c            |   22 +-
 src/xmlrpc.h            |    5 
 tests/xmlrpctest.c      |   81 ++++-----
 17 files changed, 883 insertions(+), 1147 deletions(-)


Daniel.


Index: src/buf.c
===================================================================
RCS file: /data/cvs/libvirt/src/buf.c,v
retrieving revision 1.15
diff -u -p -r1.15 buf.c
--- src/buf.c	10 Apr 2008 16:54:54 -0000	1.15
+++ src/buf.c	28 Apr 2008 13:52:15 -0000
@@ -18,8 +18,37 @@
 #include <stdarg.h>
 #include <ctype.h>
 
+#define __VIR_BUFFER_C__
+
 #include "buf.h"
 
+
+/* If adding more fields, ensure to edit buf.h to match
+   the number of fields */
+struct _virBuffer {
+    unsigned int size;
+    unsigned int use;
+    unsigned int error;
+    char *content;
+};
+
+/**
+ * virBufferFail
+ * @buf: the buffer
+ *
+ * Mark the buffer has having failed a memory allocation,
+ * freeing the content and setting the error flag.
+ */
+static void
+virBufferNoMemory(const virBufferPtr buf)
+{
+    free(buf->content);
+    buf->content = NULL;
+    buf->size = 0;
+    buf->use = 0;
+    buf->error = 1;
+}
+
 /**
  * virBufferGrow:
  * @buf:  the buffer
@@ -27,7 +56,7 @@
  *
  * Grow the available space of a buffer to at least @len bytes.
  *
- * Returns the new available space or -1 in case of error
+ * Returns zero on success or -1 on error
  */
 static int
 virBufferGrow(virBufferPtr buf, unsigned int len)
@@ -35,18 +64,22 @@ virBufferGrow(virBufferPtr buf, unsigned
     int size;
     char *newbuf;
 
-    if (buf == NULL)
-        return (-1);
-    if (len + buf->use < buf->size)
-        return (0);
+    if (buf->error)
+        return -1;
+
+    if ((len + buf->use) < buf->size)
+        return 0;
 
     size = buf->use + len + 1000;
 
     newbuf = realloc(buf->content, size);
-    if (newbuf == NULL) return -1;
+    if (newbuf == NULL) {
+        virBufferNoMemory(buf);
+        return -1;
+    }
     buf->content = newbuf;
     buf->size = size;
-    return (buf->size - buf->use);
+    return 0;
 }
 
 /**
@@ -58,33 +91,29 @@ virBufferGrow(virBufferPtr buf, unsigned
  * Add a string range to an XML buffer. if len == -1, the length of
  * str is recomputed to the full string.
  *
- * Returns 0 successful, -1 in case of internal or API error.
  */
-int
-__virBufferAdd(virBufferPtr buf, const char *str, int len)
+void
+__virBufferAdd(const virBufferPtr buf, const char *str, int len)
 {
     unsigned int needSize;
 
-    if ((str == NULL) || (buf == NULL)) {
-        return -1;
-    }
-    if (len == 0)
-        return 0;
+    if ((str == NULL) || (buf == NULL) || (len == 0))
+        return;
+
+    if (buf->error)
+        return;
 
     if (len < 0)
         len = strlen(str);
 
     needSize = buf->use + len + 2;
-    if (needSize > buf->size) {
-        if (!virBufferGrow(buf, needSize - buf->use)) {
-            return (-1);
-        }
-    }
+    if (needSize > buf->size &&
+        virBufferGrow(buf, needSize - buf->use) < 0)
+        return;
 
     memcpy (&buf->content[buf->use], str, len);
     buf->use += len;
-    buf->content[buf->use] = 0;
-    return (0);
+    buf->content[buf->use] = '\0';
 }
 
 /**
@@ -94,89 +123,85 @@ __virBufferAdd(virBufferPtr buf, const c
  *
  * Add a single character 'c' to a buffer.
  *
- * Returns 0 if successful, -1 in the case of error.
  */
-int
+void
 __virBufferAddChar (virBufferPtr buf, char c)
 {
     unsigned int needSize;
 
     if (buf == NULL)
-        return -1;
+        return;
+
+    if (buf->error)
+        return;
 
     needSize = buf->use + 2;
-    if (needSize > buf->size)
-        if (!virBufferGrow (buf, needSize - buf->use))
-            return -1;
+    if (needSize > buf->size &&
+        virBufferGrow (buf, needSize - buf->use) < 0)
+        return;
 
     buf->content[buf->use++] = c;
-    buf->content[buf->use] = 0;
-
-    return 0;
+    buf->content[buf->use] = '\0';
 }
 
 /**
- * virBufferNew:
- * @size:  creation size in bytes
+ * virBufferContentAndReset:
+ * @buf: Buffer
  *
- * Creates a new buffer
+ * Get the content from the buffer and free (only) the buffer structure.
+ * The caller owns the returned string & should free it when no longer
+ * required. The buffer object is reset to its initial state.
  *
- * Returns a pointer to the buffer or NULL in case of error
+ * Returns the buffer content or NULL in case of error.
  */
-virBufferPtr
-virBufferNew(unsigned int size)
+char *
+__virBufferContentAndReset(const virBufferPtr buf)
 {
-    virBufferPtr buf;
+    char *str;
+    if (buf == NULL)
+        return NULL;
 
-    if (!(buf = malloc(sizeof(*buf)))) return NULL;
-    if (size && (buf->content = malloc(size))==NULL) {
-        free(buf);
+    if (buf->error) {
+        memset(buf, 0, sizeof(*buf));
         return NULL;
     }
-    buf->size = size;
-    buf->use = 0;
 
-    return buf;
+    str = buf->content;
+    memset(buf, 0, sizeof(*buf));
+    return str;
 }
 
 /**
- * virBufferFree:
- * @buf: the buffer to deallocate
+ * virBufferError:
+ * @buf: the buffer
  *
- * Free the set of resources used by a buffer.
+ * Check to see if the buffer is in an error state due
+ * to failed memory allocation
+ *
+ * Return true if in error, 0 if normal
  */
-
-void
-virBufferFree(virBufferPtr buf)
+int
+__virBufferError(const virBufferPtr buf)
 {
-    if (buf) {
-        free(buf->content);
-        free(buf);
-    }
+    if (buf == NULL)
+        return 1;
+
+    return buf->error;
 }
 
 /**
- * virBufferContentAndFree:
- * @buf: Buffer
+ * virBufferUse:
+ * @buf: the usage of the string in the buffer
  *
- * Get the content from the buffer and free (only) the buffer structure.
- *
- * Returns the buffer content or NULL in case of error.
+ * Return the string usage in bytes
  */
-char *
-virBufferContentAndFree (virBufferPtr buf)
+unsigned int
+virBufferUse(const virBufferPtr buf)
 {
-    char *content;
-
     if (buf == NULL)
-        return(NULL);
-
-    content = buf->content;
-    if (content != NULL)
-        content[buf->use] = 0;
+        return 0;
 
-    free (buf);
-    return(content);
+    return buf->use;
 }
 
 /**
@@ -186,22 +211,22 @@ virBufferContentAndFree (virBufferPtr bu
  * @...:  the variable list of arguments
  *
  * Do a formatted print to an XML buffer.
- *
- * Returns 0 successful, -1 in case of internal or API error.
  */
-int
-__virBufferVSprintf(virBufferPtr buf, const char *format, ...)
+void
+__virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
 {
     int size, count, grow_size;
     va_list locarg, argptr;
 
-    if ((format == NULL) || (buf == NULL)) {
-        return (-1);
-    }
+    if ((format == NULL) || (buf == NULL))
+        return;
+
+    if (buf->error)
+        return;
 
     if (buf->size == 0 &&
         virBufferGrow(buf, 100) < 0)
-        return -1;
+        return;
 
     size = buf->size - buf->use - 1;
     va_start(argptr, format);
@@ -210,17 +235,17 @@ __virBufferVSprintf(virBufferPtr buf, co
                                locarg)) < 0) || (count >= size - 1)) {
         buf->content[buf->use] = 0;
         va_end(locarg);
+
         grow_size = (count > 1000) ? count : 1000;
-        if (virBufferGrow(buf, grow_size) < 0) {
-            return (-1);
-        }
+        if (virBufferGrow(buf, grow_size) < 0)
+            return;
+
         size = buf->size - buf->use - 1;
         va_copy(locarg, argptr);
     }
     va_end(locarg);
     buf->use += count;
-    buf->content[buf->use] = 0;
-    return (0);
+    buf->content[buf->use] = '\0';
 }
 
 /**
@@ -231,25 +256,27 @@ __virBufferVSprintf(virBufferPtr buf, co
  *
  * Do a formatted print with a single string to an XML buffer. The string
  * is escaped to avoid generating a not well-formed XML instance.
- *
- * Returns 0 successful, -1 in case of internal or API error.
  */
-int
-virBufferEscapeString(virBufferPtr buf, const char *format, const char *str)
+void
+virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str)
 {
     int size, count, len, grow_size;
     char *escaped, *out;
     const char *cur;
 
-    if ((format == NULL) || (buf == NULL) || (str == NULL)) {
-        return (-1);
-    }
+    if ((format == NULL) || (buf == NULL) || (str == NULL))
+        return;
+
+    if (buf->error)
+        return;
 
     len = strlen(str);
     escaped = malloc(5 * len + 1);
     if (escaped == NULL) {
-        return (-1);
+        virBufferNoMemory(buf);
+        return;
     }
+
     cur = str;
     out = escaped;
     while (*cur != 0) {
@@ -290,14 +317,13 @@ virBufferEscapeString(virBufferPtr buf, 
         grow_size = (count > 1000) ? count : 1000;
         if (virBufferGrow(buf, grow_size) < 0) {
             free(escaped);
-            return (-1);
+            return;
         }
         size = buf->size - buf->use - 1;
     }
     buf->use += count;
-    buf->content[buf->use] = 0;
+    buf->content[buf->use] = '\0';
     free(escaped);
-    return (0);
 }
 
 /**
@@ -308,10 +334,8 @@ virBufferEscapeString(virBufferPtr buf, 
  * Append the string to the buffer.  The string will be URI-encoded
  * during the append (ie any non alpha-numeric characters are replaced
  * with '%xx' hex sequences).
- *
- * Returns 0 successful, -1 in case of internal or API error.
  */
-int
+void
 virBufferURIEncodeString (virBufferPtr buf, const char *str)
 {
     int grow_size = 0;
@@ -319,6 +343,12 @@ virBufferURIEncodeString (virBufferPtr b
     unsigned char uc;
     const char *hex = "0123456789abcdef";
 
+    if ((buf == NULL) || (str == NULL))
+        return;
+
+    if (buf->error)
+        return;
+
     for (p = str; *p; ++p) {
         /* This may not work on EBCDIC. */
         if ((*p >= 'a' && *p <= 'z') ||
@@ -329,8 +359,8 @@ virBufferURIEncodeString (virBufferPtr b
             grow_size += 3; /* %ab */
     }
 
-    if (virBufferGrow (buf, grow_size) == -1)
-        return -1;
+    if (virBufferGrow (buf, grow_size) < 0)
+        return;
 
     for (p = str; *p; ++p) {
         /* This may not work on EBCDIC. */
@@ -347,7 +377,6 @@ virBufferURIEncodeString (virBufferPtr b
     }
 
     buf->content[buf->use] = '\0';
-    return 0;
 }
 
 /**
@@ -356,15 +385,16 @@ virBufferURIEncodeString (virBufferPtr b
  * @...:  the variable list of strings, the last argument must be NULL
  *
  * Concatenate strings to an XML buffer.
- *
- * Returns 0 successful, -1 in case of internal or API error.
  */
-int
+void
 virBufferStrcat(virBufferPtr buf, ...)
 {
     va_list ap;
     char *str;
 
+    if (buf->error)
+        return;
+
     va_start(ap, buf);
 
     while ((str = va_arg(ap, char *)) != NULL) {
@@ -372,13 +402,12 @@ virBufferStrcat(virBufferPtr buf, ...)
         unsigned int needSize = buf->use + len + 2;
 
         if (needSize > buf->size) {
-            if (!virBufferGrow(buf, needSize - buf->use))
-                return -1;
+            if (virBufferGrow(buf, needSize - buf->use) < 0)
+                return;
         }
         memcpy(&buf->content[buf->use], str, len);
         buf->use += len;
         buf->content[buf->use] = 0;
     }
     va_end(ap);
-    return 0;
 }
Index: src/buf.h
===================================================================
RCS file: /data/cvs/libvirt/src/buf.h,v
retrieving revision 1.5
diff -u -p -r1.5 buf.h
--- src/buf.h	20 Feb 2008 15:29:13 -0000	1.5
+++ src/buf.h	28 Apr 2008 13:52:15 -0000
@@ -20,22 +20,30 @@
  */
 typedef struct _virBuffer virBuffer;
 typedef virBuffer *virBufferPtr;
+
+#ifndef __VIR_BUFFER_C__
+#define VIR_BUFFER_INITIALIZER { 0, 0, 0, NULL }
+
+/* This struct must be kept in syn with the real struct
+   in the buf.c impl file */
 struct _virBuffer {
-    char *content;          /* The buffer content UTF8 */
-    unsigned int use;       /* The buffer size used */
-    unsigned int size;      /* The buffer size */
+    unsigned int a;
+    unsigned int b;
+    unsigned int c;
+    char *d;
 };
+#endif
 
-virBufferPtr virBufferNew(unsigned int size);
-void virBufferFree(virBufferPtr buf);
-char *virBufferContentAndFree(virBufferPtr buf);
-int __virBufferAdd(virBufferPtr buf, const char *str, int len);
-int __virBufferAddChar(virBufferPtr buf, char c);
-int __virBufferVSprintf(virBufferPtr buf, const char *format, ...)
+char *__virBufferContentAndReset(const virBufferPtr buf);
+int __virBufferError(const virBufferPtr buf);
+unsigned int virBufferUse(const virBufferPtr buf);
+void __virBufferAdd(const virBufferPtr buf, const char *str, int len);
+void __virBufferAddChar(const virBufferPtr buf, char c);
+void __virBufferVSprintf(const virBufferPtr buf, const char *format, ...)
   ATTRIBUTE_FORMAT(printf, 2, 3);
-int virBufferStrcat(virBufferPtr buf, ...);
-int virBufferEscapeString(virBufferPtr buf, const char *format, const char *str);
-int virBufferURIEncodeString (virBufferPtr buf, const char *str);
+void virBufferStrcat(const virBufferPtr buf, ...);
+void virBufferEscapeString(const virBufferPtr buf, const char *format, const char *str);
+void virBufferURIEncodeString (const virBufferPtr buf, const char *str);
 
 #define virBufferAddLit(buf_, literal_string_) \
   __virBufferAdd (buf_, "" literal_string_ "", sizeof literal_string_ - 1)
@@ -44,4 +52,7 @@ int virBufferURIEncodeString (virBufferP
 #define virBufferAddChar(b,c) __virBufferAddChar((b),(c))
 #define virBufferVSprintf(b,f,...) __virBufferVSprintf((b),(f), __VA_ARGS__)
 
+#define virBufferContentAndReset(b) __virBufferContentAndReset((b))
+#define virBufferError(b) __virBufferError((b))
+
 #endif /* __VIR_BUFFER_H__ */
Index: src/capabilities.c
===================================================================
RCS file: /data/cvs/libvirt/src/capabilities.c,v
retrieving revision 1.6
diff -u -p -r1.6 capabilities.c
--- src/capabilities.c	10 Apr 2008 16:53:29 -0000	1.6
+++ src/capabilities.c	28 Apr 2008 13:52:16 -0000
@@ -521,172 +521,127 @@ virCapabilitiesDefaultGuestEmulator(virC
 char *
 virCapabilitiesFormatXML(virCapsPtr caps)
 {
-    virBuffer xml = { NULL, 0, 0 };
+    virBuffer xml = VIR_BUFFER_INITIALIZER;
     int i, j, k;
 
-    if (virBufferAddLit(&xml, "<capabilities>\n\n") < 0)
-      goto no_memory;
-    if (virBufferAddLit(&xml, "  <host>\n") < 0)
-        goto no_memory;
-    if (virBufferAddLit(&xml, "    <cpu>\n") < 0)
-        goto no_memory;
-    if (virBufferVSprintf(&xml, "      <arch>%s</arch>\n",
-                          caps->host.arch) < 0)
-        goto no_memory;
+    virBufferAddLit(&xml, "<capabilities>\n\n");
+    virBufferAddLit(&xml, "  <host>\n");
+    virBufferAddLit(&xml, "    <cpu>\n");
+    virBufferVSprintf(&xml, "      <arch>%s</arch>\n",
+                      caps->host.arch);
 
     if (caps->host.nfeatures) {
-        if (virBufferAddLit(&xml, "      <features>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "      <features>\n");
         for (i = 0 ; i < caps->host.nfeatures ; i++) {
-            if (virBufferVSprintf(&xml, "        <%s/>\n",
-                                  caps->host.features[i]) <0)
-                goto no_memory;
+            virBufferVSprintf(&xml, "        <%s/>\n",
+                              caps->host.features[i]);
         }
-        if (virBufferAddLit(&xml, "      </features>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "      </features>\n");
     }
-    if (virBufferAddLit(&xml, "    </cpu>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&xml, "    </cpu>\n");
 
     if (caps->host.offlineMigrate) {
-        if (virBufferAddLit(&xml, "    <migration_features>\n") < 0)
-            goto no_memory;
-        if (caps->host.liveMigrate &&
-            virBufferAddLit(&xml, "      <live/>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "    <migration_features>\n");
+        if (caps->host.liveMigrate)
+            virBufferAddLit(&xml, "      <live/>\n");
         if (caps->host.nmigrateTrans) {
-            if (virBufferAddLit(&xml, "      <uri_transports>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&xml, "      <uri_transports>\n");
             for (i = 0 ; i < caps->host.nmigrateTrans ; i++) {
-                if (virBufferVSprintf(&xml, "        <uri_transport>%s</uri_transport>\n",
-                                      caps->host.migrateTrans[i]) < 0)
-                    goto no_memory;
+                virBufferVSprintf(&xml, "        <uri_transport>%s</uri_transport>\n",
+                                      caps->host.migrateTrans[i]);
             }
-            if (virBufferAddLit(&xml, "      </uri_transports>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&xml, "      </uri_transports>\n");
         }
-        if (virBufferAddLit(&xml, "    </migration_features>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "    </migration_features>\n");
     }
 
     if (caps->host.nnumaCell) {
-        if (virBufferAddLit(&xml, "    <topology>\n") < 0)
-            goto no_memory;
-        if (virBufferVSprintf(&xml, "      <cells num='%d'>\n",
-                              caps->host.nnumaCell) < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "    <topology>\n");
+        virBufferVSprintf(&xml, "      <cells num='%d'>\n",
+                          caps->host.nnumaCell);
         for (i = 0 ; i < caps->host.nnumaCell ; i++) {
-            if (virBufferVSprintf(&xml, "        <cell id='%d'>\n",
-                                  caps->host.numaCell[i]->num) < 0)
-                goto no_memory;
-            if (virBufferVSprintf(&xml, "          <cpus num='%d'>\n",
-                                  caps->host.numaCell[i]->ncpus) < 0)
-                goto no_memory;
+            virBufferVSprintf(&xml, "        <cell id='%d'>\n",
+                              caps->host.numaCell[i]->num);
+            virBufferVSprintf(&xml, "          <cpus num='%d'>\n",
+                              caps->host.numaCell[i]->ncpus);
             for (j = 0 ; j < caps->host.numaCell[i]->ncpus ; j++)
-                if (virBufferVSprintf(&xml, "            <cpu id='%d'/>\n",
-                                      caps->host.numaCell[i]->cpus[j]) < 0)
-                    goto no_memory;
-            if (virBufferAddLit(&xml, "          </cpus>\n") < 0)
-                goto no_memory;
-            if (virBufferAddLit(&xml, "        </cell>\n") < 0)
-                goto no_memory;
-        }
-        if (virBufferAddLit(&xml, "      </cells>\n") < 0)
-            goto no_memory;
-        if (virBufferAddLit(&xml, "    </topology>\n") < 0)
-            goto no_memory;
+                virBufferVSprintf(&xml, "            <cpu id='%d'/>\n",
+                                  caps->host.numaCell[i]->cpus[j]);
+            virBufferAddLit(&xml, "          </cpus>\n");
+            virBufferAddLit(&xml, "        </cell>\n");
+        }
+        virBufferAddLit(&xml, "      </cells>\n");
+        virBufferAddLit(&xml, "    </topology>\n");
     }
-    if (virBufferAddLit(&xml, "  </host>\n\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&xml, "  </host>\n\n");
 
 
     for (i = 0 ; i < caps->nguests ; i++) {
-        if (virBufferAddLit(&xml, "  <guest>\n") < 0)
-            goto no_memory;
-        if (virBufferVSprintf(&xml, "    <os_type>%s</os_type>\n",
-                              caps->guests[i]->ostype) < 0)
-            goto no_memory;
-        if (virBufferVSprintf(&xml, "    <arch name='%s'>\n",
-                              caps->guests[i]->arch.name) < 0)
-            goto no_memory;
-        if (virBufferVSprintf(&xml, "      <wordsize>%d</wordsize>\n",
-                              caps->guests[i]->arch.wordsize) < 0)
-            goto no_memory;
-        if (caps->guests[i]->arch.defaultInfo.emulator &&
+        virBufferAddLit(&xml, "  <guest>\n");
+        virBufferVSprintf(&xml, "    <os_type>%s</os_type>\n",
+                          caps->guests[i]->ostype);
+        virBufferVSprintf(&xml, "    <arch name='%s'>\n",
+                          caps->guests[i]->arch.name);
+        virBufferVSprintf(&xml, "      <wordsize>%d</wordsize>\n",
+                          caps->guests[i]->arch.wordsize);
+        if (caps->guests[i]->arch.defaultInfo.emulator)
             virBufferVSprintf(&xml, "      <emulator>%s</emulator>\n",
-                              caps->guests[i]->arch.defaultInfo.emulator) < 0)
-            goto no_memory;
-        if (caps->guests[i]->arch.defaultInfo.loader &&
-            virBufferVSprintf(&xml, "      <loader>%s</loader>\n",
-                              caps->guests[i]->arch.defaultInfo.loader) < 0)
-            goto no_memory;
+                              caps->guests[i]->arch.defaultInfo.emulator);
+            if (caps->guests[i]->arch.defaultInfo.loader)
+                virBufferVSprintf(&xml, "      <loader>%s</loader>\n",
+                                  caps->guests[i]->arch.defaultInfo.loader);
 
         for (j = 0 ; j < caps->guests[i]->arch.defaultInfo.nmachines ; j++) {
-            if (virBufferVSprintf(&xml, "      <machine>%s</machine>\n",
-                                  caps->guests[i]->arch.defaultInfo.machines[j]) < 0)
-                goto no_memory;
+            virBufferVSprintf(&xml, "      <machine>%s</machine>\n",
+                              caps->guests[i]->arch.defaultInfo.machines[j]);
         }
 
         for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) {
-            if (virBufferVSprintf(&xml, "      <domain type='%s'>\n",
-                                  caps->guests[i]->arch.domains[j]->type) < 0)
-            goto no_memory;
-            if (caps->guests[i]->arch.domains[j]->info.emulator &&
+            virBufferVSprintf(&xml, "      <domain type='%s'>\n",
+                                  caps->guests[i]->arch.domains[j]->type);
+            if (caps->guests[i]->arch.domains[j]->info.emulator)
                 virBufferVSprintf(&xml, "        <emulator>%s</emulator>\n",
-                                  caps->guests[i]->arch.domains[j]->info.emulator) < 0)
-                goto no_memory;
-            if (caps->guests[i]->arch.domains[j]->info.loader &&
+                                  caps->guests[i]->arch.domains[j]->info.emulator);
+            if (caps->guests[i]->arch.domains[j]->info.loader)
                 virBufferVSprintf(&xml, "        <loader>%s</loader>\n",
-                                  caps->guests[i]->arch.domains[j]->info.loader) < 0)
-                goto no_memory;
+                                  caps->guests[i]->arch.domains[j]->info.loader);
 
             for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) {
-                if (virBufferVSprintf(&xml, "        <machine>%s</machine>\n",
-                                      caps->guests[i]->arch.domains[j]->info.machines[k]) < 0)
-                    goto no_memory;
+                virBufferVSprintf(&xml, "        <machine>%s</machine>\n",
+                                  caps->guests[i]->arch.domains[j]->info.machines[k]);
             }
-            if (virBufferAddLit(&xml, "      </domain>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&xml, "      </domain>\n");
         }
 
-        if (virBufferAddLit(&xml, "    </arch>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "    </arch>\n");
 
         if (caps->guests[i]->nfeatures) {
-            if (virBufferAddLit(&xml, "    <features>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&xml, "    <features>\n");
 
             for (j = 0 ; j < caps->guests[i]->nfeatures ; j++) {
                 if (STREQ(caps->guests[i]->features[j]->name, "pae") ||
                     STREQ(caps->guests[i]->features[j]->name, "nonpae") ||
                     STREQ(caps->guests[i]->features[j]->name, "ia64_be")) {
-                    if (virBufferVSprintf(&xml, "      <%s/>\n",
-                                          caps->guests[i]->features[j]->name) < 0)
-                        goto no_memory;
+                    virBufferVSprintf(&xml, "      <%s/>\n",
+                                      caps->guests[i]->features[j]->name);
                 } else {
-                    if (virBufferVSprintf(&xml, "      <%s default='%s' toggle='%s'/>\n",
-                                          caps->guests[i]->features[j]->name,
-                                          caps->guests[i]->features[j]->defaultOn ? "on" : "off",
-                                          caps->guests[i]->features[j]->toggle ? "yes" : "no") < 0)
-                        goto no_memory;
+                    virBufferVSprintf(&xml, "      <%s default='%s' toggle='%s'/>\n",
+                                      caps->guests[i]->features[j]->name,
+                                      caps->guests[i]->features[j]->defaultOn ? "on" : "off",
+                                      caps->guests[i]->features[j]->toggle ? "yes" : "no");
                 }
             }
 
-            if (virBufferAddLit(&xml, "    </features>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&xml, "    </features>\n");
         }
 
-
-        if (virBufferAddLit(&xml, "  </guest>\n\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&xml, "  </guest>\n\n");
     }
 
-    if (virBufferAddLit(&xml, "</capabilities>\n") < 0)
-      goto no_memory;
+    virBufferAddLit(&xml, "</capabilities>\n");
 
-    return xml.content;
+    if (virBufferError(&xml))
+        return NULL;
 
- no_memory:
-    free(xml.content);
-    return NULL;
+    return virBufferContentAndReset(&xml);
 }
Index: src/conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/conf.c,v
retrieving revision 1.25
diff -u -p -r1.25 conf.c
--- src/conf.c	10 Apr 2008 16:54:54 -0000	1.25
+++ src/conf.c	28 Apr 2008 13:52:16 -0000
@@ -877,43 +877,45 @@ __virConfSetValue (virConfPtr conf,
 int
 __virConfWriteFile(const char *filename, virConfPtr conf)
 {
-    virBufferPtr buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     virConfEntryPtr cur;
     int ret;
     int fd;
+    char *content;
+    unsigned int use;
 
     if (conf == NULL)
         return(-1);
 
-    buf = virBufferNew(500);
-    if (buf == NULL) {
-        virConfError(NULL, VIR_ERR_NO_MEMORY, _("failed to allocate buffer"), 0);
-        return(-1);
-    }
-
     cur = conf->entries;
     while (cur != NULL) {
-        virConfSaveEntry(buf, cur);
+        virConfSaveEntry(&buf, cur);
         cur = cur->next;
     }
 
+    if (virBufferError(&buf)) {
+        virConfError(NULL, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0);
+        return -1;
+    }
+
     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR );
     if (fd < 0) {
         virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to open file"), 0);
-        ret = -1;
-        goto error;
+        free(virBufferContentAndReset(&buf));
+        return -1;
     }
 
-    ret = safewrite(fd, buf->content, buf->use);
+    use = virBufferUse(&buf);
+    content = virBufferContentAndReset(&buf);
+    ret = safewrite(fd, content, use);
+    free(content);
     close(fd);
-    if (ret != (int) buf->use) {
+    if (ret != (int)use) {
         virConfError(NULL, VIR_ERR_WRITE_FAILED, _("failed to save content"), 0);
-        ret = -1;
-        goto error;
+        return -1;
     }
-error:
-    virBufferFree(buf);
-    return(ret);
+
+    return ret;
 }
 
 /**
@@ -932,34 +934,35 @@ error:
 int
 __virConfWriteMem(char *memory, int *len, virConfPtr conf)
 {
-    virBufferPtr buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     virConfEntryPtr cur;
-    int ret;
+    char *content;
+    unsigned int use;
 
     if ((memory == NULL) || (len == NULL) || (*len <= 0) || (conf == NULL))
         return(-1);
 
-    buf = virBufferNew(500);
-    if (buf == NULL) {
-        virConfError(NULL, VIR_ERR_NO_MEMORY, _("failed to allocate buffer"), 0);
-        return(-1);
-    }
-
     cur = conf->entries;
     while (cur != NULL) {
-        virConfSaveEntry(buf, cur);
+        virConfSaveEntry(&buf, cur);
         cur = cur->next;
     }
 
-    if ((int) buf->use >= *len) {
-        *len = buf->use;
-        ret = -1;
-        goto error;
-    }
-    memcpy(memory, buf->content, buf->use);
-    ret = buf->use;
-    *len = buf->use;
-error:
-    virBufferFree(buf);
-    return(ret);
+    if (virBufferError(&buf)) {
+        virConfError(NULL, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0);
+        return -1;
+    }
+
+    use = virBufferUse(&buf);
+    content = virBufferContentAndReset(&buf);
+
+    if ((int)use >= *len) {
+        *len = (int)use;
+        free(content);
+        return -1;
+    }
+    memcpy(memory, content, use);
+    free(content);
+    *len = use;
+    return use;
 }
Index: src/libvirt_sym.version
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt_sym.version,v
retrieving revision 1.38
diff -u -p -r1.38 libvirt_sym.version
--- src/libvirt_sym.version	28 Feb 2008 17:06:32 -0000	1.38
+++ src/libvirt_sym.version	28 Apr 2008 13:52:17 -0000
@@ -184,6 +184,8 @@
         __virBufferVSprintf;
         __virBufferAdd;
         __virBufferAddChar;
+        __virBufferContentAndReset;
+        __virBufferError;
 
 	__virMacAddrCompare;
 
Index: src/lxc_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/lxc_conf.c,v
retrieving revision 1.8
diff -u -p -r1.8 lxc_conf.c
--- src/lxc_conf.c	10 Apr 2008 16:54:54 -0000	1.8
+++ src/lxc_conf.c	28 Apr 2008 13:52:18 -0000
@@ -688,99 +688,49 @@ char *lxcGenerateXML(virConnectPtr conn,
                      lxc_vm_t *vm,
                      lxc_vm_def_t *def)
 {
-    virBufferPtr buf = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     lxc_mount_t *mount;
 
-    buf = virBufferNew(LXC_MAX_XML_LENGTH);
-    if (!buf) {
-        goto no_memory;
-    }
-
-    if (lxcIsActiveVM(vm)) {
-        if (virBufferVSprintf(buf, "<domain type='%s' id='%d'>\n",
-                              LXC_DOMAIN_TYPE, vm->def->id) < 0) {
-            goto no_memory;
-        }
-    } else {
-        if (virBufferVSprintf(buf, "<domain type='%s'>\n",
-                              LXC_DOMAIN_TYPE) < 0) {
-            goto no_memory;
-        }
-    }
+    if (lxcIsActiveVM(vm))
+        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n",
+                          LXC_DOMAIN_TYPE, vm->def->id);
+    else
+        virBufferVSprintf(&buf, "<domain type='%s'>\n",
+                          LXC_DOMAIN_TYPE);
 
-    if (virBufferVSprintf(buf, "    <name>%s</name>\n", def->name) < 0) {
-        goto no_memory;
-    }
+    virBufferVSprintf(&buf, "    <name>%s</name>\n", def->name);
 
     uuid = def->uuid;
     virUUIDFormat(uuid, uuidstr);
-    if (virBufferVSprintf(buf, "    <uuid>%s</uuid>\n", uuidstr) < 0) {
-        goto no_memory;
-    }
-
-    if (virBufferAddLit(buf, "    <os>\n") < 0) {
-        goto no_memory;
-    }
-
-    if (virBufferVSprintf(buf, "        <init>%s</init>\n", def->init) < 0) {
-        goto no_memory;
-    }
-
-    if (virBufferAddLit(buf, "    </os>\n") < 0) {
-        goto no_memory;
-    }
-
-    if (virBufferVSprintf(buf, "    <memory>%d</memory>\n", def->maxMemory) < 0) {
-        goto no_memory;
-    }
-
-    if (virBufferAddLit(buf, "    <devices>\n") < 0) {
-        goto no_memory;
-    }
+    virBufferVSprintf(&buf, "    <uuid>%s</uuid>\n", uuidstr);
+    virBufferAddLit(&buf, "    <os>\n");
+    virBufferVSprintf(&buf, "        <init>%s</init>\n", def->init);
+    virBufferAddLit(&buf, "    </os>\n");
+    virBufferVSprintf(&buf, "    <memory>%d</memory>\n", def->maxMemory);
+    virBufferAddLit(&buf, "    <devices>\n");
 
     /* loop adding mounts */
     for (mount = def->mounts; mount; mount = mount->next) {
-        if (virBufferAddLit(buf, "        <filesystem type='mount'>\n") < 0) {
-            goto no_memory;
-        }
-
-        if (virBufferVSprintf(buf, "            <source dir='%s'/>\n",
-                              mount->source) < 0) {
-            goto no_memory;
-        }
-
-        if (virBufferVSprintf(buf, "            <target dir='%s'/>\n",
-                              mount->target) < 0) {
-            goto no_memory;
-        }
-
-        if (virBufferAddLit(buf, "        </filesystem>\n") < 0) {
-            goto no_memory;
-        }
-
-    }
-
-    if (virBufferVSprintf(buf, "        <console tty='%s'/>\n", def->tty) < 0) {
-        goto no_memory;
+        virBufferAddLit(&buf, "        <filesystem type='mount'>\n");
+        virBufferVSprintf(&buf, "            <source dir='%s'/>\n",
+                          mount->source);
+        virBufferVSprintf(&buf, "            <target dir='%s'/>\n",
+                          mount->target);
+        virBufferAddLit(&buf, "        </filesystem>\n");
     }
 
-    if (virBufferAddLit(buf, "    </devices>\n") < 0) {
-        goto no_memory;
-    }
+    virBufferVSprintf(&buf, "        <console tty='%s'/>\n", def->tty);
+    virBufferAddLit(&buf, "    </devices>\n");
+    virBufferAddLit(&buf, "</domain>\n");
 
-    if (virBufferAddLit(buf, "</domain>\n") < 0) {
-        goto no_memory;
+    if (virBufferError(&buf)) {
+        lxcError(conn, NULL, VIR_ERR_NO_MEMORY,_("allocate buffer"));
+        return NULL;
     }
 
-    return virBufferContentAndFree(buf);
-
-no_memory:
-    lxcError(conn, NULL, VIR_ERR_NO_MEMORY, "generateXml");
-    virBufferFree(buf);
-
-    return NULL;
+    return virBufferContentAndReset(&buf);
 }
 
 void lxcFreeVMDef(lxc_vm_def_t *vmdef)
Index: src/qemu_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_conf.c,v
retrieving revision 1.49
diff -u -p -r1.49 qemu_conf.c
--- src/qemu_conf.c	25 Apr 2008 20:46:13 -0000	1.49
+++ src/qemu_conf.c	28 Apr 2008 13:52:20 -0000
@@ -3359,14 +3359,12 @@ static int qemudGenerateXMLChar(virBuffe
     if (STREQ(type, "console") &&
         dev->srcType == QEMUD_CHR_SRC_TYPE_PTY &&
         dev->srcData.file.path[0] != '\0') {
-        if (virBufferVSprintf(buf, "    <%s type='%s' tty='%s'>\n",
-                              type, types[dev->srcType],
-                              dev->srcData.file.path) < 0)
-            return -1;
+        virBufferVSprintf(buf, "    <%s type='%s' tty='%s'>\n",
+                          type, types[dev->srcType],
+                          dev->srcData.file.path);
     } else {
-        if (virBufferVSprintf(buf, "    <%s type='%s'>\n",
-                              type, types[dev->srcType]) < 0)
-            return -1;
+        virBufferVSprintf(buf, "    <%s type='%s'>\n",
+                          type, types[dev->srcType]);
     }
 
     switch (dev->srcType) {
@@ -3382,74 +3380,62 @@ static int qemudGenerateXMLChar(virBuffe
     case QEMUD_CHR_SRC_TYPE_PIPE:
         if (dev->srcType != QEMUD_CHR_SRC_TYPE_PTY ||
             dev->srcData.file.path[0]) {
-            if (virBufferVSprintf(buf, "      <source path='%s'/>\n",
-                                  dev->srcData.file.path) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source path='%s'/>\n",
+                              dev->srcData.file.path);
         }
         break;
 
     case QEMUD_CHR_SRC_TYPE_UDP:
         if (dev->srcData.udp.bindService[0] != '\0' &&
             dev->srcData.udp.bindHost[0] != '\0') {
-            if (virBufferVSprintf(buf, "      <source mode='bind' host='%s' service='%s'/>\n",
-                                  dev->srcData.udp.bindHost,
-                                  dev->srcData.udp.bindService) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source mode='bind' host='%s' service='%s'/>\n",
+                              dev->srcData.udp.bindHost,
+                              dev->srcData.udp.bindService);
         } else if (dev->srcData.udp.bindHost[0] !='\0') {
-            if (virBufferVSprintf(buf, "      <source mode='bind' host='%s'/>\n",
-                                  dev->srcData.udp.bindHost) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source mode='bind' host='%s'/>\n",
+                              dev->srcData.udp.bindHost);
         } else if (dev->srcData.udp.bindService[0] != '\0') {
-            if (virBufferVSprintf(buf, "      <source mode='bind' service='%s'/>\n",
-                                  dev->srcData.udp.bindService) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source mode='bind' service='%s'/>\n",
+                              dev->srcData.udp.bindService);
         }
 
         if (dev->srcData.udp.connectService[0] != '\0' &&
             dev->srcData.udp.connectHost[0] != '\0') {
-            if (virBufferVSprintf(buf, "      <source mode='connect' host='%s' service='%s'/>\n",
-                                  dev->srcData.udp.connectHost,
-                                  dev->srcData.udp.connectService) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source mode='connect' host='%s' service='%s'/>\n",
+                              dev->srcData.udp.connectHost,
+                              dev->srcData.udp.connectService);
         } else if (dev->srcData.udp.connectHost[0] != '\0') {
-            if (virBufferVSprintf(buf, "      <source mode='connect' host='%s'/>\n",
-                                  dev->srcData.udp.connectHost) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source mode='connect' host='%s'/>\n",
+                              dev->srcData.udp.connectHost);
         } else if (dev->srcData.udp.connectService[0] != '\0') {
-            if (virBufferVSprintf(buf, "      <source mode='connect' service='%s'/>\n",
-                                  dev->srcData.udp.connectService) < 0)
-                return -1;
+            virBufferVSprintf(buf, "      <source mode='connect' service='%s'/>\n",
+                              dev->srcData.udp.connectService);
         }
 
         break;
 
     case QEMUD_CHR_SRC_TYPE_TCP:
-        if (virBufferVSprintf(buf, "      <source mode='%s' host='%s' service='%s'/>\n",
-                              dev->srcData.tcp.listen ? "bind" : "connect",
-                              dev->srcData.tcp.host,
-                              dev->srcData.tcp.service) < 0)
-            return -1;
-        if (virBufferVSprintf(buf, "      <protocol type='%s'/>\n",
-                              dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET
-                              ? "telnet" : "raw") < 0)
-            return -1;
+        virBufferVSprintf(buf, "      <source mode='%s' host='%s' service='%s'/>\n",
+                          dev->srcData.tcp.listen ? "bind" : "connect",
+                          dev->srcData.tcp.host,
+                          dev->srcData.tcp.service);
+        virBufferVSprintf(buf, "      <protocol type='%s'/>\n",
+                          dev->srcData.tcp.protocol == QEMUD_CHR_SRC_TCP_PROTOCOL_TELNET
+                          ? "telnet" : "raw");
         break;
 
     case QEMUD_CHR_SRC_TYPE_UNIX:
-        if (virBufferVSprintf(buf, "      <source mode='%s' path='%s'/>\n",
-                              dev->srcData.nix.listen ? "bind" : "connect",
-                              dev->srcData.nix.path) < 0)
-            return -1;
+        virBufferVSprintf(buf, "      <source mode='%s' path='%s'/>\n",
+                          dev->srcData.nix.listen ? "bind" : "connect",
+                          dev->srcData.nix.path);
         break;
     }
 
-    if (virBufferVSprintf(buf, "      <target port='%d'/>\n",
-                          dev->dstPort) < 0)
-        return -1;
+    virBufferVSprintf(buf, "      <target port='%d'/>\n",
+                      dev->dstPort);
 
-    if (virBufferVSprintf(buf, "    </%s>\n",
-                          type) < 0)
-        return -1;
+    virBufferVSprintf(buf, "    </%s>\n",
+                      type);
 
     return 0;
 }
@@ -3461,7 +3447,7 @@ char *qemudGenerateXML(virConnectPtr con
                        struct qemud_vm *vm,
                        struct qemud_vm_def *def,
                        int live) {
-    virBufferPtr buf = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     const struct qemud_vm_disk_def *disk;
@@ -3471,10 +3457,6 @@ char *qemudGenerateXML(virConnectPtr con
     const char *type = NULL;
     int n;
 
-    buf = virBufferNew (QEMUD_MAX_XML_LEN);
-    if (!buf)
-        goto no_memory;
-
     switch (def->virtType) {
     case QEMUD_VIRT_QEMU:
         type = "qemu";
@@ -3492,49 +3474,34 @@ char *qemudGenerateXML(virConnectPtr con
         goto cleanup;
     }
 
-    if (qemudIsActiveVM(vm) && live) {
-        if (virBufferVSprintf(buf, "<domain type='%s' id='%d'>\n", type, vm->id) < 0)
-            goto no_memory;
-    } else {
-        if (virBufferVSprintf(buf, "<domain type='%s'>\n", type) < 0)
-            goto no_memory;
-    }
+    if (qemudIsActiveVM(vm) && live)
+        virBufferVSprintf(&buf, "<domain type='%s' id='%d'>\n", type, vm->id);
+    else
+        virBufferVSprintf(&buf, "<domain type='%s'>\n", type);
 
-    if (virBufferVSprintf(buf, "  <name>%s</name>\n", def->name) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", def->name);
 
     uuid = def->uuid;
     virUUIDFormat(uuid, uuidstr);
-    if (virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf, "  <memory>%lu</memory>\n", def->maxmem) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf, "  <currentMemory>%lu</currentMemory>\n", def->memory) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf, "  <vcpu>%d</vcpu>\n", def->vcpus) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
 
-    if (virBufferAddLit(buf, "  <os>\n") < 0)
-        goto no_memory;
-
-    if (def->virtType == QEMUD_VIRT_QEMU) {
-        if (virBufferVSprintf(buf, "    <type arch='%s' machine='%s'>%s</type>\n",
-                              def->os.arch, def->os.machine, def->os.type) < 0)
-            goto no_memory;
-    } else {
-        if (virBufferVSprintf(buf, "    <type>%s</type>\n", def->os.type) < 0)
-            goto no_memory;
-    }
+    virBufferVSprintf(&buf, "  <memory>%lu</memory>\n", def->maxmem);
+    virBufferVSprintf(&buf, "  <currentMemory>%lu</currentMemory>\n", def->memory);
+    virBufferVSprintf(&buf, "  <vcpu>%d</vcpu>\n", def->vcpus);
+    virBufferAddLit(&buf, "  <os>\n");
+
+    if (def->virtType == QEMUD_VIRT_QEMU)
+        virBufferVSprintf(&buf, "    <type arch='%s' machine='%s'>%s</type>\n",
+                          def->os.arch, def->os.machine, def->os.type);
+    else
+        virBufferVSprintf(&buf, "    <type>%s</type>\n", def->os.type);
 
     if (def->os.kernel[0])
-        if (virBufferVSprintf(buf, "    <kernel>%s</kernel>\n", def->os.kernel) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "    <kernel>%s</kernel>\n", def->os.kernel);
     if (def->os.initrd[0])
-        if (virBufferVSprintf(buf, "    <initrd>%s</initrd>\n", def->os.initrd) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "    <initrd>%s</initrd>\n", def->os.initrd);
     if (def->os.cmdline[0])
-        if (virBufferVSprintf(buf, "    <cmdline>%s</cmdline>\n", def->os.cmdline) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "    <cmdline>%s</cmdline>\n", def->os.cmdline);
 
     for (n = 0 ; n < def->os.nBootDevs ; n++) {
         const char *boottype = "hd";
@@ -3552,41 +3519,29 @@ char *qemudGenerateXML(virConnectPtr con
             boottype = "network";
             break;
         }
-        if (virBufferVSprintf(buf, "    <boot dev='%s'/>\n", boottype) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "    <boot dev='%s'/>\n", boottype);
     }
 
-    if (virBufferAddLit(buf, "  </os>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf, "  </os>\n");
 
     if (def->features & QEMUD_FEATURE_ACPI) {
-        if (virBufferAddLit(buf, "  <features>\n") < 0)
-            goto no_memory;
-        if (virBufferAddLit(buf, "    <acpi/>\n") < 0)
-            goto no_memory;
-        if (virBufferAddLit(buf, "  </features>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "  <features>\n");
+        virBufferAddLit(&buf, "    <acpi/>\n");
+        virBufferAddLit(&buf, "  </features>\n");
     }
 
-    virBufferVSprintf(buf, "  <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
+    virBufferVSprintf(&buf, "  <clock offset='%s'/>\n", def->localtime ? "localtime" : "utc");
 
-    if (virBufferAddLit(buf, "  <on_poweroff>destroy</on_poweroff>\n") < 0)
-        goto no_memory;
-    if (def->noReboot) {
-        if (virBufferAddLit(buf, "  <on_reboot>destroy</on_reboot>\n") < 0)
-            goto no_memory;
-    } else {
-        if (virBufferAddLit(buf, "  <on_reboot>restart</on_reboot>\n") < 0)
-            goto no_memory;
-    }
-    if (virBufferAddLit(buf, "  <on_crash>destroy</on_crash>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf, "  <on_poweroff>destroy</on_poweroff>\n");
+    if (def->noReboot)
+        virBufferAddLit(&buf, "  <on_reboot>destroy</on_reboot>\n");
+    else
+        virBufferAddLit(&buf, "  <on_reboot>restart</on_reboot>\n");
 
-    if (virBufferAddLit(buf, "  <devices>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf, "  <on_crash>destroy</on_crash>\n");
+    virBufferAddLit(&buf, "  <devices>\n");
 
-    if (virBufferVSprintf(buf, "    <emulator>%s</emulator>\n", def->os.binary) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, "    <emulator>%s</emulator>\n", def->os.binary);
 
     disk = def->disks;
     while (disk) {
@@ -3603,24 +3558,19 @@ char *qemudGenerateXML(virConnectPtr con
             "cdrom",
             "floppy",
         };
-        if (virBufferVSprintf(buf, "    <disk type='%s' device='%s'>\n",
-                              types[disk->type], devices[disk->device]) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "    <disk type='%s' device='%s'>\n",
+                          types[disk->type], devices[disk->device]);
 
         if (disk->src[0])
-            if (virBufferVSprintf(buf, "      <source %s='%s'/>\n",
-                                  typeAttrs[disk->type], disk->src) < 0)
-                goto no_memory;
+            virBufferVSprintf(&buf, "      <source %s='%s'/>\n",
+                              typeAttrs[disk->type], disk->src);
 
-        if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", disk->dst) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "      <target dev='%s'/>\n", disk->dst);
 
         if (disk->readonly)
-            if (virBufferAddLit(buf, "      <readonly/>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&buf, "      <readonly/>\n");
 
-        if (virBufferAddLit(buf, "    </disk>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "    </disk>\n");
 
         disk = disk->next;
     }
@@ -3636,69 +3586,53 @@ char *qemudGenerateXML(virConnectPtr con
             "network",
             "bridge",
         };
-        if (virBufferVSprintf(buf, "    <interface type='%s'>\n",
-                              types[net->type]) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "    <interface type='%s'>\n",
+                          types[net->type]);
 
-        if (virBufferVSprintf(buf, "      <mac address='%02x:%02x:%02x:%02x:%02x:%02x'/>\n",
-                              net->mac[0], net->mac[1], net->mac[2],
-                              net->mac[3], net->mac[4], net->mac[5]) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, "      <mac address='%02x:%02x:%02x:%02x:%02x:%02x'/>\n",
+                          net->mac[0], net->mac[1], net->mac[2],
+                          net->mac[3], net->mac[4], net->mac[5]);
 
         switch (net->type) {
         case QEMUD_NET_NETWORK:
-            if (virBufferVSprintf(buf, "      <source network='%s'/>\n", net->dst.network.name) < 0)
-                goto no_memory;
+            virBufferVSprintf(&buf, "      <source network='%s'/>\n", net->dst.network.name);
 
-            if (net->dst.network.ifname[0] != '\0') {
-                if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", net->dst.network.ifname) < 0)
-                    goto no_memory;
-            }
+            if (net->dst.network.ifname[0] != '\0')
+                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.network.ifname);
             break;
 
         case QEMUD_NET_ETHERNET:
-            if (net->dst.ethernet.ifname[0] != '\0') {
-                if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", net->dst.ethernet.ifname) < 0)
-                    goto no_memory;
-            }
-            if (net->dst.ethernet.script[0] != '\0') {
-                if (virBufferVSprintf(buf, "      <script path='%s'/>\n", net->dst.ethernet.script) < 0)
-                    goto no_memory;
-            }
+            if (net->dst.ethernet.ifname[0] != '\0')
+                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.ethernet.ifname);
+            if (net->dst.ethernet.script[0] != '\0')
+                virBufferVSprintf(&buf, "      <script path='%s'/>\n", net->dst.ethernet.script);
             break;
 
         case QEMUD_NET_BRIDGE:
-            if (virBufferVSprintf(buf, "      <source bridge='%s'/>\n", net->dst.bridge.brname) < 0)
-                goto no_memory;
-            if (net->dst.bridge.ifname[0] != '\0') {
-                if (virBufferVSprintf(buf, "      <target dev='%s'/>\n", net->dst.bridge.ifname) < 0)
-                    goto no_memory;
-            }
+            virBufferVSprintf(&buf, "      <source bridge='%s'/>\n", net->dst.bridge.brname);
+            if (net->dst.bridge.ifname[0] != '\0')
+                virBufferVSprintf(&buf, "      <target dev='%s'/>\n", net->dst.bridge.ifname);
             break;
 
         case QEMUD_NET_SERVER:
         case QEMUD_NET_CLIENT:
         case QEMUD_NET_MCAST:
-            if (net->dst.socket.address[0] != '\0') {
-                if (virBufferVSprintf(buf, "      <source address='%s' port='%d'/>\n",
-                                      net->dst.socket.address, net->dst.socket.port) < 0)
-                    goto no_memory;
-            } else {
-                if (virBufferVSprintf(buf, "      <source port='%d'/>\n",
-                                      net->dst.socket.port) < 0)
-                    goto no_memory;
-            }
+            if (net->dst.socket.address[0] != '\0')
+                virBufferVSprintf(&buf, "      <source address='%s' port='%d'/>\n",
+                                  net->dst.socket.address, net->dst.socket.port);
+            else
+                virBufferVSprintf(&buf, "      <source port='%d'/>\n",
+                                  net->dst.socket.port);
         }
 
-        if (virBufferAddLit(buf, "    </interface>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "    </interface>\n");
 
         net = net->next;
     }
 
     chr = def->serials;
     while (chr) {
-        if (qemudGenerateXMLChar(buf, chr, "serial") < 0)
+        if (qemudGenerateXMLChar(&buf, chr, "serial") < 0)
             goto no_memory;
 
         chr = chr->next;
@@ -3706,7 +3640,7 @@ char *qemudGenerateXML(virConnectPtr con
 
     chr = def->parallels;
     while (chr) {
-        if (qemudGenerateXMLChar(buf, chr, "parallel") < 0)
+        if (qemudGenerateXMLChar(&buf, chr, "parallel") < 0)
             goto no_memory;
 
         chr = chr->next;
@@ -3714,49 +3648,41 @@ char *qemudGenerateXML(virConnectPtr con
 
     /* First serial device is the primary console */
     if (def->nserials > 0 &&
-        qemudGenerateXMLChar(buf, def->serials, "console") < 0)
+        qemudGenerateXMLChar(&buf, def->serials, "console") < 0)
         goto no_memory;
 
     input = def->inputs;
     while (input) {
-        if (input->bus != QEMU_INPUT_BUS_PS2 &&
-            virBufferVSprintf(buf, "    <input type='%s' bus='usb'/>\n",
-                              input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet") < 0)
-            goto no_memory;
+        if (input->bus != QEMU_INPUT_BUS_PS2)
+            virBufferVSprintf(&buf, "    <input type='%s' bus='usb'/>\n",
+                              input->type == QEMU_INPUT_TYPE_MOUSE ? "mouse" : "tablet");
         input = input->next;
     }
     /* If graphics is enable, add implicit mouse */
     if (def->graphicsType != QEMUD_GRAPHICS_NONE)
-        if (virBufferAddLit(buf, "    <input type='mouse' bus='ps2'/>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "    <input type='mouse' bus='ps2'/>\n");
 
     switch (def->graphicsType) {
     case QEMUD_GRAPHICS_VNC:
-        if (virBufferAddLit(buf, "    <graphics type='vnc'") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "    <graphics type='vnc'");
 
-        if (def->vncPort &&
-            virBufferVSprintf(buf, " port='%d'",
-                              qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort) < 0)
-            goto no_memory;
+        if (def->vncPort)
+            virBufferVSprintf(&buf, " port='%d'",
+                              qemudIsActiveVM(vm) && live ? def->vncActivePort : def->vncPort);
 
-        if (def->vncListen[0] &&
-            virBufferVSprintf(buf, " listen='%s'",
-                              def->vncListen) < 0)
-            goto no_memory;
+        if (def->vncListen[0])
+            virBufferVSprintf(&buf, " listen='%s'",
+                              def->vncListen);
 
-        if (def->keymap &&
-            virBufferVSprintf(buf, " keymap='%s'",
-                              def->keymap) < 0)
-            goto no_memory;
+        if (def->keymap)
+            virBufferVSprintf(&buf, " keymap='%s'",
+                              def->keymap);
 
-        if (virBufferAddLit(buf, "/>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "/>\n");
         break;
 
     case QEMUD_GRAPHICS_SDL:
-        if (virBufferAddLit(buf, "    <graphics type='sdl'/>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "    <graphics type='sdl'/>\n");
         break;
 
     case QEMUD_GRAPHICS_NONE:
@@ -3764,20 +3690,19 @@ char *qemudGenerateXML(virConnectPtr con
         break;
     }
 
-    if (virBufferAddLit(buf, "  </devices>\n") < 0)
-        goto no_memory;
-
+    virBufferAddLit(&buf, "  </devices>\n");
+    virBufferAddLit(&buf, "</domain>\n");
 
-    if (virBufferAddLit(buf, "</domain>\n") < 0)
+    if (virBufferError(&buf))
         goto no_memory;
 
-    return virBufferContentAndFree (buf);
+    return virBufferContentAndReset(&buf);
 
  no_memory:
     qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
                      "%s", _("failed to generate XML: out of memory"));
  cleanup:
-    if (buf) virBufferFree (buf);
+    free(virBufferContentAndReset(&buf));
     return NULL;
 }
 
@@ -3786,89 +3711,73 @@ char *qemudGenerateNetworkXML(virConnect
                               struct qemud_driver *driver ATTRIBUTE_UNUSED,
                               struct qemud_network *network,
                               struct qemud_network_def *def) {
-    virBufferPtr buf = 0;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
 
-    buf = virBufferNew (QEMUD_MAX_XML_LEN);
-    if (!buf)
-        goto no_memory;
+    virBufferAddLit(&buf, "<network>\n");
 
-    if (virBufferAddLit(buf, "<network>\n") < 0)
-        goto no_memory;
-
-    if (virBufferVSprintf(buf, "  <name>%s</name>\n", def->name) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", def->name);
 
     uuid = def->uuid;
     virUUIDFormat(uuid, uuidstr);
-    if (virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
 
     if (def->forward) {
         if (def->forwardDev[0]) {
-            virBufferVSprintf(buf, "  <forward dev='%s' mode='%s'/>\n",
+            virBufferVSprintf(&buf, "  <forward dev='%s' mode='%s'/>\n",
                               def->forwardDev, (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
         } else {
-            virBufferVSprintf(buf, "  <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
+            virBufferVSprintf(&buf, "  <forward mode='%s'/>\n", (def->forwardMode == QEMUD_NET_FORWARD_ROUTE ? "route" : "nat"));
         }
     }
 
-    virBufferAddLit(buf, "  <bridge");
+    virBufferAddLit(&buf, "  <bridge");
     if (qemudIsActiveNetwork(network)) {
-        if (virBufferVSprintf(buf, " name='%s'", network->bridge) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, " name='%s'", network->bridge);
     } else if (def->bridge[0]) {
-        if (virBufferVSprintf(buf, " name='%s'", def->bridge) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf, " name='%s'", def->bridge);
     }
-    if (virBufferVSprintf(buf, " stp='%s' forwardDelay='%d' />\n",
-                       def->disableSTP ? "off" : "on",
-                       def->forwardDelay) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, " stp='%s' forwardDelay='%d' />\n",
+                      def->disableSTP ? "off" : "on",
+                      def->forwardDelay);
 
     if (def->ipAddress[0] || def->netmask[0]) {
-        if (virBufferAddLit(buf, "  <ip") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "  <ip");
 
-        if (def->ipAddress[0] &&
-            virBufferVSprintf(buf, " address='%s'", def->ipAddress) < 0)
-            goto no_memory;
+        if (def->ipAddress[0])
+            virBufferVSprintf(&buf, " address='%s'", def->ipAddress);
 
-        if (def->netmask[0] &&
-            virBufferVSprintf(buf, " netmask='%s'", def->netmask) < 0)
-            goto no_memory;
+        if (def->netmask[0])
+            virBufferVSprintf(&buf, " netmask='%s'", def->netmask);
 
-        if (virBufferAddLit(buf, ">\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, ">\n");
 
         if (def->ranges) {
             struct qemud_dhcp_range_def *range = def->ranges;
-            if (virBufferAddLit(buf, "    <dhcp>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&buf, "    <dhcp>\n");
             while (range) {
-                if (virBufferVSprintf(buf, "      <range start='%s' end='%s' />\n",
-                                      range->start, range->end) < 0)
-                    goto no_memory;
+                virBufferVSprintf(&buf, "      <range start='%s' end='%s' />\n",
+                                  range->start, range->end);
                 range = range->next;
             }
-            if (virBufferAddLit(buf, "    </dhcp>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&buf, "    </dhcp>\n");
         }
 
-        if (virBufferAddLit(buf, "  </ip>\n") < 0)
-            goto no_memory;
+        virBufferAddLit(&buf, "  </ip>\n");
     }
 
-    if (virBufferAddLit(buf, "</network>\n") < 0)
+    virBufferAddLit(&buf, "</network>\n");
+
+    if (virBufferError(&buf))
         goto no_memory;
 
-    return virBufferContentAndFree (buf);
+    return virBufferContentAndReset(&buf);
 
  no_memory:
     qemudReportError(conn, NULL, NULL, VIR_ERR_NO_MEMORY,
                      "%s", _("failed to generate XML: out of memory"));
-    if (buf) virBufferFree (buf);
+    free(virBufferContentAndReset(&buf));
     return NULL;
 }
 
Index: src/qparams.c
===================================================================
RCS file: /data/cvs/libvirt/src/qparams.c,v
retrieving revision 1.3
diff -u -p -r1.3 qparams.c
--- src/qparams.c	10 Apr 2008 16:53:29 -0000	1.3
+++ src/qparams.c	28 Apr 2008 13:52:21 -0000
@@ -136,20 +136,23 @@ append_qparam (struct qparam_set *ps,
 char *
 qparam_get_query (const struct qparam_set *ps)
 {
-    virBufferPtr buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     int i, amp = 0;
 
-    buf = virBufferNew (100);
     for (i = 0; i < ps->n; ++i) {
         if (!ps->p[i].ignore) {
-            if (amp) virBufferAddChar (buf, '&');
-            virBufferStrcat (buf, ps->p[i].name, "=", NULL);
-            virBufferURIEncodeString (buf, ps->p[i].value);
+            if (amp) virBufferAddChar (&buf, '&');
+            virBufferStrcat (&buf, ps->p[i].name, "=", NULL);
+            virBufferURIEncodeString (&buf, ps->p[i].value);
             amp = 1;
         }
     }
 
-    return virBufferContentAndFree (buf);
+    if (virBufferError(&buf)) {
+        return NULL;
+    }
+
+    return virBufferContentAndReset(&buf);
 }
 
 void
Index: src/storage_conf.c
===================================================================
RCS file: /data/cvs/libvirt/src/storage_conf.c,v
retrieving revision 1.5
diff -u -p -r1.5 storage_conf.c
--- src/storage_conf.c	10 Apr 2008 16:53:29 -0000	1.5
+++ src/storage_conf.c	28 Apr 2008 13:52:21 -0000
@@ -414,7 +414,7 @@ char *
 virStoragePoolDefFormat(virConnectPtr conn,
                         virStoragePoolDefPtr def) {
     virStorageBackendPoolOptionsPtr options;
-    virBufferPtr buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     const char *type;
     char uuid[VIR_UUID_STRING_BUFLEN];
     int i;
@@ -423,126 +423,96 @@ virStoragePoolDefFormat(virConnectPtr co
     if (options == NULL)
         return NULL;
 
-    if ((buf = virBufferNew(8192)) == NULL)
-        goto no_memory;
-
     type = virStorageBackendToString(def->type);
     if (!type) {
         virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR,
                               "%s", _("unexpected pool type"));
         goto cleanup;
     }
-    if (virBufferVSprintf(buf, "<pool type='%s'>\n", type) < 0)
-        goto no_memory;
-
-    if (virBufferVSprintf(buf,"  <name>%s</name>\n", def->name) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf, "<pool type='%s'>\n", type);
+    virBufferVSprintf(&buf,"  <name>%s</name>\n", def->name);
 
     virUUIDFormat(def->uuid, uuid);
-    if (virBufferVSprintf(buf,"  <uuid>%s</uuid>\n", uuid) < 0)
-        goto no_memory;
-
-    if (virBufferVSprintf(buf,"  <capacity>%llu</capacity>\n",
-                          def->capacity) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"  <allocation>%llu</allocation>\n",
-                          def->allocation) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"  <available>%llu</available>\n",
-                          def->available) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf,"  <uuid>%s</uuid>\n", uuid);
 
+    virBufferVSprintf(&buf,"  <capacity>%llu</capacity>\n",
+                      def->capacity);
+    virBufferVSprintf(&buf,"  <allocation>%llu</allocation>\n",
+                      def->allocation);
+    virBufferVSprintf(&buf,"  <available>%llu</available>\n",
+                      def->available);
 
-    if (virBufferAddLit(buf,"  <source>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf,"  <source>\n");
     if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_HOST) &&
-        def->source.host.name &&
-        virBufferVSprintf(buf,"    <host name='%s'/>\n", def->source.host.name) < 0)
-        goto no_memory;
+        def->source.host.name)
+        virBufferVSprintf(&buf,"    <host name='%s'/>\n", def->source.host.name);
+
     if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_DEVICE) &&
         def->source.ndevice) {
         for (i = 0 ; i < def->source.ndevice ; i++) {
-            if (virBufferVSprintf(buf,"    <device path='%s'>\n", def->source.devices[i].path) < 0)
-                goto no_memory;
+            virBufferVSprintf(&buf,"    <device path='%s'>\n", def->source.devices[i].path);
             if (def->source.devices[i].nfreeExtent) {
                 int j;
                 for (j = 0 ; j < def->source.devices[i].nfreeExtent ; j++) {
-                    if (virBufferVSprintf(buf, "    <freeExtent start='%llu' end='%llu'/>\n",
-                                          def->source.devices[i].freeExtents[j].start,
-                                          def->source.devices[i].freeExtents[j].end) < 0)
-                        goto no_memory;
+                    virBufferVSprintf(&buf, "    <freeExtent start='%llu' end='%llu'/>\n",
+                                      def->source.devices[i].freeExtents[j].start,
+                                      def->source.devices[i].freeExtents[j].end);
                 }
             }
-            if (virBufferAddLit(buf,"    </device>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&buf,"    </device>\n");
         }
     }
     if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_DIR) &&
-        def->source.dir &&
-        virBufferVSprintf(buf,"    <dir path='%s'/>\n", def->source.dir) < 0)
-        goto no_memory;
+        def->source.dir)
+        virBufferVSprintf(&buf,"    <dir path='%s'/>\n", def->source.dir);
     if ((options->flags & VIR_STORAGE_BACKEND_POOL_SOURCE_ADAPTER) &&
-        def->source.adapter &&
-        virBufferVSprintf(buf,"    <adapter name='%s'/>\n", def->source.adapter) < 0)
-        goto no_memory;
+        def->source.adapter)
+        virBufferVSprintf(&buf,"    <adapter name='%s'/>\n", def->source.adapter);
 
     if (options->formatToString) {
         const char *format = (options->formatToString)(conn, def->source.format);
         if (!format)
             goto cleanup;
-        if (virBufferVSprintf(buf,"    <format type='%s'/>\n", format) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf,"    <format type='%s'/>\n", format);
     }
 
 
-    if (def->source.authType == VIR_STORAGE_POOL_AUTH_CHAP &&
-        virBufferVSprintf(buf,"    <auth type='chap' login='%s' passwd='%s'>\n",
+    if (def->source.authType == VIR_STORAGE_POOL_AUTH_CHAP)
+        virBufferVSprintf(&buf,"    <auth type='chap' login='%s' passwd='%s'>\n",
                           def->source.auth.chap.login,
-                          def->source.auth.chap.passwd) < 0)
-        goto no_memory;
-    if (virBufferAddLit(buf,"  </source>\n") < 0)
-        goto no_memory;
+                          def->source.auth.chap.passwd);
+    virBufferAddLit(&buf,"  </source>\n");
 
+    virBufferAddLit(&buf,"  <target>\n");
 
+    if (def->target.path)
+        virBufferVSprintf(&buf,"    <path>%s</path>\n", def->target.path);
 
-    if (virBufferAddLit(buf,"  <target>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf,"    <permissions>\n");
+    virBufferVSprintf(&buf,"      <mode>0%o</mode>\n",
+                      def->target.perms.mode);
+    virBufferVSprintf(&buf,"      <owner>%d</owner>\n",
+                      def->target.perms.uid);
+    virBufferVSprintf(&buf,"      <group>%d</group>\n",
+                      def->target.perms.gid);
 
-    if (def->target.path &&
-        virBufferVSprintf(buf,"    <path>%s</path>\n", def->target.path) < 0)
-        goto no_memory;
+    if (def->target.perms.label)
+        virBufferVSprintf(&buf,"      <label>%s</label>\n",
+                          def->target.perms.label);
 
-    if (virBufferAddLit(buf,"    <permissions>\n") < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"      <mode>0%o</mode>\n",
-                          def->target.perms.mode) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"      <owner>%d</owner>\n",
-                          def->target.perms.uid) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"      <group>%d</group>\n",
-                          def->target.perms.gid) < 0)
-        goto no_memory;
+    virBufferAddLit(&buf,"    </permissions>\n");
+    virBufferAddLit(&buf,"  </target>\n");
+    virBufferAddLit(&buf,"</pool>\n");
 
-    if (def->target.perms.label) {
-        if (virBufferVSprintf(buf,"      <label>%s</label>\n",
-                              def->target.perms.label) < 0)
-            goto no_memory;
-    }
-    if (virBufferAddLit(buf,"    </permissions>\n") < 0)
-        goto no_memory;
-    if (virBufferAddLit(buf,"  </target>\n") < 0)
+    if (virBufferError(&buf))
         goto no_memory;
 
-    if (virBufferAddLit(buf,"</pool>\n") < 0)
-        goto no_memory;
-
-    return virBufferContentAndFree(buf);
+    return virBufferContentAndReset(&buf);
 
  no_memory:
     virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("xml"));
  cleanup:
-    virBufferFree(buf);
+    free(virBufferContentAndReset(&buf));
     return NULL;
 }
 
@@ -804,26 +774,17 @@ virStorageVolDefFormat(virConnectPtr con
                        virStoragePoolDefPtr pool,
                        virStorageVolDefPtr def) {
     virStorageBackendVolOptionsPtr options;
-    virBufferPtr buf = virBufferNew(8192);
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
     options = virStorageBackendVolOptionsForType(pool->type);
     if (options == NULL)
         return NULL;
 
-    if (!buf)
-        goto no_memory;
-
-    if (virBufferAddLit(buf, "<volume>\n") < 0)
-        goto no_memory;
-
-    if (virBufferVSprintf(buf,"  <name>%s</name>\n", def->name) < 0)
-        goto no_memory;
-
-    if (virBufferVSprintf(buf,"  <key>%s</key>\n", def->key) < 0)
-        goto no_memory;
+    virBufferAddLit(&buf, "<volume>\n");
+    virBufferVSprintf(&buf,"  <name>%s</name>\n", def->name);
+    virBufferVSprintf(&buf,"  <key>%s</key>\n", def->key);
+    virBufferAddLit(&buf, "  <source>\n");
 
-    if (virBufferAddLit(buf, "  <source>\n") < 0)
-        goto no_memory;
     if (def->source.nextent) {
         int i;
         const char *thispath = NULL;
@@ -831,81 +792,67 @@ virStorageVolDefFormat(virConnectPtr con
             if (thispath == NULL ||
                 STRNEQ(thispath, def->source.extents[i].path)) {
                 if (thispath != NULL)
-                    if (virBufferAddLit(buf, "    </device>\n") < 0)
-                        goto no_memory;
-                if (virBufferVSprintf(buf, "    <device path='%s'>\n",
-                                      def->source.extents[i].path) < 0)
-                    goto no_memory;
+                    virBufferAddLit(&buf, "    </device>\n");
+
+                virBufferVSprintf(&buf, "    <device path='%s'>\n",
+                                  def->source.extents[i].path);
             }
 
-            if (virBufferVSprintf(buf,
-                                  "      <extent start='%llu' end='%llu'/>\n",
-                                  def->source.extents[i].start,
-                                  def->source.extents[i].end) < 0)
-                goto no_memory;
+            virBufferVSprintf(&buf,
+                              "      <extent start='%llu' end='%llu'/>\n",
+                              def->source.extents[i].start,
+                              def->source.extents[i].end);
             thispath = def->source.extents[i].path;
         }
         if (thispath != NULL)
-            if (virBufferAddLit(buf, "    </device>\n") < 0)
-                goto no_memory;
+            virBufferAddLit(&buf, "    </device>\n");
     }
-    if (virBufferAddLit(buf, "  </source>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf, "  </source>\n");
 
-    if (virBufferVSprintf(buf,"  <capacity>%llu</capacity>\n",
-                          def->capacity) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"  <allocation>%llu</allocation>\n",
-                          def->allocation) < 0)
-        goto no_memory;
+    virBufferVSprintf(&buf,"  <capacity>%llu</capacity>\n",
+                      def->capacity);
+    virBufferVSprintf(&buf,"  <allocation>%llu</allocation>\n",
+                      def->allocation);
 
-    if (virBufferAddLit(buf, "  <target>\n") < 0)
-        goto no_memory;
+    virBufferAddLit(&buf, "  <target>\n");
 
-    if (def->target.path &&
-        virBufferVSprintf(buf,"    <path>%s</path>\n", def->target.path) < 0)
-        goto no_memory;
+    if (def->target.path)
+        virBufferVSprintf(&buf,"    <path>%s</path>\n", def->target.path);
 
     if (options->formatToString) {
         const char *format = (options->formatToString)(conn,
                                                        def->target.format);
         if (!format)
             goto cleanup;
-        if (virBufferVSprintf(buf,"    <format type='%s'/>\n", format) < 0)
-            goto no_memory;
+        virBufferVSprintf(&buf,"    <format type='%s'/>\n", format);
     }
 
-    if (virBufferAddLit(buf,"    <permissions>\n") < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"      <mode>0%o</mode>\n",
-                          def->target.perms.mode) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"      <owner>%d</owner>\n",
-                          def->target.perms.uid) < 0)
-        goto no_memory;
-    if (virBufferVSprintf(buf,"      <group>%d</group>\n",
-                          def->target.perms.gid) < 0)
-        goto no_memory;
+    virBufferAddLit(&buf,"    <permissions>\n");
+    virBufferVSprintf(&buf,"      <mode>0%o</mode>\n",
+                      def->target.perms.mode);
+    virBufferVSprintf(&buf,"      <owner>%d</owner>\n",
+                      def->target.perms.uid);
+    virBufferVSprintf(&buf,"      <group>%d</group>\n",
+                      def->target.perms.gid);
 
-    if (def->target.perms.label &&
-        virBufferVSprintf(buf,"      <label>%s</label>\n",
-                          def->target.perms.label) < 0)
-        goto no_memory;
-    if (virBufferAddLit(buf,"    </permissions>\n") < 0)
-        goto no_memory;
 
-    if (virBufferAddLit(buf, "  </target>\n") < 0)
-        goto no_memory;
+    if (def->target.perms.label)
+        virBufferVSprintf(&buf,"      <label>%s</label>\n",
+                          def->target.perms.label);
+
+    virBufferAddLit(&buf,"    </permissions>\n");
+    virBufferAddLit(&buf, "  </target>\n");
+    virBufferAddLit(&buf,"</volume>\n");
 
-    if (virBufferAddLit(buf,"</volume>\n") < 0)
+    if (virBufferError(&buf))
         goto no_memory;
 
-    return virBufferContentAndFree(buf);
+    return virBufferContentAndReset(&buf);
 
  no_memory:
     virStorageReportError(conn, VIR_ERR_NO_MEMORY, "%s", _("xml"));
  cleanup:
-    virBufferFree(buf);
+    free(virBufferContentAndReset(&buf));
     return NULL;
 }
 
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.72
diff -u -p -r1.72 test.c
--- src/test.c	10 Apr 2008 16:53:29 -0000	1.72
+++ src/test.c	28 Apr 2008 13:52:23 -0000
@@ -1523,34 +1523,30 @@ static int testSetVcpus(virDomainPtr dom
 
 static char *testDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
 {
-    virBufferPtr buf;
-    char *xml;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     GET_DOMAIN(domain, NULL);
 
-    if (!(buf = virBufferNew(4000))) {
-        testError(domain->conn, domain, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__);
-        return (NULL);
-    }
-
-    virBufferVSprintf(buf, "<domain type='test' id='%d'>\n", domain->id);
-    virBufferVSprintf(buf, "  <name>%s</name>\n", domain->name);
+    virBufferVSprintf(&buf, "<domain type='test' id='%d'>\n", domain->id);
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", domain->name);
     uuid = domain->uuid;
     virUUIDFormat(uuid, uuidstr);
-    virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr);
-    virBufferVSprintf(buf, "  <memory>%lu</memory>\n", privdom->info.maxMem);
-    virBufferVSprintf(buf, "  <vcpu>%d</vcpu>\n", privdom->info.nrVirtCpu);
-    virBufferVSprintf(buf, "  <on_reboot>%s</on_reboot>\n", testRestartFlagToString(privdom->onReboot));
-    virBufferVSprintf(buf, "  <on_poweroff>%s</on_poweroff>\n", testRestartFlagToString(privdom->onPoweroff));
-    virBufferVSprintf(buf, "  <on_crash>%s</on_crash>\n", testRestartFlagToString(privdom->onCrash));
+    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
+    virBufferVSprintf(&buf, "  <memory>%lu</memory>\n", privdom->info.maxMem);
+    virBufferVSprintf(&buf, "  <vcpu>%d</vcpu>\n", privdom->info.nrVirtCpu);
+    virBufferVSprintf(&buf, "  <on_reboot>%s</on_reboot>\n", testRestartFlagToString(privdom->onReboot));
+    virBufferVSprintf(&buf, "  <on_poweroff>%s</on_poweroff>\n", testRestartFlagToString(privdom->onPoweroff));
+    virBufferVSprintf(&buf, "  <on_crash>%s</on_crash>\n", testRestartFlagToString(privdom->onCrash));
 
-    virBufferAddLit(buf, "</domain>\n");
+    virBufferAddLit(&buf, "</domain>\n");
 
-    xml = buf->content;
-    free(buf);
+    if (virBufferError(&buf)) {
+        testError(domain->conn, domain, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__);
+        return NULL;
+    }
 
-    return (xml);
+    return virBufferContentAndReset(&buf);
 }
 
 static int testNumOfDefinedDomains(virConnectPtr conn) {
@@ -1928,44 +1924,40 @@ static int testNetworkDestroy(virNetwork
 }
 
 static char *testNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
-    virBufferPtr buf;
-    char *xml;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     unsigned char *uuid;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     GET_NETWORK(network, NULL);
 
-    if (!(buf = virBufferNew(4000))) {
-        testError(network->conn, NULL, network, VIR_ERR_NO_MEMORY, __FUNCTION__);
-        return (NULL);
-    }
-
-    virBufferAddLit(buf, "<network>\n");
-    virBufferVSprintf(buf, "  <name>%s</name>\n", network->name);
+    virBufferAddLit(&buf, "<network>\n");
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", network->name);
     uuid = network->uuid;
     virUUIDFormat(uuid, uuidstr);
-    virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr);
-    virBufferVSprintf(buf, "  <bridge name='%s'/>\n", privnet->bridge);
+    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
+    virBufferVSprintf(&buf, "  <bridge name='%s'/>\n", privnet->bridge);
     if (privnet->forward) {
         if (privnet->forwardDev[0])
-            virBufferVSprintf(buf, "  <forward dev='%s'/>\n", privnet->forwardDev);
+            virBufferVSprintf(&buf, "  <forward dev='%s'/>\n", privnet->forwardDev);
         else
-            virBufferAddLit(buf, "  <forward/>\n");
+            virBufferAddLit(&buf, "  <forward/>\n");
     }
 
-    virBufferVSprintf(buf, "  <ip address='%s' netmask='%s'>\n",
+    virBufferVSprintf(&buf, "  <ip address='%s' netmask='%s'>\n",
                       privnet->ipAddress, privnet->ipNetmask);
-    virBufferAddLit(buf, "    <dhcp>\n");
-    virBufferVSprintf(buf, "      <range start='%s' end='%s'/>\n",
+    virBufferAddLit(&buf, "    <dhcp>\n");
+    virBufferVSprintf(&buf, "      <range start='%s' end='%s'/>\n",
                       privnet->dhcpStart, privnet->dhcpEnd);
-    virBufferAddLit(buf, "    </dhcp>\n");
-    virBufferAddLit(buf, "  </ip>\n");
+    virBufferAddLit(&buf, "    </dhcp>\n");
+    virBufferAddLit(&buf, "  </ip>\n");
 
-    virBufferAddLit(buf, "</network>\n");
+    virBufferAddLit(&buf, "</network>\n");
 
-    xml = buf->content;
-    free(buf);
+    if (virBufferError(&buf)) {
+        testError(network->conn, NULL, network, VIR_ERR_NO_MEMORY, __FUNCTION__);
+        return NULL;
+    }
 
-    return (xml);
+    return virBufferContentAndReset(&buf);
 }
 
 static char *testNetworkGetBridgeName(virNetworkPtr network) {
Index: src/virsh.c
===================================================================
RCS file: /data/cvs/libvirt/src/virsh.c,v
retrieving revision 1.147
diff -u -p -r1.147 virsh.c
--- src/virsh.c	28 Apr 2008 09:09:52 -0000	1.147
+++ src/virsh.c	28 Apr 2008 13:52:27 -0000
@@ -2885,10 +2885,9 @@ cmdPoolCreateAs(vshControl * ctl, vshCmd
 {
     virStoragePoolPtr pool;
     int found;
+    char *xml;
     char *name, *type, *srcHost, *srcPath, *srcDev, *target;
-    virBuffer buf;
-
-    memset(&buf, 0, sizeof(buf));
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
     if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
         return FALSE;
@@ -2905,39 +2904,36 @@ cmdPoolCreateAs(vshControl * ctl, vshCmd
     srcDev = vshCommandOptString(cmd, "source-dev", &found);
     target = vshCommandOptString(cmd, "target", &found);
 
-    if (virBufferVSprintf(&buf, "<pool type='%s'>\n", type) < 0)
-        goto cleanup;
-    if (virBufferVSprintf(&buf, "  <name>%s</name>\n", name) < 0)
-        goto cleanup;
+    virBufferVSprintf(&buf, "<pool type='%s'>\n", type);
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", name);
     if (srcHost || srcPath || srcDev) {
-        if (virBufferAddLit(&buf, "  <source>\n") < 0)
-            goto cleanup;
-        if (srcHost &&
-            virBufferVSprintf(&buf, "    <host name='%s'>\n", srcHost) < 0)
-            goto cleanup;
-        if (srcPath &&
-            virBufferVSprintf(&buf, "    <dir path='%s'/>\n", srcPath) < 0)
-            goto cleanup;
-        if (srcDev &&
-            virBufferVSprintf(&buf, "    <device path='%s'/>\n", srcDev) < 0)
-            goto cleanup;
+        virBufferAddLit(&buf, "  <source>\n");
+        if (srcHost)
+            virBufferVSprintf(&buf, "    <host name='%s'>\n", srcHost);
 
-        if (virBufferAddLit(&buf, "  </source>\n") < 0)
-            goto cleanup;
+        if (srcPath)
+            virBufferVSprintf(&buf, "    <dir path='%s'/>\n", srcPath);
+
+        if (srcDev)
+            virBufferVSprintf(&buf, "    <device path='%s'/>\n", srcDev);
+
+        virBufferAddLit(&buf, "  </source>\n");
     }
     if (target) {
-        if (virBufferAddLit(&buf, "  <target>\n") < 0)
-            goto cleanup;
-        if (virBufferVSprintf(&buf, "    <path>%s</path>\n", target) < 0)
-            goto cleanup;
-        if (virBufferAddLit(&buf, "  </target>\n") < 0)
-            goto cleanup;
+        virBufferAddLit(&buf, "  <target>\n");
+        virBufferVSprintf(&buf, "    <path>%s</path>\n", target);
+        virBufferAddLit(&buf, "  </target>\n");
     }
-    if (virBufferAddLit(&buf, "</pool>\n") < 0)
-        goto cleanup;
+    virBufferAddLit(&buf, "</pool>\n");
+
+    if (virBufferError(&buf)) {
+        vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
+        return FALSE;
+    }
+    xml = virBufferContentAndReset(&buf);
 
-    pool = virStoragePoolCreateXML(ctl->conn, buf.content, 0);
-    free (buf.content);
+    pool = virStoragePoolCreateXML(ctl->conn, xml, 0);
+    free (xml);
 
     if (pool != NULL) {
         vshPrint(ctl, _("Pool %s created\n"), name);
@@ -2949,7 +2945,7 @@ cmdPoolCreateAs(vshControl * ctl, vshCmd
     }
 
  cleanup:
-    free(buf.content);
+    free(virBufferContentAndReset(&buf));
     return FALSE;
 }
 
@@ -3028,10 +3024,9 @@ cmdPoolDefineAs(vshControl * ctl, vshCmd
 {
     virStoragePoolPtr pool;
     int found;
+    char *xml;
     char *name, *type, *srcHost, *srcPath, *srcDev, *target;
-    virBuffer buf;
-
-    memset(&buf, 0, sizeof(buf));
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
     if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
         return FALSE;
@@ -3048,39 +3043,35 @@ cmdPoolDefineAs(vshControl * ctl, vshCmd
     srcDev = vshCommandOptString(cmd, "source-dev", &found);
     target = vshCommandOptString(cmd, "target", &found);
 
-    if (virBufferVSprintf(&buf, "<pool type='%s'>\n", type) < 0)
-        goto cleanup;
-    if (virBufferVSprintf(&buf, "  <name>%s</name>\n", name) < 0)
-        goto cleanup;
+    virBufferVSprintf(&buf, "<pool type='%s'>\n", type);
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", name);
     if (srcHost || srcPath || srcDev) {
-        if (virBufferAddLit(&buf, "  <source>\n") < 0)
-            goto cleanup;
-        if (srcHost &&
-            virBufferVSprintf(&buf, "    <host>%s</host>\n", srcHost) < 0)
-            goto cleanup;
-        if (srcPath &&
-            virBufferVSprintf(&buf, "    <path>%s</path>\n", srcPath) < 0)
-            goto cleanup;
-        if (srcDev &&
-            virBufferVSprintf(&buf, "    <device>%s</device>\n", srcDev) < 0)
-            goto cleanup;
+        virBufferAddLit(&buf, "  <source>\n");
+        if (srcHost)
+            virBufferVSprintf(&buf, "    <host>%s</host>\n", srcHost);
+        if (srcPath)
+            virBufferVSprintf(&buf, "    <path>%s</path>\n", srcPath);
+        if (srcDev)
+            virBufferVSprintf(&buf, "    <device>%s</device>\n", srcDev);
 
-        if (virBufferAddLit(&buf, "  </source>\n") < 0)
-            goto cleanup;
+        virBufferAddLit(&buf, "  </source>\n");
     }
     if (target) {
-        if (virBufferAddLit(&buf, "  <target>\n") < 0)
-            goto cleanup;
-        if (virBufferVSprintf(&buf, "    <path>%s</path>\n", target) < 0)
-            goto cleanup;
-        if (virBufferAddLit(&buf, "  </target>\n") < 0)
-            goto cleanup;
+        virBufferAddLit(&buf, "  <target>\n");
+        virBufferVSprintf(&buf, "    <path>%s</path>\n", target);
+        virBufferAddLit(&buf, "  </target>\n");
     }
-    if (virBufferAddLit(&buf, "</pool>\n") < 0)
-        goto cleanup;
+    virBufferAddLit(&buf, "</pool>\n");
 
-    pool = virStoragePoolDefineXML(ctl->conn, buf.content, 0);
-    free (buf.content);
+
+    if (virBufferError(&buf)) {
+        vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
+        return FALSE;
+    }
+    xml = virBufferContentAndReset(&buf);
+
+    pool = virStoragePoolDefineXML(ctl->conn, xml, 0);
+    free (xml);
 
     if (pool != NULL) {
         vshPrint(ctl, _("Pool %s defined\n"), name);
@@ -3092,7 +3083,7 @@ cmdPoolDefineAs(vshControl * ctl, vshCmd
     }
 
  cleanup:
-    free(buf.content);
+    free(virBufferContentAndReset(&buf));
     return FALSE;
 }
 
@@ -3641,11 +3632,10 @@ cmdVolCreateAs(vshControl * ctl, vshCmd 
     virStoragePoolPtr pool;
     virStorageVolPtr vol;
     int found;
+    char *xml;
     char *name, *capacityStr, *allocationStr, *format;
     unsigned long long capacity, allocation = 0;
-    virBuffer buf;
-
-    memset(&buf, 0, sizeof(buf));
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
     if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
         return FALSE;
@@ -3671,30 +3661,28 @@ cmdVolCreateAs(vshControl * ctl, vshCmd 
 
     format = vshCommandOptString(cmd, "format", &found);
 
-    if (virBufferAddLit(&buf, "<volume>\n") < 0)
-        goto cleanup;
-    if (virBufferVSprintf(&buf, "  <name>%s</name>\n", name) < 0)
-        goto cleanup;
-    if (virBufferVSprintf(&buf, "  <capacity>%llu</capacity>\n", capacity) < 0)
-        goto cleanup;
-    if (allocationStr &&
-        virBufferVSprintf(&buf, "  <allocation>%llu</allocation>\n", allocation) < 0)
-        goto cleanup;
+    virBufferAddLit(&buf, "<volume>\n");
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", name);
+    virBufferVSprintf(&buf, "  <capacity>%llu</capacity>\n", capacity);
+    if (allocationStr)
+        virBufferVSprintf(&buf, "  <allocation>%llu</allocation>\n", allocation);
 
     if (format) {
-        if (virBufferAddLit(&buf, "  <target>\n") < 0)
-            goto cleanup;
+        virBufferAddLit(&buf, "  <target>\n");
         if (format)
-            if (virBufferVSprintf(&buf, "    <format type='%s'/>\n",format) < 0)
-                goto cleanup;
-        if (virBufferAddLit(&buf, "  </target>\n") < 0)
-            goto cleanup;
+            virBufferVSprintf(&buf, "    <format type='%s'/>\n",format);
+        virBufferAddLit(&buf, "  </target>\n");
     }
-    if (virBufferAddLit(&buf, "</volume>\n") < 0)
-        goto cleanup;
+    virBufferAddLit(&buf, "</volume>\n");
+
 
-    vol = virStorageVolCreateXML(pool, buf.content, 0);
-    free (buf.content);
+    if (virBufferError(&buf)) {
+        vshPrint(ctl, "%s", _("Failed to allocate XML buffer"));
+        return FALSE;
+    }
+    xml = virBufferContentAndReset(&buf);
+    vol = virStorageVolCreateXML(pool, xml, 0);
+    free (xml);
     virStoragePoolFree(pool);
 
     if (vol != NULL) {
@@ -3707,7 +3695,7 @@ cmdVolCreateAs(vshControl * ctl, vshCmd 
     }
 
  cleanup:
-    free(buf.content);
+    free(virBufferContentAndReset(&buf));
     virStoragePoolFree(pool);
     return FALSE;
 }
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.181
diff -u -p -r1.181 xend_internal.c
--- src/xend_internal.c	26 Apr 2008 14:22:02 -0000	1.181
+++ src/xend_internal.c	28 Apr 2008 13:52:30 -0000
@@ -608,16 +608,9 @@ xend_op_ext2(virConnectPtr xend, const c
              size_t n_error, const char *key, va_list ap)
 {
     const char *k = key, *v;
-    virBuffer buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     int ret;
-
-    buf.content = malloc(1000);
-    if (buf.content == NULL) {
-        virXendError(xend, VIR_ERR_NO_MEMORY, _("allocate new buffer"));
-        return -1;
-    }
-    buf.size = 1000;
-    buf.use = 0;
+    char *content;
 
     while (k) {
         v = va_arg(ap, const char *);
@@ -631,8 +624,14 @@ xend_op_ext2(virConnectPtr xend, const c
             virBufferVSprintf(&buf, "%s", "&");
     }
 
-    ret = http2unix(xend, xend_post(xend, path, buf.content, error, n_error));
-    free(buf.content);
+    if (virBufferError(&buf)) {
+        virXendError(NULL, VIR_ERR_NO_MEMORY, _("allocate buffer"));
+        return -1;
+    }
+
+    content = virBufferContentAndReset(&buf);
+    ret = http2unix(xend, xend_post(xend, path, content, error, n_error));
+    free(content);
 
     return ret;
 }
@@ -1437,13 +1436,11 @@ xend_parse_sexp_desc_char(virConnectPtr 
     if (STREQ(devtype, "console") &&
         STREQ(type, "pty") &&
         tty != NULL) {
-        if (virBufferVSprintf(buf, "    <%s type='%s' tty='%s'>\n",
-                              devtype, type, tty) < 0)
-            goto no_memory;
+        virBufferVSprintf(buf, "    <%s type='%s' tty='%s'>\n",
+                          devtype, type, tty);
     } else {
-        if (virBufferVSprintf(buf, "    <%s type='%s'>\n",
-                              devtype, type) < 0)
-            goto no_memory;
+        virBufferVSprintf(buf, "    <%s type='%s'>\n",
+                          devtype, type);
     }
 
     if (STREQ(type, "null") ||
@@ -1451,15 +1448,13 @@ xend_parse_sexp_desc_char(virConnectPtr 
         STREQ(type, "stdio")) {
         /* no source needed */
     } else if (STREQ(type, "pty")) {
-        if (tty &&
+        if (tty)
             virBufferVSprintf(buf, "      <source path='%s'/>\n",
-                              tty) < 0)
-            goto no_memory;
+                              tty);
     } else if (STREQ(type, "file") ||
                STREQ(type, "pipe")) {
-        if (virBufferVSprintf(buf, "      <source path='%s'/>\n",
-                              value) < 0)
-            goto no_memory;
+        virBufferVSprintf(buf, "      <source path='%s'/>\n",
+                          value);
     } else if (STREQ(type, "tcp")) {
         const char *offset = strchr(value, ':');
         const char *offset2;
@@ -1490,20 +1485,17 @@ xend_parse_sexp_desc_char(virConnectPtr 
         protocol = telnet ? "telnet":"raw";
 
         if (bindHost) {
-            if (virBufferVSprintf(buf,
-                                  "      <source mode='%s' host='%s' service='%s'/>\n",
-                                  mode, bindHost, bindPort) < 0)
-                goto no_memory;
+            virBufferVSprintf(buf,
+                              "      <source mode='%s' host='%s' service='%s'/>\n",
+                              mode, bindHost, bindPort);
         } else {
-            if (virBufferVSprintf(buf,
-                                  "      <source mode='%s' service='%s'/>\n",
-                                  mode, bindPort) < 0)
-                goto no_memory;
-        }
-        if (virBufferVSprintf(buf,
-                              "      <protocol type='%s'/>\n",
-                              protocol) < 0)
-            goto no_memory;
+            virBufferVSprintf(buf,
+                              "      <source mode='%s' service='%s'/>\n",
+                              mode, bindPort);
+        }
+        virBufferVSprintf(buf,
+                          "      <protocol type='%s'/>\n",
+                          protocol);
     } else if (STREQ(type, "udp")) {
         const char *offset = strchr(value, ':');
         const char *offset2, *offset3;
@@ -1543,28 +1535,24 @@ xend_parse_sexp_desc_char(virConnectPtr 
 
         if (connectPort) {
             if (connectHost) {
-                if (virBufferVSprintf(buf,
-                                      "      <source mode='connect' host='%s' service='%s'/>\n",
-                                      connectHost, connectPort) < 0)
-                    goto no_memory;
+                virBufferVSprintf(buf,
+                                  "      <source mode='connect' host='%s' service='%s'/>\n",
+                                  connectHost, connectPort);
             } else {
-                if (virBufferVSprintf(buf,
-                                      "      <source mode='connect' service='%s'/>\n",
-                                      connectPort) < 0)
-                    goto no_memory;
+                virBufferVSprintf(buf,
+                                  "      <source mode='connect' service='%s'/>\n",
+                                  connectPort);
             }
         }
         if (bindPort) {
             if (bindHost) {
-                if (virBufferVSprintf(buf,
-                                      "      <source mode='bind' host='%s' service='%s'/>\n",
-                                      bindHost, bindPort) < 0)
-                    goto no_memory;
+                virBufferVSprintf(buf,
+                                  "      <source mode='bind' host='%s' service='%s'/>\n",
+                                  bindHost, bindPort);
             } else {
-                if (virBufferVSprintf(buf,
-                                      "      <source mode='bind' service='%s'/>\n",
-                                      bindPort) < 0)
-                    goto no_memory;
+                virBufferVSprintf(buf,
+                                  "      <source mode='bind' service='%s'/>\n",
+                                  bindPort);
             }
         }
 
@@ -1582,18 +1570,15 @@ xend_parse_sexp_desc_char(virConnectPtr 
             strstr(offset, ",listen") != NULL)
             dolisten = 1;
 
-        if (virBufferVSprintf(buf, "      <source mode='%s' path='%s'/>\n",
-                              dolisten ? "bind" : "connect", path) < 0)
-            goto no_memory;
+        virBufferVSprintf(buf, "      <source mode='%s' path='%s'/>\n",
+                          dolisten ? "bind" : "connect", path);
     }
 
-    if (virBufferVSprintf(buf, "      <target port='%d'/>\n",
-                          portNum) < 0)
-        goto no_memory;
-
-    if (virBufferVSprintf(buf, "    </%s>\n",
-                          devtype) < 0)
-        goto no_memory;
+    virBufferVSprintf(buf, "      <target port='%d'/>\n",
+                      portNum);
+
+    virBufferVSprintf(buf, "    </%s>\n",
+                      devtype);
 
     ret = 0;
 
@@ -1635,7 +1620,7 @@ xend_parse_sexp_desc(virConnectPtr conn,
     struct sexpr *cur, *node;
     const char *tmp;
     char *tty;
-    virBuffer buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     int hvm = 0, bootloader = 0, vfb = 0;
     int domid = -1;
     int max_mem, cur_mem;
@@ -1647,11 +1632,6 @@ xend_parse_sexp_desc(virConnectPtr conn,
         /* ERROR */
         return (NULL);
     }
-    buf.content = malloc(4000);
-    if (buf.content == NULL)
-        return (NULL);
-    buf.size = 4000;
-    buf.use = 0;
 
     tmp = sexpr_node(root, "domain/domid");
     if (tmp == NULL && xendConfigVersion < 3) { /* Old XenD, domid was mandatory */
@@ -2097,11 +2077,15 @@ xend_parse_sexp_desc(virConnectPtr conn,
     virBufferAddLit(&buf, "  </devices>\n");
     virBufferAddLit(&buf, "</domain>\n");
 
-    buf.content[buf.use] = 0;
-    return (buf.content);
+    if (virBufferError(&buf)) {
+        virXendError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"));
+        return NULL;
+    }
+
+    return virBufferContentAndReset(&buf);
 
   error:
-    free(buf.content);
+    free(virBufferContentAndReset(&buf));
     return (NULL);
 }
 
Index: src/xm_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.c,v
retrieving revision 1.71
diff -u -p -r1.71 xm_internal.c
--- src/xm_internal.c	26 Apr 2008 14:22:02 -0000	1.71
+++ src/xm_internal.c	28 Apr 2008 13:52:32 -0000
@@ -579,8 +579,7 @@ int xenXMDomainGetInfo(virDomainPtr doma
  * domain, suitable for later feeding for virDomainCreateLinux
  */
 char *xenXMDomainFormatXML(virConnectPtr conn, virConfPtr conf) {
-    virBufferPtr buf;
-    char *xml;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     const char *name;
     unsigned char uuid[VIR_UUID_BUFLEN];
     char uuidstr[VIR_UUID_STRING_BUFLEN];
@@ -602,12 +601,10 @@ char *xenXMDomainFormatXML(virConnectPtr
     if (xenXMConfigGetUUID(conf, "uuid", uuid) < 0)
         return (NULL);
 
-    buf = virBufferNew(4096);
-
-    virBufferAddLit(buf, "<domain type='xen'>\n");
-    virBufferVSprintf(buf, "  <name>%s</name>\n", name);
+    virBufferAddLit(&buf, "<domain type='xen'>\n");
+    virBufferVSprintf(&buf, "  <name>%s</name>\n", name);
     virUUIDFormat(uuid, uuidstr);
-    virBufferVSprintf(buf, "  <uuid>%s</uuid>\n", uuidstr);
+    virBufferVSprintf(&buf, "  <uuid>%s</uuid>\n", uuidstr);
 
     if ((xenXMConfigGetString(conf, "builder", &str) == 0) &&
         !strcmp(str, "hvm"))
@@ -615,10 +612,10 @@ char *xenXMDomainFormatXML(virConnectPtr
 
     if (hvm) {
         const char *boot;
-        virBufferAddLit(buf, "  <os>\n");
-        virBufferAddLit(buf, "    <type>hvm</type>\n");
+        virBufferAddLit(&buf, "  <os>\n");
+        virBufferAddLit(&buf, "    <type>hvm</type>\n");
         if (xenXMConfigGetString(conf, "kernel", &str) == 0)
-            virBufferVSprintf(buf, "    <loader>%s</loader>\n", str);
+            virBufferVSprintf(&buf, "    <loader>%s</loader>\n", str);
 
         if (xenXMConfigGetString(conf, "boot", &boot) < 0)
             boot = "c";
@@ -637,90 +634,90 @@ char *xenXMDomainFormatXML(virConnectPtr
                 dev = "hd";
                 break;
             }
-            virBufferVSprintf(buf, "    <boot dev='%s'/>\n", dev);
+            virBufferVSprintf(&buf, "    <boot dev='%s'/>\n", dev);
             boot++;
         }
 
-        virBufferAddLit(buf, "  </os>\n");
+        virBufferAddLit(&buf, "  </os>\n");
     } else {
 
         if (xenXMConfigGetString(conf, "bootloader", &str) == 0)
-            virBufferVSprintf(buf, "  <bootloader>%s</bootloader>\n", str);
+            virBufferVSprintf(&buf, "  <bootloader>%s</bootloader>\n", str);
         if (xenXMConfigGetString(conf, "bootargs", &str) == 0)
-            virBufferEscapeString(buf, "  <bootloader_args>%s</bootloader_args>\n", str);
+            virBufferEscapeString(&buf, "  <bootloader_args>%s</bootloader_args>\n", str);
         if (xenXMConfigGetString(conf, "kernel", &str) == 0) {
-            virBufferAddLit(buf, "  <os>\n");
-            virBufferAddLit(buf, "    <type>linux</type>\n");
-            virBufferVSprintf(buf, "    <kernel>%s</kernel>\n", str);
+            virBufferAddLit(&buf, "  <os>\n");
+            virBufferAddLit(&buf, "    <type>linux</type>\n");
+            virBufferVSprintf(&buf, "    <kernel>%s</kernel>\n", str);
             if (xenXMConfigGetString(conf, "ramdisk", &str) == 0)
-                virBufferVSprintf(buf, "    <initrd>%s</initrd>\n", str);
+                virBufferVSprintf(&buf, "    <initrd>%s</initrd>\n", str);
             if (xenXMConfigGetString(conf, "extra", &str) == 0)
-                virBufferEscapeString(buf, "    <cmdline>%s</cmdline>\n", str);
-            virBufferAddLit(buf, "  </os>\n");
+                virBufferEscapeString(&buf, "    <cmdline>%s</cmdline>\n", str);
+            virBufferAddLit(&buf, "  </os>\n");
         }
     }
 
     if (xenXMConfigGetInt(conf, "memory", &val) < 0)
         val = MIN_XEN_GUEST_SIZE * 2;
-    virBufferVSprintf(buf, "  <currentMemory>%ld</currentMemory>\n",
+    virBufferVSprintf(&buf, "  <currentMemory>%ld</currentMemory>\n",
                       val * 1024);
 
     if (xenXMConfigGetInt(conf, "maxmem", &val) < 0)
         if (xenXMConfigGetInt(conf, "memory", &val) < 0)
             val = MIN_XEN_GUEST_SIZE * 2;
-    virBufferVSprintf(buf, "  <memory>%ld</memory>\n", val * 1024);
+    virBufferVSprintf(&buf, "  <memory>%ld</memory>\n", val * 1024);
 
-    virBufferAddLit(buf, "  <vcpu");
+    virBufferAddLit(&buf, "  <vcpu");
     if (xenXMConfigGetString(conf, "cpus", &str) == 0) {
         char *ranges;
 
         ranges = virConvertCpuSet(conn, str, 0);
         if (ranges != NULL) {
-            virBufferVSprintf(buf, " cpuset='%s'", ranges);
+            virBufferVSprintf(&buf, " cpuset='%s'", ranges);
             free(ranges);
         } else
-            virBufferVSprintf(buf, " cpuset='%s'", str);
+            virBufferVSprintf(&buf, " cpuset='%s'", str);
     }
     if (xenXMConfigGetInt(conf, "vcpus", &val) < 0)
         val = 1;
-    virBufferVSprintf(buf, ">%ld</vcpu>\n", val);
+    virBufferVSprintf(&buf, ">%ld</vcpu>\n", val);
 
     if (xenXMConfigGetString(conf, "on_poweroff", &str) < 0)
         str = "destroy";
-    virBufferVSprintf(buf, "  <on_poweroff>%s</on_poweroff>\n", str);
+    virBufferVSprintf(&buf, "  <on_poweroff>%s</on_poweroff>\n", str);
 
     if (xenXMConfigGetString(conf, "on_reboot", &str) < 0)
         str = "restart";
-    virBufferVSprintf(buf, "  <on_reboot>%s</on_reboot>\n", str);
+    virBufferVSprintf(&buf, "  <on_reboot>%s</on_reboot>\n", str);
 
     if (xenXMConfigGetString(conf, "on_crash", &str) < 0)
         str = "restart";
-    virBufferVSprintf(buf, "  <on_crash>%s</on_crash>\n", str);
+    virBufferVSprintf(&buf, "  <on_crash>%s</on_crash>\n", str);
 
 
     if (hvm) {
-        virBufferAddLit(buf, "  <features>\n");
+        virBufferAddLit(&buf, "  <features>\n");
         if (xenXMConfigGetInt(conf, "pae", &val) == 0 &&
             val)
-            virBufferAddLit(buf, "    <pae/>\n");
+            virBufferAddLit(&buf, "    <pae/>\n");
         if (xenXMConfigGetInt(conf, "acpi", &val) == 0 &&
             val)
-            virBufferAddLit(buf, "    <acpi/>\n");
+            virBufferAddLit(&buf, "    <acpi/>\n");
         if (xenXMConfigGetInt(conf, "apic", &val) == 0 &&
             val)
-            virBufferAddLit(buf, "    <apic/>\n");
-        virBufferAddLit(buf, "  </features>\n");
+            virBufferAddLit(&buf, "    <apic/>\n");
+        virBufferAddLit(&buf, "  </features>\n");
 
         if (xenXMConfigGetInt(conf, "localtime", &val) < 0)
             val = 0;
-        virBufferVSprintf(buf, "  <clock offset='%s'/>\n", val ? "localtime" : "utc");
+        virBufferVSprintf(&buf, "  <clock offset='%s'/>\n", val ? "localtime" : "utc");
     }
 
-    virBufferAddLit(buf, "  <devices>\n");
+    virBufferAddLit(&buf, "  <devices>\n");
 
     if (hvm) {
         if (xenXMConfigGetString(conf, "device_model", &str) == 0)
-            virBufferVSprintf(buf, "    <emulator>%s</emulator>\n", str);
+            virBufferVSprintf(&buf, "    <emulator>%s</emulator>\n", str);
     }
 
     list = virConfGetValue(conf, "disk");
@@ -808,23 +805,23 @@ char *xenXMDomainFormatXML(virConnectPtr
                 tmp[0] = '\0';
             }
 
-            virBufferVSprintf(buf, "    <disk type='%s' device='%s'>\n",
+            virBufferVSprintf(&buf, "    <disk type='%s' device='%s'>\n",
                               block ? "block" : "file",
                               cdrom ? "cdrom" : "disk");
             if (drvType[0])
-                virBufferVSprintf(buf, "      <driver name='%s' type='%s'/>\n", drvName, drvType);
+                virBufferVSprintf(&buf, "      <driver name='%s' type='%s'/>\n", drvName, drvType);
             else
-                virBufferVSprintf(buf, "      <driver name='%s'/>\n", drvName);
+                virBufferVSprintf(&buf, "      <driver name='%s'/>\n", drvName);
             if (src[0])
-                virBufferVSprintf(buf, "      <source %s='%s'/>\n", block ? "dev" : "file", src);
-            virBufferVSprintf(buf, "      <target dev='%s'/>\n", dev);
+                virBufferVSprintf(&buf, "      <source %s='%s'/>\n", block ? "dev" : "file", src);
+            virBufferVSprintf(&buf, "      <target dev='%s'/>\n", dev);
             if (!strcmp(head, "r") ||
                 !strcmp(head, "ro"))
-                virBufferAddLit(buf, "      <readonly/>\n");
+                virBufferAddLit(&buf, "      <readonly/>\n");
             else if ((!strcmp(head, "w!")) ||
                      (!strcmp(head, "!")))
-                virBufferAddLit(buf, "      <shareable/>\n");
-            virBufferAddLit(buf, "    </disk>\n");
+                virBufferAddLit(&buf, "      <shareable/>\n");
+            virBufferAddLit(&buf, "    </disk>\n");
 
         skipdisk:
             list = list->next;
@@ -833,12 +830,12 @@ char *xenXMDomainFormatXML(virConnectPtr
 
     if (hvm && priv->xendConfigVersion == 1) {
         if (xenXMConfigGetString(conf, "cdrom", &str) == 0) {
-            virBufferAddLit(buf, "    <disk type='file' device='cdrom'>\n");
-            virBufferAddLit(buf, "      <driver name='file'/>\n");
-            virBufferVSprintf(buf, "      <source file='%s'/>\n", str);
-            virBufferAddLit(buf, "      <target dev='hdc'/>\n");
-            virBufferAddLit(buf, "      <readonly/>\n");
-            virBufferAddLit(buf, "    </disk>\n");
+            virBufferAddLit(&buf, "    <disk type='file' device='cdrom'>\n");
+            virBufferAddLit(&buf, "      <driver name='file'/>\n");
+            virBufferVSprintf(&buf, "      <source file='%s'/>\n", str);
+            virBufferAddLit(&buf, "      <target dev='hdc'/>\n");
+            virBufferAddLit(&buf, "      <readonly/>\n");
+            virBufferAddLit(&buf, "    </disk>\n");
         }
     }
 
@@ -909,16 +906,16 @@ char *xenXMDomainFormatXML(virConnectPtr
                 type = 1;
             }
 
-            virBufferAddLit(buf, "    <interface type='bridge'>\n");
+            virBufferAddLit(&buf, "    <interface type='bridge'>\n");
             if (mac[0])
-                virBufferVSprintf(buf, "      <mac address='%s'/>\n", mac);
+                virBufferVSprintf(&buf, "      <mac address='%s'/>\n", mac);
             if (type == 1 && bridge[0])
-                virBufferVSprintf(buf, "      <source bridge='%s'/>\n", bridge);
+                virBufferVSprintf(&buf, "      <source bridge='%s'/>\n", bridge);
             if (script[0])
-                virBufferVSprintf(buf, "      <script path='%s'/>\n", script);
+                virBufferVSprintf(&buf, "      <script path='%s'/>\n", script);
             if (ip[0])
-                virBufferVSprintf(buf, "      <ip address='%s'/>\n", ip);
-            virBufferAddLit(buf, "    </interface>\n");
+                virBufferVSprintf(&buf, "      <ip address='%s'/>\n", ip);
+            virBufferAddLit(&buf, "    </interface>\n");
 
         skipnic:
             list = list->next;
@@ -928,9 +925,9 @@ char *xenXMDomainFormatXML(virConnectPtr
     if (hvm) {
         if (xenXMConfigGetString(conf, "usbdevice", &str) == 0 && str) {
             if (!strcmp(str, "tablet"))
-                virBufferAddLit(buf, "    <input type='tablet' bus='usb'/>\n");
+                virBufferAddLit(&buf, "    <input type='tablet' bus='usb'/>\n");
             else if (!strcmp(str, "mouse"))
-                virBufferAddLit(buf, "    <input type='mouse' bus='usb'/>\n");
+                virBufferAddLit(&buf, "    <input type='mouse' bus='usb'/>\n");
             /* Ignore else branch - probably some other non-input device we don't
                support in libvirt yet */
         }
@@ -1003,54 +1000,56 @@ char *xenXMDomainFormatXML(virConnectPtr
     }
 
     if (vnc || sdl) {
-        virBufferVSprintf(buf, "    <input type='mouse' bus='%s'/>\n", hvm ? "ps2":"xen");
+        virBufferVSprintf(&buf, "    <input type='mouse' bus='%s'/>\n", hvm ? "ps2":"xen");
     }
     if (vnc) {
-        virBufferVSprintf(buf,
+        virBufferVSprintf(&buf,
                           "    <graphics type='vnc' port='%ld'",
                           (vncunused ? -1 : 5900+vncdisplay));
         if (vnclisten) {
-            virBufferVSprintf(buf, " listen='%s'", vnclisten);
+            virBufferVSprintf(&buf, " listen='%s'", vnclisten);
         }
         if (vncpasswd) {
-            virBufferVSprintf(buf, " passwd='%s'", vncpasswd);
+            virBufferVSprintf(&buf, " passwd='%s'", vncpasswd);
         }
         if (keymap) {
-            virBufferVSprintf(buf, " keymap='%s'", keymap);
+            virBufferVSprintf(&buf, " keymap='%s'", keymap);
         }
-        virBufferAddLit(buf, "/>\n");
+        virBufferAddLit(&buf, "/>\n");
     }
     if (sdl) {
-        virBufferAddLit(buf, "    <graphics type='sdl'/>\n");
+        virBufferAddLit(&buf, "    <graphics type='sdl'/>\n");
     }
 
     if (hvm) {
         if (xenXMConfigGetString(conf, "parallel", &str) == 0) {
             if (STRNEQ(str, "none"))
-                xend_parse_sexp_desc_char(conn, buf, "parallel", 0, str, NULL);
+                xend_parse_sexp_desc_char(conn, &buf, "parallel", 0, str, NULL);
         }
         if (xenXMConfigGetString(conf, "serial", &str) == 0) {
             if (STRNEQ(str, "none")) {
-                xend_parse_sexp_desc_char(conn, buf, "serial", 0, str, NULL);
+                xend_parse_sexp_desc_char(conn, &buf, "serial", 0, str, NULL);
                 /* Add back-compat console tag for primary console */
-                xend_parse_sexp_desc_char(conn, buf, "console", 0, str, NULL);
+                xend_parse_sexp_desc_char(conn, &buf, "console", 0, str, NULL);
             }
         }
     } else {
         /* Paravirt implicitly always has a single console */
-        virBufferAddLit(buf, "    <console type='pty'>\n");
-        virBufferAddLit(buf, "      <target port='0'/>\n");
-        virBufferAddLit(buf, "    </console>\n");
+        virBufferAddLit(&buf, "    <console type='pty'>\n");
+        virBufferAddLit(&buf, "      <target port='0'/>\n");
+        virBufferAddLit(&buf, "    </console>\n");
     }
 
-    virBufferAddLit(buf, "  </devices>\n");
+    virBufferAddLit(&buf, "  </devices>\n");
+
+    virBufferAddLit(&buf, "</domain>\n");
 
-    virBufferAddLit(buf, "</domain>\n");
+    if (virBufferError(&buf)) {
+        xenXMError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"));
+        return NULL;
+    }
 
-    xml = buf->content;
-    buf->content = NULL;
-    virBufferFree(buf);
-    return (xml);
+    return virBufferContentAndReset(&buf);
 }
 
 
@@ -1254,7 +1253,7 @@ int xenXMDomainPinVcpu(virDomainPtr doma
 {
     const char *filename;
     xenXMConfCachePtr entry;
-    virBufferPtr mapbuf;
+    virBuffer mapbuf = VIR_BUFFER_INITIALIZER;
     char *mapstr = NULL;
     char *ranges = NULL;
     int i, j, n, comma = 0;
@@ -1288,33 +1287,24 @@ int xenXMDomainPinVcpu(virDomainPtr doma
     }
 
     /* from bit map, build character string of mapped CPU numbers */
-    mapbuf = virBufferNew (16);
-    if (mapbuf == NULL) {
-        xenXMError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__);
-        return -1;
-    }
     for (i = 0; i < maplen; i++)
         for (j = 0; j < 8; j++)
             if ((cpumap[i] & (1 << j))) {
                 n = i*8 + j;
 
-                if (comma) {
-                    if (virBufferAddLit (mapbuf, ",") == -1) {
-                        xenXMError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__);
-                        virBufferFree (mapbuf);
-                    return -1;
-                    }
-                }
+                if (comma)
+                    virBufferAddLit (&mapbuf, ",");
                 comma = 1;
 
-                if (virBufferVSprintf (mapbuf, "%d", n) == -1) {
-                    xenXMError (domain->conn, VIR_ERR_NO_MEMORY, __FUNCTION__);
-                    virBufferFree (mapbuf);
-                    return -1;
-                }
+                virBufferVSprintf (&mapbuf, "%d", n);
             }
 
-    mapstr = virBufferContentAndFree (mapbuf);
+    if (virBufferError(&mapbuf)) {
+        xenXMError(domain->conn, VIR_ERR_NO_MEMORY, _("allocate buffer"));
+        return -1;
+    }
+
+    mapstr = virBufferContentAndReset(&mapbuf);
 
     /* convert the mapstr to a range based string */
     ranges = virConvertCpuSet(domain->conn, mapstr, 0);
Index: src/xml.c
===================================================================
RCS file: /data/cvs/libvirt/src/xml.c,v
retrieving revision 1.118
diff -u -p -r1.118 xml.c
--- src/xml.c	26 Apr 2008 14:22:02 -0000	1.118
+++ src/xml.c	28 Apr 2008 13:52:33 -0000
@@ -102,19 +102,13 @@ parseCpuNumber(const char **str, int max
 char *
 virSaveCpuSet(virConnectPtr conn, char *cpuset, int maxcpu)
 {
-    virBufferPtr buf;
-    char *ret;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     int start, cur;
     int first = 1;
 
     if ((cpuset == NULL) || (maxcpu <= 0) || (maxcpu > 100000))
         return (NULL);
 
-    buf = virBufferNew(1000);
-    if (buf == NULL) {
-        virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 1000);
-        return (NULL);
-    }
     cur = 0;
     start = -1;
     while (cur < maxcpu) {
@@ -123,27 +117,32 @@ virSaveCpuSet(virConnectPtr conn, char *
                 start = cur;
         } else if (start != -1) {
             if (!first)
-                virBufferAddLit(buf, ",");
+                virBufferAddLit(&buf, ",");
             else
                 first = 0;
             if (cur == start + 1)
-                virBufferVSprintf(buf, "%d", start);
+                virBufferVSprintf(&buf, "%d", start);
             else
-                virBufferVSprintf(buf, "%d-%d", start, cur - 1);
+                virBufferVSprintf(&buf, "%d-%d", start, cur - 1);
             start = -1;
         }
         cur++;
     }
     if (start != -1) {
         if (!first)
-            virBufferAddLit(buf, ",");
+            virBufferAddLit(&buf, ",");
         if (maxcpu == start + 1)
-            virBufferVSprintf(buf, "%d", start);
+            virBufferVSprintf(&buf, "%d", start);
         else
-            virBufferVSprintf(buf, "%d-%d", start, maxcpu - 1);
+            virBufferVSprintf(&buf, "%d-%d", start, maxcpu - 1);
     }
-    ret = virBufferContentAndFree(buf);
-    return (ret);
+
+    if (virBufferError(&buf)) {
+        virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 1000);
+        return NULL;
+    }
+
+    return virBufferContentAndReset(&buf);
 }
 
 /**
@@ -1054,11 +1053,9 @@ virDomainParseXMLOSDescHVM(virConnectPtr
         char scratch[PATH_MAX];
         if (virDomainParseXMLOSDescHVMChar(conn, scratch, sizeof(scratch), cur) < 0)
             goto error;
-        if (virBufferVSprintf(buf, "(parallel %s)", scratch) < 0)
-            goto no_memory;
+        virBufferVSprintf(buf, "(parallel %s)", scratch);
     } else {
-        if (virBufferAddLit(buf, "(parallel none)") < 0)
-            goto no_memory;
+        virBufferAddLit(buf, "(parallel none)");
     }
 
     cur = virXPathNode("/domain/devices/serial[1]", ctxt);
@@ -1066,8 +1063,7 @@ virDomainParseXMLOSDescHVM(virConnectPtr
         char scratch[PATH_MAX];
         if (virDomainParseXMLOSDescHVMChar(conn, scratch, sizeof(scratch), cur) < 0)
             goto error;
-        if (virBufferVSprintf(buf, "(serial %s)", scratch) < 0)
-            goto no_memory;
+        virBufferVSprintf(buf, "(serial %s)", scratch);
     } else {
         res = virXPathBoolean("count(domain/devices/console) > 0", ctxt);
         if (res < 0) {
@@ -1075,27 +1071,20 @@ virDomainParseXMLOSDescHVM(virConnectPtr
             goto error;
         }
         if (res) {
-            if (virBufferAddLit(buf, "(serial pty)") < 0)
-                goto no_memory;
+            virBufferAddLit(buf, "(serial pty)");
         } else {
-            if (virBufferAddLit(buf, "(serial none)") < 0)
-                goto no_memory;
+            virBufferAddLit(buf, "(serial none)");
         }
     }
 
     str = virXPathString("string(/domain/clock/@offset)", ctxt);
-    if (str != NULL && !strcmp(str, "localtime")) {
-        if (virBufferAddLit(buf, "(localtime 1)") < 0)
-            goto no_memory;
+    if (str != NULL && STREQ(str, "localtime")) {
+        virBufferAddLit(buf, "(localtime 1)");
     }
     free(str);
 
     return (0);
 
-no_memory:
-    virXMLError(conn, VIR_ERR_XML_ERROR,
-                _("cannot allocate memory for buffer"), 0);
-
   error:
     free(nodes);
     return (-1);
@@ -1509,7 +1498,7 @@ virDomainParseXMLDesc(virConnectPtr conn
     xmlDocPtr xml = NULL;
     xmlNodePtr node;
     char *nam = NULL;
-    virBuffer buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     xmlChar *prop;
     xmlParserCtxtPtr pctxt;
     xmlXPathContextPtr ctxt = NULL;
@@ -1525,11 +1514,6 @@ virDomainParseXMLDesc(virConnectPtr conn
 
     if (name != NULL)
         *name = NULL;
-    buf.content = malloc(1000);
-    if (buf.content == NULL)
-        return (NULL);
-    buf.size = 1000;
-    buf.use = 0;
 
     pctxt = xmlNewParserCtxt();
     if ((pctxt == NULL) || (pctxt->sax == NULL)) {
@@ -1787,7 +1771,6 @@ virDomainParseXMLDesc(virConnectPtr conn
 
 
     virBufferAddLit(&buf, ")"); /* closes (vm */
-    buf.content[buf.use] = 0;
 
     xmlXPathFreeContext(ctxt);
     xmlFreeDoc(xml);
@@ -1798,7 +1781,12 @@ virDomainParseXMLDesc(virConnectPtr conn
     else
         free(nam);
 
-    return (buf.content);
+    if (virBufferError(&buf)) {
+        virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0);
+        return NULL;
+    }
+
+    return virBufferContentAndReset(&buf);
 
   error:
     free(nam);
@@ -1809,7 +1797,7 @@ virDomainParseXMLDesc(virConnectPtr conn
         xmlFreeDoc(xml);
     if (pctxt != NULL)
         xmlFreeParserCtxt(pctxt);
-    free(buf.content);
+    free(virBufferContentAndReset(&buf));
     return (NULL);
 }
 
@@ -1834,14 +1822,8 @@ virParseXMLDevice(virConnectPtr conn, co
 {
     xmlDocPtr xml = NULL;
     xmlNodePtr node;
-    virBuffer buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
 
-    buf.content = malloc(1000);
-    if (buf.content == NULL)
-        return (NULL);
-    buf.size = 1000;
-    buf.use = 0;
-    buf.content[0] = 0;
     xml = xmlReadDoc((const xmlChar *) xmldesc, "device.xml", NULL,
                      XML_PARSE_NOENT | XML_PARSE_NONET |
                      XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
@@ -1856,9 +1838,6 @@ virParseXMLDevice(virConnectPtr conn, co
         if (virDomainParseXMLDiskDesc(conn, node, &buf, hvm,
                                       xendConfigVersion) != 0)
             goto error;
-        /* SXP is not created when device is "floppy". */
-        else if (buf.use == 0)
-            goto error;
     } else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
         if (virDomainParseXMLIfDesc(conn, node, &buf, hvm,
                                     xendConfigVersion) != 0)
@@ -1867,14 +1846,20 @@ virParseXMLDevice(virConnectPtr conn, co
         virXMLError(conn, VIR_ERR_XML_ERROR, (const char *) node->name, 0);
         goto error;
     }
-  cleanup:
-    if (xml != NULL)
-        xmlFreeDoc(xml);
-    return buf.content;
+
+    xmlFreeDoc(xml);
+
+    if (virBufferError(&buf)) {
+        virXMLError(conn, VIR_ERR_NO_MEMORY, _("allocate buffer"), 0);
+        return NULL;
+    }
+
+    return virBufferContentAndReset(&buf);
+
   error:
-    free(buf.content);
-    buf.content = NULL;
-    goto cleanup;
+    free(virBufferContentAndReset(&buf));
+    xmlFreeDoc(xml);
+    return NULL;
 }
 
 
Index: src/xmlrpc.c
===================================================================
RCS file: /data/cvs/libvirt/src/xmlrpc.c,v
retrieving revision 1.13
diff -u -p -r1.13 xmlrpc.c
--- src/xmlrpc.c	10 Apr 2008 16:54:54 -0000	1.13
+++ src/xmlrpc.c	28 Apr 2008 13:52:34 -0000
@@ -363,14 +363,12 @@ void xmlRpcValueMarshal(xmlRpcValuePtr v
     virBufferStrcat(buf, "</value>\n", NULL);
 }
 
-virBufferPtr xmlRpcMarshalRequest(const char *request,
-                                  int argc, xmlRpcValuePtr *argv)
+void xmlRpcMarshalRequest(const char *request,
+                          virBufferPtr buf,
+                          int argc, xmlRpcValuePtr *argv)
 {
-    virBufferPtr buf;
     int i;
 
-    buf = virBufferNew(1024);
-
     virBufferStrcat(buf,
                     "<?xml version=\"1.0\"?>\n"
                     "<methodCall>\n"
@@ -386,7 +384,6 @@ virBufferPtr xmlRpcMarshalRequest(const 
     virBufferStrcat(buf,
                     "  </params>\n"
                     "</methodCall>\n", NULL);
-    return buf;
 }
 
 xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault)
@@ -564,13 +561,14 @@ int xmlRpcCall(xmlRpcContextPtr context,
     va_list ap;
     int argc;
     xmlRpcValuePtr *argv;
-    virBufferPtr buf;
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
     char *ret;
     xmlDocPtr xml;
     xmlNodePtr node;
     bool fault;
     xmlRpcValuePtr value;
     void *retval = NULL;
+    char *content;
 
     va_start(ap, fmt);
 
@@ -582,16 +580,16 @@ int xmlRpcCall(xmlRpcContextPtr context,
 
     va_end(ap);
 
-    buf = xmlRpcMarshalRequest(method, argc, argv);
+    xmlRpcMarshalRequest(method, &buf, argc, argv);
 
     xmlRpcArgvFree(argc, argv);
 
-    if (!buf)
+    if (virBufferError(&buf))
         return -1;
 
-    ret = xmlRpcCallRaw(context->uri, buf->content);
-
-    virBufferFree(buf);
+    content = virBufferContentAndReset(&buf);
+    ret = xmlRpcCallRaw(context->uri, content);
+    free(content);
 
     if (!ret)
         return -1;
Index: src/xmlrpc.h
===================================================================
RCS file: /data/cvs/libvirt/src/xmlrpc.h,v
retrieving revision 1.4
diff -u -p -r1.4 xmlrpc.h
--- src/xmlrpc.h	10 Apr 2008 16:54:54 -0000	1.4
+++ src/xmlrpc.h	28 Apr 2008 13:52:34 -0000
@@ -89,8 +89,9 @@ struct _xmlRpcContext;
 xmlRpcValuePtr *xmlRpcArgvNew(const char *fmt, va_list ap, int *argc);
 void xmlRpcArgvFree(int argc, xmlRpcValuePtr *argv);
 
-virBufferPtr xmlRpcMarshalRequest(const char *request,
-                                  int argc, xmlRpcValuePtr *argv);
+void xmlRpcMarshalRequest(const char *request,
+                          virBufferPtr buf,
+                          int argc, xmlRpcValuePtr *argv);
 
 xmlRpcValuePtr xmlRpcUnmarshalResponse(xmlNodePtr node, bool *is_fault);
 
Index: tests/xmlrpctest.c
===================================================================
RCS file: /data/cvs/libvirt/tests/xmlrpctest.c,v
retrieving revision 1.11
diff -u -p -r1.11 xmlrpctest.c
--- tests/xmlrpctest.c	10 Apr 2008 16:54:54 -0000	1.11
+++ tests/xmlrpctest.c	28 Apr 2008 13:52:34 -0000
@@ -59,22 +59,20 @@ testMethodPlusDOUBLE(const void *data)
     return retval==(10.1234+10.1234) ? 0 : -1;
 }
 
-static virBufferPtr
-marshalRequest(const char *fmt, ...)
+static void
+marshalRequest(virBufferPtr buf, const char *fmt, ...)
 {
     int argc;
     xmlRpcValuePtr *argv;
-    virBufferPtr buf;
     va_list ap;
 
     va_start(ap, fmt);
     argv = xmlRpcArgvNew(fmt, ap, &argc);
     va_end(ap);
 
-    buf = xmlRpcMarshalRequest("test", argc, argv);
+    xmlRpcMarshalRequest("test", buf, argc, argv);
 
     xmlRpcArgvFree(argc, argv);
-    return buf;
 }
 
 static int
@@ -132,14 +130,21 @@ testMarshalRequestINT(const void *data)
     int num = INT_MAX;
     int ret = 0;
     int check = data ? *((int *)data) : 0;
-    virBufferPtr buf = marshalRequest("i", num);
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    marshalRequest(&buf, "i", num);
+    char *content;
+
+    if (virBufferError(&buf))
+        return -1;
+
+    content = virBufferContentAndReset(&buf);
 
     if (check)
-        ret = checkRequestValue(buf->content,
+        ret = checkRequestValue(content,
                 "number(/methodCall/params/param[1]/value/int)",
                 XML_RPC_INTEGER, (void *) &num);
 
-    virBufferFree(buf);
+    free(content);
     return ret;
 }
 
@@ -149,13 +154,21 @@ testMarshalRequestSTRING(const void *dat
     const char *str = "This library will be really sexy.";
     int ret = 0;
     int check = data ? *((int *)data) : 0;
-    virBufferPtr buf = marshalRequest("s", str);
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    char *content;
+
+    marshalRequest(&buf, "s", str);
 
+    if (virBufferError(&buf))
+        return -1;
+
+    content = virBufferContentAndReset(&buf);
     if (check)
-        ret = checkRequestValue(buf->content,
+        ret = checkRequestValue(content,
                 "string(/methodCall/params/param[1]/value/string)",
                 XML_RPC_STRING, (void *) str);
-    virBufferFree(buf);
+
+    free(content);
     return ret;
 }
 
@@ -165,42 +178,24 @@ testMarshalRequestDOUBLE(const void *dat
     double num = 123456789.123;
     int ret = 0;
     int check = data ? *((int *)data) : 0;
-    virBufferPtr buf = marshalRequest("f", num);
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
+    char *content;
+
+    marshalRequest(&buf, "f", num);
 
+    if (virBufferError(&buf))
+        return -1;
+
+    content = virBufferContentAndReset(&buf);
     if (check)
-        ret = checkRequestValue(buf->content,
+        ret = checkRequestValue(content,
                 "number(/methodCall/params/param[1]/value/double)",
                 XML_RPC_DOUBLE, (void *) &num);
 
-    virBufferFree(buf);
+    free(content);
     return ret;
 }
 
-static int
-testBufferStrcat(const void *data ATTRIBUTE_UNUSED)
-{
-    virBufferPtr buf = virBufferNew(1000*32);  /* don't waste time with realloc */
-    int i;
-
-    for (i=0; i < 1000; i++)
-        virBufferStrcat(buf, "My name is ", "libvirt", ".\n", NULL);
-
-    virBufferFree(buf);
-    return 0;
-}
-
-static int
-testBufferVSprintf(const void *data ATTRIBUTE_UNUSED)
-{
-    virBufferPtr buf = virBufferNew(1000*32);  /* don't waste time with realloc */
-    int i;
-
-    for (i=0; i < 1000; i++)
-        virBufferVSprintf(buf, "My name is %s.\n", "libvirt");
-
-    virBufferFree(buf);
-    return 0;
-}
 
 int
 main(int argc, char **argv)
@@ -263,13 +258,7 @@ main(int argc, char **argv)
                 NLOOPS, testMarshalRequestSTRING, NULL) != 0)
         ret = -1;
 
-    if (virtTestRun("Buffer: strcat", NLOOPS, testBufferStrcat, NULL) != 0)
-        ret = -1;
-    if (virtTestRun("Buffer: sprintf", NLOOPS, testBufferVSprintf, NULL) != 0)
-        ret = -1;
-
-
-        exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
+    exit(ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
 }
 
 

-- 
|: Red Hat, Engineering, Boston   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list