fire_special_watches() can only be called after setup_structure() has
been called.  If it is called before setup_structure(), the hashtable
search will segfault as the nodes hashtable has not been allocated.

Normally, dom0 is setup up first and setup_structure() runs before any
other domain.

If we iterate xenmanage_poll_changed_domain() to discover domains, there
is no guarantee the local domain running xenstored will be created
first.  Suppress firing special watches until the hashtable has been
allocated.

Signed-off-by: Jason Andryuk <jason.andr...@amd.com>
---
With a known domid, xenstored could construct that first and the iterate
skipping itself.
---
 tools/xenstored/core.c   | 5 +++++
 tools/xenstored/core.h   | 1 +
 tools/xenstored/domain.c | 6 +++++-
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 37e4dd5a5b..550e879a00 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2321,6 +2321,11 @@ void setup_structure(bool live_update)
        }
 }
 
+bool setup_structure_complete(void)
+{
+       return nodes != NULL;
+}
+
 int remember_string(struct hashtable *hash, const char *str)
 {
        char *k = talloc_strdup(NULL, str);
diff --git a/tools/xenstored/core.h b/tools/xenstored/core.h
index 632886cecf..3fe80f7c66 100644
--- a/tools/xenstored/core.h
+++ b/tools/xenstored/core.h
@@ -301,6 +301,7 @@ const struct node *read_node_const(struct connection *conn, 
const void *ctx,
 int rm_node(struct connection *conn, const void *ctx, const char *name);
 
 void setup_structure(bool live_update);
+bool setup_structure_complete(void);
 struct connection *new_connection(const struct interface_funcs *funcs);
 struct connection *add_socket_connection(int fd);
 struct connection *get_connection_by_id(unsigned int conn_id);
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index d2b6fffa62..5443b4e608 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -579,9 +579,13 @@ static void domain_tree_remove(struct domain *domain)
 
 static void fire_special_watches(const char *name)
 {
-       void *ctx = talloc_new(NULL);
+       void *ctx;
        const struct node *node;
 
+       if (!setup_structure_complete())
+               return;
+
+       ctx = talloc_new(NULL);
        if (!ctx)
                return;
 
-- 
2.50.0


Reply via email to