diff options
author | Ian Jackson <ian.jackson@eu.citrix.com> | 2012-06-28 18:43:27 +0100 |
---|---|---|
committer | Ian Jackson <ian.jackson@eu.citrix.com> | 2012-06-28 18:43:27 +0100 |
commit | ac29cf9641e2db5f7dea35df5d049d26724a6602 (patch) | |
tree | c954ab04a70f773f3aa984900ce941ead61bfa95 /tools/libxl/libxl_dm.c | |
parent | 89be6c47e353484af1ec7b4aab79696145bbfdb0 (diff) | |
download | xen-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.c | 14 |
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) |