WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH, RFC]: xl: start implementing "the policy" wrt memory

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH, RFC]: xl: start implementing "the policy" wrt memory allocations
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Fri, 6 Aug 2010 15:20:02 +0100
Cc: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Delivery-date: Fri, 06 Aug 2010 07:25:09 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
It is libxl policy to return objects to callers which the caller must
free. It therefore a matter of correctness for libxl to only free it's
internal scratch allocations and never to free things which may be
returned so as to avoid double-free error conditions.

This patch (probably won't apply and is dirty as hell for now) - begins
to implement this. The approach taken is to use gcc's visibility
attribute to hide libxl internal functions from callers. This includes
the libxl garbage collection routines. These routines now take a new
structure libxl_gc which contains the garbage collection variables and a
back-pointer to the associated libxl context. Other changes include
returning void from libxl_*free* and abort()'ing when it goes wrong.

Working on this patch exposed numerous violations of the policy:
 - libxl_domid_to_name()
 - libxl_get_version_info()
 - libxl_list_vcpu()
 - libxl_list_nics()
 - libxl_device_net2_list()
 - perhaps others

domid_to_name has numerous in and out of library callers so for that I
introduced a libxl-internal _libxl_domid_to_name() which participates in
libxl garbage collection - a little too subtle for my taste but perhaps
something to be lived with.

The others would benefit from destructor functions such as Ian
Campbell's patch introduced.

A side effect of the gcc visibility stuff is getting rid of about a
thousand GOT/PLT entries which shaves 1-2KB off the binary size and
ought to speed up dynamic linking.

What needs to be done from here is a thorough audit of the policy and a
lot of time alone in a dark room doing bad things to xl with valgrind :)

I am thinking eventually of 4 logical changesets:
 1. Fix flagrant policy violations
 2. Get rid of leakiness with the new gc stuff (bulk of patch)
 3. Sprinkle the _hidden macros around
 4. Not decided how best to handle xs vs. NULL paths yet...
    probably xs_$(OP)f() w/ printf semantics built-in?

Comments, suggestions?

 tools/libxl/flexarray.c        |    3 
 tools/libxl/flexarray.h        |   12 
 tools/libxl/libxl.c            | 1006 ++++++++++++++++++++++++-----------------
 tools/libxl/libxl.h            |    5 
 tools/libxl/libxl_bootloader.c |   52 +-
 tools/libxl/libxl_device.c     |  102 +---
 tools/libxl/libxl_dom.c        |  198 +++++---
 tools/libxl/libxl_exec.c       |   20 
 tools/libxl/libxl_internal.c   |   79 +--
 tools/libxl/libxl_internal.h   |  134 +++--
 tools/libxl/libxl_pci.c        |  366 +++++++-------
 tools/libxl/libxl_utils.c      |  146 +++--
 tools/libxl/libxl_utils.h      |    2 
 tools/libxl/libxl_xshelp.c     |   29 -
 tools/libxl/xl_cmdimpl.c       |   12 
 16 files changed, 1258 insertions(+), 910 deletions(-)

diff -r e49e70e31a99 tools/libxl/flexarray.c
--- a/tools/libxl/flexarray.c   Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/flexarray.c   Fri Aug 06 15:00:14 2010 +0100
@@ -13,8 +13,7 @@
  * GNU Lesser General Public License for more details.
  */
 
-#include <stdlib.h>
-#include "flexarray.h"
+#include "libxl_internal.h"
 
 flexarray_t *flexarray_make(int size, int autogrow)
 {
diff -r e49e70e31a99 tools/libxl/flexarray.h
--- a/tools/libxl/flexarray.h   Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/flexarray.h   Fri Aug 06 15:00:14 2010 +0100
@@ -22,12 +22,12 @@ typedef struct flexarray {
     void **data; /* array of pointer */
 } flexarray_t;
 
-flexarray_t *flexarray_make(int size, int autogrow);
-void flexarray_free(flexarray_t *array);
-int flexarray_grow(flexarray_t *array, int extents);
-int flexarray_set(flexarray_t *array, unsigned int index, void *ptr);
-int flexarray_get(flexarray_t *array, int index, void **ptr);
+_hidden flexarray_t *flexarray_make(int size, int autogrow);
+_hidden void flexarray_free(flexarray_t *array);
+_hidden int flexarray_grow(flexarray_t *array, int extents);
+_hidden int flexarray_set(flexarray_t *array, unsigned int index, void *ptr);
+_hidden int flexarray_get(flexarray_t *array, int index, void **ptr);
 
-void **flexarray_contents(flexarray_t *array);
+_hidden void **flexarray_contents(flexarray_t *array);
 
 #endif
diff -r e49e70e31a99 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl.c       Fri Aug 06 15:00:14 2010 +0100
@@ -45,17 +45,12 @@ int libxl_ctx_init(libxl_ctx *ctx, int v
         return ERROR_VERSION;
     memset(ctx, 0, sizeof(libxl_ctx));
     ctx->lg = lg;
-    ctx->alloc_maxsize = 256;
-    ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *));
-    if (!ctx->alloc_ptrs)
-        return ERROR_NOMEM;
     memset(&ctx->version_info, 0, sizeof(libxl_version_info));
 
     ctx->xch = xc_interface_open(lg,lg,0);
     if (!ctx->xch) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, 
                         "cannot open libxc handle");
-        free(ctx->alloc_ptrs);
         return ERROR_FAIL;
     }
 
@@ -64,7 +59,6 @@ int libxl_ctx_init(libxl_ctx *ctx, int v
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, errno, 
                         "cannot connect to xenstore");
         xc_interface_close(ctx->xch);
-        free(ctx->alloc_ptrs);
         return ERROR_FAIL;
     }
     return 0;
@@ -72,8 +66,6 @@ int libxl_ctx_init(libxl_ctx *ctx, int v
 
 int libxl_ctx_free(libxl_ctx *ctx)
 {
-    libxl_free_all(ctx);
-    free(ctx->alloc_ptrs);
     xc_interface_close(ctx->xch);
     if (ctx->xsh) xs_daemon_close(ctx->xsh); 
     return 0;
@@ -84,6 +76,7 @@ int libxl_ctx_free(libxl_ctx *ctx)
 int libxl_domain_make(libxl_ctx *ctx, libxl_domain_create_info *info,
                        uint32_t *domid)
 {
+    libxl_gc gc = INIT_GC(ctx);
     int flags, ret, i, rc;
     char *uuid_string;
     char *rw_paths[] = { "device", "device/suspend/event-channel" , "data"};
@@ -95,8 +88,11 @@ int libxl_domain_make(libxl_ctx *ctx, li
     xs_transaction_t t;
     xen_domain_handle_t handle;
 
-    uuid_string = libxl_uuid2string(ctx, info->uuid);
-    if (!uuid_string) return ERROR_NOMEM;
+    uuid_string = libxl_uuid2string(&gc, info->uuid);
+    if (!uuid_string) {
+        libxl_free_all(&gc);
+        return ERROR_NOMEM;
+    }
 
     flags = info->hvm ? XEN_DOMCTL_CDF_hvm_guest : 0;
     flags |= info->hap ? XEN_DOMCTL_CDF_hap : 0;
@@ -109,22 +105,27 @@ int libxl_domain_make(libxl_ctx *ctx, li
     ret = xc_domain_create(ctx->xch, info->ssidref, handle, flags, domid);
     if (ret < 0) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain creation fail");
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
 
     ret = xc_cpupool_movedomain(ctx->xch, info->poolid, *domid);
     if (ret < 0) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "domain move fail");
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
 
-    dom_path = libxl_xs_get_dompath(ctx, *domid);
-    if (!dom_path)
+    dom_path = libxl_xs_get_dompath(&gc, *domid);
+    if (!dom_path) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
-
-    vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string);
+    }
+
+    vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string);
     if (!vm_path) {
         XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate create paths");
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
 
@@ -145,42 +146,48 @@ retry_transaction:
     xs_mkdir(ctx->xsh, t, vm_path);
     xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
 
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
+    xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
     rc = libxl_domain_rename(ctx, *domid, 0, info->name, t);
-    if (rc) return rc;
+    if (rc) {
+        libxl_free_all(&gc);
+        return rc;
+    }
 
     for (i = 0; i < ARRAY_SIZE(rw_paths); i++) {
-        char *path = libxl_sprintf(ctx, "%s/%s", dom_path, rw_paths[i]);
+        char *path = libxl_sprintf(&gc, "%s/%s", dom_path, rw_paths[i]);
         xs_mkdir(ctx->xsh, t, path);
         xs_set_permissions(ctx->xsh, t, path, rwperm, ARRAY_SIZE(rwperm));
-        libxl_free(ctx, path);
+        libxl_free(&gc, path);
     }
     for (i = 0; i < ARRAY_SIZE(ro_paths); i++) {
-        char *path = libxl_sprintf(ctx, "%s/%s", dom_path, ro_paths[i]);
+        char *path = libxl_sprintf(&gc, "%s/%s", dom_path, ro_paths[i]);
         xs_mkdir(ctx->xsh, t, path);
         xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
-        libxl_free(ctx, path);
+        libxl_free(&gc, path);
     }
 
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, 
strlen(uuid_string));
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/name", vm_path), info->name, 
strlen(info->name));
+    xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, 
strlen(uuid_string));
+    xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/name", vm_path), info->name, 
strlen(info->name));
     if (info->poolname)
-        xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/pool_name", vm_path), 
info->poolname, strlen(info->poolname));
-
-    libxl_xs_writev(ctx, t, dom_path, info->xsdata);
-    libxl_xs_writev(ctx, t, libxl_sprintf(ctx, "%s/platform", dom_path), 
info->platformdata);
-
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, 
"%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
+        xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/pool_name", vm_path), 
info->poolname, strlen(info->poolname));
+
+    libxl_xs_writev(&gc, t, dom_path, info->xsdata);
+    libxl_xs_writev(&gc, t, libxl_sprintf(&gc, "%s/platform", dom_path), 
info->platformdata);
+
+    xs_write(ctx->xsh, t, libxl_sprintf(&gc, 
"%s/control/platform-feature-multiprocessor-suspend", dom_path), "1", 1);
 
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid,
                         const char *old_name, const char *new_name,
-                        xs_transaction_t trans) {
+                        xs_transaction_t trans)
+{
+    libxl_gc gc = INIT_GC(ctx);
     char *dom_path = 0;
     const char *name_path;
     char *got_old_name;
@@ -188,10 +195,10 @@ int libxl_domain_rename(libxl_ctx *ctx, 
     xs_transaction_t our_trans = 0;
     int rc;
 
-    dom_path = libxl_xs_get_dompath(ctx, domid);
+    dom_path = libxl_xs_get_dompath(&gc, domid);
     if (!dom_path) goto x_nomem;
 
-    name_path= libxl_sprintf(ctx, "%s/name", dom_path);
+    name_path= libxl_sprintf(&gc, "%s/name", dom_path);
     if (!name_path) goto x_nomem;
 
  retry_transaction:
@@ -248,8 +255,8 @@ int libxl_domain_rename(libxl_ctx *ctx, 
 
     rc = 0;
  x_rc:
-    if (dom_path) libxl_free(ctx, dom_path);
     if (our_trans) xs_transaction_end(ctx->xsh, our_trans, 1);
+    libxl_free_all(&gc);
     return rc;
 
  x_fail:  rc = ERROR_FAIL;  goto x_rc;
@@ -258,38 +265,39 @@ int libxl_domain_rename(libxl_ctx *ctx, 
 
 int libxl_domain_build(libxl_ctx *ctx, libxl_domain_build_info *info, uint32_t 
domid, libxl_domain_build_state *state)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char **vments = NULL, **localents = NULL;
     struct timeval start_time;
     int i, ret;
 
-    ret = build_pre(ctx, domid, info, state);
+    ret = build_pre(&gc, domid, info, state);
     if (ret) goto out;
 
     gettimeofday(&start_time, NULL);
 
     if (info->hvm) {
-        ret = build_hvm(ctx, domid, info, state);
+        ret = build_hvm(&gc, domid, info, state);
         if (ret) goto out;
 
-        vments = libxl_calloc(ctx, 7, sizeof(char *));
+        vments = libxl_calloc(&gc, 7, sizeof(char *));
         vments[0] = "rtc/timeoffset";
         vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
         vments[2] = "image/ostype";
         vments[3] = "hvm";
         vments[4] = "start_time";
-        vments[5] = libxl_sprintf(ctx, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+        vments[5] = libxl_sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
     } else {
-        ret = build_pv(ctx, domid, info, state);
+        ret = build_pv(&gc, domid, info, state);
         if (ret) goto out;
 
-        vments = libxl_calloc(ctx, 11, sizeof(char *));
+        vments = libxl_calloc(&gc, 11, sizeof(char *));
         i = 0;
         vments[i++] = "image/ostype";
         vments[i++] = "linux";
         vments[i++] = "image/kernel";
         vments[i++] = (char*) info->kernel.path;
         vments[i++] = "start_time";
-        vments[i++] = libxl_sprintf(ctx, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+        vments[i++] = libxl_sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
         if (info->u.pv.ramdisk.path) {
             vments[i++] = "image/ramdisk";
             vments[i++] = (char*) info->u.pv.ramdisk.path;
@@ -299,12 +307,13 @@ int libxl_domain_build(libxl_ctx *ctx, l
             vments[i++] = (char*) info->u.pv.cmdline;
         }
     }
-    ret = build_post(ctx, domid, info, state, vments, localents);
+    ret = build_post(&gc, domid, info, state, vments, localents);
 out:
     libxl_file_reference_unmap(ctx, &info->kernel);
     if (!info->hvm)
            libxl_file_reference_unmap(ctx, &info->u.pv.ramdisk);
 
+    libxl_free_all(&gc);
     return ret;
 }
 
@@ -312,35 +321,36 @@ int libxl_domain_restore(libxl_ctx *ctx,
                          uint32_t domid, int fd, libxl_domain_build_state 
*state,
                          libxl_device_model_info *dm_info)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char **vments = NULL, **localents = NULL;
     struct timeval start_time;
     int i, ret, esave, flags;
 
-    ret = build_pre(ctx, domid, info, state);
+    ret = build_pre(&gc, domid, info, state);
     if (ret) goto out;
 
-    ret = restore_common(ctx, domid, info, state, fd);
+    ret = restore_common(&gc, domid, info, state, fd);
     if (ret) goto out;
 
     gettimeofday(&start_time, NULL);
 
     if (info->hvm) {
-        vments = libxl_calloc(ctx, 7, sizeof(char *));
+        vments = libxl_calloc(&gc, 7, sizeof(char *));
         vments[0] = "rtc/timeoffset";
         vments[1] = (info->u.hvm.timeoffset) ? info->u.hvm.timeoffset : "";
         vments[2] = "image/ostype";
         vments[3] = "hvm";
         vments[4] = "start_time";
-        vments[5] = libxl_sprintf(ctx, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+        vments[5] = libxl_sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
     } else {
-        vments = libxl_calloc(ctx, 11, sizeof(char *));
+        vments = libxl_calloc(&gc, 11, sizeof(char *));
         i = 0;
         vments[i++] = "image/ostype";
         vments[i++] = "linux";
         vments[i++] = "image/kernel";
         vments[i++] = (char*) info->kernel.path;
         vments[i++] = "start_time";
-        vments[i++] = libxl_sprintf(ctx, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
+        vments[i++] = libxl_sprintf(&gc, "%lu.%02d", 
start_time.tv_sec,(int)start_time.tv_usec/10000);
         if (info->u.pv.ramdisk.path) {
             vments[i++] = "image/ramdisk";
             vments[i++] = (char*) info->u.pv.ramdisk.path;
@@ -350,7 +360,7 @@ int libxl_domain_restore(libxl_ctx *ctx,
             vments[i++] = (char*) info->u.pv.cmdline;
         }
     }
-    ret = build_post(ctx, domid, info, state, vments, localents);
+    ret = build_post(&gc, domid, info, state, vments, localents);
     if (ret) goto out;
 
     dm_info->saved_state = NULL;
@@ -378,28 +388,35 @@ out:
     }
 
     errno = esave;
+    libxl_free_all(&gc);
     return ret;
 }
 
 int libxl_domain_resume(libxl_ctx *ctx, uint32_t domid)
 {
-    if (is_hvm(ctx, domid)) {
+    libxl_gc gc = INIT_GC(ctx);
+
+    if (is_hvm(&gc, domid)) {
         XL_LOG(ctx, XL_LOG_DEBUG, "Called domain_resume on "
                 "non-cooperative hvm domain %u", domid);
+        libxl_free_all(&gc);
         return ERROR_NI;
     }
     if (xc_domain_resume(ctx->xch, domid, 1)) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, 
                         "xc_domain_resume failed for domain %u", 
                         domid);
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
     if (!xs_resume_domain(ctx->xsh, domid)) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, 
                         "xs_resume_domain failed for domain %u", 
                         domid);
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -412,6 +429,7 @@ int libxl_domain_resume(libxl_ctx *ctx, 
 int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid,
                           libxl_domain_create_info *info, const char 
*name_suffix, libxl_uuid new_uuid)
 {
+    libxl_gc gc = INIT_GC(ctx);
     struct xs_permissions roperm[2];
     xs_transaction_t t;
     char *preserved_name;
@@ -421,17 +439,29 @@ int libxl_domain_preserve(libxl_ctx *ctx
 
     int rc;
 
-    preserved_name = libxl_sprintf(ctx, "%s%s", info->name, name_suffix);
-    if (!preserved_name) return ERROR_NOMEM;
-
-    uuid_string = libxl_uuid2string(ctx, new_uuid);
-    if (!uuid_string) return ERROR_NOMEM;
-
-    dom_path = libxl_xs_get_dompath(ctx, domid);
-    if (!dom_path) return ERROR_FAIL;
-
-    vm_path = libxl_sprintf(ctx, "/vm/%s", uuid_string);
-    if (!vm_path) return ERROR_FAIL;
+    preserved_name = libxl_sprintf(&gc, "%s%s", info->name, name_suffix);
+    if (!preserved_name) {
+        libxl_free_all(&gc);
+        return ERROR_NOMEM;
+    }
+
+    uuid_string = libxl_uuid2string(&gc, new_uuid);
+    if (!uuid_string) {
+        libxl_free_all(&gc);
+        return ERROR_NOMEM;
+    }
+
+    dom_path = libxl_xs_get_dompath(&gc, domid);
+    if (!dom_path) {
+        libxl_free_all(&gc);
+        return ERROR_FAIL;
+    }
+
+    vm_path = libxl_sprintf(&gc, "/vm/%s", uuid_string);
+    if (!vm_path) {
+        libxl_free_all(&gc);
+        return ERROR_FAIL;
+    }
 
     roperm[0].id = 0;
     roperm[0].perms = XS_PERM_NONE;
@@ -445,16 +475,20 @@ int libxl_domain_preserve(libxl_ctx *ctx
     xs_mkdir(ctx->xsh, t, vm_path);
     xs_set_permissions(ctx->xsh, t, vm_path, roperm, ARRAY_SIZE(roperm));
 
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
+    xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/vm", dom_path), vm_path, 
strlen(vm_path));
     rc = libxl_domain_rename(ctx, domid, info->name, preserved_name, t);
-    if (rc) return rc;
-
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/uuid", vm_path), uuid_string, 
strlen(uuid_string));
+    if (rc) {
+        libxl_free_all(&gc);
+        return rc;
+    }
+
+    xs_write(ctx->xsh, t, libxl_sprintf(&gc, "%s/uuid", vm_path), uuid_string, 
strlen(uuid_string));
 
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
 
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -508,7 +542,8 @@ libxl_dominfo * libxl_list_domain(libxl_
 }
 
 int libxl_domain_info(libxl_ctx *ctx, libxl_dominfo *info_r,
-                      uint32_t domid) {
+                      uint32_t domid)
+{
     xc_domaininfo_t xcinfo;
     int ret;
 
@@ -523,7 +558,7 @@ int libxl_domain_info(libxl_ctx *ctx, li
     return 0;
 }
 
-libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
+libxl_poolinfo *libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
 {
     libxl_poolinfo *ptr;
     int i, ret;
@@ -550,7 +585,7 @@ libxl_poolinfo * libxl_list_pool(libxl_c
 }
 
 /* this API call only list VM running on this host. a VM can be an aggregate 
of multiple domains. */
-libxl_vminfo * libxl_list_vm(libxl_ctx *ctx, int *nb_vm)
+libxl_vminfo *libxl_list_vm(libxl_ctx *ctx, int *nb_vm)
 {
     libxl_vminfo *ptr;
     int index, i, ret;
@@ -581,13 +616,17 @@ libxl_vminfo * libxl_list_vm(libxl_ctx *
 int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
                          uint32_t domid, int fd)
 {
-    int hvm = is_hvm(ctx, domid);
+    libxl_gc gc = INIT_GC(ctx);
+    int hvm = is_hvm(&gc, domid);
     int live = info != NULL && info->flags & XL_SUSPEND_LIVE;
     int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG;
 
-    core_suspend(ctx, domid, fd, hvm, live, debug);
-    if (hvm)
-        return save_device_model(ctx, domid, fd);
+    core_suspend(&gc, domid, fd, hvm, live, debug);
+    if (hvm) {
+        libxl_free_all(&gc);
+        return save_device_model(&gc, domid, fd);
+    }
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -617,23 +656,26 @@ int libxl_domain_core_dump(libxl_ctx *ct
 
 int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *path;
     char *state;
     int ret;
 
-    if (is_hvm(ctx, domid)) {
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", 
domid);
-        state = libxl_xs_read(ctx, XBT_NULL, path);
+    if (is_hvm(&gc, domid)) {
+        path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d/state", 
domid);
+        state = libxl_xs_read(&gc, XBT_NULL, path);
         if (state != NULL && !strcmp(state, "paused")) {
-            libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, 
"/local/domain/0/device-model/%d/command", domid), "continue");
-            libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL);
+            libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, 
"/local/domain/0/device-model/%d/command", domid), "continue");
+            libxl_wait_for_device_model(&gc, domid, "running", NULL, NULL);
         }
     }
     ret = xc_domain_unpause(ctx->xch, domid);
     if (ret<0) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unpausing domain %d", domid);
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -647,41 +689,50 @@ static char *req_table[] = {
 
 int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid, int req)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *shutdown_path;
     char *dom_path;
 
-    if (req > ARRAY_SIZE(req_table))
+    if (req > ARRAY_SIZE(req_table)) {
+        libxl_free_all(&gc);
         return ERROR_INVAL;
-
-    dom_path = libxl_xs_get_dompath(ctx, domid);
-    if (!dom_path)
+    }
+
+    dom_path = libxl_xs_get_dompath(&gc, domid);
+    if (!dom_path) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
-
-    shutdown_path = libxl_sprintf(ctx, "%s/control/shutdown", dom_path);
+    }
+
+    shutdown_path = libxl_sprintf(&gc, "%s/control/shutdown", dom_path);
 
     xs_write(ctx->xsh, XBT_NULL, shutdown_path, req_table[req], 
strlen(req_table[req]));
-    if (is_hvm(ctx,domid)) {
+    if (is_hvm(&gc,domid)) {
         unsigned long acpi_s_state = 0;
         unsigned long pvdriver = 0;
         int ret;
         ret = xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_ACPI_S_STATE, 
&acpi_s_state);
         if (ret<0) {
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting ACPI S-state");
+            libxl_free_all(&gc);
             return ERROR_FAIL;
         }
         ret = xc_get_hvm_param(ctx->xch, domid, HVM_PARAM_CALLBACK_IRQ, 
&pvdriver);
         if (ret<0) {
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "getting HVM callback IRQ");
+            libxl_free_all(&gc);
             return ERROR_FAIL;
         }
         if (!pvdriver || acpi_s_state != 0) {
             ret = xc_domain_shutdown(ctx->xch, domid, req);
             if (ret<0) {
                 XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "unpausing domain");
+                libxl_free_all(&gc);
                 return ERROR_FAIL;
             }
        }
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -703,21 +754,27 @@ int libxl_wait_for_domain_death(libxl_ct
 
 int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t guest_domid, 
libxl_device_disk *disks, int num_disks, libxl_waiter *waiter)
 {
+    libxl_gc gc = INIT_GC(ctx);
+    uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid);
     int i;
-    uint32_t domid = libxl_get_stubdom_id(ctx, guest_domid);
 
     if (!domid)
         domid = guest_domid;
 
     for (i = 0; i < num_disks; i++) {
         if (asprintf(&(waiter[i].path), "%s/device/vbd/%d/eject",
-                     libxl_xs_get_dompath(ctx, domid),
-                     device_disk_dev_number(disks[i].virtpath)) < 0)
+                     libxl_xs_get_dompath(&gc, domid),
+                     device_disk_dev_number(disks[i].virtpath)) < 0) {
+            libxl_free_all(&gc);
             return -1;
-        if (asprintf(&(waiter[i].token), "%d", LIBXL_EVENT_DISK_EJECT) < 0)
+        }
+        if (asprintf(&(waiter[i].token), "%d", LIBXL_EVENT_DISK_EJECT) < 0) {
+            libxl_free_all(&gc);
             return -1;
+        }
         xs_watch(ctx->xsh, waiter->path, waiter->token);
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -771,49 +828,57 @@ int libxl_event_get_domain_death_info(li
 
 int libxl_event_get_disk_eject_info(libxl_ctx *ctx, uint32_t domid, 
libxl_event *event, libxl_device_disk *disk)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *path;
     char *backend;
     char *value;
 
-    value = libxl_xs_read(ctx, XBT_NULL, event->path);
-
-    if (!value || strcmp(value,  "eject"))
+    value = libxl_xs_read(&gc, XBT_NULL, event->path);
+
+    if (!value || strcmp(value,  "eject")) {
+        libxl_free_all(&gc);
         return 0;
+    }
 
     path = strdup(event->path);
     path[strlen(path) - 6] = '\0';
-    backend = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", 
path));
+    backend = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", 
path));
 
     disk->backend_domid = 0;
     disk->domid = domid;
     disk->physpath = NULL;
     disk->phystype = 0;
     /* this value is returned to the user: do not free right away */
-    disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", 
backend));
+    disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", 
backend));
     disk->unpluggable = 1;
     disk->readwrite = 0;
     disk->is_cdrom = 1;
 
     free(path);
+    libxl_free_all(&gc);
     return 1;
 }
 
