[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v5 07/11] tools/xenstored: Auto-introduce domains


  • To: <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jason Andryuk <jason.andryuk@xxxxxxx>
  • Date: Fri, 25 Jul 2025 19:58:54 -0400
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=lists.xenproject.org smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=bu6qy110dZsnS4i5GXYzfa2hnOIRH0xP9Njjyy2eshE=; b=Mv6Pf0g13VUCq0of8tVQlAO94C6eNeQUpDLNwckpVWGNAv2nPmpM1NaD2+drYvXBbVhAAz5T3wY1O0j755d4JaQRdenIvsKT2oKCZbrcTdBAaDFfWHW0xXYCBC8iO9xGHIcpOse0232acHuYeiBEhYnyVsh183YbyxkPiKdNEMwvOkAMu1Kd6ccnEHIy6EdSZ7f+xR0OVhp3eUVjVRSo1FOCvBaB2HNPsuBbjjaQPWMTozy/GtSUwjsX/K2cJktlGXki/GOuS/Ykx/KBJjClEEcJXFXpEEl79Lq2rIoNZxi5v+QJjvo0ovmbqi/Tw4tgOVquTITvM7y2QVkmIZ7R/A==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=w+gDYA7JrCwrAXH10ErsbD9ixPIhK/S9hSaJKUWApPHYeFuLYAqujcCvmyjdoTk/k/BscR1kausV6vJb1UPCHUdbg6PEplExJiX2853nFNCg/hsaSMJpEI6c+BmruO5vgDqksAIlho12vRleFFmsteyY55A5rvbCh/U15ctKVZ20tT72j+8ewkqRGhqqikzBUbaIn+K149HCbQw0JgJJ7eJXXOOsfXYFTQfJbASHufHR6W4mdM71Wpne1WkDz+tWiVZygZ8b7pqumiorFfq2m3J3y8Tk3QqaSW6mijp7myDv0W1S5uTkWYaUl1cJv7OLkUigY57ouql6FscIUKNHlg==
  • Cc: Jason Andryuk <jason.andryuk@xxxxxxx>, Juergen Gross <jgross@xxxxxxxx>, Julien Grall <julien@xxxxxxx>, Anthony PERARD <anthony.perard@xxxxxxxxxx>
  • Delivery-date: Fri, 25 Jul 2025 23:59:49 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

Replace dom0_init() with init_domains() which uses libxenmanage to
iterate through all existing domains, storing them in a list.  The xenstore
domain is introduced first, and then all the other domains are
introduced.  The xenstore domain needs to be introduced first to setup
structures needed for firing watches.

dom0_domid is updated with the xenstore domain, since it really
indicates the local domain.

priv_domid is set to the control domain.  This makes it limited to a
single domain.

These features let xenstore automatically connect any existing domains,
which means it doesn't need to be done manually from init-dom0less.

For a legacy dom0, the result should be unchanged.

For a late xenstore stubdom it should also be the same, but priv_domid
would be set automatically to control domain (which default to 0
normally).

Always signal the event channel for initial domains.  This gets dom0 (a
local xenstored domain) to connect.

Also always write XENSTORE_CONNECTED since we know we are connected at
this point.

To support ARM dom0less domains with xen,enhanced = "no-xenstore" a
failed introduce_domain() becomes non-fatal.  Normally,
HVM_PARAM_STORE_EVTCHN is used to identify .

priv_domid from the command line is used, or the first control domain is
used.

dom0_domid will set to the last xenstore found.  This will handle dom0
or dom0less, where only 1 xenstore domain can exist, or stubdom, where
dom0 and dom1 exist, and we want to take the stubdom.

Signed-off-by: Jason Andryuk <jason.andryuk@xxxxxxx>
---
v5:
Add init_domain() helper and call for dom0_domid first outside loop.
Fix HVM_PARAM_STORE_EVTCHN typo
Only take first priv_domid and respect command line setting
Take last dom0_domid
Set priv_domid & dom0_domid default values - bail if both unset
Use talloc_realloc
Remove domain_conn_reset()
---
 tools/xenstored/core.c   |   6 +--
 tools/xenstored/domain.c | 100 ++++++++++++++++++++++++++++++---------
 tools/xenstored/domain.h |   2 +-
 3 files changed, 82 insertions(+), 26 deletions(-)

diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c
index 37e4dd5a5b..dbf3548a8e 100644
--- a/tools/xenstored/core.c
+++ b/tools/xenstored/core.c
@@ -2564,9 +2564,9 @@ static struct option options[] = {
 #endif
        { NULL, 0, NULL, 0 } };
 
-int dom0_domid = 0;
+int dom0_domid = DOMID_INVALID;
 int dom0_event = 0;
