libxl: ao abort: Support aborting where we spot domain death

Make an active libxl__domaindeathcheck contain an active
libxl__ao_abortable.

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 abort domain
creation while the bootloader is running.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
v2: New in this version of the series.
This commit is contained in:
Ian Jackson authored and Ian Jackson committed 2015-06-26 16:53:51 +01:00
1 parent 668a3dd1f0
commit 005bc3b588
3 files changed
+59 -14

No files matched your search

+7 -4
View File
@@ -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)
@@ -610,10 +611,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,
+46 -4
View File
@@ -933,6 +933,18 @@ int libxl__ev_devstate_wait(libxl__ao *ao, libxl__ev_devstate *ds,
* futile.
*/
void libxl__domaindeathcheck_init(libxl__domaindeathcheck *dc)
{
libxl__ao_abortable_init(&dc->abrt);
libxl__ev_xswatch_init(&dc->watch);
}
void libxl__domaindeathcheck_stop(libxl__gc *gc, libxl__domaindeathcheck *dc)
{
libxl__ao_abortable_deregister(&dc->abrt);
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)
{
@@ -941,6 +953,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);
@@ -949,15 +963,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);
}
int libxl__domaindeathcheck_start(libxl__gc *gc,
static void domaindeathcheck_abort(libxl__egc *egc,
libxl__ao_abortable *abrt,
int rc)
{
libxl__domaindeathcheck *dc = CONTAINER_OF(abrt, *dc, abrt);
EGC_GC;
libxl__domaindeathcheck_stop(gc,dc);
dc->callback(egc, dc, rc);
}
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->abrt.ao = ao;
dc->abrt.callback = domaindeathcheck_abort;
rc = libxl__ao_abortable_register(&dc->abrt);
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;
}
/*
+6 -6
View File
@@ -1263,7 +1263,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 ABORTED */);
struct libxl__domaindeathcheck {
/* must be filled in by caller, and remain valid: */
@@ -1271,16 +1272,15 @@ struct libxl__domaindeathcheck {
uint32_t domid;
libxl___domaindeathcheck_callback *callback;
/* private */
libxl__ao_abortable abrt;
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);
/*
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.