From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Jackson Subject: [PATCH 23/29] libxl: cancellation: Support cancellation where we spot domain death Date: Tue, 10 Feb 2015 20:10:10 +0000 Message-ID: <1423599016-32639-24-git-send-email-ian.jackson@eu.citrix.com> References: <1423599016-32639-1-git-send-email-ian.jackson@eu.citrix.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1423599016-32639-1-git-send-email-ian.jackson@eu.citrix.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: xen-devel@lists.xensource.com Cc: Ian Jackson , Euan Harris List-Id: xen-devel@lists.xenproject.org Make an active libxl__domaindeathcheck contain an active libxl__ao_cancellable. Consequential changes are: * domaindeath callbacks now take an rc value. * libxl__domaindeathcheck_start takes an ao, not a gc. * bootloader_domaindeath plumbs the rc through to its caller. * libxl__domaindeathcheck_init and _stop are not quite trivial any more so are moved from (inline functions) in libxl_internal.h, to ordinary functions defined in libxl_event.c. * libxl__domaindeathcheck_start is not trivial any more, and now has the standard error-handling pattern. The only current user of libxl__domaindeathcheck is the bootloader. So the result is that now it is possible to effectively cancel domain creation while the bootloader is running. Signed-off-by: Ian Jackson --- v2: New in this version of the series. --- tools/libxl/libxl_bootloader.c | 11 +++++---- tools/libxl/libxl_event.c | 50 ++++++++++++++++++++++++++++++++++++---- tools/libxl/libxl_internal.h | 12 +++++----- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c index c3f3a1f..21f92dc 100644 --- a/tools/libxl/libxl_bootloader.c +++ b/tools/libxl/libxl_bootloader.c @@ -33,7 +33,8 @@ static void bootloader_keystrokes_copyfail(libxl__egc *egc, libxl__datacopier_state *dc, int onwrite, int errnoval); static void bootloader_display_copyfail(libxl__egc *egc, libxl__datacopier_state *dc, int onwrite, int errnoval); -static void bootloader_domaindeath(libxl__egc*, libxl__domaindeathcheck *dc); +static void bootloader_domaindeath(libxl__egc*, libxl__domaindeathcheck *dc, + int rc); static void bootloader_finished(libxl__egc *egc, libxl__ev_child *child, pid_t pid, int status); @@ -496,7 +497,7 @@ static void bootloader_gotptys(libxl__egc *egc, libxl__openpty_state *op) bl->deathcheck.what = "stopping bootloader"; bl->deathcheck.domid = bl->domid; bl->deathcheck.callback = bootloader_domaindeath; - rc = libxl__domaindeathcheck_start(gc, &bl->deathcheck); + rc = libxl__domaindeathcheck_start(ao, &bl->deathcheck); if (rc) goto out; if (bl->console_available) @@ -608,10 +609,12 @@ static void bootloader_display_copyfail(libxl__egc *egc, bootloader_copyfail(egc, "bootloader output", bl, 1, onwrite, errnoval); } -static void bootloader_domaindeath(libxl__egc *egc, libxl__domaindeathcheck *dc) +static void bootloader_domaindeath(libxl__egc *egc, + libxl__domaindeathcheck *dc, + int rc) { libxl__bootloader_state *bl = CONTAINER_OF(dc, *bl, deathcheck); - bootloader_stop(egc, bl, ERROR_DOMAIN_DESTROYED); + bootloader_stop(egc, bl, rc); } static void bootloader_finished(libxl__egc *egc, libxl__ev_child *child, diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c index ba549f2..dd9658d 100644 --- a/tools/libxl/libxl_event.c +++ b/tools/libxl/libxl_event.c @@ -920,6 +920,18 @@ int libxl__ev_devstate_wait(libxl__ao *ao, libxl__ev_devstate *ds, * futile. */ +void libxl__domaindeathcheck_init(libxl__domaindeathcheck *dc) +{ + libxl__ao_cancellable_init(&dc->cancel); + libxl__ev_xswatch_init(&dc->watch); +} + +void libxl__domaindeathcheck_stop(libxl__gc *gc, libxl__domaindeathcheck *dc) +{ + libxl__ao_cancellable_deregister(&dc->cancel); + libxl__ev_xswatch_deregister(gc,&dc->watch); +} + static void domaindeathcheck_callback(libxl__egc *egc, libxl__ev_xswatch *w, const char *watch_path, const char *event_path) { @@ -928,6 +940,8 @@ static void domaindeathcheck_callback(libxl__egc *egc, libxl__ev_xswatch *w, const char *p = libxl__xs_read(gc, XBT_NULL, watch_path); if (p) return; + libxl__domaindeathcheck_stop(gc,dc); + if (errno!=ENOENT) { LIBXL__EVENT_DISASTER(egc,"failed to read xenstore" " for domain detach check", errno, 0); @@ -936,15 +950,43 @@ static void domaindeathcheck_callback(libxl__egc *egc, libxl__ev_xswatch *w, LOG(ERROR,"%s: domain %"PRIu32" removed (%s no longer in xenstore)", dc->what, dc->domid, watch_path); - dc->callback(egc, dc); + dc->callback(egc, dc, ERROR_DOMAIN_DESTROYED); +} + +static void domaindeathcheck_cancel(libxl__egc *egc, + libxl__ao_cancellable *cancel, + int rc) +{ + libxl__domaindeathcheck *dc = CONTAINER_OF(cancel, *dc, cancel); + EGC_GC; + + libxl__domaindeathcheck_stop(gc,dc); + dc->callback(egc, dc, rc); } -int libxl__domaindeathcheck_start(libxl__gc *gc, +int libxl__domaindeathcheck_start(libxl__ao *ao, libxl__domaindeathcheck *dc) { + AO_GC; + int rc; const char *path = GCSPRINTF("/local/domain/%"PRIu32, dc->domid); - return libxl__ev_xswatch_register(gc, &dc->watch, - domaindeathcheck_callback, path); + + libxl__domaindeathcheck_init(dc); + + dc->cancel.ao = ao; + dc->cancel.callback = domaindeathcheck_cancel; + rc = libxl__ao_cancellable_register(&dc->cancel); + if (rc) goto out; + + rc = libxl__ev_xswatch_register(gc, &dc->watch, + domaindeathcheck_callback, path); + if (rc) goto out; + + return 0; + + out: + libxl__domaindeathcheck_stop(gc,dc); + return rc; } /* diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h index a251b43..9ab3ab7 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -1238,7 +1238,8 @@ _hidden int libxl__ev_devstate_wait(libxl__ao *ao, libxl__ev_devstate *ds, typedef struct libxl__domaindeathcheck libxl__domaindeathcheck; typedef void libxl___domaindeathcheck_callback(libxl__egc *egc, - libxl__domaindeathcheck*); + libxl__domaindeathcheck*, + int rc /* DESTROYED or CANCELLED */); struct libxl__domaindeathcheck { /* must be filled in by caller, and remain valid: */ @@ -1246,16 +1247,15 @@ struct libxl__domaindeathcheck { uint32_t domid; libxl___domaindeathcheck_callback *callback; /* private */ + libxl__ao_cancellable cancel; libxl__ev_xswatch watch; }; -_hidden int libxl__domaindeathcheck_start(libxl__gc *gc, +_hidden int libxl__domaindeathcheck_start(libxl__ao *ao, libxl__domaindeathcheck *dc); -static inline void libxl__domaindeathcheck_init - (libxl__domaindeathcheck *dc) { libxl__ev_xswatch_init(&dc->watch); } -static inline void libxl__domaindeathcheck_stop(libxl__gc *gc, - libxl__domaindeathcheck *dc) { libxl__ev_xswatch_deregister(gc,&dc->watch); } +void libxl__domaindeathcheck_init(libxl__domaindeathcheck *dc); +void libxl__domaindeathcheck_stop(libxl__gc *gc, libxl__domaindeathcheck *dc); /* -- 1.7.10.4