mirror of
https://github.com/xen-project/xen.git
synced 2026-10-30 03:00:05 +01:00
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:
1 parent
668a3dd1f0
commit
005bc3b588
3 files changed
+59
-14
No files matched your search
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
/*
|
||||
|
||||