-static int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid)
+int libxl_destroy_device_model(libxl_ctx *ctx, uint32_t domid)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *pid;
     int ret;
 
-    pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"/local/domain/%d/image/device-model-pid", domid));
+    pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"/local/domain/%d/image/device-model-pid", domid));
     if (!pid) {
         int stubdomid = libxl_get_stubdom_id(ctx, domid);
         if (!stubdomid) {
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't find device model's 
pid");
+            libxl_free_all(&gc);
             return ERROR_INVAL;
         }
         XL_LOG(ctx, XL_LOG_ERROR, "Device model is a stubdom, domid=%d\n", 
stubdomid);
-        return libxl_domain_destroy(ctx, stubdomid, 0);
+        ret = libxl_domain_destroy(ctx, stubdomid, 0);
+        libxl_free_all(&gc);
+        return ret;
     }
-    xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, 
"/local/domain/0/device-model/%d", domid));
+    xs_rm(ctx->xsh, XBT_NULL, libxl_sprintf(&gc, 
"/local/domain/0/device-model/%d", domid));
 
     ret = kill(atoi(pid), SIGHUP);
     if (ret < 0 && errno == ESRCH) {
@@ -826,33 +891,37 @@ static int libxl_destroy_device_model(li
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to kill Device Model [%d]",
                      atoi(pid));
     }
+    libxl_free_all(&gc);
     return ret;
 }
 
 int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid, int force)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *dom_path;
     char *vm_path;
     int rc, dm_present;
 
-    if (is_hvm(ctx, domid)) {
+    if (is_hvm(&gc, domid)) {
         dm_present = 1;
     } else {
         char *pid;
-        pid = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"/local/domain/%d/image/device-model-pid", domid));
+        pid = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"/local/domain/%d/image/device-model-pid", domid));
         dm_present = (pid != NULL);
-        libxl_free(ctx, pid);
+        libxl_free(&gc, pid);
     }
 
-    dom_path = libxl_xs_get_dompath(ctx, domid);
-    if (!dom_path)
+    dom_path = libxl_xs_get_dompath(&gc, domid);
+    if (!dom_path) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
+    }
 
     if (libxl_device_pci_shutdown(ctx, domid) < 0)
         XL_LOG(ctx, XL_LOG_ERROR, "pci shutdown failed for domid %d", domid);
     if (dm_present) {
         xs_write(ctx->xsh, XBT_NULL,
-                 libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", 
domid),
+                 libxl_sprintf(&gc, "/local/domain/0/device-model/%d/command", 
domid),
                  "shutdown", strlen("shutdown"));
     }
     rc = xc_domain_pause(ctx->xch, domid);
@@ -863,10 +932,10 @@ int libxl_domain_destroy(libxl_ctx *ctx,
         if (libxl_destroy_device_model(ctx, domid) < 0)
             XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for 
%d", domid);
     }
-    if (libxl_devices_destroy(ctx, domid, force) < 0)
+    if (libxl_devices_destroy(&gc, domid, force) < 0)
         XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", 
domid);
 
-    vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vm", 
dom_path));
+    vm_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", 
dom_path));
     if (vm_path)
         if (!xs_rm(ctx->xsh, XBT_NULL, vm_path))
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path);
@@ -874,22 +943,27 @@ int libxl_domain_destroy(libxl_ctx *ctx,
     if (!xs_rm(ctx->xsh, XBT_NULL, dom_path))
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", dom_path);
 
-    libxl__userdata_destroyall(ctx, domid);
+    libxl__userdata_destroyall(&gc, domid);
 
     rc = xc_domain_destroy(ctx->xch, domid);
     if (rc < 0) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for 
%d", domid);
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_console_exec(libxl_ctx *ctx, uint32_t domid, int cons_num)
 {
-    char *p = libxl_sprintf(ctx, "%s/xenconsole", libxl_private_bindir_path());
-    char *domid_s = libxl_sprintf(ctx, "%d", domid);
-    char *cons_num_s = libxl_sprintf(ctx, "%d", cons_num);
-    return execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL) == 0 ? 0 : 
ERROR_FAIL;
+    libxl_gc gc = INIT_GC(ctx);
+    char *p = libxl_sprintf(&gc, "%s/xenconsole", libxl_private_bindir_path());
+    char *domid_s = libxl_sprintf(&gc, "%d", domid);
+    char *cons_num_s = libxl_sprintf(&gc, "%d", cons_num);
+    execl(p, p, domid_s, "--num", cons_num_s, (void *)NULL);
+    libxl_free_all(&gc);
+    return ERROR_FAIL;
 }
 
 int libxl_primary_console_exec(libxl_ctx *ctx, uint32_t domid_vm)
@@ -903,6 +977,7 @@ int libxl_primary_console_exec(libxl_ctx
 
 int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass)
 {
+    libxl_gc gc = INIT_GC(ctx);
     const char *vnc_port, *vfb_back;
     const char *vnc_listen = NULL, *vnc_pass = NULL;
     int port = 0, autopass_fd = -1;
@@ -913,22 +988,22 @@ int libxl_vncviewer_exec(libxl_ctx *ctx,
         NULL,
     };
 
-    vnc_port = libxl_xs_read(ctx, XBT_NULL,
-                            libxl_sprintf(ctx,
+    vnc_port = libxl_xs_read(&gc, XBT_NULL,
+                            libxl_sprintf(&gc,
                             "/local/domain/%d/console/vnc-port", domid));
     if ( vnc_port )
         port = atoi(vnc_port) - 5900;
 
-    vfb_back = libxl_xs_read(ctx, XBT_NULL,
-                            libxl_sprintf(ctx,
+    vfb_back = libxl_xs_read(&gc, XBT_NULL,
+                            libxl_sprintf(&gc,
                             "/local/domain/%d/device/vfb/0/backend", domid));
     if ( vfb_back ) {
-        vnc_listen = libxl_xs_read(ctx, XBT_NULL,
-                            libxl_sprintf(ctx,
+        vnc_listen = libxl_xs_read(&gc, XBT_NULL,
+                            libxl_sprintf(&gc,
                             "/local/domain/%d/console/vnc-listen", domid));
         if ( autopass )
-            vnc_pass = libxl_xs_read(ctx, XBT_NULL,
-                            libxl_sprintf(ctx,
+            vnc_pass = libxl_xs_read(&gc, XBT_NULL,
+                            libxl_sprintf(&gc,
                             "/local/domain/%d/console/vnc-pass", domid));
     }
 
@@ -938,7 +1013,7 @@ int libxl_vncviewer_exec(libxl_ctx *ctx,
     if ( (vnc_bin = getenv("VNCVIEWER")) )
         args[0] = vnc_bin;
 
-    args[1] = libxl_sprintf(ctx, "%s:%d", vnc_listen, port);
+    args[1] = libxl_sprintf(&gc, "%s:%d", vnc_listen, port);
 
     if ( vnc_pass ) {
         char tmpname[] = "/tmp/vncautopass.XXXXXX";
@@ -961,10 +1036,11 @@ int libxl_vncviewer_exec(libxl_ctx *ctx,
 
 skip_autopass:
     libxl_exec(autopass_fd, -1, -1, args[0], args);
+    libxl_free_all(&gc);
     return 0;
 }
 
-static char ** libxl_build_device_model_args(libxl_ctx *ctx,
+static char ** libxl_build_device_model_args(libxl_gc *gc,
                                              libxl_device_model_info *info,
                                              libxl_device_nic *vifs,
                                              int num_vifs)
@@ -978,7 +1054,7 @@ static char ** libxl_build_device_model_
     flexarray_set(dm_args, num++, "qemu-dm");
     flexarray_set(dm_args, num++, "-d");
 
-    flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", info->domid));
+    flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", info->domid));
 
     if (info->dom_name) {
         flexarray_set(dm_args, num++, "-domain-name");
@@ -990,18 +1066,18 @@ static char ** libxl_build_device_model_
             if (info->vnclisten && strchr(info->vnclisten, ':') == NULL) {
                 flexarray_set(
                     dm_args, num++,
-                    libxl_sprintf(ctx, "%s:%d%s",
+                    libxl_sprintf(gc, "%s:%d%s",
                                   info->vnclisten,
                                   info->vncdisplay,
                                   info->vncpasswd ? ",password" : ""));
             } else {
-                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"127.0.0.1:%d", info->vncdisplay));
+                flexarray_set(dm_args, num++, libxl_sprintf(gc, 
"127.0.0.1:%d", info->vncdisplay));
             }
         } else if (info->vnclisten) {
             if (strchr(info->vnclisten, ':') != NULL) {
                 flexarray_set(dm_args, num++, info->vnclisten);
             } else {
-                flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%s:0", 
info->vnclisten));
+                flexarray_set(dm_args, num++, libxl_sprintf(gc, "%s:0", 
info->vnclisten));
             }
         } else {
             flexarray_set(dm_args, num++, "127.0.0.1:0");
@@ -1032,7 +1108,7 @@ static char ** libxl_build_device_model_
 
         if (info->videoram) {
             flexarray_set(dm_args, num++, "-videoram");
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", 
info->videoram));
+            flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", 
info->videoram));
         }
         if (info->stdvga) {
             flexarray_set(dm_args, num++, "-std-vga");
@@ -1058,24 +1134,24 @@ static char ** libxl_build_device_model_
         }
         if (info->vcpus > 1) {
             flexarray_set(dm_args, num++, "-vcpus");
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "%d", 
info->vcpus));
+            flexarray_set(dm_args, num++, libxl_sprintf(gc, "%d", 
info->vcpus));
         }
         if (info->vcpu_avail) {
             flexarray_set(dm_args, num++, "-vcpu_avail");
-            flexarray_set(dm_args, num++, libxl_sprintf(ctx, "0x%x", 
info->vcpu_avail));
+            flexarray_set(dm_args, num++, libxl_sprintf(gc, "0x%x", 
info->vcpu_avail));
         }
         for (i = 0; i < num_vifs; i++) {
             if (vifs[i].nictype == NICTYPE_IOEMU) {
-                char *smac = libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+                char *smac = libxl_sprintf(gc, "%02x:%02x:%02x:%02x:%02x:%02x",
                                            vifs[i].mac[0], vifs[i].mac[1], 
vifs[i].mac[2],
                                            vifs[i].mac[3], vifs[i].mac[4], 
vifs[i].mac[5]);
                 if (!vifs[i].ifname)
-                    vifs[i].ifname = libxl_sprintf(ctx, "tap%d.%d", 
info->domid, vifs[i].devid - 1);
+                    vifs[i].ifname = libxl_sprintf(gc, "tap%d.%d", 
info->domid, vifs[i].devid - 1);
                 flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"nic,vlan=%d,macaddr=%s,model=%s",
+                flexarray_set(dm_args, num++, libxl_sprintf(gc, 
"nic,vlan=%d,macaddr=%s,model=%s",
                             vifs[i].devid, smac, vifs[i].model));
                 flexarray_set(dm_args, num++, "-net");
-                flexarray_set(dm_args, num++, libxl_sprintf(ctx, 
"tap,vlan=%d,ifname=%s,bridge=%s",
+                flexarray_set(dm_args, num++, libxl_sprintf(gc, 
"tap,vlan=%d,ifname=%s,bridge=%s",
                             vifs[i].devid, vifs[i].ifname, vifs[i].bridge));
                 ioemu_vifs++;
             }
@@ -1102,7 +1178,7 @@ static char ** libxl_build_device_model_
     return (char **) flexarray_contents(dm_args);
 }
 
-void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
+static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
 {
     libxl_device_model_starting *starting = for_spawn;
     char *kvs[3];
@@ -1123,8 +1199,7 @@ void dm_xenstore_record_pid(void *for_sp
     xs_daemon_close(xsh);
 }
 
-static int libxl_vfb_and_vkb_from_device_model_info(libxl_ctx *ctx,
-                                                    libxl_device_model_info 
*info,
+static int libxl_vfb_and_vkb_from_device_model_info(libxl_device_model_info 
*info,
                                                     libxl_device_vfb *vfb,
                                                     libxl_device_vkb *vkb)
 {
@@ -1147,8 +1222,9 @@ static int libxl_vfb_and_vkb_from_device
     return 0;
 }
 
-static int libxl_write_dmargs(libxl_ctx *ctx, int domid, int guest_domid, char 
**args)
+static int libxl_write_dmargs(libxl_gc *gc, int domid, int guest_domid, char 
**args)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int i;
     char *vm_path;
     char *dmargs, *path;
@@ -1161,7 +1237,7 @@ static int libxl_write_dmargs(libxl_ctx 
     roperm[1].id = domid;
     roperm[1].perms = XS_PERM_READ;
 
-    vm_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"/local/domain/%d/vm", guest_domid));
+    vm_path = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, 
"/local/domain/%d/vm", guest_domid));
 
     i = 0;
     dmargs_size = 0;
@@ -1180,13 +1256,13 @@ static int libxl_write_dmargs(libxl_ctx 
         }
         i++;
     }
-    path = libxl_sprintf(ctx, "%s/image/dmargs", vm_path);
+    path = libxl_sprintf(gc, "%s/image/dmargs", vm_path);
 
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
     xs_write(ctx->xsh, t, path, dmargs, strlen(dmargs));
     xs_set_permissions(ctx->xsh, t, path, roperm, ARRAY_SIZE(roperm));
-    xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, "%s/rtc/timeoffset", 
vm_path), roperm, ARRAY_SIZE(roperm));
+    xs_set_permissions(ctx->xsh, t, libxl_sprintf(gc, "%s/rtc/timeoffset", 
vm_path), roperm, ARRAY_SIZE(roperm));
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
@@ -1194,7 +1270,7 @@ retry_transaction:
     return 0;
 }
 
-static int libxl_create_stubdom(libxl_ctx *ctx,
+static int libxl_create_stubdom(libxl_gc *gc,
                                 libxl_device_model_info *info,
                                 libxl_device_disk *disks, int num_disks,
                                 libxl_device_nic *vifs, int num_vifs,
@@ -1202,6 +1278,7 @@ static int libxl_create_stubdom(libxl_ct
                                 libxl_device_vkb *vkb,
                                 libxl_device_model_starting **starting_r)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int i, num_console = 1, ret;
     libxl_device_console *console;
     libxl_domain_create_info c_info;
@@ -1213,13 +1290,13 @@ static int libxl_create_stubdom(libxl_ct
     xs_transaction_t t;
     libxl_device_model_starting *dm_starting = 0;
 
-    args = libxl_build_device_model_args(ctx, info, vifs, num_vifs);
+    args = libxl_build_device_model_args(gc, info, vifs, num_vifs);
     if (!args)
         return ERROR_FAIL;
 
     memset(&c_info, 0x00, sizeof(libxl_domain_create_info));
     c_info.hvm = 0;
-    c_info.name = libxl_sprintf(ctx, "%s-dm", libxl_domid_to_name(ctx, 
info->domid));
+    c_info.name = libxl_sprintf(gc, "%s-dm", _libxl_domid_to_name(gc, 
info->domid));
     for (i = 0; i < 16; i++)
         c_info.uuid[i] = info->uuid[i];
 
@@ -1227,8 +1304,8 @@ static int libxl_create_stubdom(libxl_ct
     b_info.max_vcpus = 1;
     b_info.max_memkb = 32 * 1024;
     b_info.target_memkb = b_info.max_memkb;
-    b_info.kernel.path = libxl_abs_path(ctx, "ioemu-stubdom.gz", 
libxl_xenfirmwaredir_path());
-    b_info.u.pv.cmdline = libxl_sprintf(ctx, " -d %d", info->domid);
+    b_info.kernel.path = libxl_abs_path(gc, "ioemu-stubdom.gz", 
libxl_xenfirmwaredir_path());
+    b_info.u.pv.cmdline = libxl_sprintf(gc, " -d %d", info->domid);
     b_info.u.pv.ramdisk.path = "";
     b_info.u.pv.features = "";
     b_info.hvm = 0;
@@ -1238,12 +1315,12 @@ static int libxl_create_stubdom(libxl_ct
     ret = libxl_domain_build(ctx, &b_info, domid, &state);
     if (ret) return ret;
 
-    libxl_write_dmargs(ctx, domid, info->domid, args);
-    libxl_xs_write(ctx, XBT_NULL,
-                   libxl_sprintf(ctx, "%s/image/device-model-domid", 
libxl_xs_get_dompath(ctx, info->domid)),
+    libxl_write_dmargs(gc, domid, info->domid, args);
+    libxl_xs_write(gc, XBT_NULL,
+                   libxl_sprintf(gc, "%s/image/device-model-domid", 
libxl_xs_get_dompath(gc, info->domid)),
                    "%d", domid);
-    libxl_xs_write(ctx, XBT_NULL,
-                   libxl_sprintf(ctx, "%s/target", libxl_xs_get_dompath(ctx, 
domid)),
+    libxl_xs_write(gc, XBT_NULL,
+                   libxl_sprintf(gc, "%s/target", libxl_xs_get_dompath(gc, 
domid)),
                    "%d", info->domid);
     ret = xc_domain_set_target(ctx->xch, domid, info->domid);
     if (ret<0) {
@@ -1258,10 +1335,10 @@ static int libxl_create_stubdom(libxl_ct
     perm[1].perms = XS_PERM_READ;
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
-    xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, 
"/local/domain/0/device-model/%d", info->domid));
-    xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, 
"/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
-    xs_mkdir(ctx->xsh, t, libxl_sprintf(ctx, "/local/domain/%d/device/vfs", 
domid));
-    xs_set_permissions(ctx->xsh, t, libxl_sprintf(ctx, 
"/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
+    xs_mkdir(ctx->xsh, t, libxl_sprintf(gc, "/local/domain/0/device-model/%d", 
info->domid));
+    xs_set_permissions(ctx->xsh, t, libxl_sprintf(gc, 
"/local/domain/0/device-model/%d", info->domid), perm, ARRAY_SIZE(perm));
+    xs_mkdir(ctx->xsh, t, libxl_sprintf(gc, "/local/domain/%d/device/vfs", 
domid));
+    xs_set_permissions(ctx->xsh, t, libxl_sprintf(gc, 
"/local/domain/%d/device/vfs",domid), perm, ARRAY_SIZE(perm));
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
@@ -1286,7 +1363,7 @@ retry_transaction:
     if (info->serial)
         num_console++;
 
-    console = libxl_calloc(ctx, num_console, sizeof(libxl_device_console));
+    console = libxl_calloc(gc, num_console, sizeof(libxl_device_console));
     if (!console)
         return ERROR_NOMEM;
 
@@ -1311,9 +1388,9 @@ retry_transaction:
     libxl_domain_unpause(ctx, domid);
 
     if (starting_r) {
-        *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 
1);
+        *starting_r = libxl_calloc(gc, sizeof(libxl_device_model_starting), 1);
         (*starting_r)->domid = info->domid;
-        (*starting_r)->dom_path = libxl_xs_get_dompath(ctx, info->domid);
+        (*starting_r)->dom_path = libxl_xs_get_dompath(gc, info->domid);
         (*starting_r)->for_spawn = NULL;
     }
 
@@ -1327,6 +1404,7 @@ int libxl_create_device_model(libxl_ctx 
                               libxl_device_nic *vifs, int num_vifs,
                               libxl_device_model_starting **starting_r)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *path, *logfile;
     int logfile_w, null;
     int rc;
@@ -1340,60 +1418,67 @@ int libxl_create_device_model(libxl_ctx 
         libxl_device_vfb vfb;
         libxl_device_vkb vkb;
 
-        libxl_vfb_and_vkb_from_device_model_info(ctx, info, &vfb, &vkb);
-        return libxl_create_stubdom(ctx, info, disks, num_disks, vifs, 
num_vifs, &vfb, &vkb, starting_r);
+        libxl_vfb_and_vkb_from_device_model_info(info, &vfb, &vkb);
+        rc = libxl_create_stubdom(&gc, info, disks, num_disks, vifs, num_vifs, 
&vfb, &vkb, starting_r);
+        libxl_free_all(&gc);
+        return rc;
     }
 
-    args = libxl_build_device_model_args(ctx, info, vifs, num_vifs);
-    if (!args)
+    args = libxl_build_device_model_args(&gc, info, vifs, num_vifs);
+    if (!args) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
-
-    path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d", info->domid);
+    }
+
+    path = libxl_sprintf(&gc, "/local/domain/0/device-model/%d", info->domid);
     xs_mkdir(ctx->xsh, XBT_NULL, path);
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/disable_pf", path), 
"%d", !info->xen_platform_pci);
-
-    libxl_create_logfile(ctx, libxl_sprintf(ctx, "qemu-dm-%s", 
info->dom_name), &logfile);
+    libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/disable_pf", path), 
"%d", !info->xen_platform_pci);
+
+    libxl_create_logfile(ctx, libxl_sprintf(&gc, "qemu-dm-%s", 
info->dom_name), &logfile);
     logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
     free(logfile);
     null = open("/dev/null", O_RDONLY);
 
     if (starting_r) {
         rc = ERROR_NOMEM;
-        *starting_r = libxl_calloc(ctx, sizeof(libxl_device_model_starting), 
1);
+        *starting_r = libxl_calloc(&gc, sizeof(libxl_device_model_starting), 
1);
         if (!*starting_r) goto xit;
         p = *starting_r;
-        p->for_spawn = libxl_calloc(ctx, sizeof(libxl_spawn_starting), 1);
+        p->for_spawn = libxl_calloc(&gc, sizeof(libxl_spawn_starting), 1);
     } else {
         p = &buf_starting;
         p->for_spawn = NULL;
     }
 
     p->domid = info->domid;
-    p->dom_path = libxl_xs_get_dompath(ctx, info->domid);
-    if (!p->dom_path) { libxl_free(ctx, p); return ERROR_FAIL; }
+    p->dom_path = libxl_xs_get_dompath(&gc, info->domid);
+    if (!p->dom_path) {
+        libxl_free_all(&gc);
+        return ERROR_FAIL;
+    }
 
     if (info->vncpasswd) {
     retry_transaction:
         /* Find uuid and the write the vnc password to xenstore for qemu. */
         t = xs_transaction_start(ctx->xsh);
-        vm_path = libxl_xs_read(ctx,t,libxl_sprintf(ctx, "%s/vm", 
p->dom_path));
+        vm_path = libxl_xs_read(&gc,t,libxl_sprintf(&gc, "%s/vm", 
p->dom_path));
         if (vm_path) {
             /* Now write the vncpassword into it. */
-            pass_stuff = libxl_calloc(ctx, 2, sizeof(char *));
+            pass_stuff = libxl_calloc(&gc, 2, sizeof(char *));
             pass_stuff[0] = "vncpasswd";
             pass_stuff[1] = info->vncpasswd;
-            libxl_xs_writev(ctx,t,vm_path,pass_stuff);
+            libxl_xs_writev(&gc,t,vm_path,pass_stuff);
             if (!xs_transaction_end(ctx->xsh, t, 0))
                 if (errno == EAGAIN)
                     goto retry_transaction;
         }
     }
 
-    rc = libxl_spawn_spawn(ctx, p, "device model", dm_xenstore_record_pid);
+    rc = libxl_spawn_spawn(&gc, p, "device model", dm_xenstore_record_pid);
     if (rc < 0) goto xit;
     if (!rc) { /* inner child */
         libxl_exec(null, logfile_w, logfile_w,
-                   libxl_abs_path(ctx, info->device_model, 
libxl_private_bindir_path()),
+                   libxl_abs_path(&gc, info->device_model, 
libxl_private_bindir_path()),
                    args);
     }
 
@@ -1403,16 +1488,17 @@ int libxl_create_device_model(libxl_ctx 
     close(null);
     close(logfile_w);
 
+    libxl_free_all(&gc);
     return rc;
 }
 
 int libxl_detach_device_model(libxl_ctx *ctx,
                               libxl_device_model_starting *starting)
 {
+    libxl_gc gc = INIT_GC(ctx);
     int rc;
-    rc = libxl_spawn_detach(ctx, starting->for_spawn);
-    if (starting->for_spawn) libxl_free(ctx, starting->for_spawn);
-    libxl_free(ctx, starting);
+    rc = libxl_spawn_detach(&gc, starting->for_spawn);
+    libxl_free_all(&gc);
     return rc;
 }
 
@@ -1420,40 +1506,43 @@ int libxl_detach_device_model(libxl_ctx 
 int libxl_confirm_device_model_startup(libxl_ctx *ctx,
                                        libxl_device_model_starting *starting)
 {
-    int problem = libxl_wait_for_device_model(ctx, starting->domid, "running", 
NULL, NULL);
+    libxl_gc gc = INIT_GC(ctx);
+    int problem = libxl_wait_for_device_model(&gc, starting->domid, "running", 
NULL, NULL);
     int detach;
     if ( !problem )
-        problem = libxl_spawn_check(ctx, starting->for_spawn);
+        problem = libxl_spawn_check(&gc, starting->for_spawn);
     detach = libxl_detach_device_model(ctx, starting);
+    libxl_free_all(&gc);
     return problem ? problem : detach;
 }
 
 
 
/******************************************************************************/
 
-static char *get_blktap2_device(libxl_ctx *ctx,
+static char *get_blktap2_device(libxl_gc *gc,
                                const char *name, const char *type)
 {
     int minor = tap_ctl_find_minor(type, name);
     if (minor < 0)
         return NULL;
-    return libxl_sprintf(ctx, "/dev/xen/blktap-2/tapdev%d", minor);
+    return libxl_sprintf(gc, "/dev/xen/blktap-2/tapdev%d", minor);
 }
 
-static char *make_blktap2_device(libxl_ctx *ctx,
+static char *make_blktap2_device(libxl_gc *gc,
                                 const char *name, const char *type)
 {
     char *params, *devname = NULL;
     int err;
-    params = libxl_sprintf(ctx, "%s:%s", type, name);
+    params = libxl_sprintf(gc, "%s:%s", type, name);
     err = tap_ctl_create(params, &devname);
     if (!err)
-        libxl_ptr_add(ctx, devname);
+        libxl_ptr_add(gc, devname);
     return err ? NULL : devname;
 }
 
 int libxl_device_disk_add(libxl_ctx *ctx, uint32_t domid, libxl_device_disk 
*disk)
 {
+    libxl_gc gc = INIT_GC(ctx);
     flexarray_t *front;
     flexarray_t *back;
     char *backend_type;
@@ -1464,17 +1553,22 @@ int libxl_device_disk_add(libxl_ctx *ctx
     int major, minor;
 
     front = flexarray_make(16, 1);
-    if (!front)
+    if (!front) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
     back = flexarray_make(16, 1);
-    if (!back) /* leaks front if error */
+    if (!back) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
 
     backend_type = device_disk_backend_type_of_phystype(disk->phystype);
     devid = device_disk_dev_number(disk->virtpath);
     if (devid==-1) {
         XL_LOG(ctx, XL_LOG_ERROR, "Invalid or unuspported"
                " virtual disk identifier %s", disk->virtpath);
+        libxl_free_all(&gc);
         return ERROR_INVAL;
     }
 
@@ -1489,7 +1583,7 @@ int libxl_device_disk_add(libxl_ctx *ctx
 
             device_physdisk_major_minor(disk->physpath, &major, &minor);
             flexarray_set(back, boffset++, "physical-device");
-            flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", major, 
minor));
+            flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", major, 
minor));
 
             flexarray_set(back, boffset++, "params");
             flexarray_set(back, boffset++, disk->physpath);
@@ -1505,25 +1599,27 @@ int libxl_device_disk_add(libxl_ctx *ctx
             if (!tap_ctl_check(&msg)) {
                 const char *type = 
device_disk_string_of_phystype(disk->phystype);
                 char *dev;
-                dev = get_blktap2_device(ctx, disk->physpath, type);
+                dev = get_blktap2_device(&gc, disk->physpath, type);
                 if (!dev)
-                    dev = make_blktap2_device(ctx, disk->physpath, type);
-                if (!dev)
+                    dev = make_blktap2_device(&gc, disk->physpath, type);
+                if (!dev) {
+                    libxl_free_all(&gc);
                     return ERROR_FAIL;
+                }
                 flexarray_set(back, boffset++, "tapdisk-params");
-                flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s", 
device_disk_string_of_phystype(disk->phystype), disk->physpath));
+                flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s", 
device_disk_string_of_phystype(disk->phystype), disk->physpath));
                 flexarray_set(back, boffset++, "params");
-                flexarray_set(back, boffset++, libxl_strdup(ctx, dev));
+                flexarray_set(back, boffset++, libxl_strdup(&gc, dev));
                 backend_type = "phy";
                 device_physdisk_major_minor(dev, &major, &minor);
                 flexarray_set(back, boffset++, "physical-device");
-                flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x:%x", 
major, minor));
+                flexarray_set(back, boffset++, libxl_sprintf(&gc, "%x:%x", 
major, minor));
                 device.backend_kind = DEVICE_VBD;
 
                 break;
             }
             flexarray_set(back, boffset++, "params");
-            flexarray_set(back, boffset++, libxl_sprintf(ctx, "%s:%s",
+            flexarray_set(back, boffset++, libxl_sprintf(&gc, "%s:%s",
                           device_disk_string_of_phystype(disk->phystype), 
disk->physpath));
 
             device.backend_kind = DEVICE_TAP;
@@ -1531,19 +1627,20 @@ int libxl_device_disk_add(libxl_ctx *ctx
         }
         default:
             XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", 
disk->phystype);
+            libxl_free_all(&gc);
             return ERROR_INVAL;
     }
 
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", disk->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", disk->domid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "removable");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
(disk->unpluggable) ? 1 : 0));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 
(disk->unpluggable) ? 1 : 0));
     flexarray_set(back, boffset++, "bootable");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(back, boffset++, "dev");
     flexarray_set(back, boffset++, disk->virtpath);
     flexarray_set(back, boffset++, "type");
