# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1312202176 -7200
# Node ID edb96c34f4a638e8ba97933b6bd76ff72836353e
# Parent 0f36c2eec2e1576b4db6538b5f22d625587c1a15
xenstored: allow guests to reintroduce themselves
During kexec all old watches have to be removed, otherwise the new
kernel will receive unexpected events. Allow a guest to introduce itself
and cleanup all of its watches.
Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
diff -r 0f36c2eec2e1 -r edb96c34f4a6 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -315,7 +315,7 @@ void do_introduce(struct connection *con
{
struct domain *domain;
char *vec[3];
- unsigned int domid;
+ unsigned int domid, target;
unsigned long mfn;
evtchn_port_t port;
int rc;
@@ -326,7 +326,7 @@ void do_introduce(struct connection *con
return;
}
- if (conn->id != 0 || !conn->can_write) {
+ if (!conn->can_write) {
send_error(conn, EACCES);
return;
}
@@ -340,19 +340,26 @@ void do_introduce(struct connection *con
send_error(conn, EINVAL);
return;
}
+ /* Allow guest to reset all watches */
+ if (domid != DOMID_SELF && conn->id != 0) {
+ send_error(conn, EACCES);
+ return;
+ }
- domain = find_domain_by_domid(domid);
+ target = domid == DOMID_SELF ? conn->id : domid;
+
+ domain = find_domain_by_domid(target);
if (domain == NULL) {
interface = xc_map_foreign_range(
- *xc_handle, domid,
+ *xc_handle, target,
getpagesize(), PROT_READ|PROT_WRITE, mfn);
if (!interface) {
send_error(conn, errno);
return;
}
/* Hang domain off "in" until we're finished. */
- domain = new_domain(in, domid, port);
+ domain = new_domain(in, target, port);
if (!domain) {
munmap(interface, getpagesize());
send_error(conn, errno);
@@ -365,11 +372,11 @@ void do_introduce(struct connection *con
talloc_steal(domain->conn, domain);
fire_watches(NULL, "@introduceDomain", false);
- } else if ((domain->mfn == mfn) && (domain->conn != conn)) {
+ } else if ((domain->mfn == mfn) && ((domain->conn != conn) || domid ==
DOMID_SELF)) {
/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
if (domain->port)
xc_evtchn_unbind(xce_handle, domain->port);
- rc = xc_evtchn_bind_interdomain(xce_handle, domid, port);
+ rc = xc_evtchn_bind_interdomain(xce_handle, target, port);
domain->port = (rc == -1) ? 0 : rc;
domain->remote_port = port;
} else {
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|