xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 24/24] libxl: aborting bootloader invocation when domain dioes
Date: Mon, 16 Apr 2012 18:18:06 +0100	[thread overview]
Message-ID: <1334596686-8479-25-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1334596686-8479-1-git-send-email-ian.jackson@eu.citrix.com>

Cancel the bootloader (specifically, by sending it a signal) if the
domain is seen to disappear from xenstore.

We use a new utility event source libxl__domaindeathcheck which
provides a convenient wrapper for the xenstore watch.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
---
 tools/libxl/libxl_bootloader.c |   43 ++++++++++++++++++++++++++++++---------
 tools/libxl/libxl_event.c      |   31 ++++++++++++++++++++++++++++
 tools/libxl/libxl_internal.h   |   29 ++++++++++++++++++++++++++-
 3 files changed, 92 insertions(+), 11 deletions(-)

diff --git a/tools/libxl/libxl_bootloader.c b/tools/libxl/libxl_bootloader.c
index 8436c07..fb1302b 100644
--- a/tools/libxl/libxl_bootloader.c
+++ b/tools/libxl/libxl_bootloader.c
@@ -31,6 +31,7 @@ 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_finished(libxl__egc *egc, libxl__ev_child *child,
                                 pid_t pid, int status);
 
@@ -213,6 +214,7 @@ void libxl__bootloader_init(libxl__bootloader_state *bl)
     bl->ptys[0].master = bl->ptys[0].slave = 0;
     bl->ptys[1].master = bl->ptys[1].slave = 0;
     libxl__ev_child_init(&bl->child);
+    libxl__domaindeathcheck_init(&bl->deathcheck);
     bl->keystrokes.ao = bl->ao;  libxl__datacopier_init(&bl->keystrokes);
     bl->display.ao = bl->ao;     libxl__datacopier_init(&bl->display);
 }
@@ -230,6 +232,7 @@ static void bootloader_cleanup(libxl__egc *egc, libxl__bootloader_state *bl)
         free(bl->diskpath);
         bl->diskpath = 0;
     }
+    libxl__domaindeathcheck_stop(gc,&bl->deathcheck);
     libxl__datacopier_kill(&bl->keystrokes);
     libxl__datacopier_kill(&bl->display);
     for (i=0; i<2; i++) {
@@ -256,6 +259,23 @@ static void bootloader_callback(libxl__egc *egc, libxl__bootloader_state *bl,
     bl->callback(egc, bl, rc);
 }
 
+/* might be called at any time, provided it's init'd */
+static void bootloader_abort(libxl__egc *egc,
+                             libxl__bootloader_state *bl, int rc)
+{
+    STATE_AO_GC(bl->ao);
+    int r;
+
+    libxl__datacopier_kill(&bl->keystrokes);
+    libxl__datacopier_kill(&bl->display);
+    if (libxl__ev_child_inuse(&bl->child)) {
+        r = kill(bl->child.pid, SIGTERM);
+        if (r) LOGE(WARN, "after failure, failed to kill bootloader [%lu]",
+                    (unsigned long)bl->child.pid);
+    }
+    bl->rc = rc;
+}
+
 /*----- main flow of control -----*/
 
 void libxl__bootloader_run(libxl__egc *egc, libxl__bootloader_state *bl)
@@ -377,6 +397,12 @@ static void bootloader_gotptys(libxl__egc *egc, libxl__openpty_state *op)
         goto out;
     }
 
+    bl->deathcheck.what = "stopping bootloader";
+    bl->deathcheck.domid = bl->domid;
+    bl->deathcheck.callback = bootloader_domaindeath;
+    rc = libxl__domaindeathcheck_start(gc, &bl->deathcheck);
+    if (rc) goto out;
+
     if (bl->console_available)
         bl->console_available(egc, bl);
 
@@ -454,18 +480,9 @@ static void bootloader_copyfail(libxl__egc *egc, const char *which,
        libxl__bootloader_state *bl, int onwrite, int errnoval)
 {
     STATE_AO_GC(bl->ao);
-    int r;
-
     if (!onwrite && !errnoval)
         LOG(ERROR, "unexpected eof copying %s", which);
-    libxl__datacopier_kill(&bl->keystrokes);
-    libxl__datacopier_kill(&bl->display);
-    if (libxl__ev_child_inuse(&bl->child)) {
-        r = kill(bl->child.pid, SIGTERM);
-        if (r) LOGE(WARN, "after failure, failed to kill bootloader [%lu]",
-                    (unsigned long)bl->child.pid);
-    }
-    bl->rc = ERROR_FAIL;
+    bootloader_abort(egc, bl, ERROR_FAIL);
 }
 static void bootloader_keystrokes_copyfail(libxl__egc *egc,
        libxl__datacopier_state *dc, int onwrite, int errnoval)