@@ -1552,11 +1649,11 @@ int libxl_device_disk_add(libxl_ctx *ctx
     flexarray_set(back, boffset++, disk->readwrite ? "w" : "r");
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
disk->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
disk->backend_domid));
     flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(front, foffset++, "virtual-device");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", devid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", devid));
     flexarray_set(front, foffset++, "device-type");
     flexarray_set(front, foffset++, disk->is_cdrom ? "cdrom" : "disk");
 
@@ -1565,19 +1662,21 @@ int libxl_device_disk_add(libxl_ctx *ctx
         flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */
     }
 
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    libxl_device_generic_add(&gc, &device,
+                             libxl_xs_kvs_of_flexarray(&gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(&gc, front, foffset));
     flexarray_free(back);
     flexarray_free(front);
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_device_disk_del(libxl_ctx *ctx, 
                           libxl_device_disk *disk, int wait)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_device device;
-    int devid;
+    int devid, rc;
 
     devid = device_disk_dev_number(disk->virtpath);
     device.backend_domid    = disk->backend_domid;
@@ -1587,11 +1686,14 @@ int libxl_device_disk_del(libxl_ctx *ctx
     device.domid            = disk->domid;
     device.devid            = devid;
     device.kind             = DEVICE_VBD;
-    return libxl_device_del(ctx, &device, wait);
+    rc = libxl_device_del(&gc, &device, wait);
+    libxl_free_all(&gc);
+    return rc;
 }
 
 const char * libxl_device_disk_local_attach(libxl_ctx *ctx, libxl_device_disk 
*disk)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *dev = NULL;
     int phystype = disk->phystype;
     switch (phystype) {
@@ -1607,9 +1709,9 @@ const char * libxl_device_disk_local_att
             const char *msg;
             if (!tap_ctl_check(&msg)) {
                 const char *type = device_disk_string_of_phystype(phystype);
-                dev = get_blktap2_device(ctx, disk->physpath, type);
+                dev = get_blktap2_device(&gc, disk->physpath, type);
                 if (!dev)
-                    dev = make_blktap2_device(ctx, disk->physpath, type);
+                    dev = make_blktap2_device(&gc, disk->physpath, type);
             }
             break;
         }
@@ -1617,6 +1719,7 @@ const char * libxl_device_disk_local_att
             XL_LOG(ctx, XL_LOG_ERROR, "unrecognized disk physical type: %d\n", 
phystype);
             break;
     }
+    libxl_free_all(&gc);
     return dev;
 }
 
@@ -1635,6 +1738,7 @@ int libxl_device_disk_local_detach(libxl
 
/******************************************************************************/
 int libxl_device_nic_add(libxl_ctx *ctx, uint32_t domid, libxl_device_nic *nic)
 {
+    libxl_gc gc = INIT_GC(ctx);
     flexarray_t *front;
     flexarray_t *back;
     unsigned int boffset = 0;
@@ -1644,22 +1748,27 @@ int libxl_device_nic_add(libxl_ctx *ctx,
     unsigned int nb;
 
     front = flexarray_make(16, 1);
-    if (!front)
+    if (!front) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
     back = flexarray_make(16, 1);
-    if (!back)
+    if (!back) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
 
     if (nic->devid == -1) {
-        if (!(dompath = libxl_xs_get_dompath(ctx, domid))) {
+        if (!(dompath = libxl_xs_get_dompath(&gc, domid))) {
+            libxl_free_all(&gc);
             return ERROR_FAIL;
         }
-        if (!(l = libxl_xs_directory(ctx, XBT_NULL,
-                                     libxl_sprintf(ctx, "%s/device/vif", 
dompath), &nb))) {
+        if (!(l = libxl_xs_directory(&gc, XBT_NULL,
+                                     libxl_sprintf(&gc, "%s/device/vif", 
dompath), &nb))) {
             nic->devid = 0;
         } else {
             nic->devid = strtoul(l[nb - 1], NULL, 10) + 1;
-            libxl_free(ctx, l);
+            libxl_free(&gc, l);
         }
     }
 
@@ -1671,30 +1780,30 @@ int libxl_device_nic_add(libxl_ctx *ctx,
     device.kind = DEVICE_VIF;
 
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->domid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(back, boffset++, "script");
     flexarray_set(back, boffset++, nic->script);
     flexarray_set(back, boffset++, "mac");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, 
"%02x:%02x:%02x:%02x:%02x:%02x",
                                                  nic->mac[0], nic->mac[1], 
nic->mac[2],
                                                  nic->mac[3], nic->mac[4], 
nic->mac[5]));
     flexarray_set(back, boffset++, "bridge");
-    flexarray_set(back, boffset++, libxl_strdup(ctx, nic->bridge));
+    flexarray_set(back, boffset++, libxl_strdup(&gc, nic->bridge));
     flexarray_set(back, boffset++, "handle");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", nic->devid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", nic->devid));
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
nic->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
nic->backend_domid));
     flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(front, foffset++, "handle");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", nic->devid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", nic->devid));
     flexarray_set(front, foffset++, "mac");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, 
"%02x:%02x:%02x:%02x:%02x:%02x",
                                                   nic->mac[0], nic->mac[1], 
nic->mac[2],
                                                   nic->mac[3], nic->mac[4], 
nic->mac[5]));
     if (0 /* protocol != native*/) {
@@ -1702,20 +1811,23 @@ int libxl_device_nic_add(libxl_ctx *ctx,
         flexarray_set(front, foffset++, "x86_32-abi"); /* hardcoded ! */
     }
 
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    libxl_device_generic_add(&gc, &device,
+                             libxl_xs_kvs_of_flexarray(&gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(&gc, front, foffset));
 
     /* FIXME: wait for plug */
     flexarray_free(back);
     flexarray_free(front);
+    libxl_free_all(&gc);
     return 0;
 }
 
-int libxl_device_nic_del(libxl_ctx *ctx, 
+int libxl_device_nic_del(libxl_ctx *ctx,
                          libxl_device_nic *nic, int wait)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_device device;
+    int rc;
 
     device.backend_devid    = nic->devid;
     device.backend_domid    = nic->backend_domid;
@@ -1724,71 +1836,76 @@ int libxl_device_nic_del(libxl_ctx *ctx,
     device.domid            = nic->domid;
     device.kind             = DEVICE_VIF;
 
-    return libxl_device_del(ctx, &device, wait);
+    rc = libxl_device_del(&gc, &device, wait);
+    libxl_free_all(&gc);
+    return rc;
 }
 
 libxl_nicinfo *libxl_list_nics(libxl_ctx *ctx, uint32_t domid, unsigned int 
*nb)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *dompath, *nic_path_fe;
     char **l;
     char *val, *tok;
     unsigned int nb_nics, i;
     libxl_nicinfo *res, *nics;
 
-    dompath = libxl_xs_get_dompath(ctx, domid);
+    dompath = libxl_xs_get_dompath(&gc, domid);
     if (!dompath) {
+        libxl_free_all(&gc);
         return NULL;
     }
-    l = libxl_xs_directory(ctx, XBT_NULL,
-                           libxl_sprintf(ctx, "%s/device/vif", dompath), 
&nb_nics);
+    l = libxl_xs_directory(&gc, XBT_NULL,
+                           libxl_sprintf(&gc, "%s/device/vif", dompath), 
&nb_nics);
     if (!l) {
+        libxl_free_all(&gc);
         return NULL;
     }
-    res = libxl_calloc(ctx, nb_nics, sizeof (libxl_device_nic));
+    res = calloc(nb_nics, sizeof (libxl_device_nic));
     if (!res) {
-        libxl_free(ctx, l);
+        libxl_free_all(&gc);
         return NULL;
     }
     nics = res;
     for (*nb = nb_nics; nb_nics > 0; --nb_nics, ++l, ++nics) {
-        nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, *l);
-
-        nics->backend = libxl_xs_read(ctx, XBT_NULL,
-                                      libxl_sprintf(ctx, "%s/backend", 
nic_path_fe));
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
nic_path_fe));
+        nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, *l);
+
+        nics->backend = libxl_xs_read(&gc, XBT_NULL,
+                                      libxl_sprintf(&gc, "%s/backend", 
nic_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", 
nic_path_fe));
         nics->backend_id = val ? strtoul(val, NULL, 10) : -1;
 
         nics->devid = strtoul(*l, NULL, 10);
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", 
nic_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", 
nic_path_fe));
         nics->state = val ? strtoul(val, NULL, 10) : -1;
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", 
nic_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", 
nic_path_fe));
         for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
              ++i, tok = strtok(NULL, ":")) {
             nics->mac[i] = strtoul(tok, NULL, 16);
         }
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/event-channel", nic_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/event-channel", nic_path_fe));
         nics->evtch = val ? strtol(val, NULL, 10) : -1;
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/tx-ring-ref", nic_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/tx-ring-ref", nic_path_fe));
         nics->rref_tx = val ? strtol(val, NULL, 10) : -1;
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/rx-ring-ref", nic_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/rx-ring-ref", nic_path_fe));
         nics->rref_rx = val ? strtol(val, NULL, 10) : -1;
-        nics->frontend = libxl_xs_read(ctx, XBT_NULL,
-                                       libxl_sprintf(ctx, "%s/frontend", 
nics->backend));
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/frontend-id", nics->backend));
+        nics->frontend = libxl_xs_read(&gc, XBT_NULL,
+                                       libxl_sprintf(&gc, "%s/frontend", 
nics->backend));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/frontend-id", nics->backend));
         nics->frontend_id = val ? strtoul(val, NULL, 10) : -1;
-        nics->script = libxl_xs_read(ctx, XBT_NULL,
-                                     libxl_sprintf(ctx, "%s/script", 
nics->backend));
-
-        libxl_free(ctx, nic_path_fe);
+        nics->script = libxl_xs_read(&gc, XBT_NULL,
+                                     libxl_sprintf(&gc, "%s/script", 
nics->backend));
+
     }
 
-    libxl_free(ctx, l);
+    libxl_free_all(&gc);
     return res;
 }
 
 
/******************************************************************************/
 int libxl_device_net2_add(libxl_ctx *ctx, uint32_t domid, libxl_device_net2 
*net2)
 {
+    libxl_gc gc = INIT_GC(ctx);
     flexarray_t *front, *back;
     unsigned int boffset = 0, foffset = 0;
     libxl_device device;
@@ -1796,24 +1913,28 @@ int libxl_device_net2_add(libxl_ctx *ctx
     unsigned int nb;
 
     front = flexarray_make(16, 1);
-    if (!front)
+    if (!front) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
     back = flexarray_make(16, 1);
-    if (!back)
+    if (!back) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
-
-    if (!(dompath = libxl_xs_get_dompath(ctx, domid))) {
+    }
+
+    if (!(dompath = libxl_xs_get_dompath(&gc, domid))) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
-    dom = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/name", dompath));
+    dom = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/name", dompath));
 
     if (net2->devid == -1) {
-        if (!(l = libxl_xs_directory(ctx, XBT_NULL,
-                                     libxl_sprintf(ctx, "%s/device/vif2", 
dompath), &nb))) {
+        if (!(l = libxl_xs_directory(&gc, XBT_NULL,
+                                     libxl_sprintf(&gc, "%s/device/vif2", 
dompath), &nb))) {
             net2->devid = 0;
         } else {
             net2->devid = strtoul(l[nb - 1], NULL, 10) + 1;
-            libxl_free(ctx, l);
         }
     }
 
@@ -1827,134 +1948,140 @@ int libxl_device_net2_add(libxl_ctx *ctx
     flexarray_set(back, boffset++, "domain");
     flexarray_set(back, boffset++, dom);
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->domid));
 
     flexarray_set(back, boffset++, "local-trusted");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
net2->back_trusted));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 
net2->back_trusted));
     flexarray_set(back, boffset++, "mac");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, 
"%02x:%02x:%02x:%02x:%02x:%02x",
                                                  net2->back_mac[0], 
net2->back_mac[1],
                                                  net2->back_mac[2], 
net2->back_mac[3],
                                                  net2->back_mac[4], 
net2->back_mac[5]));
 
     flexarray_set(back, boffset++, "remote-trusted");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->trusted));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->trusted));
     flexarray_set(back, boffset++, "remote-mac");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, 
"%02x:%02x:%02x:%02x:%02x:%02x",
                                                  net2->front_mac[0], 
net2->front_mac[1],
                                                  net2->front_mac[2], 
net2->front_mac[3],
                                                  net2->front_mac[4], 
net2->front_mac[5]));
 
     flexarray_set(back, boffset++, "max-bypasses");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
net2->max_bypasses));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 
net2->max_bypasses));
     flexarray_set(back, boffset++, "filter-mac");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 
!!(net2->filter_mac)));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 
!!(net2->filter_mac)));
     flexarray_set(back, boffset++, "handle");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", net2->devid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", net2->devid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "state");
     flexarray_set(back, boffset++, "1");
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
net2->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
net2->backend_domid));
 
     flexarray_set(front, foffset++, "local-trusted");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", net2->trusted));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", net2->trusted));
     flexarray_set(front, foffset++, "mac");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, 
"%02x:%02x:%02x:%02x:%02x:%02x",
                                                   net2->front_mac[0], 
net2->front_mac[1],
                                                   net2->front_mac[2], 
net2->front_mac[3],
                                                   net2->front_mac[4], 
net2->front_mac[5]));
 
     flexarray_set(front, foffset++, "remote-trusted");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
net2->back_trusted));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
net2->back_trusted));
     flexarray_set(front, foffset++, "remote-mac");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, 
"%02x:%02x:%02x:%02x:%02x:%02x",
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, 
"%02x:%02x:%02x:%02x:%02x:%02x",
                                                   net2->back_mac[0], 
net2->back_mac[1],
                                                   net2->back_mac[2], 
net2->back_mac[3],
                                                   net2->back_mac[4], 
net2->back_mac[5]));
 
     flexarray_set(front, foffset++, "filter-mac");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
!!(net2->filter_mac)));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
!!(net2->filter_mac)));
     flexarray_set(front, foffset++, "state");
     flexarray_set(front, foffset++, "1");
 
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    libxl_device_generic_add(&gc, &device,
+                             libxl_xs_kvs_of_flexarray(&gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(&gc, front, foffset));
 
     /* FIXME: wait for plug */
     flexarray_free(back);
     flexarray_free(front);
+    libxl_free_all(&gc);
     return 0;
 }
 
 libxl_net2info *libxl_device_net2_list(libxl_ctx *ctx, uint32_t domid, 
unsigned int *nb)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *dompath, *net2_path_fe;
     char **l;
     char *val, *tok;
     unsigned int nb_net2s, i;
     libxl_net2info *res, *net2s;
 
-    dompath = libxl_xs_get_dompath(ctx, domid);
+    dompath = libxl_xs_get_dompath(&gc, domid);
     if (!dompath) {
+        libxl_free_all(&gc);
         return NULL;
     }
-    l = libxl_xs_directory(ctx, XBT_NULL,
-                           libxl_sprintf(ctx, "%s/device/vif2", dompath), 
&nb_net2s);
+    l = libxl_xs_directory(&gc, XBT_NULL,
+                           libxl_sprintf(&gc, "%s/device/vif2", dompath), 
&nb_net2s);
     if (!l) {
+        libxl_free_all(&gc);
         return NULL;
     }
-    res = libxl_calloc(ctx, nb_net2s, sizeof (libxl_net2info));
+    res = calloc(nb_net2s, sizeof (libxl_net2info));
     if (!res) {
-        libxl_free(ctx, l);
+        libxl_free_all(&gc);
         return NULL;
     }
     net2s = res;
     for (*nb = nb_net2s; nb_net2s > 0; --nb_net2s, ++l, ++net2s) {
-        net2_path_fe = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, *l);
-
-        net2s->backend = libxl_xs_read(ctx, XBT_NULL,
-                                       libxl_sprintf(ctx, "%s/backend", 
net2_path_fe));
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
net2_path_fe));
+        net2_path_fe = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, *l);
+
+        net2s->backend = libxl_xs_read(&gc, XBT_NULL,
+                                       libxl_sprintf(&gc, "%s/backend", 
net2_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", 
net2_path_fe));
         net2s->backend_id = val ? strtoul(val, NULL, 10) : -1;
 
         net2s->devid = strtoul(*l, NULL, 10);
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", 
net2_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", 
net2_path_fe));
         net2s->state = val ? strtoul(val, NULL, 10) : -1;
 
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", 
net2_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", 
net2_path_fe));
         for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
              ++i, tok = strtok(NULL, ":")) {
             net2s->mac[i] = strtoul(tok, NULL, 16);
         }
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/remote-trusted", net2_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/remote-trusted", net2_path_fe));
         net2s->trusted = val ? strtoul(val, NULL, 10) : -1;
 
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", 
net2_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", 
net2_path_fe));
         for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
              ++i, tok = strtok(NULL, ":")) {
             net2s->back_mac[i] = strtoul(tok, NULL, 16);
         }
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", 
net2_path_fe));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", 
net2_path_fe));
         net2s->filter_mac = val ? strtoul(val, NULL, 10) : -1;
 
-        net2s->frontend = libxl_xs_read(ctx, XBT_NULL,
-                                        libxl_sprintf(ctx, "%s/frontend", 
net2s->backend));
-        val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/frontend-id", net2s->backend));
+        net2s->frontend = libxl_xs_read(&gc, XBT_NULL,
+                                        libxl_sprintf(&gc, "%s/frontend", 
net2s->backend));
+        val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/frontend-id", net2s->backend));
         net2s->frontend_id = val ? strtoul(val, NULL, 10) : -1;
-        libxl_free(ctx, net2_path_fe);
+        libxl_free(&gc, net2_path_fe);
     }
 
-    libxl_free(ctx, l);
+    libxl_free_all(&gc);
     return res;
 }
 
 int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_device device;
+    int rc;
 
     device.backend_devid    = net2->devid;
     device.backend_domid    = net2->backend_domid;
@@ -1963,13 +2090,16 @@ int libxl_device_net2_del(libxl_ctx *ctx
     device.domid            = net2->domid;
     device.kind             = DEVICE_VIF2;
 
-    return libxl_device_del(ctx, &device, wait);
+    rc = libxl_device_del(&gc, &device, wait);
+    libxl_free_all(&gc);
+    return rc;
 }
 
 
 
/******************************************************************************/
 int libxl_device_console_add(libxl_ctx *ctx, uint32_t domid, 
libxl_device_console *console)
 {
+    libxl_gc gc = INIT_GC(ctx);
     flexarray_t *front;
     flexarray_t *back;
     unsigned int boffset = 0;
@@ -1978,13 +2108,13 @@ int libxl_device_console_add(libxl_ctx *
 
     if (console->build_state) {
         xs_transaction_t t;
-        char **ents = (char **) libxl_calloc(ctx, 9, sizeof(char *));
+        char **ents = (char **) libxl_calloc(&gc, 9, sizeof(char *));
         ents[0] = "console/port";
-        ents[1] = libxl_sprintf(ctx, "%"PRIu32, 
console->build_state->console_port);
+        ents[1] = libxl_sprintf(&gc, "%"PRIu32, 
console->build_state->console_port);
         ents[2] = "console/ring-ref";
-        ents[3] = libxl_sprintf(ctx, "%lu", console->build_state->console_mfn);
+        ents[3] = libxl_sprintf(&gc, "%lu", console->build_state->console_mfn);
         ents[4] = "console/limit";
-        ents[5] = libxl_sprintf(ctx, "%d", LIBXL_XENCONSOLE_LIMIT);
+        ents[5] = libxl_sprintf(&gc, "%d", LIBXL_XENCONSOLE_LIMIT);
         ents[6] = "console/type";
         if (console->constype == CONSTYPE_XENCONSOLED)
             ents[7] = "xenconsoled";
@@ -1992,18 +2122,22 @@ int libxl_device_console_add(libxl_ctx *
             ents[7] = "ioemu";
 retry_transaction:
         t = xs_transaction_start(ctx->xsh);
-        libxl_xs_writev(ctx, t, libxl_xs_get_dompath(ctx, console->domid), 
ents);
+        libxl_xs_writev(&gc, t, libxl_xs_get_dompath(&gc, console->domid), 
ents);
         if (!xs_transaction_end(ctx->xsh, t, 0))
             if (errno == EAGAIN)
                 goto retry_transaction;
     }
 
     front = flexarray_make(16, 1);
-    if (!front)
+    if (!front) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
     back = flexarray_make(16, 1);
-    if (!back)
+    if (!back) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
 
     device.backend_devid = console->devid;
     device.backend_domid = console->backend_domid;
@@ -2013,22 +2147,22 @@ retry_transaction:
     device.kind = DEVICE_CONSOLE;
 
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", console->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", console->domid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid));
+    flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid));
     flexarray_set(back, boffset++, "protocol");
     flexarray_set(back, boffset++, LIBXL_XENCONSOLE_PROTOCOL);
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
console->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
console->backend_domid));
     flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(front, foffset++, "limit");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
LIBXL_XENCONSOLE_LIMIT));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
LIBXL_XENCONSOLE_LIMIT));
     flexarray_set(front, foffset++, "protocol");
     flexarray_set(front, foffset++, LIBXL_XENCONSOLE_PROTOCOL);
     flexarray_set(front, foffset++, "type");
@@ -2037,18 +2171,20 @@ retry_transaction:
     else
         flexarray_set(front, foffset++, "ioemu");
 
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    libxl_device_generic_add(&gc, &device,
+                             libxl_xs_kvs_of_flexarray(&gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(&gc, front, foffset));
     flexarray_free(back);
     flexarray_free(front);
 
+    libxl_free_all(&gc);
     return 0;
 }
 
 
/******************************************************************************/
 int libxl_device_vkb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vkb *vkb)
 {
+    libxl_gc gc = INIT_GC(ctx);
     flexarray_t *front;
     flexarray_t *back;
     unsigned int boffset = 0;
@@ -2056,11 +2192,15 @@ int libxl_device_vkb_add(libxl_ctx *ctx,
     libxl_device device;
 
     front = flexarray_make(16, 1);
-    if (!front)
+    if (!front) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
     back = flexarray_make(16, 1);
-    if (!back)
+    if (!back) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
 
     device.backend_devid = vkb->devid;
     device.backend_domid = vkb->backend_domid;
@@ -2070,25 +2210,26 @@ int libxl_device_vkb_add(libxl_ctx *ctx,
     device.kind = DEVICE_VKBD;
 
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vkb->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vkb->domid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid));
+    flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid));
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
vkb->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
vkb->backend_domid));
     flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
