From: Andres Lagar-Cavilla <andres@lagarcavilla.com>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
Vincent Hanquez <vincent.hanquez@eu.citrix.com>,
"xen-devel@lists.xensource.com" <xen-devel@lists.xensource.com>
Subject: [PATCH] libxenlight: clone context to avoid GC corruption
Date: Wed, 02 Dec 2009 17:09:10 -0500 [thread overview]
Message-ID: <4B16E586.7060505@lagarcavilla.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 324 bytes --]
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@lagarcavilla.com>
[-- Attachment #2: clone_context.patch --]
[-- Type: text/x-patch, Size: 4002 bytes --]
# HG changeset patch
# User Andres Lagar-Cavilla <andres@lagarcavilla.com>
# 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@lagarcavilla.com>
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);
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2009-12-02 22:09 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-02 22:09 Andres Lagar-Cavilla [this message]
2009-12-03 12:16 ` [PATCH] libxenlight: clone context to avoid GC corruption Stefano Stabellini
2009-12-03 12:20 ` Stefano Stabellini
2009-12-03 13:57 ` Andres Lagar-Cavilla
2009-12-03 14:34 ` Stefano Stabellini
2009-12-03 15:11 ` Vincent Hanquez
2009-12-03 15:18 ` Stefano Stabellini
2009-12-03 15:18 ` andres
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B16E586.7060505@lagarcavilla.com \
--to=andres@lagarcavilla.com \
--cc=stefano.stabellini@eu.citrix.com \
--cc=vincent.hanquez@eu.citrix.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.