@@ -480,6 +497,12 @@ static void bootloader_display_copyfail(libxl__egc *egc,
     bootloader_copyfail(egc, "bootloader output", bl, onwrite, errnoval);
 }
 
+static void bootloader_domaindeath(libxl__egc *egc, libxl__domaindeathcheck *dc)
+{
+    libxl__bootloader_state *bl = CONTAINER_OF(dc, *bl, deathcheck);
+    bootloader_abort(egc, bl, ERROR_FAIL);
+}
+
 static void bootloader_finished(libxl__egc *egc, libxl__ev_child *child,
                                 pid_t pid, int status)
 {
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 991f16e..e43aedc 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -585,6 +585,37 @@ int libxl__ev_devstate_wait(libxl__gc *gc, libxl__ev_devstate *ds,
 }
 
 /*
+ * domain death/destruction
+ */
+
+static void domaindeathcheck_callback(libxl__egc *egc, libxl__ev_xswatch *w,
+                            const char *watch_path, const char *event_path)
+{
+    libxl__domaindeathcheck *dc = CONTAINER_OF(w, *dc, watch);
+    EGC_GC;
+    const char *p = libxl__xs_read(gc, XBT_NULL, watch_path);
+    if (p) return;
+
+    if (errno!=ENOENT) {
+        LIBXL__EVENT_DISASTER(egc,"failed to read xenstore"
+                              " for domain deatch check", errno, 0);
+        return;
+    }
+
+    LOG(ERROR,"%s: domain %"PRIu32" removed (%s no longer in xenstore)",
+        dc->what, dc->domid, watch_path);
+    dc->callback(egc, dc);
+}
+
+int libxl__domaindeathcheck_start(libxl__gc *gc,
+                                  libxl__domaindeathcheck *dc)
+{
+    const char *path = GCSPRINTF("/local/domain/%"PRIu32, dc->domid);
+    return libxl__ev_xswatch_register(gc, &dc->watch,
+                                      domaindeathcheck_callback, path);
+}
+
+/*
  * osevent poll
  */
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 3e90ac4..92e06f1 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -837,6 +837,33 @@ _hidden int libxl__ev_devstate_wait(libxl__gc *gc, libxl__ev_devstate *ds,
                                     const char *state_path,
                                     int state, int milliseconds);
 
+/*
+ * libxl__ev_domaindeathcheck_register - arranges to call back (once)
+ * if the domain is destroyed.  If the domain dies, we log a message
+ * of the form "<what>: <explanation of the situation, including the domid>".
+ */
+
+typedef struct libxl__domaindeathcheck libxl__domaindeathcheck;
+typedef void libxl___domaindeathcheck_callback(libxl__egc *egc,
+                                         libxl__domaindeathcheck*);
+
+struct libxl__domaindeathcheck {
+    /* must be filled in by caller, and remain valid: */
+    const char *what;
+    uint32_t domid;
+    libxl___domaindeathcheck_callback *callback;
+    /* private */
+    libxl__ev_xswatch watch;
+};
+
+_hidden int libxl__domaindeathcheck_start(libxl__gc *gc,
+                                          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); }
+
 
 /*
  * libxl__try_phy_backend - Check if there's support for the passed
@@ -1690,6 +1717,7 @@ struct libxl__bootloader_state {
     libxl__openpty_state openpty;
     libxl__openpty_result ptys[2];  /* [0] is for bootloader */
     libxl__ev_child child;
+    libxl__domaindeathcheck deathcheck;
     int nargs, argsspace;
     const char **args;
     libxl__datacopier_state keystrokes, display;
@@ -1702,7 +1730,6 @@ _hidden void libxl__bootloader_init(libxl__bootloader_state *bl);
  * If callback is passed rc==0, will have updated st->info appropriately */
 _hidden void libxl__bootloader_run(libxl__egc*, libxl__bootloader_state *st);
 