-
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1));
+
+    libxl_device_generic_add(&gc, &device,
+                             libxl_xs_kvs_of_flexarray(&gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(&gc, front, foffset));
     flexarray_free(back);
     flexarray_free(front);
 
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -2104,16 +2245,17 @@ int libxl_device_vkb_hard_shutdown(libxl
 
 libxl_device_disk *libxl_device_disk_list(libxl_ctx *ctx, uint32_t domid, int 
*num)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *be_path_tap, *be_path_vbd;
     libxl_device_disk *dend, *disks, *ret = NULL;
     char **b, **l = NULL;
     unsigned int numl;
     char *type;
 
-    be_path_vbd = libxl_sprintf(ctx, "%s/backend/vbd/%d", 
libxl_xs_get_dompath(ctx, 0), domid);
-    be_path_tap = libxl_sprintf(ctx, "%s/backend/tap/%d", 
libxl_xs_get_dompath(ctx, 0), domid);
-
-    b = l = libxl_xs_directory(ctx, XBT_NULL, be_path_vbd, &numl);
+    be_path_vbd = libxl_sprintf(&gc, "%s/backend/vbd/%d", 
libxl_xs_get_dompath(&gc, 0), domid);
+    be_path_tap = libxl_sprintf(&gc, "%s/backend/tap/%d", 
libxl_xs_get_dompath(&gc, 0), domid);
+
+    b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_vbd, &numl);
     if (l) {
         ret = realloc(ret, sizeof(libxl_device_disk) * numl);
         disks = ret;
@@ -2122,20 +2264,20 @@ libxl_device_disk *libxl_device_disk_lis
         for (; disks < dend; ++disks, ++l) {
             disks->backend_domid = 0;
             disks->domid = domid;
-            disks->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/params", be_path_vbd, *l));
-            libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype));
-            disks->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/dev", be_path_vbd, *l));
-            disks->unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/removable", be_path_vbd, *l)));
-            if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/mode", be_path_vbd, *l)), "w"))
+            disks->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/params", be_path_vbd, *l));
+            libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, 
libxl_sprintf(&gc, "%s/%s/type", be_path_vbd, *l)), &(disks->phystype));
+            disks->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/dev", be_path_vbd, *l));
+            disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, 
libxl_sprintf(&gc, "%s/%s/removable", be_path_vbd, *l)));
+            if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/mode", be_path_vbd, *l)), "w"))
                 disks->readwrite = 1;
             else
                 disks->readwrite = 0;
-            type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/frontend", be_path_vbd, *l))));
+            type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/frontend", be_path_vbd, *l))));
             disks->is_cdrom = !strcmp(type, "cdrom");
         }
-        libxl_free(ctx, b);
+        libxl_free(&gc, b);
     }
-    b = l = libxl_xs_directory(ctx, XBT_NULL, be_path_tap, &numl);
+    b = l = libxl_xs_directory(&gc, XBT_NULL, be_path_tap, &numl);
     if (l) {
         ret = realloc(ret, sizeof(libxl_device_disk) * (*num + numl));
         disks = ret + *num;
@@ -2143,56 +2285,61 @@ libxl_device_disk *libxl_device_disk_lis
         for (dend = ret + *num; disks < dend; ++disks, ++l) {
             disks->backend_domid = 0;
             disks->domid = domid;
-            disks->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/params", be_path_tap, *l));
-            libxl_string_to_phystype(ctx, libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/type", be_path_tap, *l)), &(disks->phystype));
-            disks->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/dev", be_path_tap, *l));
-            disks->unpluggable = atoi(libxl_xs_read(ctx, XBT_NULL, 
libxl_sprintf(ctx, "%s/%s/removable", be_path_tap, *l)));
-            if (!strcmp(libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/mode", be_path_tap, *l)), "w"))
+            disks->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/params", be_path_tap, *l));
+            libxl_string_to_phystype(ctx, libxl_xs_read(&gc, XBT_NULL, 
libxl_sprintf(&gc, "%s/%s/type", be_path_tap, *l)), &(disks->phystype));
+            disks->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/dev", be_path_tap, *l));
+            disks->unpluggable = atoi(libxl_xs_read(&gc, XBT_NULL, 
libxl_sprintf(&gc, "%s/%s/removable", be_path_tap, *l)));
+            if (!strcmp(libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/mode", be_path_tap, *l)), "w"))
                 disks->readwrite = 1;
             else
                 disks->readwrite = 0;
-            type = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/device-type", libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/%s/frontend", be_path_tap, *l))));
+            type = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/device-type", libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/%s/frontend", be_path_tap, *l))));
             disks->is_cdrom = !strcmp(type, "cdrom");
         }
-        libxl_free(ctx, b);
+        libxl_free(&gc, b);
     }
+    libxl_free_all(&gc);
     return ret;
 }
 
 int libxl_device_disk_getinfo(libxl_ctx *ctx, uint32_t domid,
                               libxl_device_disk *disk, libxl_diskinfo 
*diskinfo)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *dompath, *diskpath;
     char *val;
 
-    dompath = libxl_xs_get_dompath(ctx, domid);
+    dompath = libxl_xs_get_dompath(&gc, domid);
     diskinfo->devid = device_disk_dev_number(disk->virtpath);
 
     /* tap devices entries in xenstore are written as vbd devices. */
-    diskpath = libxl_sprintf(ctx, "%s/device/vbd/%d", dompath, 
diskinfo->devid);
-    diskinfo->backend = libxl_xs_read(ctx, XBT_NULL,
-                                      libxl_sprintf(ctx, "%s/backend", 
diskpath));
+    diskpath = libxl_sprintf(&gc, "%s/device/vbd/%d", dompath, 
diskinfo->devid);
+    diskinfo->backend = libxl_xs_read(&gc, XBT_NULL,
+                                      libxl_sprintf(&gc, "%s/backend", 
diskpath));
     if (!diskinfo->backend) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
diskpath));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", 
diskpath));
     diskinfo->backend_id = val ? strtoul(val, NULL, 10) : -1;
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/state", 
diskpath));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/state", 
diskpath));
     diskinfo->state = val ? strtoul(val, NULL, 10) : -1;
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/event-channel", 
diskpath));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/event-channel", 
diskpath));
     diskinfo->evtch = val ? strtoul(val, NULL, 10) : -1;
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/ring-ref", 
diskpath));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/ring-ref", 
diskpath));
     diskinfo->rref = val ? strtoul(val, NULL, 10) : -1;
-    diskinfo->frontend = libxl_xs_read(ctx, XBT_NULL,
-                                       libxl_sprintf(ctx, "%s/frontend", 
diskinfo->backend));
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/frontend-id", 
diskinfo->backend));
+    diskinfo->frontend = libxl_xs_read(&gc, XBT_NULL,
+                                       libxl_sprintf(&gc, "%s/frontend", 
diskinfo->backend));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/frontend-id", 
diskinfo->backend));
     diskinfo->frontend_id = val ? strtoul(val, NULL, 10) : -1;
 
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_cdrom_insert(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disk)
 {
+    libxl_gc gc = INIT_GC(ctx);
     int num, i;
     uint32_t stubdomid;
     libxl_device_disk *disks;
@@ -2209,6 +2356,8 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u
     }
     if (i == num) {
         XL_LOG(ctx, XL_LOG_ERROR, "Virtual device not found");
+        libxl_free_all(&gc);
+        free(disks);
         return ERROR_FAIL;
     }
     libxl_device_disk_del(ctx, disks + i, 1);
@@ -2221,28 +2370,30 @@ int libxl_cdrom_insert(libxl_ctx *ctx, u
         libxl_device_disk_add(ctx, stubdomid, disk);
         disk->domid = domid;
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
 
/******************************************************************************/
-static int libxl_build_xenpv_qemu_args(libxl_ctx *ctx,
+static int libxl_build_xenpv_qemu_args(libxl_gc *gc,
                                        libxl_device_vfb *vfb,
                                        int num_console,
                                        libxl_device_console *console,
                                        libxl_device_model_info *info)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int i = 0, j = 0, num = 0;
     memset(info, 0x00, sizeof(libxl_device_model_info));
 
     info->vnc = vfb->vnc;
     if (vfb->vnclisten)
-        info->vnclisten = libxl_strdup(ctx, vfb->vnclisten);
+        info->vnclisten = libxl_strdup(gc, vfb->vnclisten);
     info->vncdisplay = vfb->vncdisplay;
     info->vncunused = vfb->vncunused;
     if (vfb->vncpasswd)
         info->vncpasswd = vfb->vncpasswd;
     if (vfb->keymap)
-        info->keymap = libxl_strdup(ctx, vfb->keymap);
+        info->keymap = libxl_strdup(gc, vfb->keymap);
     info->sdl = vfb->sdl;
     info->opengl = vfb->opengl;
     for (i = 0; i < num_console; i++) {
@@ -2253,9 +2404,9 @@ static int libxl_build_xenpv_qemu_args(l
         uint32_t guest_domid;
         if (libxl_is_stubdom(ctx, vfb->domid, &guest_domid)) {
             char *filename;
-            char *name = libxl_sprintf(ctx, "qemu-dm-%s", 
libxl_domid_to_name(ctx, guest_domid));
+            char *name = libxl_sprintf(gc, "qemu-dm-%s", 
_libxl_domid_to_name(gc, guest_domid));
             libxl_create_logfile(ctx, name, &filename);
-            info->serial = libxl_sprintf(ctx, "file:%s", filename);
+            info->serial = libxl_sprintf(gc, "file:%s", filename);
             free(filename);
         } else {
             info->serial = "pty";
@@ -2263,7 +2414,7 @@ static int libxl_build_xenpv_qemu_args(l
         num--;
     }
     if (num > 0) {
-        info->extra = (char **) libxl_calloc(ctx, num * 2 + 1, sizeof(char *));
+        info->extra = (char **) libxl_calloc(gc, num * 2 + 1, sizeof(char *));
         for (j = 0; j < num * 2; j = j + 2) {
             info->extra[j] = "-serial";
             info->extra[j + 1] = "pty";
@@ -2271,8 +2422,8 @@ static int libxl_build_xenpv_qemu_args(l
         info->extra[j] = NULL;
     }
     info->domid = vfb->domid;
-    info->dom_name = libxl_domid_to_name(ctx, vfb->domid);
-    info->device_model = libxl_abs_path(ctx, "qemu-dm", libxl_libexec_path());
+    info->dom_name = _libxl_domid_to_name(gc, vfb->domid);
+    info->device_model = libxl_abs_path(gc, "qemu-dm", libxl_libexec_path());
     info->type = XENPV;
     return 0;
 }
@@ -2281,15 +2432,18 @@ int libxl_create_xenpv_qemu(libxl_ctx *c
                             int num_console, libxl_device_console *console,
                             libxl_device_model_starting **starting_r)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_device_model_info info;
 
-    libxl_build_xenpv_qemu_args(ctx, vfb, num_console, console, &info);
+    libxl_build_xenpv_qemu_args(&gc, vfb, num_console, console, &info);
     libxl_create_device_model(ctx, &info, NULL, 0, NULL, 0, starting_r);
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_device_vfb_add(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb *vfb)
 {
+    libxl_gc gc = INIT_GC(ctx);
     flexarray_t *front;
     flexarray_t *back;
     unsigned int boffset = 0;
@@ -2297,11 +2451,15 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
     libxl_device device;
 
     front = flexarray_make(16, 1);
-    if (!front)
+    if (!front) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
     back = flexarray_make(16, 1);
-    if (!back)
+    if (!back) {
+        libxl_free_all(&gc);
         return ERROR_NOMEM;
+    }
 
     device.backend_devid = vfb->devid;
     device.backend_domid = vfb->backend_domid;
@@ -2311,27 +2469,27 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
     device.kind = DEVICE_VFB;
 
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->domid));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->domid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", 1));
     flexarray_set(back, boffset++, "domain");
-    flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid));
+    flexarray_set(back, boffset++, _libxl_domid_to_name(&gc, domid));
     flexarray_set(back, boffset++, "vnc");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vnc));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vnc));
     flexarray_set(back, boffset++, "vnclisten");
     flexarray_set(back, boffset++, vfb->vnclisten);
     flexarray_set(back, boffset++, "vncpasswd");
     flexarray_set(back, boffset++, vfb->vncpasswd);
     flexarray_set(back, boffset++, "vncdisplay");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncdisplay));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncdisplay));
     flexarray_set(back, boffset++, "vncunused");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->vncunused));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->vncunused));
     flexarray_set(back, boffset++, "sdl");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->sdl));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->sdl));
     flexarray_set(back, boffset++, "opengl");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", vfb->opengl));
+    flexarray_set(back, boffset++, libxl_sprintf(&gc, "%d", vfb->opengl));
     if (vfb->xauthority) {
         flexarray_set(back, boffset++, "xauthority");
         flexarray_set(back, boffset++, vfb->xauthority);
@@ -2342,16 +2500,17 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
     }
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 
vfb->backend_domid));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 
vfb->backend_domid));
     flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
-
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    flexarray_set(front, foffset++, libxl_sprintf(&gc, "%d", 1));
+
+    libxl_device_generic_add(&gc, &device,
+                             libxl_xs_kvs_of_flexarray(&gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(&gc, front, foffset));
     flexarray_free(front);
     flexarray_free(back);
 
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -2369,81 +2528,95 @@ int libxl_device_vfb_hard_shutdown(libxl
 
 int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t max_memkb)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *mem, *endptr;
     uint32_t memorykb;
-    char *dompath = libxl_xs_get_dompath(ctx, domid);
-
-    mem = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", 
dompath));
+    char *dompath = libxl_xs_get_dompath(&gc, domid);
+
+    mem = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", 
dompath));
     if (!mem) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot get memory info from 
%s/memory/target\n", dompath);
+        libxl_free_all(&gc);
         return 1;
     }
     memorykb = strtoul(mem, &endptr, 10);
     if (*endptr != '\0') {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "invalid memory %s from 
%s/memory/target\n", mem, dompath);
+        libxl_free_all(&gc);
         return 1;
     }
 
     if (max_memkb < memorykb) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "memory_static_max must be greater 
than or or equal to memory_dynamic_max\n");
+        libxl_free_all(&gc);
         return 1;
     }
 
     if (domid != 0)
-        libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/memory/static-max", dompath), "%"PRIu32, max_memkb);
-
+        libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/memory/static-max", dompath), "%"PRIu32, max_memkb);
+
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t 
target_memkb, int enforce)
 {
+    libxl_gc gc = INIT_GC(ctx);
     int rc = 0;
     uint32_t memorykb = 0, videoram = 0;
     char *memmax, *endptr, *videoram_s = NULL;
-    char *dompath = libxl_xs_get_dompath(ctx, domid);
+    char *dompath = libxl_xs_get_dompath(&gc, domid);
     xc_domaininfo_t info;
     libxl_dominfo ptr;
     char *uuid;
 
     if (domid) {
-        memmax = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/memory/static-max", dompath));
+        memmax = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/memory/static-max", dompath));
         if (!memmax) {
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR,
                 "cannot get memory info from %s/memory/static-max\n", dompath);
+            libxl_free_all(&gc);
             return 1;
         }
         memorykb = strtoul(memmax, &endptr, 10);
         if (*endptr != '\0') {
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR,
                 "invalid max memory %s from %s/memory/static-max\n", memmax, 
dompath);
+            libxl_free_all(&gc);
             return 1;
         }
 
         if (target_memkb > memorykb) {
             XL_LOG(ctx, XL_LOG_ERROR,
                 "memory_dynamic_max must be less than or equal to 
memory_static_max\n");
+            libxl_free_all(&gc);
             return 1;
         }
     }
 
-    videoram_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/memory/videoram", dompath));
+    videoram_s = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/memory/videoram", dompath));
     videoram = videoram_s ? atoi(videoram_s) : 0;
 
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/memory/target", 
dompath), "%"PRIu32, target_memkb);
+    libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/memory/target", 
dompath), "%"PRIu32, target_memkb);
 
     rc = xc_domain_getinfolist(ctx->xch, domid, 1, &info);
-    if (rc != 1 || info.domain != domid)
+    if (rc != 1 || info.domain != domid) {
+        libxl_free_all(&gc);
         return rc;
+    }
     xcinfo2xlinfo(&info, &ptr);
-    uuid = libxl_uuid2string(ctx, ptr.uuid);
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "/vm/%s/memory", uuid), 
"%"PRIu32, target_memkb / 1024);
+    uuid = libxl_uuid2string(&gc, ptr.uuid);
+    libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "/vm/%s/memory", uuid), 
"%"PRIu32, target_memkb / 1024);
 
     if (enforce || !domid)
         memorykb = target_memkb;
     rc = xc_domain_setmaxmem(ctx->xch, domid, memorykb + 
LIBXL_MAXMEM_CONSTANT);
-    if (rc != 0)
+    if (rc != 0) {
+        libxl_free_all(&gc);
         return rc;
+    }
     rc = xc_domain_memory_set_pod_target(ctx->xch, domid, (target_memkb - 
videoram) / 4, NULL, NULL, NULL);
+    libxl_free_all(&gc);
     return rc;
 }
 
@@ -2492,6 +2665,7 @@ int libxl_get_physinfo(libxl_ctx *ctx, l
 
 const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx)
 {
+    libxl_gc gc = INIT_GC(ctx);
     union {
         xen_extraversion_t xen_extra;
         xen_compile_info_t xen_cc;
@@ -2506,23 +2680,24 @@ const libxl_version_info* libxl_get_vers
     if (info->xen_version_extra != NULL)
         return info;
 
+    /* XXX FIXME */
     xen_version = xc_version(ctx->xch, XENVER_version, NULL);
     info->xen_version_major = xen_version >> 16;
     info->xen_version_minor = xen_version & 0xFF;
     xc_version(ctx->xch, XENVER_extraversion, &u.xen_extra);
-    info->xen_version_extra = libxl_strdup(ctx, u.xen_extra);
+    info->xen_version_extra = libxl_strdup(&gc, u.xen_extra);
 
     xc_version(ctx->xch, XENVER_compile_info, &u.xen_cc);
-    info->compiler = libxl_strdup(ctx, u.xen_cc.compiler);
-    info->compile_by = libxl_strdup(ctx, u.xen_cc.compile_by);
-    info->compile_domain = libxl_strdup(ctx, u.xen_cc.compile_domain);
-    info->compile_date = libxl_strdup(ctx, u.xen_cc.compile_date);
+    info->compiler = libxl_strdup(&gc, u.xen_cc.compiler);
+    info->compile_by = libxl_strdup(&gc, u.xen_cc.compile_by);
+    info->compile_domain = libxl_strdup(&gc, u.xen_cc.compile_domain);
+    info->compile_date = libxl_strdup(&gc, u.xen_cc.compile_date);
 
     xc_version(ctx->xch, XENVER_capabilities, &u.xen_caps);
-    info->capabilities = libxl_strdup(ctx, u.xen_caps);
+    info->capabilities = libxl_strdup(&gc, u.xen_caps);
 
     xc_version(ctx->xch, XENVER_changeset, &u.xen_chgset);
-    info->changeset = libxl_strdup(ctx, u.xen_chgset);
+    info->changeset = libxl_strdup(&gc, u.xen_chgset);
 
     xc_version(ctx->xch, XENVER_platform_parameters, &u.p_parms);
     info->virt_start = u.p_parms.virt_start;
@@ -2530,7 +2705,7 @@ const libxl_version_info* libxl_get_vers
     info->pagesize = xc_version(ctx->xch, XENVER_pagesize, NULL);
 
     xc_version(ctx->xch, XENVER_commandline, &u.xen_commandline);
-    info->commandline = libxl_strdup(ctx, u.xen_commandline);
+    info->commandline = libxl_strdup(&gc, u.xen_commandline);
 
     return info;
 }
@@ -2538,6 +2713,7 @@ const libxl_version_info* libxl_get_vers
 libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid,
                                        int *nb_vcpu, int *cpusize)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_vcpuinfo *ptr, *ret;
     xc_domaininfo_t domaininfo;
     xc_vcpuinfo_t vcpuinfo;
@@ -2552,14 +2728,15 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
         return NULL;
     }
     *cpusize = physinfo.max_cpu_id + 1;