-int priv_domid = 0;
+int priv_domid = DOMID_INVALID;
 domid_t stub_domid = DOMID_INVALID;
 
 static unsigned int get_optval_uint(const char *arg)
@@ -2757,7 +2757,7 @@ int main(int argc, char *argv[])
        /* Listen to hypervisor. */
        if (!live_update) {
                domain_init(-1);
-               dom0_init();
+               init_domains();
        }
 
        /* redirect to /dev/null now we're ready to accept connections */
diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index 71ab7aaad3..5e53fe8736 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1251,41 +1251,97 @@ const char *get_implicit_path(const struct connection 
*conn)
        return conn->domain->path;
 }
 
-void dom0_init(void)
+static bool init_domain(unsigned int domid)
 {
        evtchn_port_t port;
-       struct domain *dom0;
+       struct domain *domain;
 
-       port = get_domain_evtchn(xenbus_master_domid());
+       port = get_domain_evtchn(domid);
        if (port == -1)
-               barf_perror("Failed to initialize dom0 port");
+               barf_perror("Failed to initialize dom%u port", domid);
 
-       dom0 = introduce_domain(NULL, xenbus_master_domid(), port, false);
-       if (!dom0)
-               barf_perror("Failed to initialize dom0");
+       domain = introduce_domain(NULL, domid, port, false);
+       if (!domain) {
+               xprintf("Could not initialize dom%u", domid);
+               return false;
+       }
 
-       xenevtchn_notify(xce_handle, dom0->port);
-}
+       if (domain->interface)
+               domain->interface->connection = XENSTORE_CONNECTED;
 
-void stubdom_init(void)
+       xenevtchn_notify(xce_handle, domain->port);
+
+       return true;
+}
+void init_domains(void)
 {
-#ifdef __MINIOS__
-       struct domain *stubdom;
-       evtchn_port_t port;
+       unsigned int *domids = NULL;
+       unsigned int nr_domids = 0;
+       unsigned int domid;
+       unsigned int state;
+       unsigned int caps;
+       uint64_t unique_id;
+       int introduce_count = 0;
 
-       if (stub_domid < 0)
-               return;
+       while (!xenmanage_poll_changed_domain(xm_handle, &domid, &state, &caps,
+                                             &unique_id)) {
+               nr_domids++;
+               domids = talloc_realloc(NULL, domids, unsigned int, nr_domids);
+               if (!domids)
+                       barf_perror("Failed to reallocate domids");
+
+               domids[nr_domids - 1] = domid;
+
+               if (caps & XENMANAGE_GETDOMSTATE_CAP_CONTROL) {
+                       /*
+                        * Only update with first found - otherwise use command
+                        * line.
+                        */
+                       if (priv_domid == DOMID_INVALID)
+                               priv_domid = domid;
+               }
 
-       port = get_domain_evtchn(stub_domid);
-       if (port == -1)
-               barf_perror("Failed to initialize stubdom port");
+               if (caps & XENMANAGE_GETDOMSTATE_CAP_XENSTORE) {
+                       /*
+                        * Update with last found.  dom0 or dom0less will only
+                        * have 1 domain.  stubdom there will be dom0 and dom1,
+                        * so this will take the second for stubdom.
+                        */
+                       dom0_domid = domid;
+               }
+       }
+
+       if (dom0_domid == DOMID_INVALID)
+               dom0_domid = priv_domid;
 
-       stubdom = introduce_domain(NULL, stub_domid, port, false);
-       if (!stubdom)
-               barf_perror("Failed to initialize stubdom");
+       if (dom0_domid == DOMID_INVALID)
+               barf("Could not determine xenstore domid\n");
 
-       xenevtchn_notify(xce_handle, stubdom->port);
+       /*
+        * Local domid must be first to setup structures for firing the special
+        * watches.
+        */
+       if (init_domain(dom0_domid))
+               introduce_count++;
+
+       for (unsigned int i = 0; i < nr_domids; i++) {
+               domid = domids[i];
+               if (domid == dom0_domid)
+                       continue;
 
+               if (init_domain(domid))
+                       introduce_count++;
+       }
+
+       talloc_free(domids);
+
+       if (introduce_count == 0)
+               barf("Did not initialize any domains");
+}
+
+void stubdom_init(void)
+{
+#ifdef __MINIOS__
        mount_9pfs();
 #endif
 }
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index 844ac11510..6a78f06935 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -84,7 +84,7 @@ int do_reset_watches(const void *ctx, struct connection *conn,
 
 void domain_early_init(void);
 void domain_init(int evtfd);
-void dom0_init(void);
+void init_domains(void);
 void stubdom_init(void);
 void domain_deinit(void);
 void ignore_connection(struct connection *conn, unsigned int err);
-- 
2.50.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.