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);
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)
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,
* 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)
{
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);
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_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__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->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;
}
/*
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: */
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);
/*