The XS_INTRODUCE command has two parameters: the mfn (or better: gfn)
of the domain's xenstore ring page and the event channel of the
domain for communicating with Xenstore.
The gfn is not really needed. It is stored in the per-domain struct
in xenstored and in case of another XS_INTRODUCE for the domain it
is tested to match the original value. If it doesn't match the
command is aborted via EINVAL.
Today there aren't multiple XS_INTRODUCE requests for the same domain
issued, so the mfn/gfn can just be ignored and multiple XS_INTRODUCE
commands can be rejected without testing the mfn/gfn.
Signed-off-by: Juergen Gross <jgross@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
V2:
- remove mfn from struct domain (Julien Grall)
- replace mfn by gfn in comments (Julien Grall)
---
tools/xenstore/xenstored_domain.c | 53 +++++++++++++++------------------------
1 file changed, 20 insertions(+), 33 deletions(-)
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 5858185211..1ca11e5e9e 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -55,10 +55,6 @@ struct domain
repeated domain introductions. */
evtchn_port_t remote_port;
- /* The mfn associated with the event channel, used only to validate
- repeated domain introductions. */
- unsigned long mfn;
-
/* Domain path in store. */
char *path;
@@ -363,13 +359,12 @@ static void domain_conn_reset(struct domain *domain)
domain->interface->rsp_cons = domain->interface->rsp_prod = 0;
}
-/* domid, mfn, evtchn, path */
+/* domid, gfn, evtchn, path */
int do_introduce(struct connection *conn, struct buffered_data *in)
{
struct domain *domain;
char *vec[3];
unsigned int domid;
- unsigned long mfn;
evtchn_port_t port;
int rc;
struct xenstore_domain_interface *interface;
@@ -381,7 +376,7 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
return EACCES;
domid = atoi(vec[0]);
- mfn = atol(vec[1]);
+ /* Ignore the gfn, we don't need it. */
port = atoi(vec[2]);
/* Sanity check args. */
@@ -390,34 +385,26 @@ int do_introduce(struct connection *conn, struct buffered_data *in)
domain = find_domain_by_domid(domid);
- if (domain == NULL) {
- interface = map_interface(domid);
- if (!interface)
- return errno;
- /* Hang domain off "in" until we're finished. */
- domain = new_domain(in, domid, port);
- if (!domain) {
- rc = errno;
- unmap_interface(interface);
- return rc;
- }
- domain->interface = interface;
- domain->mfn = mfn;
-
- /* Now domain belongs to its connection. */
- talloc_steal(domain->conn, domain);
-
- fire_watches(NULL, in, "@introduceDomain", false);
- } else if ((domain->mfn == mfn) && (domain->conn != conn)) {
- /* Use XS_INTRODUCE for recreating the xenbus event-channel. */
- if (domain->port)
- xenevtchn_unbind(xce_handle, domain->port);
- rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
- domain->port = (rc == -1) ? 0 : rc;
- domain->remote_port = port;
- } else
+ if (domain)
return EINVAL;
+ interface = map_interface(domid);
+ if (!interface)
+ return errno;
+ /* Hang domain off "in" until we're finished. */
+ domain = new_domain(in, domid, port);
+ if (!domain) {
+ rc = errno;
+ unmap_interface(interface);
+ return rc;
+ }
+ domain->interface = interface;
+
+ /* Now domain belongs to its connection. */
+ talloc_steal(domain->conn, domain);
+
+ fire_watches(NULL, in, "@introduceDomain", false);
+
domain_conn_reset(domain);
send_ack(conn, XS_INTRODUCE);
--
2.16.4