Can you give the following patch a try? This applies to 4.8.
Not sure if there is a better way to fix it though. Ian and Roger?
---8<---
From 8542a1d4f537cb5719ebd245872d0256df816670 Mon Sep 17 00:00:00 2001
From: Wei Liu <wei.liu2@xxxxxxxxxx>
Date: Wed, 3 May 2017 17:55:42 +0100
Subject: [PATCH] libxl: fix backend_watch_callback
That function needs to cope with spurious events. The original "skip"
path blindly freed dguest even when it needed to stay in ddomain list.
Free dguest iff it is newly added to the list. That way we don't free
the one that should stay on the list and we don't unnecessarily add a
stale dguest entry to ddomain list.
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx>
---
tools/libxl/libxl.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index acf714e1f9..ed542c0977 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -3842,6 +3842,7 @@ static void backend_watch_callback(libxl__egc *egc,
libxl__ev_xswatch *watch,
libxl__device *dev = NULL;
libxl__ddomain_device *ddev = NULL;
libxl__ddomain_guest *dguest = NULL;
+ bool new_dguest = false;
bool free_ao = false;
/* Check if event_path ends with "state" or "online" and truncate it. */
@@ -3888,6 +3889,7 @@ static void backend_watch_callback(libxl__egc *egc,
libxl__ev_xswatch *watch,
LIBXL_SLIST_INSERT_HEAD(&ddomain->guests, dguest, next);
LOG(DEBUG, "added domain %u to the list of active guests",
dguest->domid);
+ new_dguest = true;
}
ddev = search_for_device(dguest, dev);
if (ddev == NULL && state == XenbusStateClosed) {
@@ -3947,7 +3949,13 @@ skip:
libxl__nested_ao_free(nested_ao);
free(dev);
free(ddev);
- free(dguest);
+ if (new_dguest) {
+ LIBXL_SLIST_REMOVE(&ddomain->guests, dguest, libxl__ddomain_guest,
+ next);
+ LOG(DEBUG, "removed domain %u from the list of active guests",
+ dguest->domid);
+ free(dguest);
+ }
return;
}