All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>,
	Euan Harris <euan.harris@citrix.com>
Subject: [PATCH 12/29] libxl: events: Permit timeouts to signal cancellation
Date: Tue, 10 Feb 2015 20:09:59 +0000	[thread overview]
Message-ID: <1423599016-32639-13-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1423599016-32639-1-git-send-email-ian.jackson@eu.citrix.com>

The callback functions provided by users must take an rc value.  This
rc value can be ERROR_TIMEDOUT or ERROR_CANCELLED.

Users of xswait are now expected to deal correctly with
ERROR_CANCELLED.  If they experience this, it hasn't been logged.
And the caller won't log it either since it's not TIMEDOUT.
Luckily this is correct, so we can just change the doc comment.

Currently nothing generates ERROR_CANCELLED; in particular the
timeouts cannot in fact signal cancellation.

There should be no publicly visible change except that some error
returns from libxl will change from ERROR_FAIL to ERROR_TIMEDOUT, and
some changes to debugging messages.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
---
 tools/libxl/libxl_aoutils.c        |   11 ++++++++---
 tools/libxl/libxl_device.c         |    8 +++++---
 tools/libxl/libxl_dom.c            |   29 ++++++++++++++++++++---------
 tools/libxl/libxl_event.c          |    8 ++++----
 tools/libxl/libxl_internal.h       |   12 +++++++-----
 tools/libxl/libxl_test_timedereg.c |    8 +++++---
 6 files changed, 49 insertions(+), 27 deletions(-)