-    ptr = libxl_calloc(ctx, domaininfo.max_vcpu_id + 1, sizeof 
(libxl_vcpuinfo));
+    /* XXX FIXME */
+    ptr = libxl_calloc(&gc, domaininfo.max_vcpu_id + 1, sizeof 
(libxl_vcpuinfo));
     if (!ptr) {
         return NULL;
     }
 
     ret = ptr;
     for (*nb_vcpu = 0; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) {
-        ptr->cpumap = libxl_calloc(ctx, (*cpusize + 63) / 64, sizeof 
(uint64_t));
+        ptr->cpumap = libxl_calloc(&gc, (*cpusize + 63) / 64, sizeof 
(uint64_t));
         if (!ptr->cpumap) {
             return NULL;
         }
@@ -2593,6 +2770,7 @@ int libxl_set_vcpuaffinity(libxl_ctx *ct
 
 int libxl_set_vcpucount(libxl_ctx *ctx, uint32_t domid, uint32_t count)
 {
+    libxl_gc gc = INIT_GC(ctx);
     xc_domaininfo_t domaininfo;
     char *dompath;
     int i;
@@ -2604,14 +2782,15 @@ int libxl_set_vcpucount(libxl_ctx *ctx, 
     if (!count || ((domaininfo.max_vcpu_id + 1) < count)) {
         return ERROR_INVAL;
     }
-    if (!(dompath = libxl_xs_get_dompath(ctx, domid)))
+    if (!(dompath = libxl_xs_get_dompath(&gc, domid)))
         return ERROR_FAIL;
 
     for (i = 0; i <= domaininfo.max_vcpu_id; ++i) {
-        libxl_xs_write(ctx, XBT_NULL,
-                       libxl_sprintf(ctx, "%s/cpu/%u/availability", dompath, 
i),
+        libxl_xs_write(&gc, XBT_NULL,
+                       libxl_sprintf(&gc, "%s/cpu/%u/availability", dompath, 
i),
                        "%s", ((1 << i) & ((1 << count) - 1)) ? "online" : 
"offline");
     }
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -2725,10 +2904,12 @@ int libxl_send_trigger(libxl_ctx *ctx, u
 
 int libxl_send_sysrq(libxl_ctx *ctx, uint32_t domid, char sysrq)
 {
-    char *dompath = libxl_xs_get_dompath(ctx, domid);
-
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/control/sysrq", 
dompath), "%c", sysrq);
-
+    libxl_gc gc = INIT_GC(ctx);
+    char *dompath = libxl_xs_get_dompath(&gc, domid);
+
+    libxl_xs_write(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/control/sysrq", 
dompath), "%c", sysrq);
+
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -2815,20 +2996,25 @@ void libxl_xen_console_read_finish(libxl
 
 uint32_t libxl_vm_get_start_time(libxl_ctx *ctx, uint32_t domid)
 {
-    char *dompath = libxl_xs_get_dompath(ctx, domid);
+    libxl_gc gc = INIT_GC(ctx);
+    char *dompath = libxl_xs_get_dompath(&gc, domid);
     char *vm_path, *start_time;
+    uint32_t ret;
 
     vm_path = libxl_xs_read(
-        ctx, XBT_NULL, libxl_sprintf(ctx, "%s/vm", dompath));
+        &gc, XBT_NULL, libxl_sprintf(&gc, "%s/vm", dompath));
     start_time = libxl_xs_read(
-        ctx, XBT_NULL, libxl_sprintf(ctx, "%s/start_time", vm_path));
+        &gc, XBT_NULL, libxl_sprintf(&gc, "%s/start_time", vm_path));
     if (start_time == NULL) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, -1,
                         "Can't get start time of domain '%d'", domid);
+        libxl_free_all(&gc);
         return -1;
     }
 
-    return strtoul(start_time, NULL, 10);
+    ret = strtoul(start_time, NULL, 10);
+    libxl_free_all(&gc);
+    return ret;
 }
 
 char *libxl_tmem_list(libxl_ctx *ctx, uint32_t domid, int use_long)
diff -r e49e70e31a99 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl.h       Fri Aug 06 15:00:14 2010 +0100
@@ -57,10 +57,6 @@ typedef struct {
     xc_interface *xch;
     struct xs_handle *xsh;
 
-    /* mini-GC */
-    int alloc_maxsize;
-    void **alloc_ptrs;
-
     /* for callers who reap children willy-nilly; caller must only
      * set this after libxl_init and before any other call - or
      * may leave them untouched */
@@ -127,7 +123,6 @@ int libxl_run_bootloader(libxl_ctx *ctx,
                          libxl_device_disk *disk,
                          uint32_t domid);
 
-char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid);
   /* 0 means ERROR_ENOMEM, which we have logged */
 
 /* events handling */
diff -r e49e70e31a99 tools/libxl/libxl_bootloader.c
--- a/tools/libxl/libxl_bootloader.c    Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_bootloader.c    Fri Aug 06 15:00:14 2010 +0100
@@ -30,7 +30,7 @@
 #define XENCONSOLED_BUF_SIZE 16
 #define BOOTLOADER_BUF_SIZE 1024
 
-static char **make_bootloader_args(libxl_ctx *ctx,
+static char **make_bootloader_args(libxl_gc *gc,
                                    libxl_domain_build_info *info,
                                    uint32_t domid,
                                    const char *fifo, const char *disk)
@@ -45,20 +45,20 @@ static char **make_bootloader_args(libxl
     flexarray_set(args, nr++, (char *)info->u.pv.bootloader);
 
     if (info->kernel.path)
-        flexarray_set(args, nr++, libxl_sprintf(ctx, "--kernel=%s", 
info->kernel.path));
+        flexarray_set(args, nr++, libxl_sprintf(gc, "--kernel=%s", 
info->kernel.path));
     if (info->u.pv.ramdisk.path)
-        flexarray_set(args, nr++, libxl_sprintf(ctx, "--ramdisk=%s", 
info->u.pv.ramdisk.path));
+        flexarray_set(args, nr++, libxl_sprintf(gc, "--ramdisk=%s", 
info->u.pv.ramdisk.path));
     if (info->u.pv.cmdline && *info->u.pv.cmdline != '\0')
-        flexarray_set(args, nr++, libxl_sprintf(ctx, "--args=%s", 
info->u.pv.cmdline));
+        flexarray_set(args, nr++, libxl_sprintf(gc, "--args=%s", 
info->u.pv.cmdline));
 
-    flexarray_set(args, nr++, libxl_sprintf(ctx, "--output=%s", fifo));
+    flexarray_set(args, nr++, libxl_sprintf(gc, "--output=%s", fifo));
     flexarray_set(args, nr++, "--output-format=simple0");
-    flexarray_set(args, nr++, libxl_sprintf(ctx, "--output-directory=%s", 
"/var/run/libxl/"));
+    flexarray_set(args, nr++, libxl_sprintf(gc, "--output-directory=%s", 
"/var/run/libxl/"));
 
     if (info->u.pv.bootloader_args) {
         char *saveptr;
         /* Operate on a duplicate since strtok modifes the argument */
-        char *dup = libxl_strdup(ctx, info->u.pv.bootloader_args);
+        char *dup = libxl_strdup(gc, info->u.pv.bootloader_args);
         char *t = strtok_r(dup, " \t\n", &saveptr);
         do {
             flexarray_set(args, nr++, t);
@@ -161,7 +161,7 @@ static pid_t fork_exec_bootloader(int *m
  * if there is actual data to write, otherwise this would loop too fast,
  * eating up CPU time.
  */
-static char * bootloader_interact(libxl_ctx *ctx, int xenconsoled_fd, int 
bootloader_fd, int fifo_fd)
+static char * bootloader_interact(libxl_gc *gc, int xenconsoled_fd, int 
bootloader_fd, int fifo_fd)
 {
     int ret;
 
@@ -263,7 +263,7 @@ static char * bootloader_interact(libxl_
         }
     }
 
-    libxl_ptr_add(ctx, output);
+    libxl_ptr_add(gc, output);
     return output;
 
 out_err:
@@ -300,6 +300,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
                          libxl_device_disk *disk,
                          uint32_t domid)
 {
+    libxl_gc gc = INIT_GC(ctx);
     int ret;
 
     char *fifo = NULL;
@@ -321,26 +322,38 @@ int libxl_run_bootloader(libxl_ctx *ctx,
 
     struct stat st_buf;
 
-    if (info->hvm || !info->u.pv.bootloader)
+    if (info->hvm || !info->u.pv.bootloader) {
+        libxl_free_all(&gc);
         return 0;
+    }
 
-    if (!disk)
+    if (!disk) {
+        libxl_free_all(&gc);
         return ERROR_INVAL;
+    }
 
     ret = mkdir("/var/run/libxl/", S_IRWXU);
-    if (ret < 0 && errno != EEXIST)
+    if (ret < 0 && errno != EEXIST) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
+    }
 
     ret = stat("/var/run/libxl/", &st_buf);
-    if (ret < 0)
+    if (ret < 0) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
+    }
 
-    if (!S_ISDIR(st_buf.st_mode))
+    if (!S_ISDIR(st_buf.st_mode)) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
+    }
 
     tempdir = mkdtemp(tempdir_template);
-    if (tempdir == NULL)
+    if (tempdir == NULL) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
+    }
 
     ret = asprintf(&fifo, "%s/fifo", tempdir);
     if (ret < 0) {
@@ -361,7 +374,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
         goto out;
     }
 
-    args = make_bootloader_args(ctx, info, domid, fifo, diskpath);
+    args = make_bootloader_args(&gc, info, domid, fifo, diskpath);
     if (args == NULL) {
         ret = ERROR_NOMEM;
         goto out;
@@ -385,8 +398,8 @@ int libxl_run_bootloader(libxl_ctx *ctx,
         goto out;
     }
 
-    dom_console_xs_path = libxl_sprintf(ctx, "%s/serial/0/tty", 
libxl_xs_get_dompath(ctx, domid));
-    libxl_xs_write(ctx, XBT_NULL, dom_console_xs_path, "%s", 
dom_console_slave_tty_path);
+    dom_console_xs_path = libxl_sprintf(&gc, "%s/serial/0/tty", 
libxl_xs_get_dompath(&gc, domid));
+    libxl_xs_write(&gc, XBT_NULL, dom_console_xs_path, "%s", 
dom_console_slave_tty_path);
 
     pid = fork_exec_bootloader(&bootloader_fd, (char *)info->u.pv.bootloader, 
args);
     if (pid < 0) {
@@ -408,7 +421,7 @@ int libxl_run_bootloader(libxl_ctx *ctx,
 
     fcntl(fifo_fd, F_SETFL, O_NDELAY);
 
-    blout = bootloader_interact(ctx, xenconsoled_fd, bootloader_fd, fifo_fd);
+    blout = bootloader_interact(&gc, xenconsoled_fd, bootloader_fd, fifo_fd);
     if (blout == NULL) {
         ret = ERROR_FAIL;
         goto out;
@@ -444,6 +457,7 @@ out:
 
     free(args);
 
+    libxl_free_all(&gc);
     return ret;
 }
 
diff -r e49e70e31a99 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c        Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_device.c        Fri Aug 06 15:00:14 2010 +0100
@@ -39,9 +39,10 @@ static const char *string_of_kinds[] = {
     [DEVICE_CONSOLE] = "console",
 };
 
-int libxl_device_generic_add(libxl_ctx *ctx, libxl_device *device,
+int libxl_device_generic_add(libxl_gc *gc, libxl_device *device,
                              char **bents, char **fents)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *dom_path_backend, *dom_path, *frontend_path, *backend_path;
     xs_transaction_t t;
     struct xs_permissions frontend_perms[2];
@@ -50,12 +51,12 @@ int libxl_device_generic_add(libxl_ctx *
     if (!is_valid_device_kind(device->backend_kind) || 
!is_valid_device_kind(device->kind))
         return ERROR_INVAL;
 
-    dom_path_backend = libxl_xs_get_dompath(ctx, device->backend_domid);
-    dom_path = libxl_xs_get_dompath(ctx, device->domid);
+    dom_path_backend = libxl_xs_get_dompath(gc, device->backend_domid);
+    dom_path = libxl_xs_get_dompath(gc, device->domid);
 
-    frontend_path = libxl_sprintf(ctx, "%s/device/%s/%d",
+    frontend_path = libxl_sprintf(gc, "%s/device/%s/%d",
                                   dom_path, string_of_kinds[device->kind], 
device->devid);
-    backend_path = libxl_sprintf(ctx, "%s/backend/%s/%u/%d",
+    backend_path = libxl_sprintf(gc, "%s/backend/%s/%u/%d",
                                  dom_path_backend, 
string_of_kinds[device->backend_kind], device->domid, device->devid);
 
     frontend_perms[0].id = device->domid;
@@ -81,12 +82,12 @@ retry_transaction:
     xs_mkdir(ctx->xsh, t, backend_path);
     xs_set_permissions(ctx->xsh, t, backend_path, backend_perms, 
ARRAY_SIZE(backend_perms));
 
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/backend", frontend_path), 
backend_path, strlen(backend_path));
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/frontend", backend_path), 
frontend_path, strlen(frontend_path));
+    xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/backend", frontend_path), 
backend_path, strlen(backend_path));
+    xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/frontend", backend_path), 
frontend_path, strlen(frontend_path));
 
     /* and write frontend kvs and backend kvs */
-    libxl_xs_writev(ctx, t, backend_path, bents);
-    libxl_xs_writev(ctx, t, frontend_path, fents);
+    libxl_xs_writev(gc, t, backend_path, bents);
+    libxl_xs_writev(gc, t, frontend_path, fents);
 
     if (!xs_transaction_end(ctx->xsh, t, 0)) {
         if (errno == EAGAIN)
@@ -219,11 +220,12 @@ int device_disk_dev_number(char *virtpat
     return -1;
 }
 
-int libxl_device_destroy(libxl_ctx *ctx, char *be_path, int force)
+int libxl_device_destroy(libxl_gc *gc, char *be_path, int force)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     xs_transaction_t t;
-    char *state_path = libxl_sprintf(ctx, "%s/state", be_path);
-    char *state = libxl_xs_read(ctx, XBT_NULL, state_path);
+    char *state_path = libxl_sprintf(gc, "%s/state", be_path);
+    char *state = libxl_xs_read(gc, XBT_NULL, state_path);
     if (!state)
         return 0;
     if (atoi(state) != 4) {
@@ -233,7 +235,7 @@ int libxl_device_destroy(libxl_ctx *ctx,
 
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/online", be_path), "0", 
strlen("0"));
+    xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/online", be_path), "0", 
strlen("0"));
     xs_write(ctx->xsh, t, state_path, "5", strlen("5"));
     if (!xs_transaction_end(ctx->xsh, t, 0)) {
         if (errno == EAGAIN)
@@ -248,8 +250,9 @@ retry_transaction:
         return 0;
 }
 
-int wait_for_dev_destroy(libxl_ctx *ctx, struct timeval *tv)
+int wait_for_dev_destroy(libxl_gc *gc, struct timeval *tv)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int nfds, rc;
     unsigned int n;
     fd_set rfds;
@@ -262,57 +265,52 @@ int wait_for_dev_destroy(libxl_ctx *ctx,
     if (select(nfds, &rfds, NULL, NULL, tv) > 0) {
         l1 = xs_read_watch(ctx->xsh, &n);
         if (l1 != NULL) {
-            char *state = libxl_xs_read(ctx, XBT_NULL, l1[XS_WATCH_PATH]);
+            char *state = libxl_xs_read(gc, XBT_NULL, l1[XS_WATCH_PATH]);
             if (!state || atoi(state) == 6) {
                 xs_unwatch(ctx->xsh, l1[0], l1[1]);
                 xs_rm(ctx->xsh, XBT_NULL, l1[XS_WATCH_TOKEN]);
                 XL_LOG(ctx, XL_LOG_DEBUG, "Destroyed device backend at %s", 
l1[XS_WATCH_TOKEN]);
                 rc = 0;
             }
-            libxl_free(ctx, state);
+            libxl_free(gc, state);
             free(l1);
         }
     }
     return rc;
 }
 
-int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force)
+int libxl_devices_destroy(libxl_gc *gc, uint32_t domid, int force)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *path, *be_path, *fe_path;
     unsigned int num1, num2;
     char **l1 = NULL, **l2 = NULL;
     int i, j, n = 0, n_watches = 0;
     flexarray_t *toremove;
-    libxl_ctx clone;
-
-    if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) {
-        return -1;
-    }
 
     toremove = flexarray_make(16, 1);
-    path = libxl_sprintf(&clone, "/local/domain/%d/device", domid);
-    l1 = libxl_xs_directory(&clone, XBT_NULL, path, &num1);
+    path = libxl_sprintf(gc, "/local/domain/%d/device", domid);
+    l1 = libxl_xs_directory(gc, XBT_NULL, path, &num1);
     if (!l1) {
-        XL_LOG(&clone, XL_LOG_ERROR, "%s is empty", path);
-        libxl_ctx_free(&clone);
+        XL_LOG(ctx, XL_LOG_ERROR, "%s is empty", path);
         return 0;
     }
     for (i = 0; i < num1; i++) {
         if (!strcmp("vfs", l1[i]))
             continue;
-        path = libxl_sprintf(&clone, "/local/domain/%d/device/%s", domid, 
l1[i]);
-        l2 = libxl_xs_directory(&clone, XBT_NULL, path, &num2);
+        path = libxl_sprintf(gc, "/local/domain/%d/device/%s", domid, l1[i]);
+        l2 = libxl_xs_directory(gc, XBT_NULL, path, &num2);
         if (!l2)
             continue;
         for (j = 0; j < num2; j++) {
-            fe_path = libxl_sprintf(&clone, "/local/domain/%d/device/%s/%s", 
domid, l1[i], l2[j]);
-            be_path = libxl_xs_read(&clone, XBT_NULL, libxl_sprintf(&clone, 
"%s/backend", fe_path));
+            fe_path = libxl_sprintf(gc, "/local/domain/%d/device/%s/%s", 
domid, l1[i], l2[j]);
+            be_path = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, 
"%s/backend", fe_path));
             if (be_path != NULL) {
-                if (libxl_device_destroy(&clone, be_path, force) > 0)
+                if (libxl_device_destroy(gc, be_path, force) > 0)
                     n_watches++;
-                flexarray_set(toremove, n++, libxl_dirname(&clone, be_path));
+                flexarray_set(toremove, n++, libxl_dirname(gc, be_path));
             } else {
-                xs_rm(clone.xsh, XBT_NULL, path);
+                xs_rm(ctx->xsh, XBT_NULL, path);
             }
         }
     }
@@ -326,7 +324,7 @@ int libxl_devices_destroy(libxl_ctx *ctx
         tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
         tv.tv_usec = 0;
         while (n_watches > 0) {
-            if (wait_for_dev_destroy(&clone, &tv)) {
+            if (wait_for_dev_destroy(gc, &tv)) {
                 break;
             } else {
                 n_watches--;
@@ -335,34 +333,27 @@ int libxl_devices_destroy(libxl_ctx *ctx
     }
     for (i = 0; i < n; i++) {
         flexarray_get(toremove, i, (void**) &path);
-        xs_rm(clone.xsh, XBT_NULL, path);
+        xs_rm(ctx->xsh, XBT_NULL, path);
     }
     flexarray_free(toremove);
-    libxl_ctx_free(&clone);
     return 0;
 }
 
-int libxl_device_del(libxl_ctx *ctx, libxl_device *dev, int wait)
+int libxl_device_del(libxl_gc *gc, libxl_device *dev, int wait)
 {
     char *dom_path_backend, *backend_path;
     int rc;
-    libxl_ctx clone;
-
-    if (libxl_ctx_init(&clone, LIBXL_VERSION, ctx->lg)) {
-        return -1;
-    }
 
     /* Create strings */
-    dom_path_backend    = libxl_xs_get_dompath(&clone, dev->backend_domid);
-    backend_path        = libxl_sprintf(&clone, "%s/backend/%s/%u/%d",
+    dom_path_backend    = libxl_xs_get_dompath(gc, dev->backend_domid);
+    backend_path        = libxl_sprintf(gc, "%s/backend/%s/%u/%d",
                                     dom_path_backend, 
                                     string_of_kinds[dev->backend_kind], 
                                     dev->domid, dev->devid);
-    libxl_free(&clone, dom_path_backend);
+    libxl_free(gc, dom_path_backend);
 
-    rc = libxl_device_destroy(&clone, backend_path, !wait);
+    rc = libxl_device_destroy(gc, backend_path, !wait);
     if (rc == -1) {
-        libxl_ctx_free(&clone);
         return ERROR_FAIL;
     }
 
@@ -370,21 +361,21 @@ int libxl_device_del(libxl_ctx *ctx, lib
         struct timeval tv;
         tv.tv_sec = LIBXL_DESTROY_TIMEOUT;
         tv.tv_usec = 0;
-        (void)wait_for_dev_destroy(&clone, &tv);
+        (void)wait_for_dev_destroy(gc, &tv);
     }
 
-    libxl_ctx_free(&clone);
     return 0;
 }
 
-int libxl_wait_for_device_model(libxl_ctx *ctx,
+int libxl_wait_for_device_model(libxl_gc *gc,
                                 uint32_t domid, char *state,
-                                int (*check_callback)(libxl_ctx *ctx,
+                                int (*check_callback)(libxl_gc *gc,
                                                       uint32_t domid,
                                                       const char *state,
                                                       void *userdata),
                                 void *check_callback_userdata)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *path;
     char *p;
     unsigned int len;
@@ -397,7 +388,7 @@ int libxl_wait_for_device_model(libxl_ct
     char **l = NULL;
 
     xsh = xs_daemon_open();
-    path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
+    path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
     xs_watch(xsh, path, path);
     tv.tv_sec = LIBXL_DEVICE_MODEL_START_TIMEOUT;
     tv.tv_usec = 0;
@@ -411,7 +402,7 @@ int libxl_wait_for_device_model(libxl_ct
             goto again;
 
         if ( NULL != check_callback ) {
-            rc = (*check_callback)(ctx, domid, p, check_callback_userdata);
+            rc = (*check_callback)(gc, domid, p, check_callback_userdata);
             if ( rc > 0 )
                 goto again;
         }
@@ -439,12 +430,13 @@ again:
     return -1;
 }
 
-int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state)
+int libxl_wait_for_backend(libxl_gc *gc, char *be_path, char *state)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int watchdog = 100;
     unsigned int len;
     char *p;
-    char *path = libxl_sprintf(ctx, "%s/state", be_path);
+    char *path = libxl_sprintf(gc, "%s/state", be_path);
 
     while (watchdog > 0) {
         p = xs_read(ctx->xsh, XBT_NULL, path, &len);
diff -r e49e70e31a99 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c   Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_dom.c   Fri Aug 06 15:00:14 2010 +0100
@@ -31,8 +31,9 @@
 #include "libxl.h"
 #include "libxl_internal.h"
 
-int is_hvm(libxl_ctx *ctx, uint32_t domid)
+int is_hvm(libxl_gc *gc, uint32_t domid)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     xc_domaininfo_t info;
     int ret;
 
@@ -44,8 +45,9 @@ int is_hvm(libxl_ctx *ctx, uint32_t domi
     return !!(info.flags & XEN_DOMINF_hvm_guest);
 }
 
-int get_shutdown_reason(libxl_ctx *ctx, uint32_t domid)
+int get_shutdown_reason(libxl_gc *gc, uint32_t domid)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     xc_domaininfo_t info;
     int ret;
 
@@ -59,9 +61,11 @@ int get_shutdown_reason(libxl_ctx *ctx, 
     return dominfo_get_shutdown_reason(&info);
 }
 
-int build_pre(libxl_ctx *ctx, uint32_t domid,
+int build_pre(libxl_gc *gc, uint32_t domid,
               libxl_domain_build_info *info, libxl_domain_build_state *state)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
+
     xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus);
     xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb + 
LIBXL_MAXMEM_CONSTANT);
     xc_domain_set_memmap_limit(ctx->xch, domid, 
@@ -82,10 +86,11 @@ int build_pre(libxl_ctx *ctx, uint32_t d
     return 0;
 }
 
-int build_post(libxl_ctx *ctx, uint32_t domid,
+int build_post(libxl_gc *gc, uint32_t domid,
                libxl_domain_build_info *info, libxl_domain_build_state *state,
                char **vms_ents, char **local_ents)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *dom_path, *vm_path;
     xs_transaction_t t;
     char **ents;
@@ -95,50 +100,51 @@ int build_post(libxl_ctx *ctx, uint32_t 
     xc_cpuid_apply_policy(ctx->xch, domid);
 #endif
 
-    ents = libxl_calloc(ctx, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
+    ents = libxl_calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
     ents[0] = "memory/static-max";
-    ents[1] = libxl_sprintf(ctx, "%d", info->max_memkb);
+    ents[1] = libxl_sprintf(gc, "%d", info->max_memkb);
     ents[2] = "memory/target";
-    ents[3] = libxl_sprintf(ctx, "%d", info->target_memkb);
+    ents[3] = libxl_sprintf(gc, "%d", info->target_memkb);
     ents[4] = "memory/videoram";
-    ents[5] = libxl_sprintf(ctx, "%d", info->video_memkb);
+    ents[5] = libxl_sprintf(gc, "%d", info->video_memkb);
     ents[6] = "domid";
-    ents[7] = libxl_sprintf(ctx, "%d", domid);
+    ents[7] = libxl_sprintf(gc, "%d", domid);
     ents[8] = "store/port";
-    ents[9] = libxl_sprintf(ctx, "%"PRIu32, state->store_port);
+    ents[9] = libxl_sprintf(gc, "%"PRIu32, state->store_port);
     ents[10] = "store/ring-ref";
-    ents[11] = libxl_sprintf(ctx, "%lu", state->store_mfn);
+    ents[11] = libxl_sprintf(gc, "%lu", state->store_mfn);
     for (i = 0; i < info->max_vcpus; i++) {
-        ents[12+(i*2)]   = libxl_sprintf(ctx, "cpu/%d/availability", i);
+        ents[12+(i*2)]   = libxl_sprintf(gc, "cpu/%d/availability", i);
         ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << 
i)))
                             ? "offline" : "online";
     }
 
-    dom_path = libxl_xs_get_dompath(ctx, domid);
+    dom_path = libxl_xs_get_dompath(gc, domid);
     if (!dom_path)
         return ERROR_FAIL;
 
-    vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(ctx, "%s/vm", 
dom_path), NULL);
+    vm_path = xs_read(ctx->xsh, XBT_NULL, libxl_sprintf(gc, "%s/vm", 
dom_path), NULL);
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
 
-    libxl_xs_writev(ctx, t, dom_path, ents);
-    libxl_xs_writev(ctx, t, dom_path, local_ents);
-    libxl_xs_writev(ctx, t, vm_path, vms_ents);
+    libxl_xs_writev(gc, t, dom_path, ents);
+    libxl_xs_writev(gc, t, dom_path, local_ents);
+    libxl_xs_writev(gc, t, vm_path, vms_ents);
 
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
     xs_introduce_domain(ctx->xsh, domid, state->store_mfn, state->store_port);
     free(vm_path);
-    libxl_free(ctx, ents);
-    libxl_free(ctx, dom_path);
+    libxl_free(gc, ents);
+    libxl_free(gc, dom_path);
     return 0;
 }
 
-int build_pv(libxl_ctx *ctx, uint32_t domid,
+int build_pv(libxl_gc *gc, uint32_t domid,
              libxl_domain_build_info *info, libxl_domain_build_state *state)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     struct xc_dom_image *dom;
     int ret;
     int flags = 0;
@@ -215,9 +221,10 @@ out:
     return ret == 0 ? 0 : ERROR_FAIL;
 }
 
-int build_hvm(libxl_ctx *ctx, uint32_t domid,
+int build_hvm(libxl_gc *gc, uint32_t domid,
               libxl_domain_build_info *info, libxl_domain_build_state *state)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int ret;
 
     if (info->kernel.mapped) {
@@ -230,7 +237,7 @@ int build_hvm(libxl_ctx *ctx, uint32_t d
         domid,
         (info->max_memkb - info->video_memkb) / 1024,
         (info->target_memkb - info->video_memkb) / 1024,
-        libxl_abs_path(ctx, (char *)info->kernel.path,
+        libxl_abs_path(gc, (char *)info->kernel.path,
                        libxl_xenfirmwaredir_path()));
     if (ret) {
         XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, ret, "hvm building failed");
@@ -245,11 +252,12 @@ int build_hvm(libxl_ctx *ctx, uint32_t d
     return 0;
 }
 
-int restore_common(libxl_ctx *ctx, uint32_t domid,
+int restore_common(libxl_gc *gc, uint32_t domid,
                    libxl_domain_build_info *info, libxl_domain_build_state 
*state,
                    int fd)
 {
     /* read signature */
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int rc;
     rc = xc_domain_restore(ctx->xch, fd, domid,
                              state->store_port, &state->store_mfn,
@@ -263,7 +271,7 @@ int restore_common(libxl_ctx *ctx, uint3
 }
 
 struct suspendinfo {
-    libxl_ctx *ctx;
+    libxl_gc *gc;
     int xce; /* event channel handle */
     int suspend_eventchn;
     int domid;
@@ -291,43 +299,44 @@ static void core_suspend_switch_qemu_log
 static int core_suspend_callback(void *data)
 {
     struct suspendinfo *si = data;
+    libxl_ctx *ctx = libxl_gc_owner(si->gc);
     unsigned long s_state = 0;
     int ret;
     char *path, *state = "suspend";
     int watchdog = 60;
 
     if (si->hvm)
-        xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, 
&s_state);
+        xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, 
&s_state);
     if ((s_state == 0) && (si->suspend_eventchn >= 0)) {
         ret = xc_evtchn_notify(si->xce, si->suspend_eventchn);
         if (ret < 0) {
-            XL_LOG(si->ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", 
ret);
+            XL_LOG(ctx, XL_LOG_ERROR, "xc_evtchn_notify failed ret=%d", ret);
             return 0;
         }
-        ret = xc_await_suspend(si->ctx->xch, si->xce, si->suspend_eventchn);
+        ret = xc_await_suspend(ctx->xch, si->xce, si->suspend_eventchn);
         if (ret < 0) {
-            XL_LOG(si->ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", 
ret);
+            XL_LOG(ctx, XL_LOG_ERROR, "xc_await_suspend failed ret=%d", ret);
             return 0;
         }
         return 1;
     }
-    path = libxl_sprintf(si->ctx, "%s/control/shutdown", 
libxl_xs_get_dompath(si->ctx, si->domid));
-    libxl_xs_write(si->ctx, XBT_NULL, path, "suspend");
+    path = libxl_sprintf(si->gc, "%s/control/shutdown", 
libxl_xs_get_dompath(si->gc, si->domid));
+    libxl_xs_write(si->gc, XBT_NULL, path, "suspend");
     if (si->hvm) {
         unsigned long hvm_pvdrv, hvm_s_state;
-        xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, 
&hvm_pvdrv);
-        xc_get_hvm_param(si->ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, 
&hvm_s_state);
+        xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_CALLBACK_IRQ, 
&hvm_pvdrv);
+        xc_get_hvm_param(ctx->xch, si->domid, HVM_PARAM_ACPI_S_STATE, 
&hvm_s_state);
         if (!hvm_pvdrv || hvm_s_state) {
-            XL_LOG(si->ctx, XL_LOG_DEBUG, "Calling xc_domain_shutdown on the 
domain");
-            xc_domain_shutdown(si->ctx->xch, si->domid, SHUTDOWN_suspend);
+            XL_LOG(ctx, XL_LOG_DEBUG, "Calling xc_domain_shutdown on the 
domain");
+            xc_domain_shutdown(ctx->xch, si->domid, SHUTDOWN_suspend);
         }
     }
-    XL_LOG(si->ctx, XL_LOG_DEBUG, "wait for the guest to suspend");
+    XL_LOG(ctx, XL_LOG_DEBUG, "wait for the guest to suspend");
     while (!strcmp(state, "suspend") && watchdog > 0) {
         xc_domaininfo_t info;
 
         usleep(100000);
-        ret = xc_domain_getinfolist(si->ctx->xch, si->domid, 1, &info);
+        ret = xc_domain_getinfolist(ctx->xch, si->domid, 1, &info);
         if (ret == 1 && info.domain == si->domid && info.flags & 
XEN_DOMINF_shutdown) {
             int shutdown_reason;
 
@@ -335,19 +344,20 @@ static int core_suspend_callback(void *d
             if (shutdown_reason == SHUTDOWN_suspend)
                 return 1;
         }
-        state = libxl_xs_read(si->ctx, XBT_NULL, path);
+        state = libxl_xs_read(si->gc, XBT_NULL, path);
         watchdog--;
     }
     if (!strcmp(state, "suspend")) {
-        XL_LOG(si->ctx, XL_LOG_ERROR, "guest didn't suspend in time");
-        libxl_xs_write(si->ctx, XBT_NULL, path, "");
+        XL_LOG(ctx, XL_LOG_ERROR, "guest didn't suspend in time");
+        libxl_xs_write(si->gc, XBT_NULL, path, "");
     }
     return 1;
 }
 
-int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd,
+int core_suspend(libxl_gc *gc, uint32_t domid, int fd,
                int hvm, int live, int debug)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int flags;
     int port;
     struct save_callbacks callbacks;
@@ -360,7 +370,7 @@ int core_suspend(libxl_ctx *ctx, uint32_
     si.domid = domid;
     si.flags = flags;
     si.hvm = hvm;
-    si.ctx = ctx;
+    si.gc = gc;
     si.suspend_eventchn = -1;
 
     si.xce = xc_evtchn_open();
@@ -373,7 +383,7 @@ int core_suspend(libxl_ctx *ctx, uint32_
         if (port < 0) {
             XL_LOG(ctx, XL_LOG_WARNING, "Failed to get the suspend evtchn 
port");
         } else {
-            si.suspend_eventchn = xc_suspend_evtchn_init(si.ctx->xch, si.xce, 
si.domid, port);
+            si.suspend_eventchn = xc_suspend_evtchn_init(ctx->xch, si.xce, 
si.domid, port);
 
             if (si.suspend_eventchn < 0)
                 XL_LOG(ctx, XL_LOG_WARNING, "Suspend event channel 
initialization failed");
@@ -389,22 +399,23 @@ int core_suspend(libxl_ctx *ctx, uint32_
                    &core_suspend_switch_qemu_logdirty);
 
     if (si.suspend_eventchn > 0)
-        xc_suspend_evtchn_release(si.ctx->xch, si.xce, domid, 
si.suspend_eventchn);
+        xc_suspend_evtchn_release(ctx->xch, si.xce, domid, 
si.suspend_eventchn);
     if (si.xce > 0)
         xc_evtchn_close(si.xce);
 
     return 0;
 }
 
-int save_device_model(libxl_ctx *ctx, uint32_t domid, int fd)
+int save_device_model(libxl_gc *gc, uint32_t domid, int fd)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int fd2, c;
     char buf[1024];
-    char *filename = libxl_sprintf(ctx, "/var/lib/xen/qemu-save.%d", domid);
+    char *filename = libxl_sprintf(gc, "/var/lib/xen/qemu-save.%d", domid);
 
     XL_LOG(ctx, XL_LOG_DEBUG, "Saving device model state to %s", filename);
-    libxl_xs_write(ctx, XBT_NULL, libxl_sprintf(ctx, 
"/local/domain/0/device-model/%d/command", domid), "save");
-    libxl_wait_for_device_model(ctx, domid, "paused", NULL, NULL);
+    libxl_xs_write(gc, XBT_NULL, libxl_sprintf(gc, 
"/local/domain/0/device-model/%d/command", domid), "save");
+    libxl_wait_for_device_model(gc, domid, "paused", NULL, NULL);
 
     c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE),
                             "saved-state file", "qemu signature");
@@ -427,15 +438,20 @@ int save_device_model(libxl_ctx *ctx, ui
     return 0;
 }
 
-char *libxl_uuid2string(libxl_ctx *ctx, const libxl_uuid uuid) {
-    char *s = string_of_uuid(ctx, uuid);
+char *libxl_uuid2string(libxl_gc *gc, const libxl_uuid uuid)
+{
+    libxl_ctx *ctx = libxl_gc_owner(gc);
+    char *s;
+    s = string_of_uuid(gc, uuid);
     if (!s) XL_LOG(ctx, XL_LOG_ERROR, "cannot allocate for uuid");
     return s;
 }
 
-static const char *userdata_path(libxl_ctx *ctx, uint32_t domid,
+static const char *userdata_path(libxl_gc *gc, uint32_t domid,
                                       const char *userdata_userid,
-                                      const char *wh) {
+                                      const char *wh)
+{
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *path, *uuid_string;
     libxl_dominfo info;
     int rc;
@@ -446,9 +462,9 @@ static const char *userdata_path(libxl_c
                      " for domain %"PRIu32, domid);
         return NULL;
     }
-    uuid_string = string_of_uuid(ctx, info.uuid);
+    uuid_string = string_of_uuid(gc, info.uuid);
 
-    path = libxl_sprintf(ctx, "/var/lib/xen/"
+    path = libxl_sprintf(gc, "/var/lib/xen/"
                          "userdata-%s.%s.%s",
                          wh, uuid_string, userdata_userid);
     if (!path)
@@ -457,7 +473,9 @@ static const char *userdata_path(libxl_c
     return path;
 }
 
-static int userdata_delete(libxl_ctx *ctx, const char *path) {
+static int userdata_delete(libxl_gc *gc, const char *path)
+{
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int r;
     r = unlink(path);
     if (r) {
@@ -467,12 +485,14 @@ static int userdata_delete(libxl_ctx *ct
     return 0;
 }
 
-void libxl__userdata_destroyall(libxl_ctx *ctx, uint32_t domid) {
+void libxl__userdata_destroyall(libxl_gc *gc, uint32_t domid)
+{
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     const char *pattern;
     glob_t gl;
     int r, i;
 
-    pattern = userdata_path(ctx, domid, "*", "?");
+    pattern = userdata_path(gc, domid, "*", "?");
     if (!pattern) return;
 
     gl.gl_pathc = 0;
@@ -483,14 +503,16 @@ void libxl__userdata_destroyall(libxl_ct
     if (r) XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "glob failed for %s", pattern);
 
     for (i=0; i<gl.gl_pathc; i++) {
-        userdata_delete(ctx, gl.gl_pathv[i]);
+        userdata_delete(gc, gl.gl_pathv[i]);
     }
     globfree(&gl);
 }
 
 int libxl_userdata_store(libxl_ctx *ctx, uint32_t domid,
                               const char *userdata_userid,
-                              const uint8_t *data, int datalen) {
+                              const uint8_t *data, int datalen)
+{
+    libxl_gc gc = INIT_GC(ctx);
     const char *filename;
     const char *newfilename;
     int e;
@@ -498,30 +520,47 @@ int libxl_userdata_store(libxl_ctx *ctx,
     FILE *f = 0;
     size_t rs;
 
-    filename = userdata_path(ctx, domid, userdata_userid, "d");
-    if (!filename) return ERROR_NOMEM;
+    filename = userdata_path(&gc, domid, userdata_userid, "d");
+    if (!filename) {
+        libxl_free_all(&gc);
+        return ERROR_NOMEM;
+    }
 
-    if (!datalen)
-        return userdata_delete(ctx, filename);
+    if (!datalen) {
+        int rc;
+        rc = userdata_delete(&gc, filename);
+        libxl_free_all(&gc);
+        return rc;
+    }
 
-    newfilename = userdata_path(ctx, domid, userdata_userid, "n");
-    if (!newfilename) return ERROR_NOMEM;
+    newfilename = userdata_path(&gc, domid, userdata_userid, "n");
+    if (!newfilename) {
+        libxl_free_all(&gc);
+        return ERROR_NOMEM;
+    }
 
     fd= open(newfilename, O_RDWR|O_CREAT|O_TRUNC, 0600);
-    if (fd<0) goto xe;
+    if (fd<0)
+        goto xe;
 
     f= fdopen(fd, "wb");
-    if (!f) goto xe;
+    if (!f)
+        goto xe;
     fd = -1;
 
     rs = fwrite(data, 1, datalen, f);
-    if (rs != datalen) { assert(ferror(f)); goto xe; }
+    if (rs != datalen) {
+        assert(ferror(f));
+        goto xe;
+    }
 
-    if (fclose(f)) goto xe;
+    if (fclose(f))
+        goto xe;
     f = 0;
 
     if (rename(newfilename,filename)) goto xe;
 
+    libxl_free_all(&gc);
     return 0;
 
  xe:
@@ -532,29 +571,40 @@ int libxl_userdata_store(libxl_ctx *ctx,
     errno = e;
     XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "cannot write %s for %s",
                  newfilename, filename);
+    libxl_free_all(&gc);
     return ERROR_FAIL;
 }
 
 int libxl_userdata_retrieve(libxl_ctx *ctx, uint32_t domid,
                                  const char *userdata_userid,
-                                 uint8_t **data_r, int *datalen_r) {
+                                 uint8_t **data_r, int *datalen_r)
+{
+    libxl_gc gc = INIT_GC(ctx);
     const char *filename;
     int e;
     int datalen = 0;
     void *data = 0;
 
-    filename = userdata_path(ctx, domid, userdata_userid, "d");
-    if (!filename) return ERROR_NOMEM;
+
+    filename = userdata_path(&gc, domid, userdata_userid, "d");
+    if (!filename) {
+        libxl_free_all(&gc);
+        return ERROR_NOMEM;
+    }
 
     e = libxl_read_file_contents(ctx, filename, data_r ? &data : 0, &datalen);
 
     if (!e && !datalen) {
         XL_LOG(ctx, XL_LOG_ERROR, "userdata file %s is empty", filename);
-        if (data_r) assert(!*data_r);
+        if (data_r)
+            assert(!*data_r);
         return ERROR_FAIL;
     }
 
-    if (data_r) *data_r = data;
-    if (datalen_r) *datalen_r = datalen;
+    if (data_r)
+        *data_r = data;
+    if (datalen_r)
+        *datalen_r = datalen;
+    libxl_free_all(&gc);
     return 0;
 }
diff -r e49e70e31a99 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c  Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_exec.c  Fri Aug 06 15:00:14 2010 +0100
@@ -88,19 +88,20 @@ void libxl_report_child_exitstatus(libxl
     }
 }
 
-int libxl_spawn_spawn(libxl_ctx *ctx,
+int libxl_spawn_spawn(libxl_gc *gc,
                       libxl_device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn,
                                                 pid_t innerchild))
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     pid_t child, got;
     int status;
     pid_t intermediate;
     libxl_spawn_starting *for_spawn = starting->for_spawn;
 
     if (for_spawn) {
-        for_spawn->what = libxl_strdup(ctx, what);
+        for_spawn->what = libxl_strdup(gc, what);
         if (!for_spawn->what) return ERROR_NOMEM;
     }
 
@@ -135,13 +136,14 @@ int libxl_spawn_spawn(libxl_ctx *ctx,
           ? WTERMSIG(status)+128 : -1);
 }
 
-static void report_spawn_intermediate_status(libxl_ctx *ctx,
+static void report_spawn_intermediate_status(libxl_gc *gc,
                                  libxl_spawn_starting *for_spawn,
                                  int status)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     if (!WIFEXITED(status)) {
         /* intermediate process did the logging itself if it exited */
-        char *intermediate_what = libxl_sprintf(ctx,
+        char *intermediate_what = libxl_sprintf(gc,
                           "%s intermediate process (startup monitor)",
                           for_spawn->what);
         libxl_report_child_exitstatus(ctx, XL_LOG_ERROR, intermediate_what,
@@ -149,9 +151,10 @@ static void report_spawn_intermediate_st
     }
 }
 
-int libxl_spawn_detach(libxl_ctx *ctx,
+int libxl_spawn_detach(libxl_gc *gc,
                        libxl_spawn_starting *for_spawn)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     int r, status;
     pid_t got;
     int rc = 0;
@@ -170,7 +173,7 @@ int libxl_spawn_detach(libxl_ctx *ctx,
         got = call_waitpid(ctx->waitpid_instead, for_spawn->intermediate, 
&status, 0);
         assert(got == for_spawn->intermediate);
         if (!(WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL)) {
-            report_spawn_intermediate_status(ctx, for_spawn, status);
+            report_spawn_intermediate_status(gc, for_spawn, status);
             rc = ERROR_FAIL;
         }
         for_spawn->intermediate = 0;
@@ -182,8 +185,9 @@ int libxl_spawn_detach(libxl_ctx *ctx,
     return rc;
 }
 
-int libxl_spawn_check(libxl_ctx *ctx, void *for_spawn_void)
+int libxl_spawn_check(libxl_gc *gc, void *for_spawn_void)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     libxl_spawn_starting *for_spawn = for_spawn_void;
     pid_t got;
     int status;
@@ -195,7 +199,7 @@ int libxl_spawn_check(libxl_ctx *ctx, vo
     if (!got) return 0;
 
     assert(got == for_spawn->intermediate);
-    report_spawn_intermediate_status(ctx, for_spawn, status);
+    report_spawn_intermediate_status(gc, for_spawn, status);
 
     for_spawn->intermediate = 0;
     return ERROR_FAIL;
diff -r e49e70e31a99 tools/libxl/libxl_internal.c
--- a/tools/libxl/libxl_internal.c      Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_internal.c      Fri Aug 06 15:00:14 2010 +0100
@@ -28,7 +28,7 @@ int libxl_error_set(libxl_ctx *ctx, int 
     return 0;
 }
 
-int libxl_ptr_add(libxl_ctx *ctx, void *ptr)
+int libxl_ptr_add(libxl_gc *gc, void *ptr)
 {
     int i;
     void **re;
@@ -37,85 +37,92 @@ int libxl_ptr_add(libxl_ctx *ctx, void *
         return 0;
 
     /* fast case: we have space in the array for storing the pointer */
-    for (i = 0; i < ctx->alloc_maxsize; i++) {
-        if (!ctx->alloc_ptrs[i]) {
-            ctx->alloc_ptrs[i] = ptr;
+    for (i = 0; i < gc->alloc_maxsize; i++) {
+        if (!gc->alloc_ptrs[i]) {
+            gc->alloc_ptrs[i] = ptr;
             return 0;
         }
     }
     /* realloc alloc_ptrs manually with calloc/free/replace */
-    re = calloc(ctx->alloc_maxsize + 25, sizeof(void *));
+    re = calloc(gc->alloc_maxsize + 25, sizeof(void *));
     if (!re)
         return -1;
-    for (i = 0; i < ctx->alloc_maxsize; i++)
-        re[i] = ctx->alloc_ptrs[i];
+    for (i = 0; i < gc->alloc_maxsize; i++)
+        re[i] = gc->alloc_ptrs[i];
     /* assign the next pointer */
     re[i] = ptr;
 
     /* replace the old alloc_ptr */
-    free(ctx->alloc_ptrs);
-    ctx->alloc_ptrs = re;
-    ctx->alloc_maxsize += 25;
+    free(gc->alloc_ptrs);
+    gc->alloc_ptrs = re;
+    gc->alloc_maxsize += 25;
     return 0;
 }
 
-int libxl_free(libxl_ctx *ctx, void *ptr)
+void libxl_free(libxl_gc *gc, void *ptr)
 {
     int i;
 
     if (!ptr)
-        return 0;
+        return;
 
     /* remove the pointer from the tracked ptrs */
-    for (i = 0; i < ctx->alloc_maxsize; i++) {
-        if (ctx->alloc_ptrs[i] == ptr) {
-            ctx->alloc_ptrs[i] = NULL;
+    for (i = 0; i < gc->alloc_maxsize; i++) {
+        if (gc->alloc_ptrs[i] == ptr) {
+            gc->alloc_ptrs[i] = NULL;
             free(ptr);
-            return 0;
+            return;
         }
     }
     /* haven't find the pointer, really bad */
-    return -1;
+    abort();
 }
 
-int libxl_free_all(libxl_ctx *ctx)
+void libxl_free_all(libxl_gc *gc)
 {
     void *ptr;
     int i;
 
-    for (i = 0; i < ctx->alloc_maxsize; i++) {
-        ptr = ctx->alloc_ptrs[i];
-        ctx->alloc_ptrs[i] = NULL;
+    for (i = 0; i < gc->alloc_maxsize; i++) {
+        ptr = gc->alloc_ptrs[i];
+        gc->alloc_ptrs[i] = NULL;
         free(ptr);
     }
-    return 0;
+
+    free(gc->alloc_ptrs);
+    gc->alloc_ptrs = NULL;
+    gc->alloc_maxsize = 0;
+    if ( sizeof(void *) == 4 )
+        gc->owner = (void *)0xdeadbeef;
+    else
+        gc->owner = (void *)0xfeedfacedeadbeef;
 }
 
-void *libxl_zalloc(libxl_ctx *ctx, int bytes)
+void *libxl_zalloc(libxl_gc *gc, int bytes)
 {
     void *ptr = calloc(bytes, 1);
     if (!ptr) {
-        libxl_error_set(ctx, ENOMEM);
+        libxl_error_set(libxl_gc_owner(gc), ENOMEM);
         return NULL;
     }
 
-    libxl_ptr_add(ctx, ptr);
+    libxl_ptr_add(gc, ptr);
     return ptr;
 }
 
-void *libxl_calloc(libxl_ctx *ctx, size_t nmemb, size_t size)
+void *libxl_calloc(libxl_gc *gc, size_t nmemb, size_t size)
 {
     void *ptr = calloc(nmemb, size);
     if (!ptr) {
-        libxl_error_set(ctx, ENOMEM);
+        libxl_error_set(libxl_gc_owner(gc), ENOMEM);
         return NULL;
     }
 
-    libxl_ptr_add(ctx, ptr);
+    libxl_ptr_add(gc, ptr);
     return ptr;
 }
 
-char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...)
+char *libxl_sprintf(libxl_gc *gc, const char *fmt, ...)
 {
     char *s;
     va_list ap;
@@ -129,7 +136,7 @@ char *libxl_sprintf(libxl_ctx *ctx, cons
         return NULL;
     }
 
-    s = libxl_zalloc(ctx, ret + 1);
+    s = libxl_zalloc(gc, ret + 1);
     if (s) {
         va_start(ap, fmt);
         ret = vsnprintf(s, ret + 1, fmt, ap);
@@ -138,20 +145,20 @@ char *libxl_sprintf(libxl_ctx *ctx, cons
     return s;
 }
 
-char *libxl_strdup(libxl_ctx *ctx, const char *c)
+char *libxl_strdup(libxl_gc *gc, const char *c)
 {
     char *s = strdup(c);
 
     if (s)
-        libxl_ptr_add(ctx, s);
+        libxl_ptr_add(gc, s);
 
     return s;
 }
 
-char *libxl_dirname(libxl_ctx *ctx, const char *s)
+char *libxl_dirname(libxl_gc *gc, const char *s)
 {
     char *c;
-    char *ptr = libxl_strdup(ctx, s);
+    char *ptr = libxl_strdup(gc, s);
 
     c = strrchr(ptr, '/');
     if (!c)
@@ -197,10 +204,10 @@ void xl_log(libxl_ctx *ctx, xentoollog_l
     va_end(ap);
 }
 
-char *libxl_abs_path(libxl_ctx *ctx, char *s, const char *path)
+char *libxl_abs_path(libxl_gc *gc, char *s, const char *path)
 {
     if (!s || s[0] == '/')
         return s;
-    return libxl_sprintf(ctx, "%s/%s", path, s);
+    return libxl_sprintf(gc, "%s/%s", path, s);
 }
 
diff -r e49e70e31a99 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_internal.h      Fri Aug 06 15:00:14 2010 +0100
@@ -25,6 +25,14 @@
 #include <xenctrl.h>
 #include "xentoollog.h"
 
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+#define _hidden __attribute__((visibility("hidden")))
+#define _protected __attribute__((visibility("protected")))
+#else
+#define _hidden
+#define _protected
+#endif
+
 #include "flexarray.h"
 #include "libxl_utils.h"
 
@@ -51,13 +59,13 @@
   /* all of these macros preserve errno (saving and restoring) */
 
 /* logging */
-void xl_logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
+_hidden void xl_logv(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
              const char *file /* may be 0 */, int line /* ignored if !file */,
              const char *func /* may be 0 */,
              char *fmt, va_list al)
      __attribute__((format(printf,7,0)));
 
-void xl_log(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
+_hidden void xl_log(libxl_ctx *ctx, xentoollog_level msglevel, int errnoval,
             const char *file /* may be 0 */, int line /* ignored if !file */,
             const char *func /* may be 0 */,
             char *fmt, ...)
@@ -99,79 +107,99 @@ typedef struct {
 #define PRINTF_ATTRIBUTE(x, y) __attribute__((format(printf, x, y)))
 
 #define UUID_FMT 
"%02hhx%02hhx%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
-#define string_of_uuid(ctx, u) \
-    libxl_sprintf(ctx, UUID_FMT, \
+#define string_of_uuid(gc, u) \
+    libxl_sprintf(gc, UUID_FMT, \
                 (u)[0], (u)[1], (u)[2], (u)[3], (u)[4], (u)[5], (u)[6], 
(u)[7], \
                 (u)[8], (u)[9], (u)[10], (u)[11], (u)[12], (u)[13], (u)[14], 
(u)[15])
 
-int xs_writev(struct xs_handle *xsh, xs_transaction_t t, char *dir, char 
*kvs[]);
+_hidden int xs_writev(struct xs_handle *xsh, xs_transaction_t t, char *dir, 
char *kvs[]);
+
+typedef struct {
+    /* mini-GC */
+    int alloc_maxsize;
+    void **alloc_ptrs;
+
+    libxl_ctx *owner;
+} libxl_gc;
+
+#define INIT_GC(ctx) (libxl_gc){.alloc_maxsize = 0, .alloc_ptrs = 0, .owner = 
ctx}
+
+static inline libxl_ctx *libxl_gc_owner(libxl_gc *gc)
+{
+    return gc->owner;
+}
+
+static inline void libxl_gc_init(libxl_gc *gc, libxl_ctx *ctx)
+{
+    gc->alloc_maxsize = 0;
+    gc->alloc_ptrs = 0;
+    gc->owner = ctx;
+}
 
 /* memory allocation tracking/helpers */
-int libxl_ptr_add(libxl_ctx *ctx, void *ptr);
-int libxl_free(libxl_ctx *ctx, void *ptr);
-int libxl_free_all(libxl_ctx *ctx);
-void *libxl_zalloc(libxl_ctx *ctx, int bytes);
-void *libxl_calloc(libxl_ctx *ctx, size_t nmemb, size_t size);
-char *libxl_sprintf(libxl_ctx *ctx, const char *fmt, ...) PRINTF_ATTRIBUTE(2, 
3);
-char *libxl_strdup(libxl_ctx *ctx, const char *c);
-char *libxl_dirname(libxl_ctx *ctx, const char *s);
+_hidden int libxl_ptr_add(libxl_gc *gc, void *ptr);
+_hidden void libxl_free(libxl_gc *gc, void *ptr);
+_hidden void libxl_free_all(libxl_gc *gc);
+_hidden void *libxl_zalloc(libxl_gc *gc, int bytes);
+_hidden void *libxl_calloc(libxl_gc *gc, size_t nmemb, size_t size);
+_hidden char *libxl_sprintf(libxl_gc *gc, const char *fmt, ...) 
PRINTF_ATTRIBUTE(2, 3);
+_hidden char *libxl_strdup(libxl_gc *gc, const char *c);
+_hidden char *libxl_dirname(libxl_gc *gc, const char *s);
 
-char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int 
length);
-int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t,
+_hidden char **libxl_xs_kvs_of_flexarray(libxl_gc *gc, flexarray_t *array, int 
length);
+_hidden int libxl_xs_writev(libxl_gc *gc, xs_transaction_t t,
                     char *dir, char **kvs);
-int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t,
+_hidden int libxl_xs_write(libxl_gc *gc, xs_transaction_t t,
                    char *path, char *fmt, ...) PRINTF_ATTRIBUTE(4, 5);
-char *libxl_xs_get_dompath(libxl_ctx *ctx, uint32_t domid); // logs errs
-char *libxl_xs_read(libxl_ctx *ctx, xs_transaction_t t, char *path);
-char **libxl_xs_directory(libxl_ctx *ctx, xs_transaction_t t, char *path, 
unsigned int *nb);
+_hidden char *libxl_xs_get_dompath(libxl_gc *gc, uint32_t domid); // logs errs
+_hidden char *libxl_xs_read(libxl_gc *gc, xs_transaction_t t, char *path);
+_hidden char **libxl_xs_directory(libxl_gc *gc, xs_transaction_t t, char 
*path, unsigned int *nb);
 
 /* from xl_dom */
-int is_hvm(libxl_ctx *ctx, uint32_t domid);
-int get_shutdown_reason(libxl_ctx *ctx, uint32_t domid);
+_hidden int is_hvm(libxl_gc *gc, uint32_t domid);
+_hidden int get_shutdown_reason(libxl_gc *gc, uint32_t domid);
 #define dominfo_get_shutdown_reason(info) (((info)->flags >> 
XEN_DOMINF_shutdownshift) & XEN_DOMINF_shutdownmask)
 
-int build_pre(libxl_ctx *ctx, uint32_t domid,
+_hidden int build_pre(libxl_gc *gc, uint32_t domid,
               libxl_domain_build_info *info, libxl_domain_build_state *state);
-int build_post(libxl_ctx *ctx, uint32_t domid,
+_hidden int build_post(libxl_gc *gc, uint32_t domid,
                libxl_domain_build_info *info, libxl_domain_build_state *state,
                char **vms_ents, char **local_ents);
 
-int build_pv(libxl_ctx *ctx, uint32_t domid,
+_hidden int build_pv(libxl_gc *gc, uint32_t domid,
              libxl_domain_build_info *info, libxl_domain_build_state *state);
-int build_hvm(libxl_ctx *ctx, uint32_t domid,
+_hidden int build_hvm(libxl_gc *gc, uint32_t domid,
               libxl_domain_build_info *info, libxl_domain_build_state *state);
 
-int restore_common(libxl_ctx *ctx, uint32_t domid,
+_hidden int restore_common(libxl_gc *gc, uint32_t domid,
                    libxl_domain_build_info *info, libxl_domain_build_state 
*state, int fd);
-int core_suspend(libxl_ctx *ctx, uint32_t domid, int fd, int hvm, int live, 
int debug);
-int save_device_model(libxl_ctx *ctx, uint32_t domid, int fd);
-void libxl__userdata_destroyall(libxl_ctx *ctx, uint32_t domid);
+_hidden int core_suspend(libxl_gc *gc, uint32_t domid, int fd, int hvm, int 
live, int debug);
+_hidden int save_device_model(libxl_gc *gc, uint32_t domid, int fd);
+_hidden void libxl__userdata_destroyall(libxl_gc *gc, uint32_t domid);
 
 /* from xl_device */
-char *device_disk_backend_type_of_phystype(libxl_disk_phystype phystype);
-char *device_disk_string_of_phystype(libxl_disk_phystype phystype);
+_hidden char *device_disk_backend_type_of_phystype(libxl_disk_phystype 
phystype);
+_hidden char *device_disk_string_of_phystype(libxl_disk_phystype phystype);
 
-int device_physdisk_major_minor(const char *physpath, int *major, int *minor);
-int device_disk_dev_number(char *virtpath);
+_hidden int device_physdisk_major_minor(const char *physpath, int *major, int 
*minor);
+_hidden int device_disk_dev_number(char *virtpath);
 
-int libxl_device_generic_add(libxl_ctx *ctx, libxl_device *device,
+_hidden int libxl_device_generic_add(libxl_gc *gc, libxl_device *device,
                              char **bents, char **fents);
-int libxl_device_del(libxl_ctx *ctx, libxl_device *dev, int wait);
-int libxl_device_destroy(libxl_ctx *ctx, char *be_path, int force);
-int libxl_devices_destroy(libxl_ctx *ctx, uint32_t domid, int force);
-int libxl_wait_for_device_model(libxl_ctx *ctx,
+_hidden int libxl_device_del(libxl_gc *gc, libxl_device *dev, int wait);
+_hidden int libxl_device_destroy(libxl_gc *gc, char *be_path, int force);
+_hidden int libxl_devices_destroy(libxl_gc *gc, uint32_t domid, int force);
+_hidden int libxl_wait_for_device_model(libxl_gc *gc,
                                 uint32_t domid, char *state,
-                                int (*check_callback)(libxl_ctx *ctx,
+                                int (*check_callback)(libxl_gc *gc,
                                                       uint32_t domid,
                                                       const char *state,
                                                       void *userdata),
                                 void *check_callback_userdata);
-int libxl_wait_for_backend(libxl_ctx *ctx, char *be_path, char *state);
-int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int 
bus,
-                           unsigned int dev, unsigned int func);
+_hidden int libxl_wait_for_backend(libxl_gc *gc, char *be_path, char *state);
 
 /* from xenguest (helper */
-int hvm_build_set_params(xc_interface *handle, uint32_t domid,
+_hidden int hvm_build_set_params(xc_interface *handle, uint32_t domid,
                          libxl_domain_build_info *info,
                          int store_evtchn, unsigned long *store_mfn);
 
@@ -192,7 +220,7 @@ struct libxl_device_model_starting {
     int domid;
 };
 
-int libxl_spawn_spawn(libxl_ctx *ctx,
+_hidden int libxl_spawn_spawn(libxl_gc *gc,
                       libxl_device_model_starting *starting,
                       const char *what,
                       void (*intermediate_hook)(void *for_spawn, pid_t 
innerchild));
@@ -202,11 +230,11 @@ int libxl_spawn_spawn(libxl_ctx *ctx,
    *    0   caller is now the inner child, should probably call libxl_exec
    * Caller, may pass 0 for for_spawn, in which case no need to detach.
    */
-int libxl_spawn_detach(libxl_ctx *ctx,
+_hidden int libxl_spawn_detach(libxl_gc *gc,
                        libxl_spawn_starting *for_spawn);
   /* Logs errors.  Idempotent, but only permitted after successful
    * call to libxl_spawn_spawn, and no point calling it again if it fails. */
-int libxl_spawn_check(libxl_ctx *ctx,
+_hidden int libxl_spawn_check(libxl_gc *gc,
                       void *for_spawn);
   /* Logs errors but also returns them.
    * for_spawn must actually be a  libxl_spawn_starting*  but
@@ -215,19 +243,21 @@ int libxl_spawn_check(libxl_ctx *ctx,
 
  /* low-level stuff, for synchronous subprocesses etc. */
 
-void libxl_exec(int stdinfd, int stdoutfd, int stderrfd, char *arg0, char 
**args); // logs errors, never returns
-void libxl_log_child_exitstatus(libxl_ctx *ctx,
+_hidden void libxl_exec(int stdinfd, int stdoutfd, int stderrfd, char *arg0, 
char **args); // logs errors, never returns
+_hidden void libxl_log_child_exitstatus(libxl_gc *gc,
                                 const char *what, pid_t pid, int status);
 
-char *libxl_abs_path(libxl_ctx *ctx, char *s, const char *path);
+_hidden char *libxl_abs_path(libxl_gc *gc, char *s, const char *path);
 
 #define XL_LOG_DEBUG   XTL_DEBUG
 #define XL_LOG_INFO    XTL_INFO
 #define XL_LOG_WARNING XTL_WARN
 #define XL_LOG_ERROR   XTL_ERROR
 
-/* Error handling */
-int libxl_xc_error(int xc_err);
+/* string formatting */
+_hidden char *libxl_uuid2string(libxl_gc *gc, const libxl_uuid uuid);
+
+_hidden char *_libxl_domid_to_name(libxl_gc *gc, uint32_t domid);
+_hidden int _libxl_name_to_domid(libxl_gc *gc, const char *name, uint32_t 
*domid);
 
 #endif
-
diff -r e49e70e31a99 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c   Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_pci.c   Fri Aug 06 15:00:14 2010 +0100
@@ -196,8 +196,45 @@ parse_error:
     return ERROR_INVAL;
 }
 
-static int libxl_create_pci_backend(libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev, int num)
+static int pci_reset(libxl_gc *gc, unsigned int domain, unsigned int bus,
+                         unsigned int dev, unsigned int func)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
+    char *reset;
+    int fd, rc;
+
+    reset = libxl_sprintf(gc, "%s/pciback/do_flr", SYSFS_PCI_DEV);
+    fd = open(reset, O_WRONLY);
+    if (fd > 0) {
+        char *buf = libxl_sprintf(gc, PCI_BDF, domain, bus, dev, func);
+        rc = write(fd, buf, strlen(buf));
+        if (rc < 0)
+            XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc);
+        close(fd);
+        return rc < 0 ? rc : 0;
+    }
+    if (errno != ENOENT)
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", 
reset);
+    reset = libxl_sprintf(gc, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, 
bus, dev, func);
+    fd = open(reset, O_WRONLY);
+    if (fd > 0) {
+        rc = write(fd, "1", 1);
+        if (rc < 0)
+            XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, 
rc);
+        close(fd);
+        return rc < 0 ? rc : 0;
+    }
+    if (errno == ENOENT) {
+        XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn't support PCI device reset 
from sysfs");
+    } else {
+        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", 
reset);
+    }
+    return -1;
+}
+
+static int libxl_create_pci_backend(libxl_gc *gc, uint32_t domid, 
libxl_device_pci *pcidev, int num)
+{
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     flexarray_t *front;
     flexarray_t *back;
     unsigned int boffset = 0;
@@ -223,59 +260,60 @@ static int libxl_create_pci_backend(libx
     device.kind = DEVICE_PCI;
 
     flexarray_set(back, boffset++, "frontend-id");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", domid));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", domid));
     flexarray_set(back, boffset++, "online");
     flexarray_set(back, boffset++, "1");
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1));
     flexarray_set(back, boffset++, "domain");
     flexarray_set(back, boffset++, libxl_domid_to_name(ctx, domid));
     for (i = 0; i < num; i++) {
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", i));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, 
pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", i));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, 
pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "key-%d", i));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, 
pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "dev-%d", i));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, 
pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func));
         if (pcidev->vdevfn) {
-            flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", i));
-            flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", 
pcidev->vdevfn));
+            flexarray_set(back, boffset++, libxl_sprintf(gc, "vdevfn-%d", i));
+            flexarray_set(back, boffset++, libxl_sprintf(gc, "%x", 
pcidev->vdevfn));
         }
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", i));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", i));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "opts-%d", i));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, 
"msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "state-%d", i));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1));
     }
     flexarray_set(back, boffset++, "num_devs");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", num));
 
     flexarray_set(front, foffset++, "backend-id");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 0));
+    flexarray_set(front, foffset++, libxl_sprintf(gc, "%d", 0));
     flexarray_set(front, foffset++, "state");
-    flexarray_set(front, foffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(front, foffset++, libxl_sprintf(gc, "%d", 1));
 
-    libxl_device_generic_add(ctx, &device,
-                             libxl_xs_kvs_of_flexarray(ctx, back, boffset),
-                             libxl_xs_kvs_of_flexarray(ctx, front, foffset));
+    libxl_device_generic_add(gc, &device,
+                             libxl_xs_kvs_of_flexarray(gc, back, boffset),
+                             libxl_xs_kvs_of_flexarray(gc, front, foffset));
 
     flexarray_free(back);
     flexarray_free(front);
     return 0;
 }
 
-static int libxl_device_pci_add_xenstore(libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev)
+static int libxl_device_pci_add_xenstore(libxl_gc *gc, uint32_t domid, 
libxl_device_pci *pcidev)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     flexarray_t *back;
     char *num_devs, *be_path;
     int num = 0;
     unsigned int boffset = 0;
     xs_transaction_t t;
 
-    be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", 
libxl_xs_get_dompath(ctx, 0), domid);
-    num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", 
be_path));
+    be_path = libxl_sprintf(gc, "%s/backend/pci/%d/0", 
libxl_xs_get_dompath(gc, 0), domid);
+    num_devs = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/num_devs", 
be_path));
     if (!num_devs)
-        return libxl_create_pci_backend(ctx, domid, pcidev, 1);
+        return libxl_create_pci_backend(gc, domid, pcidev, 1);
 
-    if (!is_hvm(ctx, domid)) {
-        if (libxl_wait_for_backend(ctx, be_path, "4") < 0)
+    if (!is_hvm(gc, domid)) {
+        if (libxl_wait_for_backend(gc, be_path, "4") < 0)
             return ERROR_FAIL;
     }
 
@@ -285,27 +323,27 @@ static int libxl_device_pci_add_xenstore
 
     XL_LOG(ctx, XL_LOG_DEBUG, "Adding new pci device to xenstore");
     num = atoi(num_devs);
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "key-%d", num));
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "dev-%d", num));
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "key-%d", num));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "dev-%d", num));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, PCI_BDF, pcidev->domain, 
pcidev->bus, pcidev->dev, pcidev->func));
     if (pcidev->vdevfn) {
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "vdevfn-%d", num));
-        flexarray_set(back, boffset++, libxl_sprintf(ctx, "%x", 
pcidev->vdevfn));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "vdevfn-%d", num));
+        flexarray_set(back, boffset++, libxl_sprintf(gc, "%x", 
pcidev->vdevfn));
     }
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "opts-%d", num));
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, 
"msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "state-%d", num));
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 1));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "opts-%d", num));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, 
"msitranslate=%d,power_mgmt=%d", pcidev->msitranslate, pcidev->power_mgmt));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "state-%d", num));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 1));
     flexarray_set(back, boffset++, "num_devs");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", num + 1));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", num + 1));
     flexarray_set(back, boffset++, "state");
