mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
tools/xenstored: Auto-introduce domains
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@amd.com> Reviewed-by: Juergen Gross <jgross@suse.com>
This commit is contained in:
1 parent
cec885de7f
commit
e5b0a94055
3 files changed
+84
-30
No files matched your search
@@ -2567,9 +2567,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)
|
||||
@@ -2760,7 +2760,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 */
|
||||
|
||||
+80
-26
@@ -1325,43 +1325,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;
|
||||
|
||||
xenevtchn_notify(xce_handle, domain->port);
|
||||
|
||||
return true;
|
||||
}
|
||||
void init_domains(void)
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (dom0_domid == DOMID_INVALID)
|
||||
barf("Could not determine xenstore domid\n");
|
||||
|
||||
/*
|
||||
* 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(bool live_update)
|
||||
{
|
||||
#ifdef __MINIOS__
|
||||
struct domain *stubdom;
|
||||
evtchn_port_t port;
|
||||
|
||||
if (stub_domid < 0)
|
||||
return;
|
||||
|
||||
if (!live_update) {
|
||||
port = get_domain_evtchn(stub_domid);
|
||||
if (port == -1)
|
||||
barf_perror("Failed to initialize stubdom port");
|
||||
|
||||
stubdom = introduce_domain(NULL, stub_domid, port, false);
|
||||
if (!stubdom)
|
||||
barf_perror("Failed to initialize stubdom");
|
||||
|
||||
xenevtchn_notify(xce_handle, stubdom->port);
|
||||
}
|
||||
|
||||
mount_9pfs(live_update);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ int do_set_feature(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(bool live_update);
|
||||
void domain_deinit(void);
|
||||
void ignore_connection(struct connection *conn, unsigned int err);
|
||||
|
||||