diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-10-06 16:07:52 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2005-10-06 16:07:52 +0100 |
commit | c804adf4b64a5755c885b681c32591d2e67aa636 (patch) | |
tree | 618b3e8823bd2cbbba9091988dab2c4ab102cf7c /tools/xenstore/xenstored_domain.c | |
parent | 0c6f366280979dae46309b894d21b2c99fa5e816 (diff) | |
download | xen-c804adf4b64a5755c885b681c32591d2e67aa636.tar.gz xen-c804adf4b64a5755c885b681c32591d2e67aa636.tar.bz2 xen-c804adf4b64a5755c885b681c32591d2e67aa636.zip |
Change how event channels are allocated and used by the control
tools. /dev/xen/evtchn is now used by daemons to connect to
remote domains: the advantage is that the local ports are garbage
collected automatically if the daemon dies. xen no longer
constructs end-to-end event-channel port pairs -- it allocates an
unbound port in new domU and writes that port to xenstore. It is
then picked up by teh appropriate daemon which does interdomain bind
via /dev/xen/evtchn.
Signed-off-by: Keir Fraser <keir@xensource.com>
Diffstat (limited to 'tools/xenstore/xenstored_domain.c')
-rw-r--r-- | tools/xenstore/xenstored_domain.c | 36 |
1 files changed, 23 insertions, 13 deletions
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 9ac1b28eef..69ace083d9 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -36,6 +36,8 @@ #include "xenstored_watch.h" #include "xenstored_test.h" +#include <xen/linux/evtchn.h> + static int *xc_handle; static int eventchn_fd; static int virq_port; @@ -77,9 +79,6 @@ struct ringbuf_head char buf[0]; } __attribute__((packed)); -#define EVENTCHN_BIND _IO('E', 2) -#define EVENTCHN_UNBIND _IO('E', 3) - /* FIXME: Mark connection as broken (close it?) when this happens. */ static bool check_buffer(const struct ringbuf_head *h) { @@ -207,14 +206,17 @@ static int readchn(struct connection *conn, void *data, unsigned int len) static int destroy_domain(void *_domain) { struct domain *domain = _domain; + struct ioctl_evtchn_unbind unbind; list_del(&domain->list); - if (domain->port && - (ioctl(eventchn_fd, EVENTCHN_UNBIND, domain->port) != 0)) - eprintf("> Unbinding port %i failed!\n", domain->port); + if (domain->port) { + unbind.port = domain->port; + if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1) + eprintf("> Unbinding port %i failed!\n", domain->port); + } - if(domain->page) + if (domain->page) munmap(domain->page, getpagesize()); return 0; @@ -278,6 +280,9 @@ static struct domain *new_domain(void *context, domid_t domid, const char *path) { struct domain *domain; + struct ioctl_evtchn_bind_interdomain bind; + int rc; + domain = talloc(context, struct domain); domain->port = 0; domain->shutdown = 0; @@ -298,10 +303,13 @@ static struct domain *new_domain(void *context, domid_t domid, domain->output = domain->page + getpagesize()/2; /* Tell kernel we're interested in this event. */ - if (ioctl(eventchn_fd, EVENTCHN_BIND, port) != 0) + bind.remote_domain = domid; + bind.remote_port = port; + rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + if (rc == -1) return NULL; - domain->port = port; + domain->port = rc; domain->conn = new_connection(writechn, readchn); domain->conn->domain = domain; return domain; @@ -445,6 +453,8 @@ void restore_existing_connections(void) int domain_init(void) { struct stat st; + struct ioctl_evtchn_bind_virq bind; + int rc; /* The size of the ringbuffer: half a page minus head structure. */ ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head); @@ -482,11 +492,11 @@ int domain_init(void) if (eventchn_fd < 0) barf_perror("Failed to open evtchn device"); - if (xc_evtchn_bind_virq(*xc_handle, VIRQ_DOM_EXC, &virq_port)) - barf_perror("Failed to bind to domain exception virq"); - - if (ioctl(eventchn_fd, EVENTCHN_BIND, virq_port) != 0) + bind.virq = VIRQ_DOM_EXC; + rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); + if (rc == -1) barf_perror("Failed to bind to domain exception virq port"); + virq_port = rc; return eventchn_fd; } |