aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenstore/xenstored_domain.c
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-10-06 16:07:52 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2005-10-06 16:07:52 +0100
commitc804adf4b64a5755c885b681c32591d2e67aa636 (patch)
tree618b3e8823bd2cbbba9091988dab2c4ab102cf7c /tools/xenstore/xenstored_domain.c
parent0c6f366280979dae46309b894d21b2c99fa5e816 (diff)
downloadxen-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.c36
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;
}