-    flexarray_set(back, boffset++, libxl_sprintf(ctx, "%d", 7));
+    flexarray_set(back, boffset++, libxl_sprintf(gc, "%d", 7));
 
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
-    libxl_xs_writev(ctx, t, be_path,
-                    libxl_xs_kvs_of_flexarray(ctx, back, boffset));
+    libxl_xs_writev(gc, t, be_path,
+                    libxl_xs_kvs_of_flexarray(gc, back, boffset));
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
@@ -314,29 +352,30 @@ retry_transaction:
     return 0;
 }
 
-static int libxl_device_pci_remove_xenstore(libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev)
+static int libxl_device_pci_remove_xenstore(libxl_gc *gc, uint32_t domid, 
libxl_device_pci *pcidev)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *be_path, *num_devs_path, *num_devs, *xsdev, *tmp, *tmppath;
     int num, i, j;
     xs_transaction_t t;
     unsigned int domain = 0, bus = 0, dev = 0, func = 0;
 
-    be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", 
libxl_xs_get_dompath(ctx, 0), domid);
-    num_devs_path = libxl_sprintf(ctx, "%s/num_devs", be_path);
-    num_devs = libxl_xs_read(ctx, XBT_NULL, num_devs_path);
+    be_path = libxl_sprintf(gc, "%s/backend/pci/%d/0", 
libxl_xs_get_dompath(gc, 0), domid);
+    num_devs_path = libxl_sprintf(gc, "%s/num_devs", be_path);
+    num_devs = libxl_xs_read(gc, XBT_NULL, num_devs_path);
     if (!num_devs)
         return ERROR_INVAL;
     num = atoi(num_devs);
 
