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] libxenlight: clone context to avoid GC corruption

To: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>, Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] libxenlight: clone context to avoid GC corruption
From: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>
Date: Wed, 02 Dec 2009 17:09:10 -0500
Cc:
Delivery-date: Wed, 02 Dec 2009 14:09:45 -0800
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
User-agent: Thunderbird 2.0.0.23 (X11/20090817)
Provide a function to clone a context. This is necessary
because simply copying the structs will eventually
corrup the GC: maxsize is updated in the cloned context
but not in the originating one, yet they have the same
array of referenced pointers alloc_ptrs.

Signed-off-by: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>

# HG changeset patch
# User Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>
# Date 1259791324 18000
# Node ID e8611d9965607659d2cb16864694983f35c2d83a
# Parent  684a4d0abc86dbded4ceda68f7b5e1b4806ff1d7
Provide a function to clone a context. This is necessary
because simply copying the structs will eventually
corrup the GC: maxsize is updated in the cloned context
but not in the originating one, yet they have the same 
array of referenced pointers alloc_ptrs.

Signed-off-by: Andres Lagar-Cavilla <andres@xxxxxxxxxxxxxxxx>

diff -r 684a4d0abc86 -r e8611d996560 libxl.c
--- a/libxl.c
+++ b/libxl.c
@@ -656,9 +656,16 @@ void dm_xenstore_record_pid(struct libxl
     struct libxl_device_model_starting *starting = for_spawn;
     struct libxl_ctx clone;
     char *kvs[3];
-    int rc;
+    int rc, cloned;
 
-    clone = *ctx;
+    if (libxl_clone_context(ctx, &clone)) {
+        XL_LOG(ctx, XL_LOG_ERROR, "Out of memory when cloning context");
+        /* Throw a prayer fallback */
+        clone = *ctx;
+        cloned = 0;
+    } else {
+        cloned = 1;
+    }
     clone.xsh = xs_daemon_open();
     /* we mustn't use the parent's handle in the child */
 
@@ -669,6 +676,7 @@ void dm_xenstore_record_pid(struct libxl
     if (rc) XL_LOG_ERRNO(&clone, XL_LOG_ERROR,
                          "Couldn't record device model pid %ld at %s/%s",
                          (unsigned long)innerchild, starting->dom_path, kvs);
+    if (cloned) libxl_discard_cloned_context(&clone);
     xs_daemon_close(clone.xsh);
 }
 
diff -r 684a4d0abc86 -r e8611d996560 libxl_device.c
--- a/libxl_device.c
+++ b/libxl_device.c
@@ -212,7 +212,12 @@ int libxl_devices_destroy(struct libxl_c
     fd_set rfds;
     struct timeval tv;
     flexarray_t *toremove;
-    struct libxl_ctx clone = *ctx;
+    struct libxl_ctx clone;
+
+    if (libxl_clone_context(ctx, &clone)) {
+        XL_LOG(ctx, XL_LOG_ERROR, "Out of memory when cloning context");
+        return ERROR_NOMEM;
+    }
 
     clone.xsh = xs_daemon_open();
     toremove = flexarray_make(16, 1);
@@ -220,6 +225,7 @@ int libxl_devices_destroy(struct libxl_c
     l1 = libxl_xs_directory(&clone, XBT_NULL, path, &num1);
     if (!l1) {
         XL_LOG(&clone, XL_LOG_ERROR, "%s is empty", path);
+        libxl_discard_cloned_context(&clone);
         xs_daemon_close(clone.xsh);
         return -1;
     }
@@ -269,6 +275,7 @@ int libxl_devices_destroy(struct libxl_c
         xs_rm(clone.xsh, XBT_NULL, path);
     }
     flexarray_free(toremove);
+    libxl_discard_cloned_context(&clone);
     xs_daemon_close(clone.xsh);
     return 0;
 }
diff -r 684a4d0abc86 -r e8611d996560 libxl_internal.c
--- a/libxl_internal.c
+++ b/libxl_internal.c
@@ -28,6 +28,28 @@ int libxl_error_set(struct libxl_ctx *ct
     return 0;
 }
 
+int libxl_clone_context(struct libxl_ctx *from, struct libxl_ctx *to)
+{
+    /* We could just copy the structs, but since
+     * maxsize is not a pointer we need to take care
+     * of our own GC. */
+    *to = *from;
+    to->alloc_ptrs = NULL;
+    to->alloc_maxsize = 256;
+    to->alloc_ptrs = calloc(to->alloc_maxsize, sizeof(void *));
+    if (!to->alloc_ptrs)
+        return ERROR_NOMEM;
+    return 0;
+}
+
+void libxl_discard_cloned_context(struct libxl_ctx *ctx)
+{
+    /* We only need to worry about GC-related fields */
+    (void)libxl_ctx_free(ctx);
+    if (ctx->alloc_ptrs)
+        free(ctx->alloc_ptrs);
+}
+
 int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr)
 {
     int i;
diff -r 684a4d0abc86 -r e8611d996560 libxl_internal.h
--- a/libxl_internal.h
+++ b/libxl_internal.h
@@ -63,6 +63,8 @@ typedef struct {
 #define PRINTF_ATTRIBUTE(x, y) __attribute__((format(printf, x, y)))
 
 /* memory allocation tracking/helpers */
+int libxl_clone_context(struct libxl_ctx *from, struct libxl_ctx *to);
+void libxl_discard_cloned_context(struct libxl_ctx *ctx);
 int libxl_ptr_add(struct libxl_ctx *ctx, void *ptr);
 int libxl_free(struct libxl_ctx *ctx, void *ptr);
 int libxl_free_all(struct libxl_ctx *ctx);
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel