[PATCH 7/8] tools/xenstored: expand special watch handling with depth feature

Juergen Gross posted 8 patches 1 week, 3 days ago
[PATCH 7/8] tools/xenstored: expand special watch handling with depth feature
Posted by Juergen Gross 1 week, 3 days ago
With XENSTORE_SERVER_FEATURE_WATCHDEPTH available, special watch
handling needs to be extended:

- when a special watch is set with depth = 1, the domid is added to
  the watch event

- it is possible to watch for @releaseDomain/<domid>

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xenstored/domain.c | 37 ++++++++++++++++++++++++++++---------
 1 file changed, 28 insertions(+), 9 deletions(-)

diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 866c0aa908..1fe8abbea9 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -613,7 +613,12 @@ static void domain_tree_remove(struct domain *domain)
 	walk_node_tree(domain, NULL, "@introduceDomain", &walkfuncs, domain);
 }
 
-static void fire_special_watches(const char *name)
+#define WATCH_NODOM	1	/* Fire watches without <domid> extension. */
+#define WATCH_DOM	2	/* Fire watches with <domid> extension. */
+#define WATCH_BOTH	(WATCH_NODOM | WATCH_DOM)
+
+static void fire_special_watches(const char *name, unsigned int domid,
+				 unsigned int watchdom_flag)
 {
 	void *ctx = talloc_new(NULL);
 	const struct node *node;
@@ -623,9 +628,19 @@ static void fire_special_watches(const char *name)
 
 	node = read_node_const(NULL, ctx, name);
 
-	if (node)
-		fire_watches(NULL, ctx, name, node, true, NULL);
-	else
+	if (node) {
+		if (watchdom_flag & WATCH_NODOM)
+			fire_watches(NULL, ctx, name, node, MATCH_NODEPTH,
+				     NULL);
+		if (watchdom_flag & WATCH_DOM) {
+			char name_dom[24]; /* max. "@introduceDomain/domid" */
+
+			snprintf(name_dom, sizeof(name_dom),
+				 "%s/%u", name, domid);
+			fire_watches(NULL, ctx, name_dom, node, MATCH_DEPTH,
+				     NULL);
+		}
+	} else
 		log("special node %s not found\n", name);
 
 	talloc_free(ctx);
@@ -650,7 +665,7 @@ static int destroy_domain(void *_domain)
 	if (domain->interface)
 		unmap_interface(domain->domid, domain->interface);
 
-	fire_special_watches("@releaseDomain");
+	fire_special_watches("@releaseDomain", domain->domid, WATCH_BOTH);
 
 	wrl_domain_destroy(domain);
 
@@ -678,10 +693,13 @@ static int do_check_domain(struct domain *domain, bool *notify,
 		if ((state & XENMANAGE_GETDOMSTATE_STATE_SHUTDOWN)
 		    && !domain->shutdown) {
 			domain->shutdown = true;
+			fire_special_watches("@releaseDomain", domain->domid,
+					     WATCH_DOM);
 			*notify = true;
 		}
-		if (!(state & XENMANAGE_GETDOMSTATE_STATE_DEAD))
+		if (!(state & XENMANAGE_GETDOMSTATE_STATE_DEAD)) {
 			return 0;
+		}
 	}
 	if (domain->conn) {
 		/* domain is a talloc child of domain->conn. */
@@ -720,7 +738,7 @@ void check_domains(void)
 		;
 
 	if (notify)
-		fire_special_watches("@releaseDomain");
+		fire_special_watches("@releaseDomain", 0, WATCH_NODOM);
 }
 
 static struct domain *find_domain_struct(unsigned int domid)
@@ -744,7 +762,7 @@ static void do_check_domains(void)
 	}
 
 	if (notify)
-		fire_special_watches("@releaseDomain");
+		fire_special_watches("@releaseDomain", 0, WATCH_NODOM);
 }
 
 /* We scan all domains rather than use the information given here. */
@@ -1097,7 +1115,8 @@ static struct domain *introduce_domain(const void *ctx,
 		talloc_steal(domain->conn, domain);
 
 		if (!is_priv_domain && !restore)
-			fire_special_watches("@introduceDomain");
+			fire_special_watches("@introduceDomain", domid,
+					     WATCH_BOTH);
 	} else {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
-- 
2.53.0