diff --git a/tools/libxl/libxl_aoutils.c b/tools/libxl/libxl_aoutils.c
index 891cdb8..0b6d750 100644
--- a/tools/libxl/libxl_aoutils.c
+++ b/tools/libxl/libxl_aoutils.c
@@ -80,12 +80,13 @@ void xswait_xswatch_callback(libxl__egc *egc, libxl__ev_xswatch *xsw,
 }
 
 void xswait_timeout_callback(libxl__egc *egc, libxl__ev_time *ev,
-                             const struct timeval *requested_abs)
+                             const struct timeval *requested_abs,
+                             int rc)
 {
     EGC_GC;
     libxl__xswait_state *xswa = CONTAINER_OF(ev, *xswa, time_ev);
     LOG(DEBUG, "%s: xswait timeout (path=%s)", xswa->what, xswa->path);
-    xswait_report_error(egc, xswa, ERROR_TIMEDOUT);
+    xswait_report_error(egc, xswa, rc);
 }
 
 static void xswait_report_error(libxl__egc *egc, libxl__xswait_state *xswa,
@@ -455,11 +456,15 @@ int libxl__openptys(libxl__openpty_state *op,
 
 static void async_exec_timeout(libxl__egc *egc,
                                libxl__ev_time *ev,
-                               const struct timeval *requested_abs)
+                               const struct timeval *requested_abs,
+                               int rc)
 {
     libxl__async_exec_state *aes = CONTAINER_OF(ev, *aes, time);
     STATE_AO_GC(aes->ao);
 
+    if (!aes->rc)
+        aes->rc = rc;
+
     libxl__ev_time_deregister(gc, &aes->time);
 
     assert(libxl__ev_child_inuse(&aes->child));
diff --git a/tools/libxl/libxl_device.c b/tools/libxl/libxl_device.c
index 84114ff..3b1c3b2 100644
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -717,7 +717,7 @@ out:
 
 /* This callback is part of the Qemu devices Badge */
 static void device_qemu_timeout(libxl__egc *egc, libxl__ev_time *ev,
-                                const struct timeval *requested_abs);
+                                const struct timeval *requested_abs, int rc);
 
 static void device_backend_callback(libxl__egc *egc, libxl__ev_devstate *ds,
                                    int rc);
@@ -880,7 +880,7 @@ out:
 }
 
 static void device_qemu_timeout(libxl__egc *egc, libxl__ev_time *ev,
-                                const struct timeval *requested_abs)
+                                const struct timeval *requested_abs, int rc)
 {
     libxl__ao_device *aodev = CONTAINER_OF(ev, *aodev, timeout);
     STATE_AO_GC(aodev->ao);
@@ -888,7 +888,9 @@ static void device_qemu_timeout(libxl__egc *egc, libxl__ev_time *ev,
     char *state_path = GCSPRINTF("%s/state", be_path);
     const char *xs_state;
     xs_transaction_t t = 0;
-    int rc = 0;
+
+    if (rc != ERROR_TIMEDOUT)
+        goto out;
 
     libxl__ev_time_deregister(gc, &aodev->timeout);
 
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index e292cb3..87b5fdd 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -943,7 +943,8 @@ static void domain_suspend_callback_common_done(libxl__egc *egc,
  */
 
 static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev,
-                                    const struct timeval *requested_abs);
+                                    const struct timeval *requested_abs,
+                                    int rc);
 static void switch_logdirty_xswatch(libxl__egc *egc, libxl__ev_xswatch*,
                             const char *watch_path, const char *event_path);
 static void switch_logdirty_done(libxl__egc *egc,
@@ -1069,7 +1070,8 @@ void libxl__domain_suspend_common_switch_qemu_logdirty
     }
 }
 static void switch_logdirty_timeout(libxl__egc *egc, libxl__ev_time *ev,
-                                    const struct timeval *requested_abs)
+                                    const struct timeval *requested_abs,
+                                    int rc)
 {
     libxl__domain_suspend_state *dss = CONTAINER_OF(ev, *dss, logdirty.timeout);
     STATE_AO_GC(dss->ao);
@@ -1218,7 +1220,7 @@ static void suspend_common_wait_guest_watch(libxl__egc *egc,
 static void suspend_common_wait_guest_check(libxl__egc *egc,
         libxl__domain_suspend_state *dss);
 static void suspend_common_wait_guest_timeout(libxl__egc *egc,
-      libxl__ev_time *ev, const struct timeval *requested_abs);
+      libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
 
 static void domain_suspend_common_done(libxl__egc *egc,
                                        libxl__domain_suspend_state *dss,
@@ -1452,12 +1454,15 @@ static void suspend_common_wait_guest_check(libxl__egc *egc,
 }
 
 static void suspend_common_wait_guest_timeout(libxl__egc *egc,
-      libxl__ev_time *ev, const struct timeval *requested_abs)
+      libxl__ev_time *ev, const struct timeval *requested_abs, int rc)
 {
     libxl__domain_suspend_state *dss = CONTAINER_OF(ev, *dss, guest_timeout);
     STATE_AO_GC(dss->ao);
-    LOG(ERROR, "guest did not suspend, timed out");
-    domain_suspend_common_done(egc, dss, ERROR_GUEST_TIMEDOUT);
+    if (rc == ERROR_TIMEDOUT) {
+        LOG(ERROR, "guest did not suspend, timed out");
+        rc = ERROR_GUEST_TIMEDOUT;
+    }
+    domain_suspend_common_done(egc, dss, rc);
 }
 
 static void domain_suspend_common_guest_suspended(libxl__egc *egc,
@@ -1690,7 +1695,8 @@ static void remus_devices_commit_cb(libxl__egc *egc,
                                     libxl__remus_devices_state *rds,
                                     int rc);
 static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev,
-                                  const struct timeval *requested_abs);
+                                  const struct timeval *requested_abs,
+                                  int rc);
 
 static void libxl__remus_domain_checkpoint_callback(void *data)
 {
@@ -1765,7 +1771,8 @@ out:
 }
 
 static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev,
-                                  const struct timeval *requested_abs)
+                                  const struct timeval *requested_abs,
+                                  int rc)
 {
     libxl__domain_suspend_state *dss =
                             CONTAINER_OF(ev, *dss, checkpoint_timeout);
@@ -1777,7 +1784,11 @@ static void remus_next_checkpoint(libxl__egc *egc, libxl__ev_time *ev,
      * (xc_domain_save.c). in order to continue executing the infinite loop
      * (suspend, checkpoint, resume) in xc_domain_save().
      */
-    libxl__xc_domain_saverestore_async_callback_done(egc, &dss->shs, 1);
+
+    if (rc)
+        dss->rc = rc;
+
+    libxl__xc_domain_saverestore_async_callback_done(egc, &dss->shs, !rc);
 }
 
 /*----- main code for suspending, in order of execution -----*/
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 1a97cf8..7b4b141 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -383,7 +383,7 @@ void libxl__ev_time_deregister(libxl__gc *gc, libxl__ev_time *ev)
     return;
 }
 