-
 /*----- Domain creation -----*/
 
 typedef struct libxl__domain_create_state libxl__domain_create_state;
-- 
1.7.2.5

  parent reply	other threads:[~2012-04-16 17:18 UTC|newest]

Thread overview: 56+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-04-16 17:17 [PATCH v7 00/24] libxl: subprocess handling Ian Jackson
2012-04-16 17:17 ` [PATCH 01/24] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-04-16 17:17 ` [PATCH 02/24] libxl: support multiple libxl__ev_fds for the same fd Ian Jackson
2012-04-16 17:17 ` [PATCH 03/24] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-04-16 17:17 ` [PATCH 04/24] autoconf: trim the configure script; use autoheader Ian Jackson
2012-04-17  9:18   ` Ian Campbell
2012-04-17 13:18     ` Ian Jackson
2012-04-17 13:22       ` Ian Campbell
2012-04-17 14:07         ` Roger Pau Monne
2012-04-16 17:17 ` [PATCH 05/24] autoconf: New test for openpty et al Ian Jackson
2012-04-17  9:20   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 06/24] libxl: provide libxl__remove_file " Ian Jackson
2012-04-16 17:17 ` [PATCH 07/24] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-04-16 17:17 ` [PATCH 08/24] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-04-16 17:17 ` [PATCH 09/24] libxl: provide libxl__datacopier_* Ian Jackson
2012-04-17  9:37   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 10/24] libxl: provide libxl__openpty_* Ian Jackson
2012-04-16 17:17 ` [PATCH 11/24] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-04-16 17:17 ` [PATCH 12/24] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-04-16 17:17 ` [PATCH 13/24] libxl: log bootloader output Ian Jackson
2012-04-16 17:17 ` [PATCH 14/24] libxl: Allow AO_GC and EGC_GC even if not used Ian Jackson
2012-04-16 17:17 ` [PATCH 15/24] libxl: remove ctx->waitpid_instead Ian Jackson
2012-04-17  9:40   ` Ian Campbell
2012-04-17 13:24     ` Ian Jackson
2012-04-16 17:17 ` [PATCH 16/24] libxl: change some structures to unit arrays Ian Jackson
2012-04-17  9:41   ` Ian Campbell
2012-04-16 17:17 ` [PATCH 17/24] libxl: ao: convert libxl__spawn_* Ian Jackson
2012-04-17 15:17   ` Ian Campbell
2012-04-17 17:03     ` Ian Jackson
2012-04-18 10:12       ` Ian Campbell
2012-04-18 10:52         ` Ian Jackson
2012-04-18 11:07           ` Ian Campbell
2012-04-16 17:18 ` [PATCH 18/24] libxl: make libxl_create run bootloader via callback Ian Jackson
2012-04-24 13:46   ` Ian Campbell
2012-04-24 13:54     ` Ian Jackson
2012-04-16 17:18 ` [PATCH 19/24] libxl: provide progress reporting for long-running operations Ian Jackson
2012-04-24 13:59   ` Ian Campbell
2012-04-25 13:38     ` Ian Jackson
2012-04-16 17:18 ` [PATCH 20/24] libxl: remove malloc failure handling from NEW_EVENT Ian Jackson
2012-04-24 14:01   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 21/24] libxl: convert console callback to libxl_asyncprogress_how Ian Jackson
2012-04-24 14:05   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 22/24] libxl: clarify definition of "slow" operation Ian Jackson
2012-04-24 14:06   ` Ian Campbell
2012-04-16 17:18 ` [PATCH 23/24] libxl: child processes cleanups Ian Jackson
2012-04-24 14:12   ` Ian Campbell
2012-04-24 14:27     ` Ian Jackson
2012-04-24 15:05       ` Ian Campbell
2012-04-24 15:07         ` Ian Campbell
2012-04-24 15:22     ` Ian Jackson
2012-04-24 15:32       ` Ian Campbell
2012-04-16 17:18 ` Ian Jackson [this message]
2012-04-24 14:18   ` [PATCH 24/24] libxl: aborting bootloader invocation when domain dioes Ian Campbell
2012-04-24 14:38     ` Ian Jackson
2012-04-24 15:08       ` Ian Campbell
2012-04-24 15:26         ` Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1334596686-8479-25-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).