aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-06-15 13:11:31 +0100
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>2006-06-15 13:11:31 +0100
commit76f880fe7dc70b529cca572dcb0ae9815a76afff (patch)
tree36052febe9557e84b01d422b28d4fb96bef0eaec
parenta8bdc8130ef1242b2db60cad430ad1ba336cf102 (diff)
downloadxen-76f880fe7dc70b529cca572dcb0ae9815a76afff.tar.gz
xen-76f880fe7dc70b529cca572dcb0ae9815a76afff.tar.bz2
xen-76f880fe7dc70b529cca572dcb0ae9815a76afff.zip
[TOOLS] Introduce xc_evtchn_*() interface for interacting with /dev/xen/evtchn.
No longer open the device as non-blocking: all reads immediately follow a select() on the device indicating it's ready to read. Signed-off-by: John Levon <john.levon@sun.com>
-rw-r--r--tools/console/daemon/io.c64
-rw-r--r--tools/console/daemon/utils.c26
-rw-r--r--tools/console/daemon/utils.h3
-rw-r--r--tools/ioemu/target-i386-dm/helper2.c32
-rw-r--r--tools/libxc/xc_linux.c118
-rw-r--r--tools/libxc/xenctrl.h54
-rw-r--r--tools/xenmon/xenbaked.c55
-rw-r--r--tools/xenstore/fake_libxc.c4
-rw-r--r--tools/xenstore/xenstored_core.c13
-rw-r--r--tools/xenstore/xenstored_domain.c79
10 files changed, 253 insertions, 195 deletions
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index deea3ef6ec..5c0eaa0d9d 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -24,8 +24,8 @@
#include "io.h"
#include <xenctrl.h>
#include <xs.h>
-#include <xen/linux/evtchn.h>
#include <xen/io/console.h>
+#include <xenctrl.h>
#include <malloc.h>
#include <stdlib.h>
@@ -36,7 +36,6 @@
#include <unistd.h>
#include <termios.h>
#include <stdarg.h>
-#include <sys/ioctl.h>
#include <sys/mman.h>
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
@@ -64,19 +63,12 @@ struct domain
char *conspath;
int ring_ref;
evtchn_port_t local_port;
- int evtchn_fd;
+ int xce_handle;
struct xencons_interface *interface;
};
static struct domain *dom_head;
-static void evtchn_notify(struct domain *dom)
-{
- struct ioctl_evtchn_notify notify;
- notify.port = dom->local_port;
- (void)ioctl(dom->evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-
static void buffer_append(struct domain *dom)
{
struct buffer *buffer = &dom->buffer;
@@ -106,7 +98,7 @@ static void buffer_append(struct domain *dom)
mb();
intf->out_cons = cons;
- evtchn_notify(dom);
+ xc_evtchn_notify(dom->xce_handle, dom->local_port);
if (buffer->max_capacity &&
buffer->size > buffer->max_capacity) {
@@ -234,7 +226,6 @@ int xs_gather(struct xs_handle *xs, const char *dir, ...)
static int domain_create_ring(struct domain *dom)
{
int err, remote_port, ring_ref, rc;
- struct ioctl_evtchn_bind_interdomain bind;
err = xs_gather(xs, dom->conspath,
"ring-ref", "%u", &ring_ref,
@@ -258,24 +249,24 @@ static int domain_create_ring(struct domain *dom)
}
dom->local_port = -1;
- if (dom->evtchn_fd != -1)
- close(dom->evtchn_fd);
+ if (dom->xce_handle != -1)
+ xc_evtchn_close(dom->xce_handle);
/* Opening evtchn independently for each console is a bit
* wasteful, but that's how the code is structured... */
- dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
- if (dom->evtchn_fd == -1) {
+ dom->xce_handle = xc_evtchn_open();
+ if (dom->xce_handle == -1) {
err = errno;
goto out;
}
- bind.remote_domain = dom->domid;
- bind.remote_port = remote_port;
- rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+ rc = xc_evtchn_bind_interdomain(dom->xce_handle,
+ dom->domid, remote_port);
+
if (rc == -1) {
err = errno;
- close(dom->evtchn_fd);
- dom->evtchn_fd = -1;
+ xc_evtchn_close(dom->xce_handle);
+ dom->xce_handle = -1;
goto out;
}
dom->local_port = rc;
@@ -285,8 +276,8 @@ static int domain_create_ring(struct domain *dom)
if (dom->tty_fd == -1) {
err = errno;
- close(dom->evtchn_fd);
- dom->evtchn_fd = -1;
+ xc_evtchn_close(dom->xce_handle);
+ dom->xce_handle = -1;
dom->local_port = -1;
goto out;
}
@@ -344,7 +335,7 @@ static struct domain *create_domain(int domid)
dom->ring_ref = -1;
dom->local_port = -1;
dom->interface = NULL;
- dom->evtchn_fd = -1;
+ dom->xce_handle = -1;
if (!watch_domain(dom, true))
goto out;
@@ -409,9 +400,9 @@ static void shutdown_domain(struct domain *d)
if (d->interface != NULL)
munmap(d->interface, getpagesize());
d->interface = NULL;
- if (d->evtchn_fd != -1)
- close(d->evtchn_fd);
- d->evtchn_fd = -1;
+ if (d->xce_handle != -1)
+ xc_evtchn_close(d->xce_handle);
+ d->xce_handle = -1;
cleanup_domain(d);
}
@@ -483,7 +474,7 @@ static void handle_tty_read(struct domain *dom)
}
wmb();
intf->in_prod = prod;
- evtchn_notify(dom);
+ xc_evtchn_notify(dom->xce_handle, dom->local_port);
} else {
close(dom->tty_fd);
dom->tty_fd = -1;
@@ -516,14 +507,14 @@ static void handle_tty_write(struct domain *dom)
static void handle_ring_read(struct domain *dom)
{
- evtchn_port_t v;
+ evtchn_port_t port;
- if (!read_sync(dom->evtchn_fd, &v, sizeof(v)))
+ if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
return;
buffer_append(dom);
- (void)write_sync(dom->evtchn_fd, &v, sizeof(v));
+ (void)xc_evtchn_unmask(dom->xce_handle, port);
}
static void handle_xs(void)
@@ -566,9 +557,10 @@ void handle_io(void)
max_fd = MAX(xs_fileno(xs), max_fd);
for (d = dom_head; d; d = d->next) {
- if (d->evtchn_fd != -1) {
- FD_SET(d->evtchn_fd, &readfds);
- max_fd = MAX(d->evtchn_fd, max_fd);
+ if (d->xce_handle != -1) {
+ int evtchn_fd = xc_evtchn_fd(d->xce_handle);
+ FD_SET(evtchn_fd, &readfds);
+ max_fd = MAX(evtchn_fd, max_fd);
}
if (d->tty_fd != -1) {
@@ -588,8 +580,8 @@ void handle_io(void)
for (d = dom_head; d; d = n) {
n = d->next;
- if (d->evtchn_fd != -1 &&
- FD_ISSET(d->evtchn_fd, &readfds))
+ if (d->xce_handle != -1 &&
+ FD_ISSET(xc_evtchn_fd(d->xce_handle), &readfds))
handle_ring_read(d);
if (d->tty_fd != -1) {
diff --git a/tools/console/daemon/utils.c b/tools/console/daemon/utils.c
index 524e8068dc..40c64211d2 100644
--- a/tools/console/daemon/utils.c
+++ b/tools/console/daemon/utils.c
@@ -39,32 +39,6 @@
struct xs_handle *xs;
int xc;
-bool _read_write_sync(int fd, void *data, size_t size, bool do_read)
-{
- size_t offset = 0;
- ssize_t len;
-
- while (offset < size) {
- if (do_read) {
- len = read(fd, data + offset, size - offset);
- } else {
- len = write(fd, data + offset, size - offset);
- }
-
- if (len < 1) {
- if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
- continue;
- } else {
- return false;
- }
- } else {
- offset += len;
- }
- }
-
- return true;
-}
-
static void child_exit(int sig)
{
while (waitpid(-1, NULL, WNOHANG) > 0);
diff --git a/tools/console/daemon/utils.h b/tools/console/daemon/utils.h
index 6dc6f0d49d..44b3e2a22c 100644
--- a/tools/console/daemon/utils.h
+++ b/tools/console/daemon/utils.h
@@ -29,9 +29,6 @@
void daemonize(const char *pidfile);
bool xen_setup(void);
-#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true)
-#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false)
-bool _read_write_sync(int fd, void *data, size_t size, bool do_read);
extern struct xs_handle *xs;
extern int xc;
diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c
index a596c6edab..2256d6b63d 100644
--- a/tools/ioemu/target-i386-dm/helper2.c
+++ b/tools/ioemu/target-i386-dm/helper2.c
@@ -47,11 +47,9 @@
#include <limits.h>
#include <fcntl.h>
-#include <sys/ioctl.h>
#include <xenctrl.h>
#include <xen/hvm/ioreq.h>
-#include <xen/linux/evtchn.h>
#include "cpu.h"
#include "exec-all.h"
@@ -123,7 +121,7 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
}
//the evtchn fd for polling
-int evtchn_fd = -1;
+int xce_handle = -1;
//which vcpu we are serving
int send_vcpu = 0;
@@ -170,11 +168,10 @@ static ioreq_t* __cpu_get_ioreq(int vcpu)
//retval--the number of ioreq packet
static ioreq_t* cpu_get_ioreq(void)
{
- int i, rc;
+ int i;
evtchn_port_t port;
- rc = read(evtchn_fd, &port, sizeof(port));
- if ( rc == sizeof(port) ) {
+ if ( (port = xc_evtchn_pending(xce_handle)) != -1 ) {
for ( i = 0; i < vcpus; i++ )
if ( shared_page->vcpu_iodata[i].dm_eport == port )
break;
@@ -184,8 +181,7 @@ static ioreq_t* cpu_get_ioreq(void)
exit(1);
}
- // unmask the wanted port again
- write(evtchn_fd, &port, sizeof(port));
+ xc_evtchn_unmask(xce_handle, port);
//get the io packet from shared memory
send_vcpu = i;
@@ -436,6 +432,7 @@ int main_loop(void)
extern int shutdown_requested;
CPUState *env = global_env;
int retval;
+ int evtchn_fd = xc_evtchn_fd(xce_handle);
extern void main_loop_wait(int);
/* Watch stdin (fd 0) to see when it has input. */
@@ -475,11 +472,9 @@ int main_loop(void)
main_loop_wait(0);
if (env->send_event) {
- struct ioctl_evtchn_notify notify;
-
env->send_event = 0;
- notify.port = shared_page->vcpu_iodata[send_vcpu].dm_eport;
- (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
+ (void)xc_evtchn_notify(xce_handle,
+ shared_page->vcpu_iodata[send_vcpu].dm_eport);
}
}
destroy_hvm_domain();
@@ -511,7 +506,6 @@ static void qemu_hvm_reset(void *unused)
CPUState * cpu_init()
{
CPUX86State *env;
- struct ioctl_evtchn_bind_interdomain bind;
int i, rc;
cpu_exec_init();
@@ -523,21 +517,19 @@ CPUState * cpu_init()
cpu_single_env = env;
- if (evtchn_fd != -1)//the evtchn has been opened by another cpu object
+ if (xce_handle != -1)//the evtchn has been opened by another cpu object
return NULL;
- //use nonblock reading not polling, may change in future.
- evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK);
- if (evtchn_fd == -1) {
+ xce_handle = xc_evtchn_open();
+ if (xce_handle == -1) {
fprintf(logfile, "open evtchn device error %d\n", errno);
return NULL;
}
/* FIXME: how about if we overflow the page here? */
- bind.remote_domain = domid;
for ( i = 0; i < vcpus; i++ ) {
- bind.remote_port = shared_page->vcpu_iodata[i].vp_eport;
- rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+ rc = xc_evtchn_bind_interdomain(xce_handle, domid,
+ shared_page->vcpu_iodata[i].vp_eport);
if ( rc == -1 ) {
fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
return NULL;
diff --git a/tools/libxc/xc_linux.c b/tools/libxc/xc_linux.c
index 6c280a316d..d1a81d5899 100644
--- a/tools/libxc/xc_linux.c
+++ b/tools/libxc/xc_linux.c
@@ -103,6 +103,124 @@ int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
(unsigned long)hypercall);
}
+#define EVTCHN_DEV_NAME "/dev/xen/evtchn"
+#define EVTCHN_DEV_MAJOR 10
+#define EVTCHN_DEV_MINOR 201
+
+int xc_evtchn_open(void)
+{
+ struct stat st;
+ int fd;
+
+ /* Make sure any existing device file links to correct device. */
+ if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
+ (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
+ (void)unlink(EVTCHN_DEV_NAME);
+
+reopen:
+ if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 )
+ {
+ if ( (errno == ENOENT) &&
+ ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
+ (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
+ makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) )
+ goto reopen;
+
+ PERROR("Could not open event channel interface");
+ return -1;
+ }
+
+ return fd;
+}
+
+int xc_evtchn_close(int xce_handle)
+{
+ return close(xce_handle);
+}
+
+int xc_evtchn_fd(int xce_handle)
+{
+ return xce_handle;
+}
+
+int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
+{
+ struct ioctl_evtchn_notify notify;
+
+ notify.port = port;
+
+ return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
+evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
+ evtchn_port_t remote_port)
+{
+ struct ioctl_evtchn_bind_interdomain bind;
+
+ bind.remote_domain = domid;
+ bind.remote_port = remote_port;
+
+ return ioctl(xce_handle, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+}
+
+int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
+{
+ struct ioctl_evtchn_unbind unbind;
+
+ unbind.port = port;
+
+ return ioctl(xce_handle, IOCTL_EVTCHN_UNBIND, &unbind);
+}
+
+evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
+{
+ struct ioctl_evtchn_bind_virq bind;
+
+ bind.virq = virq;
+
+ return ioctl(xce_handle, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+}
+
+static int dorw(int fd, char *data, size_t size, int do_write)
+{
+ size_t offset = 0;
+ ssize_t len;
+
+ while ( offset < size )
+ {
+ if (do_write)
+ len = write(fd, data + offset, size - offset);
+ else
+ len = read(fd, data + offset, size - offset);
+
+ if ( len == -1 )
+ {
+ if ( errno == EINTR )
+ continue;
+ return -1;
+ }
+
+ offset += len;
+ }
+
+ return 0;
+}
+
+evtchn_port_t xc_evtchn_pending(int xce_handle)
+{
+ evtchn_port_t port;
+
+ if ( dorw(xce_handle, (char *)&port, sizeof(port), 0) == -1 )
+ return -1;
+
+ return port;
+}
+
+int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
+{
+ return dorw(xce_handle, (char *)&port, sizeof(port), 1);
+}
+
/*
* Local variables:
* mode: C
diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h
index bd380a5a02..f6093752b6 100644
--- a/tools/libxc/xenctrl.h
+++ b/tools/libxc/xenctrl.h
@@ -604,4 +604,58 @@ int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);
int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size);
+/*
+ * Return a handle to the event channel driver, or -1 on failure, in which case
+ * errno will be set appropriately.
+ */
+int xc_evtchn_open(void);
+
+/*
+ * Close a handle previously allocated with xc_evtchn_open().
+ */
+int xc_evtchn_close(int xce_handle);
+
+/*
+ * Return an fd that can be select()ed on for further calls to
+ * xc_evtchn_pending().
+ */
+int xc_evtchn_fd(int xce_handle);
+
+/*
+ * Notify the given event channel. Returns -1 on failure, in which case
+ * errno will be set appropriately.
+ */
+int xc_evtchn_notify(int xce_handle, evtchn_port_t port);
+
+/*
+ * Returns a new event port bound to the remote port for the given domain ID,
+ * or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
+ evtchn_port_t remote_port);
+
+/*
+ * Unbind the given event channel. Returns -1 on failure, in which case errno
+ * will be set appropriately.
+ */
+int xc_evtchn_unbind(int xce_handle, evtchn_port_t port);
+
+/*
+ * Bind an event channel to the given VIRQ. Returns the event channel bound to
+ * the VIRQ, or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq);
+
+/*
+ * Return the next event channel to become pending, or -1 on failure, in which
+ * case errno will be set appropriately.
+ */
+evtchn_port_t xc_evtchn_pending(int xce_handle);
+
+/*
+ * Unmask the given event channel. Returns -1 on failure, in which case errno
+ * will be set appropriately.
+ */
+int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
+
#endif
diff --git a/tools/xenmon/xenbaked.c b/tools/xenmon/xenbaked.c
index 15b59c0b9c..945a5c47f9 100644
--- a/tools/xenmon/xenbaked.c
+++ b/tools/xenmon/xenbaked.c
@@ -33,9 +33,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
@@ -45,7 +42,6 @@
#include <xen/xen.h>
#include <string.h>
#include <sys/select.h>
-#include <xen/linux/evtchn.h>
#define PERROR(_m, _a...) \
do { \
@@ -256,51 +252,29 @@ void log_event(int event_id)
stat_map[0].event_count++; // other
}
-#define EVTCHN_DEV_NAME "/dev/xen/evtchn"
-#define EVTCHN_DEV_MAJOR 10
-#define EVTCHN_DEV_MINOR 201
-
int virq_port;
-int eventchn_fd = -1;
+int xce_handle = -1;
/* Returns the event channel handle. */
/* Stolen from xenstore code */
int eventchn_init(void)
{
- struct stat st;
- struct ioctl_evtchn_bind_virq bind;
int rc;
// to revert to old way:
if (0)
return -1;
- /* Make sure any existing device file links to correct device. */
- if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
- (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
- (void)unlink(EVTCHN_DEV_NAME);
-
- reopen:
- eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
- if (eventchn_fd == -1) {
- if ((errno == ENOENT) &&
- ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
- (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
- makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0))
- goto reopen;
- return -errno;
- }
-
- if (eventchn_fd < 0)
+ xce_handle = xc_evtchn_open();
+
+ if (xce_handle < 0)
perror("Failed to open evtchn device");
- bind.virq = VIRQ_TBUF;
- rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
- if (rc == -1)
+ if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1)
perror("Failed to bind to domain exception virq port");
virq_port = rc;
- return eventchn_fd;
+ return xce_handle;
}
void wait_for_event(void)
@@ -309,27 +283,30 @@ void wait_for_event(void)
fd_set inset;
evtchn_port_t port;
struct timeval tv;
+ int evtchn_fd;
- if (eventchn_fd < 0) {
+ if (xce_handle < 0) {
nanosleep(&opts.poll_sleep, NULL);
return;
}
+ evtchn_fd = xc_evtchn_fd(xce_handle);
+
FD_ZERO(&inset);
- FD_SET(eventchn_fd, &inset);
+ FD_SET(evtchn_fd, &inset);
tv.tv_sec = 1;
tv.tv_usec = 0;
// tv = millis_to_timespec(&opts.poll_sleep);
- ret = select(eventchn_fd+1, &inset, NULL, NULL, &tv);
+ ret = select(evtchn_fd+1, &inset, NULL, NULL, &tv);
- if ( (ret == 1) && FD_ISSET(eventchn_fd, &inset)) {
- if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
+ if ( (ret == 1) && FD_ISSET(evtchn_fd, &inset)) {
+ if ((port = xc_evtchn_pending(xce_handle)) == -1)
perror("Failed to read from event fd");
// if (port == virq_port)
// printf("got the event I was looking for\r\n");
-
- if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
+
+ if (xc_evtchn_unmask(xce_handle, port) == -1)
perror("Failed to write to event fd");
}
}
diff --git a/tools/xenstore/fake_libxc.c b/tools/xenstore/fake_libxc.c
index 06d272930c..77c2095a4e 100644
--- a/tools/xenstore/fake_libxc.c
+++ b/tools/xenstore/fake_libxc.c
@@ -37,7 +37,7 @@ static int xs_test_pid;
static evtchn_port_t port;
/* The event channel maps to a signal, shared page to an mmapped file. */
-void evtchn_notify(int local_port)
+void xc_evtchn_notify(int xce_handle, int local_port)
{
assert(local_port == port);
if (kill(xs_test_pid, SIGUSR2) != 0)
@@ -124,7 +124,7 @@ void fake_ack_event(void)
signal(SIGUSR2, send_to_fd);
}
-int fake_open_eventchn(void)
+int xc_evtchn_open(void)
{
int fds[2];
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index ec31977cdd..25330f9906 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -54,7 +54,7 @@
#include "hashtable.h"
-extern int eventchn_fd; /* in xenstored_domain.c */
+extern int xce_handle; /* in xenstored_domain.c */
static bool verbose = false;
LIST_HEAD(connections);
@@ -353,8 +353,11 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock)
set_fd(sock, inset, &max);
set_fd(ro_sock, inset, &max);
- set_fd(eventchn_fd, inset, &max);
set_fd(reopen_log_pipe[0], inset, &max);
+
+ if (xce_handle != -1)
+ set_fd(xc_evtchn_fd(xce_handle), inset, &max);
+
list_for_each_entry(i, &connections, list) {
if (i->domain)
continue;
@@ -1769,6 +1772,7 @@ int main(int argc, char *argv[])
bool outputpid = false;
bool no_domain_init = false;
const char *pidfile = NULL;
+ int evtchn_fd = -1;
while ((opt = getopt_long(argc, argv, "DE:F:HNPS:T:RLVW:", options,
NULL)) != -1) {
@@ -1907,6 +1911,9 @@ int main(int argc, char *argv[])
signal(SIGUSR1, stop_failtest);
#endif
+ if (xce_handle != -1)
+ evtchn_fd = xc_evtchn_fd(xce_handle);
+
/* Get ready to listen to the tools. */
max = initialize_set(&inset, &outset, *sock, *ro_sock);
@@ -1934,7 +1941,7 @@ int main(int argc, char *argv[])
if (FD_ISSET(*ro_sock, &inset))
accept_connection(*ro_sock, false);
- if (eventchn_fd > 0 && FD_ISSET(eventchn_fd, &inset))
+ if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset))
handle_event();
list_for_each_entry(i, &connections, list) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 5bfe0a403f..40cc20386a 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -18,15 +18,10 @@
*/
#include <stdio.h>
-#include <linux/ioctl.h>
-#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
//#define DEBUG
#include "utils.h"
@@ -37,12 +32,11 @@
#include "xenstored_test.h"
#include <xenctrl.h>
-#include <xen/sys/evtchn.h>
static int *xc_handle;
static evtchn_port_t virq_port;
-int eventchn_fd = -1;
+int xce_handle = -1;
struct domain
{
@@ -83,19 +77,6 @@ struct domain
static LIST_HEAD(domains);
-#ifndef TESTING
-static void evtchn_notify(int port)
-{
- int rc;
-
- struct ioctl_evtchn_notify notify;
- notify.port = port;
- rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-#else
-extern void evtchn_notify(int port);
-#endif
-
/* FIXME: Mark connection as broken (close it?) when this happens. */
static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
{
@@ -146,7 +127,7 @@ static int writechn(struct connection *conn, const void *data, unsigned int len)
mb();
intf->rsp_prod += len;
- evtchn_notify(conn->domain->port);
+ xc_evtchn_notify(xce_handle, conn->domain->port);
return len;
}
@@ -176,7 +157,7 @@ static int readchn(struct connection *conn, void *data, unsigned int len)
mb();
intf->req_cons += len;
- evtchn_notify(conn->domain->port);
+ xc_evtchn_notify(xce_handle, conn->domain->port);
return len;
}
@@ -184,13 +165,11 @@ 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) {
- unbind.port = domain->port;
- if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1)
+ if (xc_evtchn_unbind(xce_handle, domain->port) == -1)
eprintf("> Unbinding port %i failed!\n", domain->port);
}
@@ -231,14 +210,14 @@ void handle_event(void)
{
evtchn_port_t port;
- if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
+ if ((port = xc_evtchn_pending(xce_handle)) == -1)
barf_perror("Failed to read from event fd");
if (port == virq_port)
domain_cleanup();
#ifndef TESTING
- if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
+ if (xc_evtchn_unmask(xce_handle, port) == -1)
barf_perror("Failed to write to event fd");
#endif
}
@@ -269,7 +248,6 @@ static struct domain *new_domain(void *context, unsigned int domid,
int port)
{
struct domain *domain;
- struct ioctl_evtchn_bind_interdomain bind;
int rc;
@@ -283,9 +261,7 @@ static struct domain *new_domain(void *context, unsigned int domid,
talloc_set_destructor(domain, destroy_domain);
/* Tell kernel we're interested in this event. */
- bind.remote_domain = domid;
- bind.remote_port = port;
- rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+ rc = xc_evtchn_bind_interdomain(xce_handle, domid, port);
if (rc == -1)
return NULL;
domain->port = rc;
@@ -490,23 +466,14 @@ static int dom0_init(void)
talloc_steal(dom0->conn, dom0);
- evtchn_notify(dom0->port);
+ xc_evtchn_notify(xce_handle, dom0->port);
return 0;
}
-
-
-#define EVTCHN_DEV_NAME "/dev/xen/evtchn"
-#define EVTCHN_DEV_MAJOR 10
-#define EVTCHN_DEV_MINOR 201
-
-
/* Returns the event channel handle. */
int domain_init(void)
{
- struct stat st;
- struct ioctl_evtchn_bind_virq bind;
int rc;
xc_handle = talloc(talloc_autofree_context(), int);
@@ -519,39 +486,19 @@ int domain_init(void)
talloc_set_destructor(xc_handle, close_xc_handle);
-#ifdef TESTING
- eventchn_fd = fake_open_eventchn();
- (void)&st;
-#else
- /* Make sure any existing device file links to correct device. */
- if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
- (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
- (void)unlink(EVTCHN_DEV_NAME);
-
- reopen:
- eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
- if (eventchn_fd == -1) {
- if ((errno == ENOENT) &&
- ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
- (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
- makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0))
- goto reopen;
- return -errno;
- }
-#endif
- if (eventchn_fd < 0)
+ xce_handle = xc_evtchn_open();
+
+ if (xce_handle < 0)
barf_perror("Failed to open evtchn device");
if (dom0_init() != 0)
barf_perror("Failed to initialize dom0 state");
- bind.virq = VIRQ_DOM_EXC;
- rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
- if (rc == -1)
+ if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1)
barf_perror("Failed to bind to domain exception virq port");
virq_port = rc;
- return eventchn_fd;
+ return xce_handle;
}
void domain_entry_inc(struct connection *conn)