-    if (!is_hvm(ctx, domid)) {
-        if (libxl_wait_for_backend(ctx, be_path, "4") < 0) {
+    if (!is_hvm(gc, domid)) {
+        if (libxl_wait_for_backend(gc, be_path, "4") < 0) {
             XL_LOG(ctx, XL_LOG_DEBUG, "pci backend at %s is not ready", 
be_path);
             return ERROR_FAIL;
         }
     }
 
     for (i = 0; i < num; i++) {
-        xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", 
be_path, i));
+        xsdev = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, "%s/dev-%d", 
be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
         if (domain == pcidev->domain && bus == pcidev->bus &&
             pcidev->dev == dev && pcidev->func == func) {
@@ -350,14 +389,14 @@ static int libxl_device_pci_remove_xenst
 
 retry_transaction:
     t = xs_transaction_start(ctx->xsh);
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i), "5", 
strlen("5"));
-    xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state", be_path), "7", 
strlen("7"));
+    xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, i), "5", 
strlen("5"));
+    xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state", be_path), "7", 
strlen("7"));
     if (!xs_transaction_end(ctx->xsh, t, 0))
         if (errno == EAGAIN)
             goto retry_transaction;
 
-    if (!is_hvm(ctx, domid)) {
-        if (libxl_wait_for_backend(ctx, be_path, "4") < 0) {
+    if (!is_hvm(gc, domid)) {
+        if (libxl_wait_for_backend(gc, be_path, "4") < 0) {
             XL_LOG(ctx, XL_LOG_DEBUG, "pci backend at %s is not ready", 
be_path);
             return ERROR_FAIL;
         }
@@ -365,42 +404,42 @@ retry_transaction:
 
 retry_transaction2:
     t = xs_transaction_start(ctx->xsh);
-    xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, i));
-    xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, i));
-    xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, i));
-    xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, i));
-    xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, i));
-    xs_rm(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, i));
-    libxl_xs_write(ctx, t, num_devs_path, "%d", num - 1);
+    xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, i));
+    xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/key-%d", be_path, i));
+    xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/dev-%d", be_path, i));
+    xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/vdev-%d", be_path, i));
+    xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/opts-%d", be_path, i));
+    xs_rm(ctx->xsh, t, libxl_sprintf(gc, "%s/vdevfn-%d", be_path, i));
+    libxl_xs_write(gc, t, num_devs_path, "%d", num - 1);
     for (j = i + 1; j < num; j++) {
-        tmppath = libxl_sprintf(ctx, "%s/state-%d", be_path, j);
-        tmp = libxl_xs_read(ctx, t, tmppath);
-        xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/state-%d", be_path, j - 
1), tmp, strlen(tmp));
+        tmppath = libxl_sprintf(gc, "%s/state-%d", be_path, j);
+        tmp = libxl_xs_read(gc, t, tmppath);
+        xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/state-%d", be_path, j - 
1), tmp, strlen(tmp));
         xs_rm(ctx->xsh, t, tmppath);
-        tmppath = libxl_sprintf(ctx, "%s/dev-%d", be_path, j);
-        tmp = libxl_xs_read(ctx, t, tmppath);
-        xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/dev-%d", be_path, j - 1), 
tmp, strlen(tmp));
+        tmppath = libxl_sprintf(gc, "%s/dev-%d", be_path, j);
+        tmp = libxl_xs_read(gc, t, tmppath);
+        xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/dev-%d", be_path, j - 1), 
tmp, strlen(tmp));
         xs_rm(ctx->xsh, t, tmppath);
-        tmppath = libxl_sprintf(ctx, "%s/key-%d", be_path, j);
-        tmp = libxl_xs_read(ctx, t, tmppath);
-        xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/key-%d", be_path, j - 1), 
tmp, strlen(tmp));
+        tmppath = libxl_sprintf(gc, "%s/key-%d", be_path, j);
+        tmp = libxl_xs_read(gc, t, tmppath);
+        xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/key-%d", be_path, j - 1), 
tmp, strlen(tmp));
         xs_rm(ctx->xsh, t, tmppath);
-        tmppath = libxl_sprintf(ctx, "%s/vdev-%d", be_path, j);
-        tmp = libxl_xs_read(ctx, t, tmppath);
+        tmppath = libxl_sprintf(gc, "%s/vdev-%d", be_path, j);
+        tmp = libxl_xs_read(gc, t, tmppath);
         if (tmp) {
-            xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdev-%d", be_path, j 
- 1), tmp, strlen(tmp));
+            xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/vdev-%d", be_path, j - 
1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
-        tmppath = libxl_sprintf(ctx, "%s/opts-%d", be_path, j);
-        tmp = libxl_xs_read(ctx, t, tmppath);
+        tmppath = libxl_sprintf(gc, "%s/opts-%d", be_path, j);
+        tmp = libxl_xs_read(gc, t, tmppath);
         if (tmp) {
-            xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/opts-%d", be_path, j 
- 1), tmp, strlen(tmp));
+            xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/opts-%d", be_path, j - 
1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
-        tmppath = libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, j);
-        tmp = libxl_xs_read(ctx, t, tmppath);
+        tmppath = libxl_sprintf(gc, "%s/vdevfn-%d", be_path, j);
+        tmp = libxl_xs_read(gc, t, tmppath);
         if (tmp) {
-            xs_write(ctx->xsh, t, libxl_sprintf(ctx, "%s/vdevfn-%d", be_path, 
j - 1), tmp, strlen(tmp));
+            xs_write(ctx->xsh, t, libxl_sprintf(gc, "%s/vdevfn-%d", be_path, j 
- 1), tmp, strlen(tmp));
             xs_rm(ctx->xsh, t, tmppath);
         }
     }
@@ -409,8 +448,8 @@ retry_transaction2:
             goto retry_transaction2;
 
     if (num == 1) {
-        char *fe_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/frontend", be_path));
-        libxl_device_destroy(ctx, be_path, 1);
+        char *fe_path = libxl_xs_read(gc, XBT_NULL, libxl_sprintf(gc, 
"%s/frontend", be_path));
+        libxl_device_destroy(gc, be_path, 1);
         xs_rm(ctx->xsh, XBT_NULL, be_path);
         xs_rm(ctx->xsh, XBT_NULL, fe_path);
         return 0;
@@ -419,7 +458,7 @@ retry_transaction2:
     return 0;
 }
 
-static int get_all_assigned_devices(libxl_ctx *ctx, libxl_device_pci **list, 
int *num)
+static int get_all_assigned_devices(libxl_gc *gc, libxl_device_pci **list, int 
*num)
 {
     libxl_device_pci *pcidevs = NULL;
     char **domlist;
@@ -428,21 +467,21 @@ static int get_all_assigned_devices(libx
     *list = NULL;
     *num = 0;
 
-    domlist = libxl_xs_directory(ctx, XBT_NULL, "/local/domain", &nd);
+    domlist = libxl_xs_directory(gc, XBT_NULL, "/local/domain", &nd);
     for(i = 0; i < nd; i++) {
         char *path, *num_devs;
 
-        path = libxl_sprintf(ctx, "/local/domain/0/backend/pci/%s/0/num_devs", 
domlist[i]);
-        num_devs = libxl_xs_read(ctx, XBT_NULL, path);
+        path = libxl_sprintf(gc, "/local/domain/0/backend/pci/%s/0/num_devs", 
domlist[i]);
+        num_devs = libxl_xs_read(gc, XBT_NULL, path);
         if ( num_devs ) {
             int ndev = atoi(num_devs), j;
             char *devpath, *bdf;
 
             pcidevs = calloc(sizeof(*pcidevs), ndev);
             for(j = (pcidevs) ? 0 : ndev; j < ndev; j++) {
-                devpath = libxl_sprintf(ctx, 
"/local/domain/0/backend/pci/%s/0/dev-%u",
+                devpath = libxl_sprintf(gc, 
"/local/domain/0/backend/pci/%s/0/dev-%u",
                                         domlist[i], j);
-                bdf = libxl_xs_read(ctx, XBT_NULL, devpath);
+                bdf = libxl_xs_read(gc, XBT_NULL, devpath);
                 if ( bdf ) {
                     unsigned dom, bus, dev, func;
                     if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
@@ -487,6 +526,7 @@ static int is_assigned(libxl_device_pci 
 
 int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, 
int *num)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_device_pci *pcidevs = NULL, *new, *assigned;
     struct dirent *de;
     DIR *dir;
@@ -495,9 +535,11 @@ int libxl_device_pci_list_assignable(lib
     *num = 0;
     *list = NULL;
 
-    rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
-    if ( rc )
+    rc = get_all_assigned_devices(&gc, &assigned, &num_assigned);
+    if ( rc ) {
+        libxl_free_all(&gc);
         return rc;
+    }
 
     dir = opendir(SYSFS_PCIBACK_DRIVER);
     if ( NULL == dir ) {
@@ -507,6 +549,7 @@ int libxl_device_pci_list_assignable(lib
             XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Couldn't open %s", 
SYSFS_PCIBACK_DRIVER);
         }
         free(assigned);
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
 
@@ -532,12 +575,14 @@ int libxl_device_pci_list_assignable(lib
 
     closedir(dir);
     free(assigned);
+    libxl_free_all(&gc);
     *list = pcidevs;
     return 0;
 }
 
-static int pci_multifunction_check(libxl_ctx *ctx, libxl_device_pci *pcidev, 
unsigned int *func_mask)
+static int pci_multifunction_check(libxl_gc *gc, libxl_device_pci *pcidev, 
unsigned int *func_mask)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     struct dirent *de;
     DIR *dir;
 
@@ -563,7 +608,7 @@ static int pci_multifunction_check(libxl
         if ( pcidev->dev != dev )
             continue;
 
-        path = libxl_sprintf(ctx, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, 
bus, dev, func);
+        path = libxl_sprintf(gc, "%s/" PCI_BDF, SYSFS_PCIBACK_DRIVER, dom, 
bus, dev, func);
         if ( lstat(path, &st) ) {
             if ( errno == ENOENT )
                 XL_LOG(ctx, XL_LOG_ERROR, PCI_BDF " is not assigned to pciback 
driver",
@@ -580,7 +625,7 @@ static int pci_multifunction_check(libxl
     return 0;
 }
 
-static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, 
void *priv)
+static int pci_ins_check(libxl_gc *gc, uint32_t domid, const char *state, void 
*priv)
 {
     char *orig_state = priv;
 
@@ -594,32 +639,33 @@ static int pci_ins_check(libxl_ctx *ctx,
     return 1;
 }
  
-static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
+static int do_pci_add(libxl_gc *gc, uint32_t domid, libxl_device_pci *pcidev)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *path;
     char *state, *vdevfn;
     int rc, hvm;
 
-    hvm = is_hvm(ctx, domid);
+    hvm = is_hvm(gc, domid);
     if (hvm) {
-        if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 
0) {
+        if (libxl_wait_for_device_model(gc, domid, "running", NULL, NULL) < 0) 
{
             return ERROR_FAIL;
         }
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", 
domid);
-        state = libxl_xs_read(ctx, XBT_NULL, path);
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", 
domid);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", 
domid);
+        state = libxl_xs_read(gc, XBT_NULL, path);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", 
domid);
         if (pcidev->vdevfn)
-            libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain,
+            libxl_xs_write(gc, XBT_NULL, path, PCI_BDF_VDEVFN, pcidev->domain,
                            pcidev->bus, pcidev->dev, pcidev->func, 
pcidev->vdevfn);
         else
-            libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain,
+            libxl_xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
                            pcidev->bus, pcidev->dev, pcidev->func);
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", 
domid);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/command", 
domid);
         xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
-        rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, 
state);
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", 
domid);
-        vdevfn = libxl_xs_read(ctx, XBT_NULL, path);
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", 
domid);
+        rc = libxl_wait_for_device_model(gc, domid, NULL, pci_ins_check, 
state);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", 
domid);
+        vdevfn = libxl_xs_read(gc, XBT_NULL, path);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", 
domid);
         if ( rc < 0 )
             XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", 
vdevfn);
         else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 )
@@ -628,7 +674,7 @@ static int do_pci_add(libxl_ctx *ctx, ui
         if ( rc )
             return ERROR_FAIL;
     } else {
-        char *sysfs_path = libxl_sprintf(ctx, 
SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
+        char *sysfs_path = libxl_sprintf(gc, 
SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, 
pcidev->func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned long long start = 0, end = 0, flags = 0, size = 0;
@@ -663,7 +709,7 @@ static int do_pci_add(libxl_ctx *ctx, ui
             }
         }
         fclose(f);
-        sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", 
pcidev->domain,
+        sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/irq", 
pcidev->domain,
                                    pcidev->bus, pcidev->dev, pcidev->func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
@@ -695,17 +741,18 @@ out:
         }
     }
 
