File libxl-restore-cleanup-left-xenstore-entries.patch of Package xen.1589
From 92f8d0e968f128445cb43569ecef0e131a8c077c Mon Sep 17 00:00:00 2001
From: Chunyan Liu <cyliu@suse.com>
Date: Tue, 18 Nov 2014 17:10:58 +0800
Subject: [PATCH] fix restore: xenstore entries left when restore failed
While running libvirt-tck domain/102-broken-save-restore.t
test (save domain, corrupt saved file by truncate the last 512k,
then restore), found that restore domain failed, but domain
related xenstore entries still exist in xenstore.
Add a patch to clear xenstore entries in this case.
Signed-off-by: Chunyan Liu <cyliu@suse.com>
---
tools/libxl/libxl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
Index: xen-4.4.3-testing/tools/libxl/libxl.c
===================================================================
--- xen-4.4.3-testing.orig/tools/libxl/libxl.c
+++ xen-4.4.3-testing/tools/libxl/libxl.c
@@ -1414,6 +1414,54 @@ static void devices_destroy_cb(libxl__eg
libxl__devices_remove_state *drs,
int rc);
+static void libxl_clear_xs_entry(libxl__gc *gc, uint32_t domid)
+{
+ const char *dom_path, *vm_path;
+ char *path;
+ unsigned int num_kinds, num_dev_xsentries;
+ char **kinds = NULL, **devs = NULL;
+ int i, j;
+
+ /* remove libxl path */
+ libxl__xs_rm_checked(gc, XBT_NULL, libxl__xs_libxl_path(gc, domid));
+
+ dom_path = libxl__xs_get_dompath(gc, domid);
+ if (!dom_path)
+ return;
+
+ /* remove backend entries */
+ path = GCSPRINTF("%s/device", dom_path);
+ kinds = libxl__xs_directory(gc, XBT_NULL, path, &num_kinds);
+ if (kinds && num_kinds) {
+ for (i = 0; i < num_kinds; i++) {
+ path = GCSPRINTF("%s/device/%s", dom_path, kinds[i]);
+ devs = libxl__xs_directory(gc, XBT_NULL, path, &num_dev_xsentries);
+ if (!devs)
+ continue;
+ for (j = 0; j < num_dev_xsentries; j++) {
+ path = GCSPRINTF("%s/device/%s/%s/backend",
+ dom_path, kinds[i], devs[j]);
+ path = libxl__xs_read(gc, XBT_NULL, path);
+ if (path)
+ libxl__xs_rm_checked(gc, XBT_NULL, path);
+ }
+ }
+ }
+
+ path = GCSPRINTF("%s/console/backend", dom_path);
+ path = libxl__xs_read(gc, XBT_NULL, path);
+ if (path)
+ libxl__xs_rm_checked(gc, XBT_NULL, path);
+
+ /* remove vm path */
+ vm_path = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/vm", dom_path));
+ if (vm_path)
+ libxl__xs_rm_checked(gc, XBT_NULL, vm_path);
+
+ /* remove dom path */
+ libxl__xs_rm_checked(gc, XBT_NULL, dom_path);
+}
+
void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
{
STATE_AO_GC(dis->ao);
@@ -1429,6 +1477,10 @@ void libxl__destroy_domid(libxl__egc *eg
break;
case ERROR_INVAL:
LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "non-existant domain %d", domid);
+ /* domain may not started successfully but some xenstore entries
+ * might be created already in earlier stage. We need to clear
+ * those entries. */
+ libxl_clear_xs_entry(gc, domid);
default:
goto out;
}