-
-
Notifications
You must be signed in to change notification settings - Fork 52
/
0614-libxl-Fix-race-condition-in-domain-suspension.patch
75 lines (65 loc) · 2.95 KB
/
0614-libxl-Fix-race-condition-in-domain-suspension.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
From 8d68f1f26f4dcea3957d66470adc5cf1cd3f2d79 Mon Sep 17 00:00:00 2001
From: Demi Marie Obenour <[email protected]>
Date: Thu, 22 Sep 2022 12:27:32 -0400
Subject: [PATCH] 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 <[email protected]>
---
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 1c7ceee60dbf..1ee3e5d88af8 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);
@@ -408,7 +409,7 @@ static void suspend_common_wait_guest_watch(libxl__egc *egc,
suspend_common_wait_guest_check(egc, dsps);
}
-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);
@@ -427,7 +428,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;
@@ -438,11 +439,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,
@@ -450,6 +455,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;
--
2.44.0