[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 4/5] libxl: Fix race condition in domain suspension



Check if the domain has suspended after setting the XenStore watch to
prevent race conditions.  Also check if a guest has suspended when the
timeout handler is called, and do not consider this to be a timeout.

Signed-off-by: Demi Marie Obenour <demi@xxxxxxxxxxxxxxxxxxxxxx>
---
 tools/libs/light/libxl_dom_suspend.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/tools/libs/light/libxl_dom_suspend.c 
b/tools/libs/light/libxl_dom_suspend.c
index 
d276b3c17e70105c19c82e9da570a24297d039f5..42c0e0a152e04fab34152d711564ffe148f24a4c
 100644
--- a/tools/libs/light/libxl_dom_suspend.c
+++ b/tools/libs/light/libxl_dom_suspend.c
@@ -209,7 +209,8 @@ static void 
domain_suspend_common_wait_guest_evtchn(libxl__egc *egc,
         libxl__ev_evtchn *evev);
 static void suspend_common_wait_guest_watch(libxl__egc *egc,
       libxl__ev_xswatch *xsw, const char *watch_path, const char *event_path);
-static void suspend_common_wait_guest_check(libxl__egc *egc,
+/* Returns true if a callback was called, false otherwise */
+static bool suspend_common_wait_guest_check(libxl__egc *egc,
         libxl__domain_suspend_state *dsps);
 static void suspend_common_wait_guest_timeout(libxl__egc *egc,
       libxl__ev_time *ev, const struct timeval *requested_abs, int rc);
@@ -426,7 +427,7 @@ static int check_guest_status(libxl__gc *gc, const uint32_t 
domid,
     return 0;
 }
 
-static void suspend_common_wait_guest_check(libxl__egc *egc,
+static bool suspend_common_wait_guest_check(libxl__egc *egc,
         libxl__domain_suspend_state *dsps)
 {
     STATE_AO_GC(dsps->ao);
@@ -441,7 +442,7 @@ static void suspend_common_wait_guest_check(libxl__egc *egc,
 
     if (!(info.flags & XEN_DOMINF_shutdown))
         /* keep waiting */
-        return;
+        return false;
 
     shutdown_reason = (info.flags >> XEN_DOMINF_shutdownshift)
         & XEN_DOMINF_shutdownmask;
@@ -452,11 +453,15 @@ static void suspend_common_wait_guest_check(libxl__egc 
*egc,
     }
 
     LOGD(DEBUG, domid, "guest has suspended");
+    dsps->guest_responded = 1;
+    libxl__xswait_stop(gc, &dsps->pvcontrol);
     domain_suspend_common_guest_suspended(egc, dsps);
-    return;
+    return true;
 
  err:
+    libxl__xswait_stop(gc, &dsps->pvcontrol);
     domain_suspend_common_done(egc, dsps, ERROR_FAIL);
+    return true;
 }
 
 static void suspend_common_wait_guest_timeout(libxl__egc *egc,
@@ -464,6 +469,8 @@ static void suspend_common_wait_guest_timeout(libxl__egc 
*egc,
 {
     libxl__domain_suspend_state *dsps = CONTAINER_OF(ev, *dsps, guest_timeout);
     STATE_AO_GC(dsps->ao);
+    if (suspend_common_wait_guest_check(egc, dsps))
+        return;
     if (rc == ERROR_TIMEDOUT) {
         LOGD(ERROR, dsps->domid, "guest did not suspend, timed out");
         rc = ERROR_GUEST_TIMEDOUT;
-- 
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.