[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 25/28] libxl: cancellation: Handle SIGTERM in save/restore helper
During startup of the save/restore helper, set the disposition of SIGTERM appropriately. For restore, we can simply die immediately - there is no point trying to do any kind of cleanup on what is now going to be a trashed domain. For save, we want to arrange that libxc's cleanup code (eg turning off logdirty) takes place. So our signal handler replaces the fd with one on which writes will fail, causing libxc's own loop to fail next time it actually tries to do a write. Currently this has only a minor beneficial effect: we don't send the helper a SIGTERM ourselves, and if someone else contrives to send our helper a SIGTERM they have probably sent one to libxl too in which case things are going to be a bit messy anyway. But in the next patch libxl is going to use SIGTERM itself on ao cancellation. Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v2: New in this version of the series. --- tools/libxl/libxl_save_helper.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tools/libxl/libxl_save_helper.c b/tools/libxl/libxl_save_helper.c index 7514b2e..0be77c9 100644 --- a/tools/libxl/libxl_save_helper.c +++ b/tools/libxl/libxl_save_helper.c @@ -40,8 +40,10 @@ #include <unistd.h> #include <assert.h> #include <inttypes.h> +#include <fcntl.h> #include "libxl.h" +#include "libxl_utils.h" #include "xenctrl.h" #include "xenguest.h" @@ -120,6 +122,58 @@ static void *xmalloc(size_t sz) return r; } +/*----- signal handling -----*/ + +static int unwriteable_fd; + +static void save_signal_handler(int num) +{ + /* + * We want to be able to interrupt save. But the code in libxc + * which does the actual saving is straight-through, and we need + * to execute its error path to put the guest back to sanity. + * + * So what we do is this: when we get the signal, we dup2 + * the result of open("/dev/null",O_RDONLY) onto the output fd. + * + * This is guaranteed to 1. interrupt libxc's write (causing it to + * return short, or maybe EINTR); 2. make the next write give + * EBADF, so that: 3. at latest, libxc will notice when it next + * tries to write data and will then go into its cleanup path. + * + * We make no effort here to sanitise the resulting errors. + * That's libxl's job. + */ + int esave = errno; + + int r = dup2(unwriteable_fd, io_fd); + assert(r == io_fd); /* if not we can't write an xtl message because we + * might end up interleaving on our control stream */ + + errno = esave; +} + +static void setup_signals(void (*handler)(int)) +{ + struct sigaction sa; + sigset_t spmask; + int r; + + unwriteable_fd = open("/dev/null",O_RDONLY); + if (unwriteable_fd < 0) fail(errno,"open /dev/null for reading"); + + LIBXL_FILLZERO(sa); + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + r = sigaction(SIGTERM, &sa, 0); + if (r) fail(errno,"sigaction SIGTERM failed"); + + sigemptyset(&spmask); + sigaddset(&spmask,SIGTERM); + r = sigprocmask(SIG_UNBLOCK,&spmask,0); + if (r) fail(errno,"sigprocmask unblock SIGTERM failed"); +} + /*----- helper functions called by autogenerated stubs -----*/ unsigned char * helper_allocbuf(int len, void *user) @@ -229,6 +283,8 @@ int main(int argc, char **argv) helper_setcallbacks_save(&helper_save_callbacks, cbflags); startup("save"); + setup_signals(save_signal_handler); + r = xc_domain_save(xch, io_fd, dom, max_iters, max_factor, flags, &helper_save_callbacks, hvm); complete(r); @@ -254,6 +310,8 @@ int main(int argc, char **argv) unsigned long console_mfn = 0; startup("restore"); + setup_signals(SIG_DFL); + r = xc_domain_restore(xch, io_fd, dom, store_evtchn, &store_mfn, store_domid, console_evtchn, &console_mfn, console_domid, hvm, pae, superpages, -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |