aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_dm.c
diff options
context:
space:
mode:
authorIan Jackson <ian.jackson@eu.citrix.com>2012-06-28 18:43:27 +0100
committerIan Jackson <ian.jackson@eu.citrix.com>2012-06-28 18:43:27 +0100
commitac29cf9641e2db5f7dea35df5d049d26724a6602 (patch)
treec954ab04a70f773f3aa984900ce941ead61bfa95 /tools/libxl/libxl_dm.c
parent89be6c47e353484af1ec7b4aab79696145bbfdb0 (diff)
downloadxen-ac29cf9641e2db5f7dea35df5d049d26724a6602.tar.gz
xen-ac29cf9641e2db5f7dea35df5d049d26724a6602.tar.bz2
xen-ac29cf9641e2db5f7dea35df5d049d26724a6602.zip
libxl: do not leak spawned middle children
libxl__spawn_spawn would, when libxl__spawn_detach was called, make the spawn become idle immediately. However it still has a child process which needs to be waited for: the `detachable' spawned child. This is wrong because the ultimate in-libxl caller may return to the application, with a child process still forked but not reaped libxl contrary to the documented behaviour of libxl. Instead, replace libxl__spawn_detach with libxl__spawn_initiate_detach which is asynchronous. The detachable spawned children are abolished; instead, we defer calling back to the in-libxl user until the middle child has been reaped. Also, remove erroneous comment suggesting that `death' callback parameter to libxl__ev_child_fork may be NULL. It may not, and there are no callers which pass NULL. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Acked-by: Ian Campbell <ian.campbell@citrix.com>
Diffstat (limited to 'tools/libxl/libxl_dm.c')
-rw-r--r--tools/libxl/libxl_dm.c14
1 files changed, 11 insertions, 3 deletions
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 936e3072bc..3fca1670ba 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -915,6 +915,8 @@ static void device_model_confirm(libxl__egc *egc, libxl__spawn_state *spawn,
const char *xsdata);
static void device_model_startup_failed(libxl__egc *egc,
libxl__spawn_state *spawn);
+static void device_model_detached(libxl__egc *egc,
+ libxl__spawn_state *spawn);
/* our "next step" function, called from those callbacks and elsewhere */
static void device_model_spawn_outcome(libxl__egc *egc,
@@ -1022,6 +1024,7 @@ retry_transaction:
spawn->midproc_cb = libxl__spawn_record_pid;
spawn->confirm_cb = device_model_confirm;
spawn->failure_cb = device_model_startup_failed;
+ spawn->detached_cb = device_model_detached;
rc = libxl__spawn_spawn(egc, spawn);
if (rc < 0)
@@ -1055,9 +1058,7 @@ static void device_model_confirm(libxl__egc *egc, libxl__spawn_state *spawn,
if (strcmp(xsdata, "running"))
return;
- libxl__spawn_detach(gc, spawn);
-
- device_model_spawn_outcome(egc, dmss, 0);
+ libxl__spawn_initiate_detach(gc, spawn);
}
static void device_model_startup_failed(libxl__egc *egc,
@@ -1067,6 +1068,13 @@ static void device_model_startup_failed(libxl__egc *egc,
device_model_spawn_outcome(egc, dmss, ERROR_FAIL);
}
+static void device_model_detached(libxl__egc *egc,
+ libxl__spawn_state *spawn)
+{
+ libxl__dm_spawn_state *dmss = CONTAINER_OF(spawn, *dmss, spawn);
+ device_model_spawn_outcome(egc, dmss, 0);
+}
+
static void device_model_spawn_outcome(libxl__egc *egc,
libxl__dm_spawn_state *dmss,
int rc)