-    libxl_device_pci_add_xenstore(ctx, domid, pcidev);
+    libxl_device_pci_add_xenstore(gc, domid, pcidev);
     return 0;
 }
 
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev)
 {
+    libxl_gc gc = INIT_GC(ctx);
     libxl_device_pci *assigned;
     int num_assigned, rc;
     int stubdomid = 0;
 
-    rc = get_all_assigned_devices(ctx, &assigned, &num_assigned);
+    rc = get_all_assigned_devices(&gc, &assigned, &num_assigned);
     if ( rc ) {
         XL_LOG(ctx, XL_LOG_ERROR, "cannot determine if device is assigned, 
refusing to continue");
         return ERROR_FAIL;
@@ -718,12 +765,12 @@ int libxl_device_pci_add(libxl_ctx *ctx,
     }
     free(assigned);
 
-    libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, 
pcidev->func);
+    pci_reset(&gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
 
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
         libxl_device_pci pcidev_s = *pcidev;
-        rc = do_pci_add(ctx, stubdomid, &pcidev_s);
+        rc = do_pci_add(&gc, stubdomid, &pcidev_s);
         if ( rc )
             return rc;
     }
@@ -732,7 +779,7 @@ int libxl_device_pci_add(libxl_ctx *ctx,
         unsigned int i, orig_vdev, func_mask, rc = 0;
         orig_vdev = pcidev->vdevfn & ~7U;
 
-        if ( pci_multifunction_check(ctx, pcidev, &func_mask) )
+        if ( pci_multifunction_check(&gc, pcidev, &func_mask) )
             return ERROR_FAIL;
         if ( !(pcidev->vdevfn >> 3) ) {
             XL_LOG(ctx, XL_LOG_ERROR, "Must specify a v-slot for 
multi-function devices");
@@ -743,18 +790,19 @@ int libxl_device_pci_add(libxl_ctx *ctx,
             if ( (1 << i) & func_mask ) {
                 pcidev->func = i;
                 pcidev->vdevfn = orig_vdev | i;
-                if ( do_pci_add(ctx, domid, pcidev) )
+                if ( do_pci_add(&gc, domid, pcidev) )
                     rc = ERROR_FAIL;
             }
         }
         return rc;
     }
 
-    return do_pci_add(ctx, domid, pcidev);
+    return do_pci_add(&gc, domid, pcidev);
 }
 
-static int do_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev)
+static int do_pci_remove(libxl_gc *gc, uint32_t domid, libxl_device_pci 
*pcidev)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     libxl_device_pci *assigned;
     char *path;
     char *state;
@@ -769,33 +817,33 @@ static int do_pci_remove(libxl_ctx *ctx,
         }
     }
 
-    libxl_device_pci_remove_xenstore(ctx, domid, pcidev);
+    libxl_device_pci_remove_xenstore(gc, domid, pcidev);
 
-    hvm = is_hvm(ctx, domid);
+    hvm = is_hvm(gc, domid);
     if (hvm) {
-        if (libxl_wait_for_device_model(ctx, domid, "running", NULL, NULL) < 
0) {
+        if (libxl_wait_for_device_model(gc, domid, "running", NULL, NULL) < 0) 
{
             return ERROR_FAIL;
         }
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", 
domid);
-        state = libxl_xs_read(ctx, XBT_NULL, path);
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", 
domid);
-        libxl_xs_write(ctx, XBT_NULL, path, PCI_BDF, pcidev->domain,
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", 
domid);
+        state = libxl_xs_read(gc, XBT_NULL, path);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/parameter", 
domid);
+        libxl_xs_write(gc, XBT_NULL, path, PCI_BDF, pcidev->domain,
                        pcidev->bus, pcidev->dev, pcidev->func);
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", 
domid);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/command", 
domid);
 
         /* Remove all functions at once atomically by only signalling
          * device-model for function 0 */
         if ( !pcidev->multifunction || pcidev->func == 0 ) {
             xs_write(ctx->xsh, XBT_NULL, path, "pci-rem", strlen("pci-rem"));
-            if (libxl_wait_for_device_model(ctx, domid, "pci-removed", NULL, 
NULL) < 0) {
+            if (libxl_wait_for_device_model(gc, domid, "pci-removed", NULL, 
NULL) < 0) {
                 XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in 
time");
                 return ERROR_FAIL;
             }
         }
-        path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", 
domid);
+        path = libxl_sprintf(gc, "/local/domain/0/device-model/%d/state", 
domid);
         xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
     } else {
-        char *sysfs_path = libxl_sprintf(ctx, 
SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
+        char *sysfs_path = libxl_sprintf(gc, 
SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, 
pcidev->func);
         FILE *f = fopen(sysfs_path, "r");
         unsigned int start = 0, end = 0, flags = 0, size = 0;
@@ -825,7 +873,7 @@ static int do_pci_remove(libxl_ctx *ctx,
         }
         fclose(f);
 skip1:
-        sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/irq", 
pcidev->domain,
+        sysfs_path = libxl_sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/irq", 
pcidev->domain,
                                    pcidev->bus, pcidev->dev, pcidev->func);
         f = fopen(sysfs_path, "r");
         if (f == NULL) {
@@ -847,7 +895,7 @@ skip1:
 out:
     /* don't do multiple resets while some functions are still passed through 
*/
     if ( !pcidev->multifunction || pcidev->func == 0 ) {
-        libxl_device_pci_reset(ctx, pcidev->domain, pcidev->bus, pcidev->dev, 
pcidev->func);
+        pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
     }
 
     if (!libxl_is_stubdom(ctx, domid, NULL)) {
@@ -867,39 +915,47 @@ out:
 
 int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev)
 {
+    libxl_gc gc = INIT_GC(ctx);
+    int rc;
+
     if ( pcidev->multifunction ) {
         unsigned int i, orig_vdev, func_mask, rc;
         orig_vdev = pcidev->vdevfn & ~7U;
 
-        if ( pci_multifunction_check(ctx, pcidev, &func_mask) )
+        if ( pci_multifunction_check(&gc, pcidev, &func_mask) )
             return ERROR_FAIL;
 
         for(i = 7; i < 8; --i) {
             if ( (1 << i) & func_mask ) {
                 pcidev->func = i;
                 pcidev->vdevfn = orig_vdev | i;
-                if ( do_pci_remove(ctx, domid, pcidev) )
+                if ( do_pci_remove(&gc, domid, pcidev) )
                     rc = ERROR_FAIL;
             }
         }
+        libxl_free_all(&gc);
         return rc;
     }
 
-    return do_pci_remove(ctx, domid, pcidev);
+    rc = do_pci_remove(&gc, domid, pcidev);
+    libxl_free_all(&gc);
+    return rc;
 }
 
 int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, 
uint32_t domid, int *num)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
     int n, i;
     unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
     libxl_device_pci *pcidevs;
 
-    be_path = libxl_sprintf(ctx, "%s/backend/pci/%d/0", 
libxl_xs_get_dompath(ctx, 0), domid);
-    num_devs = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/num_devs", 
be_path));
+    be_path = libxl_sprintf(&gc, "%s/backend/pci/%d/0", 
libxl_xs_get_dompath(&gc, 0), domid);
+    num_devs = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/num_devs", 
be_path));
     if (!num_devs) {
         *num = 0;
         *list = NULL;
+        libxl_free_all(&gc);
         return 0;
     }
     n = atoi(num_devs);
@@ -907,13 +963,13 @@ int libxl_device_pci_list_assigned(libxl
     *num = n;
 
     for (i = 0; i < n; i++) {
-        xsdev = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev-%d", 
be_path, i));
+        xsdev = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev-%d", 
be_path, i));
         sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        xsvdevfn = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/vdevfn-%d", be_path, i));
+        xsvdevfn = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/vdevfn-%d", be_path, i));
         if (xsvdevfn)
             vdevfn = strtol(xsvdevfn, (char **) NULL, 16);
         pcidev_init(pcidevs + i, domain, bus, dev, func, vdevfn);
-        xsopts = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/opts-%d", 
be_path, i));
+        xsopts = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/opts-%d", 
be_path, i));
         if (xsopts) {
             char *saveptr;
             char *p = strtok_r(xsopts, ",=", &saveptr);
@@ -932,6 +988,7 @@ int libxl_device_pci_list_assigned(libxl
     }
     if ( *num )
         *list = pcidevs;
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -943,45 +1000,12 @@ int libxl_device_pci_shutdown(libxl_ctx 
     rc = libxl_device_pci_list_assigned(ctx, &pcidevs, domid, &num);
     if ( rc )
         return rc;
-    for (i = 0; i < num; i++) {
-        if (libxl_device_pci_remove(ctx, domid, pcidevs + i) < 0)
-            return ERROR_FAIL;
+    for (rc = i = 0; i < num; i++) {
+        if (libxl_device_pci_remove(ctx, domid, pcidevs + i) < 0) {
+            rc = ERROR_FAIL;
+            break;
+        }
     }
     free(pcidevs);
-    return 0;
+    return rc;
 }
-
-int libxl_device_pci_reset(libxl_ctx *ctx, unsigned int domain, unsigned int 
bus,
-                         unsigned int dev, unsigned int func)
-{
-    char *reset;
-    int fd, rc;
-
-    reset = libxl_sprintf(ctx, "%s/pciback/do_flr", SYSFS_PCI_DEV);
-    fd = open(reset, O_WRONLY);
-    if (fd > 0) {
-        char *buf = libxl_sprintf(ctx, PCI_BDF, domain, bus, dev, func);
-        rc = write(fd, buf, strlen(buf));
-        if (rc < 0)
-            XL_LOG(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, rc);
-        close(fd);
-        return rc < 0 ? rc : 0;
-    }
-    if (errno != ENOENT)
-        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access pciback path %s", 
reset);
-    reset = libxl_sprintf(ctx, "%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, 
bus, dev, func);
-    fd = open(reset, O_WRONLY);
-    if (fd > 0) {
-        rc = write(fd, "1", 1);
-        if (rc < 0)
-            XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "write to %s returned %d", reset, 
rc);
-        close(fd);
-        return rc < 0 ? rc : 0;
-    }
-    if (errno == ENOENT) {
-        XL_LOG(ctx, XL_LOG_ERROR, "The kernel doesn't support PCI device reset 
from sysfs");
-    } else {
-        XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "Failed to access reset path %s", 
reset);
-    }
-    return -1;
-}
diff -r e49e70e31a99 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_utils.c Fri Aug 06 15:00:14 2010 +0100
@@ -31,7 +31,6 @@
 #include "libxl_utils.h"
 #include "libxl_internal.h"
 
-
 unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, 
unsigned int smp_cpus)
 {
     /* 256 pages (1MB) per vcpu,
@@ -51,7 +50,13 @@ char *libxl_domid_to_name(libxl_ctx *ctx
 
     snprintf(path, sizeof(path), "/local/domain/%d/name", domid);
     s = xs_read(ctx->xsh, XBT_NULL, path, &len);
-    libxl_ptr_add(ctx, s);
+    return s;
+}
+
+char *_libxl_domid_to_name(libxl_gc *gc, uint32_t domid)
+{
+    char *s = libxl_domid_to_name(libxl_gc_owner(gc), domid);
+    libxl_ptr_add(gc, s);
     return s;
 }
 
@@ -76,12 +81,13 @@ int libxl_name_to_domid(libxl_ctx *ctx, 
             ret = 0;
             break;
         }
+        free(domname);
     }
     free(dominfo);
     return ret;
 }
 
-const char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid)
+char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid)
 {
     unsigned int len;
     char path[strlen("/local/pool") + 12];
@@ -91,7 +97,6 @@ const char *libxl_poolid_to_name(libxl_c
         return "Pool-0";
     snprintf(path, sizeof(path), "/local/pool/%d/name", poolid);
     s = xs_read(ctx->xsh, XBT_NULL, path, &len);
-    libxl_ptr_add(ctx, s);
     return s;
 }
 
@@ -99,7 +104,7 @@ int libxl_name_to_poolid(libxl_ctx *ctx,
                         uint32_t *poolid)
 {
     int i, nb_pools;
-    const char *poolname;
+    char *poolname;
     libxl_poolinfo *poolinfo;
 
     poolinfo = libxl_list_pool(ctx, &nb_pools);
@@ -114,32 +119,46 @@ int libxl_name_to_poolid(libxl_ctx *ctx,
             *poolid = poolinfo[i].poolid;
             return 0;
         }
+        free(poolname);
     }
     return -1;
 }
 
 int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid)
 {
-    char * stubdom_id_s = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/image/device-model-domid", libxl_xs_get_dompath(ctx, guest_domid)));
+    libxl_gc gc = INIT_GC(ctx);
+    char * stubdom_id_s = libxl_xs_read(&gc, XBT_NULL,
+                                        libxl_sprintf(&gc, 
"%s/image/device-model-domid",
+                                                      
libxl_xs_get_dompath(&gc, guest_domid)));
+    int ret;
+
     if (stubdom_id_s)
-        return atoi(stubdom_id_s);
+        ret = atoi(stubdom_id_s);
     else
-        return 0;
+        ret = 0;
+    libxl_free_all(&gc);
+    return ret;
 }
 
 int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *target, *endptr;
     uint32_t value;
 
-    target = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/target", 
libxl_xs_get_dompath(ctx, domid)));
-    if (!target)
+    target = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/target", 
libxl_xs_get_dompath(&gc, domid)));
+    if (!target) {
+        libxl_free_all(&gc);
         return 0;
+    }
     value = strtol(target, &endptr, 10);
-    if (*endptr != '\0')
+    if (*endptr != '\0') {
+        libxl_free_all(&gc);
         return 0;
+    }
     if (target_domid)
         *target_domid = value;
+    libxl_free_all(&gc);
     return 1;
 }
 
@@ -159,26 +178,33 @@ static int logrename(libxl_ctx *ctx, con
 
 int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name)
 {
+    libxl_gc gc = INIT_GC(ctx);
     struct stat stat_buf;
     char *logfile, *logfile_new;
     int i, rc;
 
-    logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
+    logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log", name);
     if (stat(logfile, &stat_buf) == 0) {
         /* file exists, rotate */
-        logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.10", name);
+        logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log.10", name);
         unlink(logfile);
         for (i = 9; i > 0; i--) {
-            logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i);
-            logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.%d", name, i 
+ 1);
+            logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log.%d", name, i);
+            logfile_new = libxl_sprintf(&gc, "/var/log/xen/%s.log.%d", name, i 
+ 1);
             rc = logrename(ctx, logfile, logfile_new);
-            if (rc) return rc;
+            if (rc) {
+                libxl_free_all(&gc);
+                return rc;
+            }
         }
-        logfile = libxl_sprintf(ctx, "/var/log/xen/%s.log", name);
-        logfile_new = libxl_sprintf(ctx, "/var/log/xen/%s.log.1", name);
+        logfile = libxl_sprintf(&gc, "/var/log/xen/%s.log", name);
+        logfile_new = libxl_sprintf(&gc, "/var/log/xen/%s.log.1", name);
 
         rc = logrename(ctx, logfile, logfile_new);
-        if (rc) return rc;
+        if (rc) {
+            libxl_free_all(&gc);
+            return rc;
+        }
     } else {
         if (errno != ENOENT)
             XL_LOG_ERRNO(ctx, XL_LOG_WARNING, "problem checking existence of"
@@ -186,6 +212,7 @@ int libxl_create_logfile(libxl_ctx *ctx,
                          name);
     }
     *full_name = strdup(logfile);
+    libxl_free_all(&gc);
     return 0;
 }
 
@@ -394,130 +421,139 @@ int libxl_mac_to_device_nic(libxl_ctx *c
             nic->devid = nics->devid;
             memcpy(nic->mac, nics->mac, sizeof (nic->mac));
             nic->script = nics->script;
-            libxl_free(ctx, nics);
+            free(nics);
             return 0;
         }
     }
 
-    libxl_free(ctx, nics);
+    free(nics);
     return 0;
 }
 
 int libxl_devid_to_device_nic(libxl_ctx *ctx, uint32_t domid,
                               const char *devid, libxl_device_nic *nic)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *tok, *val;
     char *dompath, *nic_path_fe, *nic_path_be;
     unsigned int i;
 
     memset(nic, 0, sizeof (libxl_device_nic));
-    dompath = libxl_xs_get_dompath(ctx, domid);
+    dompath = libxl_xs_get_dompath(&gc, domid);
     if (!dompath) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
-    nic_path_fe = libxl_sprintf(ctx, "%s/device/vif/%s", dompath, devid);
-    nic_path_be = libxl_xs_read(ctx, XBT_NULL,
-                                libxl_sprintf(ctx, "%s/backend", nic_path_fe));
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
nic_path_fe));
+    nic_path_fe = libxl_sprintf(&gc, "%s/device/vif/%s", dompath, devid);
+    nic_path_be = libxl_xs_read(&gc, XBT_NULL,
+                                libxl_sprintf(&gc, "%s/backend", nic_path_fe));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", 
nic_path_fe));
     nic->backend_domid = strtoul(val, NULL, 10);
     nic->devid = strtoul(devid, NULL, 10);
-    libxl_free(ctx, val);
 
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", 
nic_path_fe));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", 
nic_path_fe));
     for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
          ++i, tok = strtok(NULL, ":")) {
         nic->mac[i] = strtoul(tok, NULL, 16);
     }
-    libxl_free(ctx, val);
-    nic->script = libxl_xs_read(ctx, XBT_NULL,
-                                libxl_sprintf(ctx, "%s/script", nic_path_be));
-    libxl_free(ctx, nic_path_fe);
-    libxl_free(ctx, nic_path_be);
+    nic->script = libxl_xs_read(&gc, XBT_NULL,
+                                libxl_sprintf(&gc, "%s/script", nic_path_be));
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_devid_to_device_disk(libxl_ctx *ctx, uint32_t domid,
                                const char *devid, libxl_device_disk *disk)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *endptr, *val;
     char *dompath, *diskpath, *be_path;
     unsigned int devid_n;
 
     devid_n = strtoul(devid, &endptr, 10);
     if (devid == endptr) {
+        libxl_free_all(&gc);
         return ERROR_INVAL;
     }
-    dompath = libxl_xs_get_dompath(ctx, domid);
-    diskpath = libxl_sprintf(ctx, "%s/device/vbd/%s", dompath, devid);
+    dompath = libxl_xs_get_dompath(&gc, domid);
+    diskpath = libxl_sprintf(&gc, "%s/device/vbd/%s", dompath, devid);
     if (!diskpath) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
 
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
diskpath));
-    if (!val)
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", 
diskpath));
+    if (!val) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
+    }
     disk->backend_domid = strtoul(val, NULL, 10);
     disk->domid = domid;
-    be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", 
diskpath));
-    disk->physpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, 
"%s/params", be_path));
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/type", be_path));
+    be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", 
diskpath));
+    disk->physpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, 
"%s/params", be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/type", be_path));
     libxl_string_to_phystype(ctx, val, &(disk->phystype));
-    disk->virtpath = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/dev", 
be_path));
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/removable", 
be_path));
+    disk->virtpath = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/dev", 
be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/removable", 
be_path));
     disk->unpluggable = !strcmp(val, "1");
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mode", be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mode", be_path));
     disk->readwrite = !!strcmp(val, "w");
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/device-type", 
diskpath));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/device-type", 
diskpath));
     disk->is_cdrom = !strcmp(val, "cdrom");
 
+    libxl_free_all(&gc);
     return 0;
 }
 
 int libxl_devid_to_device_net2(libxl_ctx *ctx, uint32_t domid,
                                const char *devid, libxl_device_net2 *net2)
 {
+    libxl_gc gc = INIT_GC(ctx);
     char *tok, *endptr, *val;
     char *dompath, *net2path, *be_path;
     unsigned int devid_n, i;
 
     devid_n = strtoul(devid, &endptr, 10);
     if (devid == endptr) {
+        libxl_free_all(&gc);
         return ERROR_INVAL;
     }
-    dompath = libxl_xs_get_dompath(ctx, domid);
-    net2path = libxl_sprintf(ctx, "%s/device/vif2/%s", dompath, devid);
+    dompath = libxl_xs_get_dompath(&gc, domid);
+    net2path = libxl_sprintf(&gc, "%s/device/vif2/%s", dompath, devid);
     if (!net2path) {
+        libxl_free_all(&gc);
         return ERROR_FAIL;
     }
     memset(net2, 0, sizeof (libxl_device_net2));
-    be_path = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend", 
net2path));
+    be_path = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend", 
net2path));
 
     net2->devid = devid_n;
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/mac", net2path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/mac", net2path));
     for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
          ++i, tok = strtok(NULL, ":")) {
         net2->front_mac[i] = strtoul(tok, NULL, 16);
     }
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-mac", 
net2path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-mac", 
net2path));
     for (i = 0, tok = strtok(val, ":"); tok && (i < 6);
          ++i, tok = strtok(NULL, ":")) {
         net2->back_mac[i] = strtoul(tok, NULL, 16);
     }
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/backend-id", 
net2path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/backend-id", 
net2path));
     net2->backend_domid = strtoul(val, NULL, 10);
 
     net2->domid = domid;
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/remote-trusted", 
be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/remote-trusted", 
be_path));
     net2->trusted = strtoul(val, NULL, 10);
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/local-trusted", 
be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/local-trusted", 
be_path));
     net2->back_trusted = strtoul(val, NULL, 10);
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", 
be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", 
be_path));
     net2->filter_mac = strtoul(val, NULL, 10);
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/filter-mac", 
net2path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/filter-mac", 
net2path));
     net2->front_filter_mac = strtoul(val, NULL, 10);
-    val = libxl_xs_read(ctx, XBT_NULL, libxl_sprintf(ctx, "%s/max-bypasses", 
be_path));
+    val = libxl_xs_read(&gc, XBT_NULL, libxl_sprintf(&gc, "%s/max-bypasses", 
be_path));
     net2->max_bypasses = strtoul(val, NULL, 10);
 
+    libxl_free_all(&gc);
     return 0;
 }
 
diff -r e49e70e31a99 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_utils.h Fri Aug 06 15:00:14 2010 +0100
@@ -22,7 +22,7 @@ unsigned long libxl_get_required_shadow_
 int libxl_name_to_domid(libxl_ctx *ctx, const char *name, uint32_t *domid);
 char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid);
 int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, uint32_t *poolid);
-const char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid);
+char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid);
 int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid);
 int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid);
 int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name);
diff -r e49e70e31a99 tools/libxl/libxl_xshelp.c
--- a/tools/libxl/libxl_xshelp.c        Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/libxl_xshelp.c        Fri Aug 06 15:00:14 2010 +0100
@@ -44,12 +44,12 @@ int xs_writev(struct xs_handle *xsh, xs_
     return 0;
 }
 
-char **libxl_xs_kvs_of_flexarray(libxl_ctx *ctx, flexarray_t *array, int 
length)
+char **libxl_xs_kvs_of_flexarray(libxl_gc *gc, flexarray_t *array, int length)
 {
     char **kvs;
     int i;
 
-    kvs = libxl_calloc(ctx, length + 2, sizeof(char *));
+    kvs = libxl_calloc(gc, length + 2, sizeof(char *));
     if (kvs) {
         for (i = 0; i < length; i += 2) {
             void *ptr;
@@ -65,9 +65,10 @@ char **libxl_xs_kvs_of_flexarray(libxl_c
     return kvs;
 }
 
-int libxl_xs_writev(libxl_ctx *ctx, xs_transaction_t t,
+int libxl_xs_writev(libxl_gc *gc, xs_transaction_t t,
                     char *dir, char *kvs[])
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *path;
     int i;
 
@@ -75,19 +76,20 @@ int libxl_xs_writev(libxl_ctx *ctx, xs_t
         return 0;
 
     for (i = 0; kvs[i] != NULL; i += 2) {
-        path = libxl_sprintf(ctx, "%s/%s", dir, kvs[i]);
+        path = libxl_sprintf(gc, "%s/%s", dir, kvs[i]);
         if (path && kvs[i + 1]) {
             int length = strlen(kvs[i + 1]);
             xs_write(ctx->xsh, t, path, kvs[i + 1], length);
         }
-        libxl_free(ctx, path);
+        libxl_free(gc, path);
     }
     return 0;
 }
 
-int libxl_xs_write(libxl_ctx *ctx, xs_transaction_t t,
+int libxl_xs_write(libxl_gc *gc, xs_transaction_t t,
                    char *path, char *fmt, ...)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *s;
     va_list ap;
     int ret;
@@ -103,35 +105,38 @@ int libxl_xs_write(libxl_ctx *ctx, xs_tr
     return 0;
 }
 
-char * libxl_xs_read(libxl_ctx *ctx, xs_transaction_t t, char *path)
+char * libxl_xs_read(libxl_gc *gc, xs_transaction_t t, char *path)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     unsigned int len;
     char *ptr;
 
     ptr = xs_read(ctx->xsh, t, path, &len);
     if (ptr != NULL) {
-        libxl_ptr_add(ctx, ptr);
+        libxl_ptr_add(gc, ptr);
         return ptr;
     }
     return 0;
 }
 
-char *libxl_xs_get_dompath(libxl_ctx *ctx, uint32_t domid)
+char *libxl_xs_get_dompath(libxl_gc *gc, uint32_t domid)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char *s = xs_get_domain_path(ctx->xsh, domid);
     if (!s) {
         XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "failed to get dompath for %" PRIu32,
                      domid);
         return NULL;
     }
-    libxl_ptr_add(ctx, s);
+    libxl_ptr_add(gc, s);
     return s;
 }
 
-char **libxl_xs_directory(libxl_ctx *ctx, xs_transaction_t t, char *path, 
unsigned int *nb)
+char **libxl_xs_directory(libxl_gc *gc, xs_transaction_t t, char *path, 
unsigned int *nb)
 {
+    libxl_ctx *ctx = libxl_gc_owner(gc);
     char **ret = NULL;
     ret = xs_directory(ctx->xsh, XBT_NULL, path, nb);
-    libxl_ptr_add(ctx, ret);
+    libxl_ptr_add(gc, ret);
     return ret;
 }
diff -r e49e70e31a99 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Thu Aug 05 15:20:22 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Fri Aug 06 15:00:14 2010 +0100
@@ -2167,8 +2167,10 @@ void list_domains(int verbose, const lib
 
     printf("Name                                        ID   Mem 
VCPUs\tState\tTime(s)\n");
     for (i = 0; i < nb_domain; i++) {
+        char *name;
+        name = libxl_domid_to_name(&ctx, info[i].domid);
         printf("%-40s %5d %5lu %5d     %c%c%c%c%c%c  %8.1f",
-                libxl_domid_to_name(&ctx, info[i].domid),
+                name,
                 info[i].domid,
                 (unsigned long) (info[i].max_memkb / 1024),
                 info[i].vcpu_online,
@@ -2179,9 +2181,13 @@ void list_domains(int verbose, const lib
                 info[i].shutdown_reason == SHUTDOWN_crash ? 'c' : '-',
                 info[i].dying ? 'd' : '-',
                 ((float)info[i].cpu_time / 1e9));
+        free(name);
         if (verbose) {
-            char *uuid = libxl_uuid2string(&ctx, info[i].uuid);
-            printf(" %s", uuid);
+            printf(" " UUID_FMT,
+                info[i].uuid[0], info[i].uuid[1], info[i].uuid[2], 
info[i].uuid[3],
+                info[i].uuid[4], info[i].uuid[5], info[i].uuid[6], 
info[i].uuid[7],
+                info[i].uuid[8], info[i].uuid[9], info[i].uuid[10], 
info[i].uuid[11],
+                info[i].uuid[12], info[i].uuid[13], info[i].uuid[14], 
info[i].uuid[15]);
         }
         putchar('\n');
     }



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH, RFC]: xl: start implementing "the policy" wrt memory allocations, Gianni Tedesco <=