-static void time_occurs(libxl__egc *egc, libxl__ev_time *etime)
+static void time_occurs(libxl__egc *egc, libxl__ev_time *etime, int rc)
 {
     DBG("ev_time=%p occurs abs=%lu.%06lu",
         etime, (unsigned long)etime->abs.tv_sec,
@@ -391,7 +391,7 @@ static void time_occurs(libxl__egc *egc, libxl__ev_time *etime)
 
     libxl__ev_time_callback *func = etime->func;
     etime->func = 0;
-    func(egc, etime, &etime->abs);
+    func(egc, etime, &etime->abs, rc);
 }
 
 
@@ -1187,7 +1187,7 @@ static void afterpoll_internal(libxl__egc *egc, libxl__poller *poller,
 
         time_deregister(gc, etime);
 
-        time_occurs(egc, etime);
+        time_occurs(egc, etime, ERROR_TIMEDOUT);
     }
 }
 
@@ -1271,7 +1271,7 @@ void libxl_osevent_occurred_timeout(libxl_ctx *ctx, void *for_libxl)
 
     LIBXL_TAILQ_REMOVE(&CTX->etimes, ev, entry);
 
-    time_occurs(egc, ev);
+    time_occurs(egc, ev, ERROR_TIMEDOUT);
 
  out:
     CTX_UNLOCK;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 02cac7b..accbab8 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -175,7 +175,8 @@ struct libxl__ev_fd {
 
 typedef struct libxl__ev_time libxl__ev_time;
 typedef void libxl__ev_time_callback(libxl__egc *egc, libxl__ev_time *ev,
-                                     const struct timeval *requested_abs);
+                                     const struct timeval *requested_abs,
+                                     int rc); /* TIMEDOUT or CANCELLED */
 struct libxl__ev_time {
     /* caller should include this in their own struct */
     /* read-only for caller, who may read only when registered: */
@@ -1108,13 +1109,13 @@ typedef struct libxl__xswait_state libxl__xswait_state;
  *     Otherwise, xswait will continue waiting and watching and
  *     will call you back later.
  *
- * rc==ERROR_TIMEDOUT
+ * rc==ERROR_TIMEDOUT, rc==ERROR_CANCELLED
  *
  *     The specified timeout was reached.
  *     This has NOT been logged (except to the debug log).
  *     xswait will not continue (but calling libxl__xswait_stop is OK).
  *
- * rc!=0, !=ERROR_TIMEDOUT
+ * rc!=0, !=ERROR_TIMEDOUT, !=ERROR_CANCELLED
  *
  *     Some other error occurred.
  *     This HAS been logged.
@@ -1154,8 +1155,9 @@ int libxl__xswait_start(libxl__gc*, libxl__xswait_state*);
 typedef struct libxl__ev_devstate libxl__ev_devstate;
 typedef void libxl__ev_devstate_callback(libxl__egc *egc, libxl__ev_devstate*,
                                          int rc);
-  /* rc will be 0, ERROR_TIMEDOUT, ERROR_INVAL (meaning path was removed),
-   * or ERROR_FAIL if other stuff went wrong (in which latter case, logged) */
+  /* rc will be 0, ERROR_TIMEDOUT, ERROR_CANCELLED, ERROR_INVAL
+   * (meaning path was removed), or ERROR_FAIL if other stuff went
+   * wrong (in which latter case, logged) */
 
 struct libxl__ev_devstate {
     /* read-only for caller, who may read only when waiting: */
diff --git a/tools/libxl/libxl_test_timedereg.c b/tools/libxl/libxl_test_timedereg.c
index e2cc27d..c464663 100644
--- a/tools/libxl/libxl_test_timedereg.c
+++ b/tools/libxl/libxl_test_timedereg.c
@@ -28,7 +28,7 @@ static libxl__ao *tao;
 static int seq;
 
 static void occurs(libxl__egc *egc, libxl__ev_time *ev,
-                   const struct timeval *requested_abs);
+                   const struct timeval *requested_abs, int rc);
 
 static void regs(libxl__ao *ao, int j)
 {
@@ -59,13 +59,15 @@ int libxl_test_timedereg(libxl_ctx *ctx, libxl_asyncop_how *ao_how)
 }
 
 static void occurs(libxl__egc *egc, libxl__ev_time *ev,
-                   const struct timeval *requested_abs)
+                   const struct timeval *requested_abs, int rc)
 {
     EGC_GC;
     int i;
 
     int off = ev - &et[0][0];
-    LOG(DEBUG,"occurs[%d][%d] seq=%d", off/NTIMES, off%NTIMES, seq);
+    LOG(DEBUG,"occurs[%d][%d] seq=%d rc=%d", off/NTIMES, off%NTIMES, seq, rc);
+
+    assert(!rc);
 
     switch (seq) {
     case 0:
-- 
1.7.10.4

  parent reply	other threads:[~2015-02-10 20:09 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-02-10 20:09 [RFC PATCH v2 00/29] libxl: Cancelling asynchronous operations Ian Jackson
2015-02-10 20:09 ` [PATCH 01/29] libxl: Further fix exit paths from libxl_device_events_handler Ian Jackson
2015-02-18 16:23   ` Roger Pau Monné
2015-03-24 10:49     ` Ian Campbell
2015-02-10 20:09 ` [PATCH 02/29] libxl: Comment cleanups Ian Jackson
2015-02-11  1:46   ` Hongyang Yang
2015-02-11 12:05     ` Ian Jackson
2015-03-30  9:08     ` Ian Campbell
2015-03-24 10:50   ` Ian Campbell
2015-02-10 20:09 ` [PATCH 03/29] libxl: suspend: switch_logdirty_done takes rc Ian Jackson
2015-03-24 10:53   ` Ian Campbell
2015-03-31 18:02     ` Ian Jackson
2015-02-10 20:09 ` [PATCH 04/29] libxl: suspend: common suspend callbacks take rc Ian Jackson
2015-03-24 10:55   ` Ian Campbell
2015-03-31 18:03     ` Ian Jackson
2015-02-10 20:09 ` [PATCH 05/29] libxl: suspend: Return correct error from callbacks Ian Jackson
2015-03-24 10:58   ` Ian Campbell
2015-02-10 20:09 ` [PATCH 06/29] libxl: Use libxl__xswait* in libxl__ao_device Ian Jackson
2015-03-24 11:04   ` Ian Campbell
2015-03-31 18:06     ` Ian Jackson
2015-04-01  9:25       ` Ian Campbell
2015-02-10 20:09 ` [PATCH 07/29] libxl: xswait/devstate: Move xswait to before devstate Ian Jackson
2015-03-24 11:05   ` Ian Campbell
2015-02-10 20:09 ` [PATCH 08/29] libxl: devstate: Use libxl__xswait* Ian Jackson
2015-03-24 11:07   ` Ian Campbell
2015-02-10 20:09 ` [PATCH 09/29] libxl: New error codes CANCELLED etc Ian Jackson
2015-03-24 11:08   ` Ian Campbell
2015-02-10 20:09 ` [PATCH 10/29] libxl: events: Make timeout and async exec setup take an ao, not a gc Ian Jackson
2015-02-11  1:04   ` Wen Congyang
2015-02-11 12:04     ` Ian Jackson
2015-03-31 18:09     ` Ian Jackson
2015-03-24 11:09   ` Ian Campbell
2015-02-10 20:09 ` [PATCH 11/29] libxl: events: Make libxl__async_exec_* pass caller an rc Ian Jackson
2015-03-24 11:20   ` Ian Campbell
2015-03-31 18:12     ` Ian Jackson
2015-04-01  9:29       ` Ian Campbell
2015-02-10 20:09 ` Ian Jackson [this message]
2015-03-24 11:22   ` [PATCH 12/29] libxl: events: Permit timeouts to signal cancellation Ian Campbell
2015-02-10 20:10 ` [PATCH 13/29] libxl: domain create: Do not destroy on cancellation Ian Jackson
2015-03-24 11:24   ` Ian Campbell
2015-03-31 18:14     ` Ian Jackson
2015-02-10 20:10 ` [PATCH 14/29] libxl: ao: Record ultimate parent of a nested ao Ian Jackson
2015-03-24 11:26   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 15/29] libxl: ao: Count the nested progeny of an ao Ian Jackson
2015-03-24 11:27   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 16/29] libxl: ao: Provide manip_refcnt Ian Jackson
2015-03-24 11:32   ` Ian Campbell
2015-03-31 18:23     ` Ian Jackson
2015-04-01  9:34       ` Ian Campbell
2015-02-10 20:10 ` [PATCH 17/29] libxl: cancellation: Provide public ao cancellation API Ian Jackson
2015-03-24 11:45   ` Ian Campbell
2015-03-31 18:26     ` Ian Jackson
2015-03-24 11:48   ` Ian Campbell
2015-03-31 18:33     ` Ian Jackson
2015-04-01  9:38       ` Ian Campbell
2015-02-10 20:10 ` [PATCH 18/29] libxl: cancellation: Provide explicit internal cancel check API Ian Jackson
2015-03-24 11:45   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 19/29] libxl: cancellation: Make timeouts cancellable Ian Jackson
2015-03-24 11:50   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 20/29] libxl: cancellation: Note that driver domain task cannot be usefully cancelled Ian Jackson
2015-02-18 16:24   ` Roger Pau Monné
2015-03-24 11:51   ` Ian Campbell
2015-03-31 18:37     ` Ian Jackson
2015-02-10 20:10 ` [PATCH 21/29] libxl: cancellation: Make spawns cancellable Ian Jackson
2015-03-24 11:53   ` Ian Campbell
2015-03-31 18:45     ` Ian Jackson
2015-04-01  9:40       ` Ian Campbell
2015-02-10 20:10 ` [PATCH 22/29] libxl: Introduce DOMAIN_DESTROYED error code Ian Jackson
2015-03-24 11:56   ` Ian Campbell
2015-03-31 18:47     ` Ian Jackson
2015-04-01  9:41       ` Ian Campbell
2015-02-10 20:10 ` [PATCH 23/29] libxl: cancellation: Support cancellation where we spot domain death Ian Jackson
2015-03-24 11:58   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 24/29] libxl: Introduce FILLZERO Ian Jackson
2015-03-24 12:03   ` Ian Campbell
2015-03-31 18:51     ` Ian Jackson
2015-04-01  9:42       ` Ian Campbell
2015-02-10 20:10 ` [PATCH 25/29] libxl: cancellation: Preparations for save/restore cancellation Ian Jackson
2015-03-24 12:04   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 26/29] libxl: cancellation: Handle SIGTERM in save/restore helper Ian Jackson
2015-03-24 12:07   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 27/29] libxl: cancellation: Cancel libxc save/restore Ian Jackson
2015-03-24 12:08   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 28/29] libxl: ao: datacopier callback gets an rc Ian Jackson
2015-03-24 12:10   ` Ian Campbell
2015-02-10 20:10 ` [PATCH 29/29] libxl: cancellation: Make datacopiers cancellable Ian Jackson
2015-03-24 12:11   ` Ian Campbell
2015-02-10 20:13 ` [RFC PATCH v2 00/29] libxl: Cancelling asynchronous operations Ian Jackson
2015-02-18 16:10 ` Euan Harris
2015-02-18 16:12   ` Ian Jackson
2015-04-07 17:08   ` Euan Harris
2015-04-07 17:19     ` Ian Jackson
2015-04-09 16:44       ` Euan Harris
2015-04-09 16:50         ` Ian Jackson
2015-04-14  9:43       ` Euan Harris
2015-03-03 12:08 ` Ian Campbell
2015-03-20 10:39   ` Euan Harris
2015-04-07 17:22   ` 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=1423599016-32639-13-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=euan.harris@citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.