[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen master] tools: split libxenvchan into new tools/libs/vchan directory



commit 8ab2429f1221ebae9fc8e72d8af205f3db93cde2
Author:     Juergen Gross <jgross@xxxxxxxx>
AuthorDate: Fri Aug 28 17:07:37 2020 +0200
Commit:     Wei Liu <wl@xxxxxxx>
CommitDate: Wed Sep 9 10:57:25 2020 +0000

    tools: split libxenvchan into new tools/libs/vchan directory
    
    There is no reason why libvchan is not placed in the tools/libs
    directory.
    
    At the same time move libxenvchan.h to a dedicated include directory
    in tools/libs/vchan in order to follow the same pattern as the other
    libraries in tools/libs.
    
    As tools/libvchan now contains no library any longer rename it to
    tools/vchan.
    
    Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
    Acked-by: Wei Liu <wl@xxxxxxx>
---
 .gitignore                             |   8 +-
 tools/Makefile                         |   2 +-
 tools/Rules.mk                         |   6 -
 tools/libs/Makefile                    |   1 +
 tools/libs/uselibs.mk                  |   2 +
 tools/libs/vchan/Makefile              |  20 ++
 tools/libs/vchan/include/libxenvchan.h | 176 +++++++++++
 tools/libs/vchan/init.c                | 461 ++++++++++++++++++++++++++++
 tools/libs/vchan/io.c                  | 388 ++++++++++++++++++++++++
 tools/libvchan/Makefile                | 100 -------
 tools/libvchan/init.c                  | 461 ----------------------------
 tools/libvchan/io.c                    | 388 ------------------------
 tools/libvchan/libxenvchan.h           | 176 -----------
 tools/libvchan/node-select.c           | 186 ------------
 tools/libvchan/node.c                  | 168 -----------
 tools/libvchan/vchan-socket-proxy.c    | 533 ---------------------------------
 tools/vchan/Makefile                   |  37 +++
 tools/vchan/node-select.c              | 186 ++++++++++++
 tools/vchan/node.c                     | 168 +++++++++++
 tools/vchan/vchan-socket-proxy.c       | 533 +++++++++++++++++++++++++++++++++
 20 files changed, 1978 insertions(+), 2022 deletions(-)

diff --git a/.gitignore b/.gitignore
index 1335034fd3..364b09506b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -134,6 +134,9 @@ tools/libs/store/utils.h
 tools/libs/store/xenstore.pc
 tools/libs/store/xs_lib.c
 tools/libs/store/include/xenstore_lib.h
+tools/libs/vchan/headers.chk
+tools/libs/vchan/libxenvchan.map
+tools/libs/vchan/xenvchan.pc
 tools/console/xenconsole
 tools/console/xenconsoled
 tools/console/client/_paths.h
@@ -209,7 +212,6 @@ tools/include/xen/*
 tools/include/xen-xsm/*
 tools/include/xen-foreign/*.(c|h|size)
 tools/include/xen-foreign/checker
-tools/libvchan/xenvchan.pc
 tools/libxl/_libxl.api-for-check
 tools/libxl/*.api-ok
 tools/libxl/*.pc
@@ -389,8 +391,8 @@ tools/misc/xenhypfs
 tools/misc/xenwatchdogd
 tools/misc/xen-hvmcrash
 tools/misc/xen-lowmemd
-tools/libvchan/vchan-node[12]
-tools/libvchan/vchan-socket-proxy
+tools/vchan/vchan-node[12]
+tools/vchan/vchan-socket-proxy
 tools/ocaml/*/.ocamldep.make
 tools/ocaml/*/*.cm[ixao]
 tools/ocaml/*/*.cmxa
diff --git a/tools/Makefile b/tools/Makefile
index 4a3646871c..0db01707a4 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -20,7 +20,7 @@ SUBDIRS-y += xenmon
 SUBDIRS-y += xenstat
 SUBDIRS-$(CONFIG_NetBSD) += xenbackendd
 SUBDIRS-y += libfsimage
-SUBDIRS-$(CONFIG_Linux) += libvchan
+SUBDIRS-$(CONFIG_Linux) += vchan
 
 # do not recurse in to a dir we are about to delete
 ifneq "$(MAKECMDGOALS)" "distclean"
diff --git a/tools/Rules.mk b/tools/Rules.mk
index 21aa8ea844..5f17492a68 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -19,7 +19,6 @@ XEN_libxenlight    = $(XEN_ROOT)/tools/libxl
 # Currently libxlutil lives in the same directory as libxenlight
 XEN_libxlutil      = $(XEN_libxenlight)
 XEN_libxenstat     = $(XEN_ROOT)/tools/xenstat/libxenstat/src
-XEN_libxenvchan    = $(XEN_ROOT)/tools/libvchan
 
 CFLAGS_xeninclude = -I$(XEN_INCLUDE)
 
@@ -114,11 +113,6 @@ SHDEPS_libxenstat  = $(SHLIB_libxenctrl) 
$(SHLIB_libxenstore)
 LDLIBS_libxenstat  = $(SHDEPS_libxenstat) 
$(XEN_libxenstat)/libxenstat$(libextension)
 SHLIB_libxenstat   = $(SHDEPS_libxenstat) -Wl,-rpath-link=$(XEN_libxenstat)
 
-CFLAGS_libxenvchan = -I$(XEN_libxenvchan) $(CFLAGS_libxengnttab) 
$(CFLAGS_libxenevtchn)
-SHDEPS_libxenvchan = $(SHLIB_libxentoollog) $(SHLIB_libxenstore) 
$(SHLIB_libxenevtchn) $(SHLIB_libxengnttab)
-LDLIBS_libxenvchan = $(SHDEPS_libxenvchan) 
$(XEN_libxenvchan)/libxenvchan$(libextension)
-SHLIB_libxenvchan  = $(SHDEPS_libxenvchan) -Wl,-rpath-link=$(XEN_libxenvchan)
-
 ifeq ($(debug),y)
 # Disable optimizations
 CFLAGS += -O0 -fno-omit-frame-pointer
diff --git a/tools/libs/Makefile b/tools/libs/Makefile
index 62bd8f5292..756d059ee7 100644
--- a/tools/libs/Makefile
+++ b/tools/libs/Makefile
@@ -13,6 +13,7 @@ SUBDIRS-y += ctrl
 SUBDIRS-y += guest
 SUBDIRS-y += hypfs
 SUBDIRS-y += store
+SUBDIRS-$(CONFIG_Linux) += vchan
 
 ifeq ($(CONFIG_RUMP),y)
 SUBDIRS-y := toolcore
diff --git a/tools/libs/uselibs.mk b/tools/libs/uselibs.mk
index a0fe0402ff..edb4b34256 100644
--- a/tools/libs/uselibs.mk
+++ b/tools/libs/uselibs.mk
@@ -22,3 +22,5 @@ LIBS_LIBS += guest
 USELIBS_guest := evtchn ctrl
 LIBS_LIBS += store
 USELIBS_store := toolcore
+LIBS_LIBS += vchan
+USELIBS_vchan := toollog store gnttab evtchn
diff --git a/tools/libs/vchan/Makefile b/tools/libs/vchan/Makefile
new file mode 100644
index 0000000000..87ff608f45
--- /dev/null
+++ b/tools/libs/vchan/Makefile
@@ -0,0 +1,20 @@
+XEN_ROOT = $(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+CFLAGS += $(CFLAGS_libxenctrl)
+
+LIBHEADER := libxenvchan.h
+
+SRCS-y += init.c
+SRCS-y += io.c
+
+include $(XEN_ROOT)/tools/libs/libs.mk
+
+$(PKG_CONFIG_LOCAL): PKG_CONFIG_INCDIR = $(XEN_libxenvchan)/include
+$(PKG_CONFIG_LOCAL): PKG_CONFIG_CFLAGS_LOCAL = $(CFLAGS_xeninclude)
+
+clean: cleanlocal
+
+.PHONY: cleanlocal
+cleanlocal:
+       rm -f libxenvchan.map
diff --git a/tools/libs/vchan/include/libxenvchan.h 
b/tools/libs/vchan/include/libxenvchan.h
new file mode 100644
index 0000000000..d6010b145d
--- /dev/null
+++ b/tools/libs/vchan/include/libxenvchan.h
@@ -0,0 +1,176 @@
+/**
+ * @file
+ * @section AUTHORS
+ *
+ * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
+ *
+ *  Authors:
+ *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
+ *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
+ *
+ * @section LICENSE
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; If not, see 
<http://www.gnu.org/licenses/>.
+ *
+ * @section DESCRIPTION
+ *
+ *  Originally borrowed from the Qubes OS Project, http://www.qubes-os.org,
+ *  this code has been substantially rewritten to use the gntdev and gntalloc
+ *  devices instead of raw MFNs and map_foreign_range.
+ *
+ *  This is a library for inter-domain communication.  A standard Xen ring
+ *  buffer is used, with a datagram-based interface built on top.  The grant
+ *  reference and event channels are shared in XenStore under the path
+ *  /local/domain/<srv-id>/data/vchan/<cli-id>/<port>/{ring-ref,event-channel}
+ *
+ *  The ring.h macros define an asymmetric interface to a shared data structure
+ *  that assumes all rings reside in a single contiguous memory space. This is
+ *  not suitable for vchan because the interface to the ring is symmetric 
except
+ *  for the setup. Unlike the producer-consumer rings defined in ring.h, the
+ *  size of the rings used in vchan are determined at execution time instead of
+ *  compile time, so the macros in ring.h cannot be used to access the rings.
+ */
+
+#include <xen/io/libxenvchan.h>
+#include <xen/xen.h>
+#include <xen/sys/evtchn.h>
+#include <xenevtchn.h>
+#include <xengnttab.h>
+
+/* Callers who don't care don't need to #include <xentoollog.h> */
+struct xentoollog_logger;
+
+struct libxenvchan_ring {
+       /* Pointer into the shared page. Offsets into buffer. */
+       struct ring_shared* shr;
+       /* ring data; may be its own shared page(s) depending on order */
+       void* buffer;
+       /**
+        * The size of the ring is (1 << order); offsets wrap around when they
+        * exceed this. This copy is required because we can't trust the order
+        * in the shared page to remain constant.
+        */
+       int order;
+};
+
+/**
+ * struct libxenvchan: control structure passed to all library calls
+ */
+struct libxenvchan {
+       /* Mapping handle for shared ring page */
+       union {
+               xengntshr_handle *gntshr; /* for server */
+               xengnttab_handle *gnttab; /* for client */
+       };
+       /* Pointer to shared ring page */
+       struct vchan_interface *ring;
+       /* event channel interface */
+       xenevtchn_handle *event;
+       uint32_t event_port;
+       /* informative flags: are we acting as server? */
+       int is_server:1;
+       /* true if server remains active when client closes (allows 
reconnection) */
+       int server_persist:1;
+       /* true if operations should block instead of returning 0 */
+       int blocking:1;
+       /* communication rings */
+       struct libxenvchan_ring read, write;
+};
+
+/**
+ * Set up a vchan, including granting pages
+ * @param logger Logger for libxc errors
+ * @param domain The peer domain that will be connecting
+ * @param xs_path Base xenstore path for storing ring/event data
+ * @param send_min The minimum size (in bytes) of the send ring (left)
+ * @param recv_min The minimum size (in bytes) of the receive ring (right)
+ * @return The structure, or NULL in case of an error
+ */
+struct libxenvchan *libxenvchan_server_init(struct xentoollog_logger *logger,
+                                            int domain, const char* xs_path,
+                                            size_t read_min, size_t write_min);
+/**
+ * Connect to an existing vchan. Note: you can reconnect to an existing vchan
+ * safely, however no locking is performed, so you must prevent multiple 
clients
+ * from connecting to a single server.
+ *
+ * @param logger Logger for libxc errors
+ * @param domain The peer domain to connect to
+ * @param xs_path Base xenstore path for storing ring/event data
+ * @return The structure, or NULL in case of an error
+ */
+struct libxenvchan *libxenvchan_client_init(struct xentoollog_logger *logger,
+                                            int domain, const char* xs_path);
+/**
+ * Close a vchan. This deallocates the vchan and attempts to free its
+ * resources. The other side is notified of the close, but can still read any
+ * data pending prior to the close.
+ */
+void libxenvchan_close(struct libxenvchan *ctrl);
+
+/**
+ * Packet-based receive: always reads exactly $size bytes.
+ * @param ctrl The vchan control structure
+ * @param data Buffer for data that was read
+ * @param size Size of the buffer and amount of data to read
+ * @return -1 on error, 0 if nonblocking and insufficient data is available, 
or $size
+ */
+int libxenvchan_recv(struct libxenvchan *ctrl, void *data, size_t size);
+/**
+ * Stream-based receive: reads as much data as possible.
+ * @param ctrl The vchan control structure
+ * @param data Buffer for data that was read
+ * @param size Size of the buffer
+ * @return -1 on error, otherwise the amount of data read (which may be zero if
+ *         the vchan is nonblocking)
+ */
+int libxenvchan_read(struct libxenvchan *ctrl, void *data, size_t size);
+/**
+ * Packet-based send: send entire buffer if possible
+ * @param ctrl The vchan control structure
+ * @param data Buffer for data to send
+ * @param size Size of the buffer and amount of data to send
+ * @return -1 on error, 0 if nonblocking and insufficient space is available, 
or $size
+ */
+int libxenvchan_send(struct libxenvchan *ctrl, const void *data, size_t size);
+/**
+ * Stream-based send: send as much data as possible.
+ * @param ctrl The vchan control structure
+ * @param data Buffer for data to send
+ * @param size Size of the buffer
+ * @return -1 on error, otherwise the amount of data sent (which may be zero if
+ *         the vchan is nonblocking)
+ */
+int libxenvchan_write(struct libxenvchan *ctrl, const void *data, size_t size);
+/**
+ * Waits for reads or writes to unblock, or for a close
+ */
+int libxenvchan_wait(struct libxenvchan *ctrl);
+/**
+ * Returns the event file descriptor for this vchan. When this FD is readable,
+ * libxenvchan_wait() will not block, and the state of the vchan has changed 
since
+ * the last invocation of libxenvchan_wait().
+ */
+int libxenvchan_fd_for_select(struct libxenvchan *ctrl);
+/**
+ * Query the state of the vchan shared page:
+ *  return 0 when one side has called libxenvchan_close() or crashed
+ *  return 1 when both sides are open
+ *  return 2 [server only] when no client has yet connected
+ */
+int libxenvchan_is_open(struct libxenvchan* ctrl);
+/** Amount of data ready to read, in bytes */
+int libxenvchan_data_ready(struct libxenvchan *ctrl);
+/** Amount of data it is possible to send without blocking */
+int libxenvchan_buffer_space(struct libxenvchan *ctrl);
diff --git a/tools/libs/vchan/init.c b/tools/libs/vchan/init.c
new file mode 100644
index 0000000000..ad4b64fbe3
--- /dev/null
+++ b/tools/libs/vchan/init.c
@@ -0,0 +1,461 @@
+/**
+ * @file
+ * @section AUTHORS
+ *
+ * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
+ *
+ *  Authors:
+ *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
+ *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
+ *
+ * @section LICENSE
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; If not, see 
<http://www.gnu.org/licenses/>.
+ *
+ * @section DESCRIPTION
+ *
+ *  This file contains the setup code used to establish the ring buffer.
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/user.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <xenstore.h>
+#include <xen/xen.h>
+#include <xen/sys/evtchn.h>
+#include <xen/sys/gntalloc.h>
+#include <xen/sys/gntdev.h>
+#include <libxenvchan.h>
+
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT 12
+#endif
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
+#define SMALL_RING_SHIFT 10
+#define LARGE_RING_SHIFT 11
+
+#define MAX_SMALL_RING (1 << SMALL_RING_SHIFT)
+#define SMALL_RING_OFFSET 1024
+#define MAX_LARGE_RING (1 << LARGE_RING_SHIFT)
+#define LARGE_RING_OFFSET 2048
+
+// if you go over this size, you'll have too many grants to fit in the shared 
page.
+#define MAX_RING_SHIFT 20
+#define MAX_RING_SIZE (1 << MAX_RING_SHIFT)
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+#define max(a,b) ((a > b) ? a : b)
+
+static int init_gnt_srv(struct libxenvchan *ctrl, int domain)
+{
+       int pages_left = ctrl->read.order >= PAGE_SHIFT ? 1 << 
(ctrl->read.order - PAGE_SHIFT) : 0;
+       int pages_right = ctrl->write.order >= PAGE_SHIFT ? 1 << 
(ctrl->write.order - PAGE_SHIFT) : 0;
+       uint32_t ring_ref = -1;
+       void *ring;
+
+       ring = xengntshr_share_page_notify(ctrl->gntshr, domain,
+                       &ring_ref, 1, offsetof(struct vchan_interface, 
srv_live),
+                       ctrl->event_port);
+
+       if (!ring)
+               goto out;
+
+       memset(ring, 0, PAGE_SIZE);
+
+       ctrl->ring = ring;
+       ctrl->read.shr = &ctrl->ring->left;
+       ctrl->write.shr = &ctrl->ring->right;
+       ctrl->ring->left_order = ctrl->read.order;
+       ctrl->ring->right_order = ctrl->write.order;
+       ctrl->ring->cli_live = 2;
+       ctrl->ring->srv_live = 1;
+       ctrl->ring->cli_notify = VCHAN_NOTIFY_WRITE;
+
+       switch (ctrl->read.order) {
+       case SMALL_RING_SHIFT:
+               ctrl->read.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
+               break;
+       case LARGE_RING_SHIFT:
+               ctrl->read.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
+               break;
+       default:
+               ctrl->read.buffer = xengntshr_share_pages(ctrl->gntshr, domain,
+                       pages_left, ctrl->ring->grants, 1);
+               if (!ctrl->read.buffer)
+                       goto out_ring;
+       }
+
+       switch (ctrl->write.order) {
+       case SMALL_RING_SHIFT:
+               ctrl->write.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
+               break;
+       case LARGE_RING_SHIFT:
+               ctrl->write.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
+               break;
+       default:
+               ctrl->write.buffer = xengntshr_share_pages(ctrl->gntshr, domain,
+                       pages_right, ctrl->ring->grants + pages_left, 1);
+               if (!ctrl->write.buffer)
+                       goto out_unmap_left;
+       }
+
+out:
+       return ring_ref;
+out_unmap_left:
+       if (pages_left)
+               xengntshr_unshare(ctrl->gntshr, ctrl->read.buffer, pages_left);
+out_ring:
+       xengntshr_unshare(ctrl->gntshr, ring, 1);
+       ring_ref = -1;
+       ctrl->ring = NULL;
+       ctrl->write.order = ctrl->read.order = 0;
+       goto out;
+}
+
+static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t 
ring_ref)
+{
+       int rv = -1;
+       uint32_t *grants;
+
+       ctrl->ring = xengnttab_map_grant_ref_notify(ctrl->gnttab,
+               domain, ring_ref, PROT_READ|PROT_WRITE,
+               offsetof(struct vchan_interface, cli_live), ctrl->event_port);
+
+       if (!ctrl->ring)
+               goto out;
+
+       ctrl->write.order = ctrl->ring->left_order;
+       ctrl->read.order = ctrl->ring->right_order;
+       ctrl->write.shr = &ctrl->ring->left;
+       ctrl->read.shr = &ctrl->ring->right;
+       if (ctrl->write.order < SMALL_RING_SHIFT || ctrl->write.order > 
MAX_RING_SHIFT)
+               goto out_unmap_ring;
+       if (ctrl->read.order < SMALL_RING_SHIFT || ctrl->read.order > 
MAX_RING_SHIFT)
+               goto out_unmap_ring;
+       if (ctrl->read.order == ctrl->write.order && ctrl->read.order < 
PAGE_SHIFT)
+               goto out_unmap_ring;
+
+       grants = ctrl->ring->grants;
+
+       switch (ctrl->write.order) {
+       case SMALL_RING_SHIFT:
+               ctrl->write.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
+               break;
+       case LARGE_RING_SHIFT:
+               ctrl->write.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
+               break;
+       default:
+               {
+                       int pages_left = 1 << (ctrl->write.order - PAGE_SHIFT);
+                       ctrl->write.buffer = 
xengnttab_map_domain_grant_refs(ctrl->gnttab,
+                               pages_left, domain, grants, 
PROT_READ|PROT_WRITE);
+                       if (!ctrl->write.buffer)
+                               goto out_unmap_ring;
+                       grants += pages_left;
+               }
+       }
+
+       switch (ctrl->read.order) {
+       case SMALL_RING_SHIFT:
+               ctrl->read.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
+               break;
+       case LARGE_RING_SHIFT:
+               ctrl->read.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
+               break;
+       default:
+               {
+                       int pages_right = 1 << (ctrl->read.order - PAGE_SHIFT);
+                       ctrl->read.buffer = 
xengnttab_map_domain_grant_refs(ctrl->gnttab,
+                               pages_right, domain, grants, PROT_READ);
+                       if (!ctrl->read.buffer)
+                               goto out_unmap_left;
+               }
+       }
+
+       rv = 0;
+ out:
+       return rv;
+ out_unmap_left:
+       if (ctrl->write.order >= PAGE_SHIFT)
+               xengnttab_unmap(ctrl->gnttab, ctrl->write.buffer,
+                               1 << (ctrl->write.order - PAGE_SHIFT));
+ out_unmap_ring:
+       xengnttab_unmap(ctrl->gnttab, ctrl->ring, 1);
+       ctrl->ring = 0;
+       ctrl->write.order = ctrl->read.order = 0;
+       rv = -1;
+       goto out;
+}
+
+static int init_evt_srv(struct libxenvchan *ctrl, int domain,
+                        struct xentoollog_logger *logger)
+{
+       xenevtchn_port_or_error_t port;
+
+       ctrl->event = xenevtchn_open(logger, 0);
+       if (!ctrl->event)
+               return -1;
+
+       port = xenevtchn_bind_unbound_port(ctrl->event, domain);
+       if (port < 0)
+               goto fail;
+       ctrl->event_port = port;
+
+       if (xenevtchn_unmask(ctrl->event, ctrl->event_port))
+               goto fail;
+
+       return 0;
+
+fail:
+       if (port >= 0)
+               xenevtchn_unbind(ctrl->event, port);
+
+       xenevtchn_close(ctrl->event);
+       ctrl->event = NULL;
+
+       return -1;
+}
+
+static int init_xs_srv(struct libxenvchan *ctrl, int domain, const char* 
xs_base, int ring_ref)
+{
+       int ret = -1;
+       struct xs_handle *xs;
+       struct xs_permissions perms[2];
+       char buf[64];
+       char ref[16];
+       char* domid_str = NULL;
+       xs_transaction_t xs_trans = XBT_NULL;
+       xs = xs_domain_open();
+       if (!xs)
+               goto fail;
+       domid_str = xs_read(xs, 0, "domid", NULL);
+       if (!domid_str)
+               goto fail_xs_open;
+
+       // owner domain is us
+       perms[0].id = atoi(domid_str);
+       // permissions for domains not listed = none
+       perms[0].perms = XS_PERM_NONE;
+       // other domains
+       perms[1].id = domain;
+       perms[1].perms = XS_PERM_READ;
+
+retry_transaction:
+       xs_trans = xs_transaction_start(xs);
+       if (!xs_trans)
+               goto fail_xs_open;
+
+       snprintf(ref, sizeof ref, "%d", ring_ref);
+       snprintf(buf, sizeof buf, "%s/ring-ref", xs_base);
+       if (!xs_write(xs, xs_trans, buf, ref, strlen(ref)))
+               goto fail_xs_open;
+       if (!xs_set_permissions(xs, xs_trans, buf, perms, 2))
+               goto fail_xs_open;
+
+       snprintf(ref, sizeof ref, "%d", ctrl->event_port);
+       snprintf(buf, sizeof buf, "%s/event-channel", xs_base);
+       if (!xs_write(xs, xs_trans, buf, ref, strlen(ref)))
+               goto fail_xs_open;
+       if (!xs_set_permissions(xs, xs_trans, buf, perms, 2))
+               goto fail_xs_open;
+
+       if (!xs_transaction_end(xs, xs_trans, 0)) {
+               if (errno == EAGAIN)
+                       goto retry_transaction;
+       } else {
+               ret = 0;
+       }
+ fail_xs_open:
+       free(domid_str);
+       xs_daemon_close(xs);
+ fail:
+       return ret;
+}
+
+static int min_order(size_t siz)
+{
+       int rv = PAGE_SHIFT;
+       while (siz > (1 << rv))
+               rv++;
+       return rv;
+}
+
+struct libxenvchan *libxenvchan_server_init(struct xentoollog_logger *logger,
+                                            int domain, const char* xs_path,
+                                            size_t left_min, size_t right_min)
+{
+       struct libxenvchan *ctrl;
+       int ring_ref;
+       if (left_min > MAX_RING_SIZE || right_min > MAX_RING_SIZE)
+               return 0;
+
+       ctrl = malloc(sizeof(*ctrl));
+       if (!ctrl)
+               return 0;
+
+       ctrl->ring = NULL;
+       ctrl->event = NULL;
+       ctrl->is_server = 1;
+       ctrl->server_persist = 0;
+
+       ctrl->read.order = min_order(left_min);
+       ctrl->write.order = min_order(right_min);
+
+       // if we can avoid allocating extra pages by using in-page rings, do so
+       if (left_min <= MAX_SMALL_RING && right_min <= MAX_LARGE_RING) {
+               ctrl->read.order = SMALL_RING_SHIFT;
+               ctrl->write.order = LARGE_RING_SHIFT;
+       } else if (left_min <= MAX_LARGE_RING && right_min <= MAX_SMALL_RING) {
+               ctrl->read.order = LARGE_RING_SHIFT;
+               ctrl->write.order = SMALL_RING_SHIFT;
+       } else if (left_min <= MAX_LARGE_RING) {
+               ctrl->read.order = LARGE_RING_SHIFT;
+       } else if (right_min <= MAX_LARGE_RING) {
+               ctrl->write.order = LARGE_RING_SHIFT;
+       }
+
+       ctrl->gntshr = xengntshr_open(logger, 0);
+       if (!ctrl->gntshr) {
+               free(ctrl);
+               return 0;
+       }
+
+       if (init_evt_srv(ctrl, domain, logger))
+               goto out;
+       ring_ref = init_gnt_srv(ctrl, domain);
+       if (ring_ref < 0)
+               goto out;
+       if (init_xs_srv(ctrl, domain, xs_path, ring_ref))
+               goto out;
+       return ctrl;
+out:
+       libxenvchan_close(ctrl);
+       return 0;
+}
+
+static int init_evt_cli(struct libxenvchan *ctrl, int domain,
+                        struct xentoollog_logger *logger)
+{
+       xenevtchn_port_or_error_t port;
+
+       ctrl->event = xenevtchn_open(logger, 0);
+       if (!ctrl->event)
+               return -1;
+
+       port = xenevtchn_bind_interdomain(ctrl->event,
+               domain, ctrl->event_port);
+       if (port < 0)
+               goto fail;
+       ctrl->event_port = port;
+
+       if (xenevtchn_unmask(ctrl->event, ctrl->event_port))
+               goto fail;
+
+       return 0;
+
+fail:
+       if (port >= 0)
+               xenevtchn_unbind(ctrl->event, port);
+
+       xenevtchn_close(ctrl->event);
+       ctrl->event = NULL;
+
+       return -1;
+}
+
+
+struct libxenvchan *libxenvchan_client_init(struct xentoollog_logger *logger,
+                                            int domain, const char* xs_path)
+{
+       struct libxenvchan *ctrl = malloc(sizeof(struct libxenvchan));
+       struct xs_handle *xs = NULL;
+       char buf[64];
+       char *ref;
+       int ring_ref;
+       unsigned int len;
+
+       if (!ctrl)
+               return 0;
+       ctrl->ring = NULL;
+       ctrl->event = NULL;
+       ctrl->gnttab = NULL;
+       ctrl->write.order = ctrl->read.order = 0;
+       ctrl->is_server = 0;
+
+       xs = xs_daemon_open();
+       if (!xs)
+               xs = xs_domain_open();
+       if (!xs)
+               goto fail;
+
+// find xenstore entry
+       snprintf(buf, sizeof buf, "%s/ring-ref", xs_path);
+       ref = xs_read(xs, 0, buf, &len);
+       if (!ref)
+               goto fail;
+       ring_ref = atoi(ref);
+       free(ref);
+       if (!ring_ref)
+               goto fail;
+       snprintf(buf, sizeof buf, "%s/event-channel", xs_path);
+       ref = xs_read(xs, 0, buf, &len);
+       if (!ref)
+               goto fail;
+       ctrl->event_port = atoi(ref);
+       free(ref);
+       if (!ctrl->event_port)
+               goto fail;
+
+       ctrl->gnttab = xengnttab_open(logger, 0);
+       if (!ctrl->gnttab)
+               goto fail;
+
+// set up event channel
+       if (init_evt_cli(ctrl, domain, logger))
+               goto fail;
+
+// set up shared page(s)
+       if (init_gnt_cli(ctrl, domain, ring_ref))
+               goto fail;
+
+       ctrl->ring->cli_live = 1;
+       ctrl->ring->srv_notify = VCHAN_NOTIFY_WRITE;
+
+       /* wake up the server */
+       xenevtchn_notify(ctrl->event, ctrl->event_port);
+
+ out:
+       if (xs)
+               xs_daemon_close(xs);
+       return ctrl;
+ fail:
+       libxenvchan_close(ctrl);
+       ctrl = NULL;
+       goto out;
+}
diff --git a/tools/libs/vchan/io.c b/tools/libs/vchan/io.c
new file mode 100644
index 0000000000..da303fbc01
--- /dev/null
+++ b/tools/libs/vchan/io.c
@@ -0,0 +1,388 @@
+/**
+ * @file
+ * @section AUTHORS
+ *
+ * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
+ *
+ *  Authors:
+ *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
+ *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
+ *
+ * @section LICENSE
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; If not, see 
<http://www.gnu.org/licenses/>.
+ *
+ * @section DESCRIPTION
+ *
+ *  This file contains the communications interface built on the ring buffer.
+ */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <sys/uio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <xenctrl.h>
+#include <libxenvchan.h>
+
+#ifndef PAGE_SHIFT
+#define PAGE_SHIFT 12
+#endif
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
+
+static inline uint32_t rd_prod(struct libxenvchan *ctrl)
+{
+       return ctrl->read.shr->prod;
+}
+
+static inline uint32_t* _rd_cons(struct libxenvchan *ctrl)
+{
+       return &ctrl->read.shr->cons;
+}
+#define rd_cons(x) (*_rd_cons(x))
+
+static inline uint32_t* _wr_prod(struct libxenvchan *ctrl)
+{
+       return &ctrl->write.shr->prod;
+}
+#define wr_prod(x) (*_wr_prod(x))
+
+static inline uint32_t wr_cons(struct libxenvchan *ctrl)
+{
+       return ctrl->write.shr->cons;
+}
+
+static inline const void* rd_ring(struct libxenvchan *ctrl)
+{
+       return ctrl->read.buffer;
+}
+
+static inline void* wr_ring(struct libxenvchan *ctrl)
+{
+       return ctrl->write.buffer;
+}
+
+static inline uint32_t wr_ring_size(struct libxenvchan *ctrl)
+{
+       return (1 << ctrl->write.order);
+}
+
+static inline uint32_t rd_ring_size(struct libxenvchan *ctrl)
+{
+       return (1 << ctrl->read.order);
+}
+
+static inline void request_notify(struct libxenvchan *ctrl, uint8_t bit)
+{
+       uint8_t *notify = ctrl->is_server ? &ctrl->ring->cli_notify : 
&ctrl->ring->srv_notify;
+       __sync_or_and_fetch(notify, bit);
+       xen_mb(); /* post the request /before/ caller re-reads any indexes */
+}
+
+static inline int send_notify(struct libxenvchan *ctrl, uint8_t bit)
+{
+       uint8_t *notify, prev;
+       xen_mb(); /* caller updates indexes /before/ we decode to notify */
+       notify = ctrl->is_server ? &ctrl->ring->srv_notify : 
&ctrl->ring->cli_notify;
+       prev = __sync_fetch_and_and(notify, ~bit);
+       if (prev & bit)
+               return xenevtchn_notify(ctrl->event, ctrl->event_port);
+       else
+               return 0;
+}
+
+/*
+ * Get the amount of buffer space available, and do nothing about
+ * notifications.
+ */
+static inline int raw_get_data_ready(struct libxenvchan *ctrl)
+{
+       uint32_t ready = rd_prod(ctrl) - rd_cons(ctrl);
+       xen_mb(); /* Ensure 'ready' is read only once. */
+       if (ready > rd_ring_size(ctrl))
+               /* We have no way to return errors.  Locking up the ring is
+                * better than the alternatives. */
+               return 0;
+       return ready;
+}
+
+/**
+ * Get the amount of buffer space available and enable notifications if needed.
+ */
+static inline int fast_get_data_ready(struct libxenvchan *ctrl, size_t request)
+{
+       int ready = raw_get_data_ready(ctrl);
+       if (ready >= request)
+               return ready;
+       /* We plan to consume all data; please tell us if you send more */
+       request_notify(ctrl, VCHAN_NOTIFY_WRITE);
+       /*
+        * If the writer moved rd_prod after our read but before request, we
+        * will not get notified even though the actual amount of data ready is
+        * above request. Reread rd_prod to cover this case.
+        */
+       return raw_get_data_ready(ctrl);
+}
+
+int libxenvchan_data_ready(struct libxenvchan *ctrl)
+{
+       /* Since this value is being used outside libxenvchan, request 
notification
+        * when it changes
+        */
+       request_notify(ctrl, VCHAN_NOTIFY_WRITE);
+       return raw_get_data_ready(ctrl);
+}
+
+/**
+ * Get the amount of buffer space available, and do nothing
+ * about notifications
+ */
+static inline int raw_get_buffer_space(struct libxenvchan *ctrl)
+{
+       uint32_t ready = wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl));
+       xen_mb(); /* Ensure 'ready' is read only once. */
+       if (ready > wr_ring_size(ctrl))
+               /* We have no way to return errors.  Locking up the ring is
+                * better than the alternatives. */
+               return 0;
+       return ready;
+}
+
+/**
+ * Get the amount of buffer space available and enable notifications if needed.
+ */
+static inline int fast_get_buffer_space(struct libxenvchan *ctrl, size_t 
request)
+{
+       int ready = raw_get_buffer_space(ctrl);
+       if (ready >= request)
+               return ready;
+       /* We plan to fill the buffer; please tell us when you've read it */
+       request_notify(ctrl, VCHAN_NOTIFY_READ);
+       /*
+        * If the reader moved wr_cons after our read but before request, we
+        * will not get notified even though the actual amount of buffer space
+        * is above request. Reread wr_cons to cover this case.
+        */
+       return raw_get_buffer_space(ctrl);
+}
+
+int libxenvchan_buffer_space(struct libxenvchan *ctrl)
+{
+       /* Since this value is being used outside libxenvchan, request 
notification
+        * when it changes
+        */
+       request_notify(ctrl, VCHAN_NOTIFY_READ);
+       return raw_get_buffer_space(ctrl);
+}
+
+int libxenvchan_wait(struct libxenvchan *ctrl)
+{
+       int ret = xenevtchn_pending(ctrl->event);
+       if (ret < 0)
+               return -1;
+       xenevtchn_unmask(ctrl->event, ret);
+       return 0;
+}
+
+/**
+ * returns -1 on error, or size on success
+ *
+ * caller must have checked that enough space is available
+ */
+static int do_send(struct libxenvchan *ctrl, const void *data, size_t size)
+{
+       int real_idx = wr_prod(ctrl) & (wr_ring_size(ctrl) - 1);
+       int avail_contig = wr_ring_size(ctrl) - real_idx;
+       if (avail_contig > size)
+               avail_contig = size;
+       xen_mb(); /* read indexes /then/ write data */
+       memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
+       if (avail_contig < size)
+       {
+               // we rolled across the end of the ring
+               memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
+       }
+       xen_wmb(); /* write data /then/ notify */
+       wr_prod(ctrl) += size;
+       if (send_notify(ctrl, VCHAN_NOTIFY_WRITE))
+               return -1;
+       return size;
+}
+
+/**
+ * returns 0 if no buffer space is available, -1 on error, or size on success
+ */
+int libxenvchan_send(struct libxenvchan *ctrl, const void *data, size_t size)
+{
+       int avail;
+       while (1) {
+               if (!libxenvchan_is_open(ctrl))
+                       return -1;
+               avail = fast_get_buffer_space(ctrl, size);
+               if (size <= avail)
+                       return do_send(ctrl, data, size);
+               if (!ctrl->blocking)
+                       return 0;
+               if (size > wr_ring_size(ctrl))
+                       return -1;
+               if (libxenvchan_wait(ctrl))
+                       return -1;
+       }
+}
+
+int libxenvchan_write(struct libxenvchan *ctrl, const void *data, size_t size)
+{
+       int avail;
+       if (!libxenvchan_is_open(ctrl))
+               return -1;
+       if (ctrl->blocking) {
+               size_t pos = 0;
+               while (1) {
+                       avail = fast_get_buffer_space(ctrl, size - pos);
+                       if (pos + avail > size)
+                               avail = size - pos;
+                       if (avail)
+                               pos += do_send(ctrl, data + pos, avail);
+                       if (pos == size)
+                               return pos;
+                       if (libxenvchan_wait(ctrl))
+                               return -1;
+                       if (!libxenvchan_is_open(ctrl))
+                               return -1;
+               }
+       } else {
+               avail = fast_get_buffer_space(ctrl, size);
+               if (size > avail)
+                       size = avail;
+               if (size == 0)
+                       return 0;
+               return do_send(ctrl, data, size);
+       }
+}
+
+/**
+ * returns -1 on error, or size on success
+ *
+ * caller must have checked that enough data is available
+ */
+static int do_recv(struct libxenvchan *ctrl, void *data, size_t size)
+{
+       int real_idx = rd_cons(ctrl) & (rd_ring_size(ctrl) - 1);
+       int avail_contig = rd_ring_size(ctrl) - real_idx;
+       if (avail_contig > size)
+               avail_contig = size;
+       xen_rmb(); /* data read must happen /after/ rd_cons read */
+       memcpy(data, rd_ring(ctrl) + real_idx, avail_contig);
+       if (avail_contig < size)
+       {
+               // we rolled across the end of the ring
+               memcpy(data + avail_contig, rd_ring(ctrl), size - avail_contig);
+       }
+       xen_mb(); /* consume /then/ notify */
+       rd_cons(ctrl) += size;
+       if (send_notify(ctrl, VCHAN_NOTIFY_READ))
+               return -1;
+       return size;
+}
+
+/**
+ * reads exactly size bytes from the vchan.
+ * returns 0 if insufficient data is available, -1 on error, or size on success
+ */
+int libxenvchan_recv(struct libxenvchan *ctrl, void *data, size_t size)
+{
+       while (1) {
+               int avail = fast_get_data_ready(ctrl, size);
+               if (size <= avail)
+                       return do_recv(ctrl, data, size);
+               if (!libxenvchan_is_open(ctrl))
+                       return -1;
+               if (!ctrl->blocking)
+                       return 0;
+               if (size > rd_ring_size(ctrl))
+                       return -1;
+               if (libxenvchan_wait(ctrl))
+                       return -1;
+       }
+}
+
+int libxenvchan_read(struct libxenvchan *ctrl, void *data, size_t size)
+{
+       while (1) {
+               int avail = fast_get_data_ready(ctrl, size);
+               if (avail && size > avail)
+                       size = avail;
+               if (avail)
+                       return do_recv(ctrl, data, size);
+               if (!libxenvchan_is_open(ctrl))
+                       return -1;
+               if (!ctrl->blocking)
+                       return 0;
+               if (libxenvchan_wait(ctrl))
+                       return -1;
+       }
+}
+
+int libxenvchan_is_open(struct libxenvchan* ctrl)
+{
+       if (ctrl->is_server)
+               return ctrl->server_persist ? 1 : ctrl->ring->cli_live;
+       else
+               return ctrl->ring->srv_live;
+}
+
+int libxenvchan_fd_for_select(struct libxenvchan *ctrl)
+{
+       return xenevtchn_fd(ctrl->event);
+}
+
+void libxenvchan_close(struct libxenvchan *ctrl)
+{
+       if (!ctrl)
+               return;
+       if (ctrl->read.order >= PAGE_SHIFT)
+               munmap(ctrl->read.buffer, 1 << ctrl->read.order);
+       if (ctrl->write.order >= PAGE_SHIFT)
+               munmap(ctrl->write.buffer, 1 << ctrl->write.order);
+       if (ctrl->ring) {
+               if (ctrl->is_server) {
+                       ctrl->ring->srv_live = 0;
+                       xengntshr_unshare(ctrl->gntshr, ctrl->ring, 1);
+               } else {
+                       ctrl->ring->cli_live = 0;
+                       xengnttab_unmap(ctrl->gnttab, ctrl->ring, 1);
+               }
+       }
+       if (ctrl->event) {
+               if (ctrl->ring)
+                       xenevtchn_notify(ctrl->event, ctrl->event_port);
+               xenevtchn_close(ctrl->event);
+       }
+       if (ctrl->is_server) {
+               if (ctrl->gntshr)
+                       xengntshr_close(ctrl->gntshr);
+       } else {
+               if (ctrl->gnttab)
+                       xengnttab_close(ctrl->gnttab);
+       }
+       free(ctrl);
+}
diff --git a/tools/libvchan/Makefile b/tools/libvchan/Makefile
deleted file mode 100644
index e718447977..0000000000
--- a/tools/libvchan/Makefile
+++ /dev/null
@@ -1,100 +0,0 @@
-#
-# tools/libvchan/Makefile
-#
-
-XEN_ROOT = $(CURDIR)/../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-LIBVCHAN_OBJS = init.o io.o
-NODE_OBJS = node.o
-NODE2_OBJS = node-select.o
-
-LIBVCHAN_PIC_OBJS = $(patsubst %.o,%.opic,$(LIBVCHAN_OBJS))
-LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxengnttab) 
$(LDLIBS_libxenevtchn)
-$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) 
$(CFLAGS_libxengnttab) $(CFLAGS_libxenevtchn)
-$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxengnttab) 
$(CFLAGS_libxenevtchn)
-vchan-socket-proxy.o: CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxenctrl) 
$(CFLAGS_libxengnttab) $(CFLAGS_libxenevtchn)
-
-MAJOR = 4.15
-MINOR = 0
-
-CFLAGS += -I../include -I.
-
-io.o io.opic: CFLAGS += $(CFLAGS_libxenctrl) # for xen_mb et al
-
-PKG_CONFIG := xenvchan.pc
-PKG_CONFIG_NAME := Xenvchan
-PKG_CONFIG_DESC := The Xenvchan library for Xen hypervisor
-PKG_CONFIG_VERSION := $(MAJOR).$(MINOR)
-PKG_CONFIG_USELIBS := $(SHLIB_libxenvchan)
-PKG_CONFIG_LIB := xenvchan
-PKG_CONFIG_REQPRIV := xentoollog,xenstore,xenevtchn,xengnttab
-
-ifneq ($(CONFIG_LIBXC_MINIOS),y)
-PKG_CONFIG_INST := $(PKG_CONFIG)
-$(PKG_CONFIG_INST): PKG_CONFIG_PREFIX = $(prefix)
-$(PKG_CONFIG_INST): PKG_CONFIG_INCDIR = $(includedir)
-$(PKG_CONFIG_INST): PKG_CONFIG_LIBDIR = $(libdir)
-endif
-
-PKG_CONFIG_LOCAL := $(foreach pc,$(PKG_CONFIG),$(PKG_CONFIG_DIR)/$(pc))
-
-$(PKG_CONFIG_LOCAL): PKG_CONFIG_PREFIX = $(XEN_ROOT)
-$(PKG_CONFIG_LOCAL): PKG_CONFIG_INCDIR = $(XEN_libxenvchan)
-$(PKG_CONFIG_LOCAL): PKG_CONFIG_LIBDIR = $(CURDIR)
-$(PKG_CONFIG_LOCAL): PKG_CONFIG_CFLAGS_LOCAL = $(CFLAGS_xeninclude)
-
-.PHONY: all
-all: libxenvchan.so vchan-node1 vchan-node2 vchan-socket-proxy libxenvchan.a 
$(PKG_CONFIG_INST) $(PKG_CONFIG_LOCAL)
-
-libxenvchan.so: libxenvchan.so.$(MAJOR)
-       ln -sf $< $@
-
-libxenvchan.so.$(MAJOR): libxenvchan.so.$(MAJOR).$(MINOR)
-       ln -sf $< $@
-
-libxenvchan.so.$(MAJOR).$(MINOR): $(LIBVCHAN_PIC_OBJS)
-       $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenvchan.so.$(MAJOR) 
$(SHLIB_LDFLAGS) -o $@ $^ $(LIBVCHAN_LIBS) $(APPEND_LDFLAGS)
-
-libxenvchan.a: $(LIBVCHAN_OBJS)
-       $(AR) rcs libxenvchan.a $^
-
-vchan-node1: $(NODE_OBJS) libxenvchan.so
-       $(CC) $(LDFLAGS) -o $@ $(NODE_OBJS) $(LDLIBS_libxenvchan) 
$(APPEND_LDFLAGS)
-
-vchan-node2: $(NODE2_OBJS) libxenvchan.so
-       $(CC) $(LDFLAGS) -o $@ $(NODE2_OBJS) $(LDLIBS_libxenvchan) 
$(APPEND_LDFLAGS)
-
-vchan-socket-proxy: vchan-socket-proxy.o libxenvchan.so
-       $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenvchan) $(LDLIBS_libxenstore) 
$(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
-
-.PHONY: install
-install: all
-       $(INSTALL_DIR) $(DESTDIR)$(libdir)
-       $(INSTALL_DIR) $(DESTDIR)$(includedir)
-       $(INSTALL_DIR) $(DESTDIR)$(bindir)
-       $(INSTALL_PROG) libxenvchan.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
-       ln -sf libxenvchan.so.$(MAJOR).$(MINOR) 
$(DESTDIR)$(libdir)/libxenvchan.so.$(MAJOR)
-       ln -sf libxenvchan.so.$(MAJOR) $(DESTDIR)$(libdir)/libxenvchan.so
-       $(INSTALL_PROG) vchan-socket-proxy $(DESTDIR)$(bindir)
-       $(INSTALL_DATA) libxenvchan.h $(DESTDIR)$(includedir)
-       $(INSTALL_DATA) libxenvchan.a $(DESTDIR)$(libdir)
-       $(INSTALL_DATA) xenvchan.pc $(DESTDIR)$(PKG_INSTALLDIR)
-
-.PHONY: uninstall
-uninstall:
-       rm -f $(DESTDIR)$(PKG_INSTALLDIR)/xenvchan.pc
-       rm -f $(DESTDIR)$(libdir)/libxenvchan.a
-       rm -f $(DESTDIR)$(includedir)/libxenvchan.h
-       rm -f $(DESTDIR)$(libdir)/libxenvchan.so
-       rm -f $(DESTDIR)$(libdir)/libxenvchan.so.$(MAJOR)
-       rm -f $(DESTDIR)$(libdir)/libxenvchan.so.$(MAJOR).$(MINOR)
-
-.PHONY: clean
-clean:
-       $(RM) -f *.o *.opic *.so* *.a vchan-node1 vchan-node2 $(DEPS_RM)
-       $(RM) -f xenvchan.pc
-
-distclean: clean
-
--include $(DEPS_INCLUDE)
diff --git a/tools/libvchan/init.c b/tools/libvchan/init.c
deleted file mode 100644
index ad4b64fbe3..0000000000
--- a/tools/libvchan/init.c
+++ /dev/null
@@ -1,461 +0,0 @@
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *
- *  Authors:
- *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- *
- * @section LICENSE
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; If not, see 
<http://www.gnu.org/licenses/>.
- *
- * @section DESCRIPTION
- *
- *  This file contains the setup code used to establish the ring buffer.
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/user.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-
-#include <xenstore.h>
-#include <xen/xen.h>
-#include <xen/sys/evtchn.h>
-#include <xen/sys/gntalloc.h>
-#include <xen/sys/gntdev.h>
-#include <libxenvchan.h>
-
-#ifndef PAGE_SHIFT
-#define PAGE_SHIFT 12
-#endif
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
-
-#define SMALL_RING_SHIFT 10
-#define LARGE_RING_SHIFT 11
-
-#define MAX_SMALL_RING (1 << SMALL_RING_SHIFT)
-#define SMALL_RING_OFFSET 1024
-#define MAX_LARGE_RING (1 << LARGE_RING_SHIFT)
-#define LARGE_RING_OFFSET 2048
-
-// if you go over this size, you'll have too many grants to fit in the shared 
page.
-#define MAX_RING_SHIFT 20
-#define MAX_RING_SIZE (1 << MAX_RING_SHIFT)
-
-#ifndef offsetof
-#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-#define max(a,b) ((a > b) ? a : b)
-
-static int init_gnt_srv(struct libxenvchan *ctrl, int domain)
-{
-       int pages_left = ctrl->read.order >= PAGE_SHIFT ? 1 << 
(ctrl->read.order - PAGE_SHIFT) : 0;
-       int pages_right = ctrl->write.order >= PAGE_SHIFT ? 1 << 
(ctrl->write.order - PAGE_SHIFT) : 0;
-       uint32_t ring_ref = -1;
-       void *ring;
-
-       ring = xengntshr_share_page_notify(ctrl->gntshr, domain,
-                       &ring_ref, 1, offsetof(struct vchan_interface, 
srv_live),
-                       ctrl->event_port);
-
-       if (!ring)
-               goto out;
-
-       memset(ring, 0, PAGE_SIZE);
-
-       ctrl->ring = ring;
-       ctrl->read.shr = &ctrl->ring->left;
-       ctrl->write.shr = &ctrl->ring->right;
-       ctrl->ring->left_order = ctrl->read.order;
-       ctrl->ring->right_order = ctrl->write.order;
-       ctrl->ring->cli_live = 2;
-       ctrl->ring->srv_live = 1;
-       ctrl->ring->cli_notify = VCHAN_NOTIFY_WRITE;
-
-       switch (ctrl->read.order) {
-       case SMALL_RING_SHIFT:
-               ctrl->read.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
-               break;
-       case LARGE_RING_SHIFT:
-               ctrl->read.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
-               break;
-       default:
-               ctrl->read.buffer = xengntshr_share_pages(ctrl->gntshr, domain,
-                       pages_left, ctrl->ring->grants, 1);
-               if (!ctrl->read.buffer)
-                       goto out_ring;
-       }
-
-       switch (ctrl->write.order) {
-       case SMALL_RING_SHIFT:
-               ctrl->write.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
-               break;
-       case LARGE_RING_SHIFT:
-               ctrl->write.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
-               break;
-       default:
-               ctrl->write.buffer = xengntshr_share_pages(ctrl->gntshr, domain,
-                       pages_right, ctrl->ring->grants + pages_left, 1);
-               if (!ctrl->write.buffer)
-                       goto out_unmap_left;
-       }
-
-out:
-       return ring_ref;
-out_unmap_left:
-       if (pages_left)
-               xengntshr_unshare(ctrl->gntshr, ctrl->read.buffer, pages_left);
-out_ring:
-       xengntshr_unshare(ctrl->gntshr, ring, 1);
-       ring_ref = -1;
-       ctrl->ring = NULL;
-       ctrl->write.order = ctrl->read.order = 0;
-       goto out;
-}
-
-static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t 
ring_ref)
-{
-       int rv = -1;
-       uint32_t *grants;
-
-       ctrl->ring = xengnttab_map_grant_ref_notify(ctrl->gnttab,
-               domain, ring_ref, PROT_READ|PROT_WRITE,
-               offsetof(struct vchan_interface, cli_live), ctrl->event_port);
-
-       if (!ctrl->ring)
-               goto out;
-
-       ctrl->write.order = ctrl->ring->left_order;
-       ctrl->read.order = ctrl->ring->right_order;
-       ctrl->write.shr = &ctrl->ring->left;
-       ctrl->read.shr = &ctrl->ring->right;
-       if (ctrl->write.order < SMALL_RING_SHIFT || ctrl->write.order > 
MAX_RING_SHIFT)
-               goto out_unmap_ring;
-       if (ctrl->read.order < SMALL_RING_SHIFT || ctrl->read.order > 
MAX_RING_SHIFT)
-               goto out_unmap_ring;
-       if (ctrl->read.order == ctrl->write.order && ctrl->read.order < 
PAGE_SHIFT)
-               goto out_unmap_ring;
-
-       grants = ctrl->ring->grants;
-
-       switch (ctrl->write.order) {
-       case SMALL_RING_SHIFT:
-               ctrl->write.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
-               break;
-       case LARGE_RING_SHIFT:
-               ctrl->write.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
-               break;
-       default:
-               {
-                       int pages_left = 1 << (ctrl->write.order - PAGE_SHIFT);
-                       ctrl->write.buffer = 
xengnttab_map_domain_grant_refs(ctrl->gnttab,
-                               pages_left, domain, grants, 
PROT_READ|PROT_WRITE);
-                       if (!ctrl->write.buffer)
-                               goto out_unmap_ring;
-                       grants += pages_left;
-               }
-       }
-
-       switch (ctrl->read.order) {
-       case SMALL_RING_SHIFT:
-               ctrl->read.buffer = ((void*)ctrl->ring) + SMALL_RING_OFFSET;
-               break;
-       case LARGE_RING_SHIFT:
-               ctrl->read.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET;
-               break;
-       default:
-               {
-                       int pages_right = 1 << (ctrl->read.order - PAGE_SHIFT);
-                       ctrl->read.buffer = 
xengnttab_map_domain_grant_refs(ctrl->gnttab,
-                               pages_right, domain, grants, PROT_READ);
-                       if (!ctrl->read.buffer)
-                               goto out_unmap_left;
-               }
-       }
-
-       rv = 0;
- out:
-       return rv;
- out_unmap_left:
-       if (ctrl->write.order >= PAGE_SHIFT)
-               xengnttab_unmap(ctrl->gnttab, ctrl->write.buffer,
-                               1 << (ctrl->write.order - PAGE_SHIFT));
- out_unmap_ring:
-       xengnttab_unmap(ctrl->gnttab, ctrl->ring, 1);
-       ctrl->ring = 0;
-       ctrl->write.order = ctrl->read.order = 0;
-       rv = -1;
-       goto out;
-}
-
-static int init_evt_srv(struct libxenvchan *ctrl, int domain,
-                        struct xentoollog_logger *logger)
-{
-       xenevtchn_port_or_error_t port;
-
-       ctrl->event = xenevtchn_open(logger, 0);
-       if (!ctrl->event)
-               return -1;
-
-       port = xenevtchn_bind_unbound_port(ctrl->event, domain);
-       if (port < 0)
-               goto fail;
-       ctrl->event_port = port;
-
-       if (xenevtchn_unmask(ctrl->event, ctrl->event_port))
-               goto fail;
-
-       return 0;
-
-fail:
-       if (port >= 0)
-               xenevtchn_unbind(ctrl->event, port);
-
-       xenevtchn_close(ctrl->event);
-       ctrl->event = NULL;
-
-       return -1;
-}
-
-static int init_xs_srv(struct libxenvchan *ctrl, int domain, const char* 
xs_base, int ring_ref)
-{
-       int ret = -1;
-       struct xs_handle *xs;
-       struct xs_permissions perms[2];
-       char buf[64];
-       char ref[16];
-       char* domid_str = NULL;
-       xs_transaction_t xs_trans = XBT_NULL;
-       xs = xs_domain_open();
-       if (!xs)
-               goto fail;
-       domid_str = xs_read(xs, 0, "domid", NULL);
-       if (!domid_str)
-               goto fail_xs_open;
-
-       // owner domain is us
-       perms[0].id = atoi(domid_str);
-       // permissions for domains not listed = none
-       perms[0].perms = XS_PERM_NONE;
-       // other domains
-       perms[1].id = domain;
-       perms[1].perms = XS_PERM_READ;
-
-retry_transaction:
-       xs_trans = xs_transaction_start(xs);
-       if (!xs_trans)
-               goto fail_xs_open;
-
-       snprintf(ref, sizeof ref, "%d", ring_ref);
-       snprintf(buf, sizeof buf, "%s/ring-ref", xs_base);
-       if (!xs_write(xs, xs_trans, buf, ref, strlen(ref)))
-               goto fail_xs_open;
-       if (!xs_set_permissions(xs, xs_trans, buf, perms, 2))
-               goto fail_xs_open;
-
-       snprintf(ref, sizeof ref, "%d", ctrl->event_port);
-       snprintf(buf, sizeof buf, "%s/event-channel", xs_base);
-       if (!xs_write(xs, xs_trans, buf, ref, strlen(ref)))
-               goto fail_xs_open;
-       if (!xs_set_permissions(xs, xs_trans, buf, perms, 2))
-               goto fail_xs_open;
-
-       if (!xs_transaction_end(xs, xs_trans, 0)) {
-               if (errno == EAGAIN)
-                       goto retry_transaction;
-       } else {
-               ret = 0;
-       }
- fail_xs_open:
-       free(domid_str);
-       xs_daemon_close(xs);
- fail:
-       return ret;
-}
-
-static int min_order(size_t siz)
-{
-       int rv = PAGE_SHIFT;
-       while (siz > (1 << rv))
-               rv++;
-       return rv;
-}
-
-struct libxenvchan *libxenvchan_server_init(struct xentoollog_logger *logger,
-                                            int domain, const char* xs_path,
-                                            size_t left_min, size_t right_min)
-{
-       struct libxenvchan *ctrl;
-       int ring_ref;
-       if (left_min > MAX_RING_SIZE || right_min > MAX_RING_SIZE)
-               return 0;
-
-       ctrl = malloc(sizeof(*ctrl));
-       if (!ctrl)
-               return 0;
-
-       ctrl->ring = NULL;
-       ctrl->event = NULL;
-       ctrl->is_server = 1;
-       ctrl->server_persist = 0;
-
-       ctrl->read.order = min_order(left_min);
-       ctrl->write.order = min_order(right_min);
-
-       // if we can avoid allocating extra pages by using in-page rings, do so
-       if (left_min <= MAX_SMALL_RING && right_min <= MAX_LARGE_RING) {
-               ctrl->read.order = SMALL_RING_SHIFT;
-               ctrl->write.order = LARGE_RING_SHIFT;
-       } else if (left_min <= MAX_LARGE_RING && right_min <= MAX_SMALL_RING) {
-               ctrl->read.order = LARGE_RING_SHIFT;
-               ctrl->write.order = SMALL_RING_SHIFT;
-       } else if (left_min <= MAX_LARGE_RING) {
-               ctrl->read.order = LARGE_RING_SHIFT;
-       } else if (right_min <= MAX_LARGE_RING) {
-               ctrl->write.order = LARGE_RING_SHIFT;
-       }
-
-       ctrl->gntshr = xengntshr_open(logger, 0);
-       if (!ctrl->gntshr) {
-               free(ctrl);
-               return 0;
-       }
-
-       if (init_evt_srv(ctrl, domain, logger))
-               goto out;
-       ring_ref = init_gnt_srv(ctrl, domain);
-       if (ring_ref < 0)
-               goto out;
-       if (init_xs_srv(ctrl, domain, xs_path, ring_ref))
-               goto out;
-       return ctrl;
-out:
-       libxenvchan_close(ctrl);
-       return 0;
-}
-
-static int init_evt_cli(struct libxenvchan *ctrl, int domain,
-                        struct xentoollog_logger *logger)
-{
-       xenevtchn_port_or_error_t port;
-
-       ctrl->event = xenevtchn_open(logger, 0);
-       if (!ctrl->event)
-               return -1;
-
-       port = xenevtchn_bind_interdomain(ctrl->event,
-               domain, ctrl->event_port);
-       if (port < 0)
-               goto fail;
-       ctrl->event_port = port;
-
-       if (xenevtchn_unmask(ctrl->event, ctrl->event_port))
-               goto fail;
-
-       return 0;
-
-fail:
-       if (port >= 0)
-               xenevtchn_unbind(ctrl->event, port);
-
-       xenevtchn_close(ctrl->event);
-       ctrl->event = NULL;
-
-       return -1;
-}
-
-
-struct libxenvchan *libxenvchan_client_init(struct xentoollog_logger *logger,
-                                            int domain, const char* xs_path)
-{
-       struct libxenvchan *ctrl = malloc(sizeof(struct libxenvchan));
-       struct xs_handle *xs = NULL;
-       char buf[64];
-       char *ref;
-       int ring_ref;
-       unsigned int len;
-
-       if (!ctrl)
-               return 0;
-       ctrl->ring = NULL;
-       ctrl->event = NULL;
-       ctrl->gnttab = NULL;
-       ctrl->write.order = ctrl->read.order = 0;
-       ctrl->is_server = 0;
-
-       xs = xs_daemon_open();
-       if (!xs)
-               xs = xs_domain_open();
-       if (!xs)
-               goto fail;
-
-// find xenstore entry
-       snprintf(buf, sizeof buf, "%s/ring-ref", xs_path);
-       ref = xs_read(xs, 0, buf, &len);
-       if (!ref)
-               goto fail;
-       ring_ref = atoi(ref);
-       free(ref);
-       if (!ring_ref)
-               goto fail;
-       snprintf(buf, sizeof buf, "%s/event-channel", xs_path);
-       ref = xs_read(xs, 0, buf, &len);
-       if (!ref)
-               goto fail;
-       ctrl->event_port = atoi(ref);
-       free(ref);
-       if (!ctrl->event_port)
-               goto fail;
-
-       ctrl->gnttab = xengnttab_open(logger, 0);
-       if (!ctrl->gnttab)
-               goto fail;
-
-// set up event channel
-       if (init_evt_cli(ctrl, domain, logger))
-               goto fail;
-
-// set up shared page(s)
-       if (init_gnt_cli(ctrl, domain, ring_ref))
-               goto fail;
-
-       ctrl->ring->cli_live = 1;
-       ctrl->ring->srv_notify = VCHAN_NOTIFY_WRITE;
-
-       /* wake up the server */
-       xenevtchn_notify(ctrl->event, ctrl->event_port);
-
- out:
-       if (xs)
-               xs_daemon_close(xs);
-       return ctrl;
- fail:
-       libxenvchan_close(ctrl);
-       ctrl = NULL;
-       goto out;
-}
diff --git a/tools/libvchan/io.c b/tools/libvchan/io.c
deleted file mode 100644
index da303fbc01..0000000000
--- a/tools/libvchan/io.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *
- *  Authors:
- *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- *
- * @section LICENSE
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; If not, see 
<http://www.gnu.org/licenses/>.
- *
- * @section DESCRIPTION
- *
- *  This file contains the communications interface built on the ring buffer.
- */
-
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <sys/uio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <xenctrl.h>
-#include <libxenvchan.h>
-
-#ifndef PAGE_SHIFT
-#define PAGE_SHIFT 12
-#endif
-
-#ifndef PAGE_SIZE
-#define PAGE_SIZE 4096
-#endif
-
-
-static inline uint32_t rd_prod(struct libxenvchan *ctrl)
-{
-       return ctrl->read.shr->prod;
-}
-
-static inline uint32_t* _rd_cons(struct libxenvchan *ctrl)
-{
-       return &ctrl->read.shr->cons;
-}
-#define rd_cons(x) (*_rd_cons(x))
-
-static inline uint32_t* _wr_prod(struct libxenvchan *ctrl)
-{
-       return &ctrl->write.shr->prod;
-}
-#define wr_prod(x) (*_wr_prod(x))
-
-static inline uint32_t wr_cons(struct libxenvchan *ctrl)
-{
-       return ctrl->write.shr->cons;
-}
-
-static inline const void* rd_ring(struct libxenvchan *ctrl)
-{
-       return ctrl->read.buffer;
-}
-
-static inline void* wr_ring(struct libxenvchan *ctrl)
-{
-       return ctrl->write.buffer;
-}
-
-static inline uint32_t wr_ring_size(struct libxenvchan *ctrl)
-{
-       return (1 << ctrl->write.order);
-}
-
-static inline uint32_t rd_ring_size(struct libxenvchan *ctrl)
-{
-       return (1 << ctrl->read.order);
-}
-
-static inline void request_notify(struct libxenvchan *ctrl, uint8_t bit)
-{
-       uint8_t *notify = ctrl->is_server ? &ctrl->ring->cli_notify : 
&ctrl->ring->srv_notify;
-       __sync_or_and_fetch(notify, bit);
-       xen_mb(); /* post the request /before/ caller re-reads any indexes */
-}
-
-static inline int send_notify(struct libxenvchan *ctrl, uint8_t bit)
-{
-       uint8_t *notify, prev;
-       xen_mb(); /* caller updates indexes /before/ we decode to notify */
-       notify = ctrl->is_server ? &ctrl->ring->srv_notify : 
&ctrl->ring->cli_notify;
-       prev = __sync_fetch_and_and(notify, ~bit);
-       if (prev & bit)
-               return xenevtchn_notify(ctrl->event, ctrl->event_port);
-       else
-               return 0;
-}
-
-/*
- * Get the amount of buffer space available, and do nothing about
- * notifications.
- */
-static inline int raw_get_data_ready(struct libxenvchan *ctrl)
-{
-       uint32_t ready = rd_prod(ctrl) - rd_cons(ctrl);
-       xen_mb(); /* Ensure 'ready' is read only once. */
-       if (ready > rd_ring_size(ctrl))
-               /* We have no way to return errors.  Locking up the ring is
-                * better than the alternatives. */
-               return 0;
-       return ready;
-}
-
-/**
- * Get the amount of buffer space available and enable notifications if needed.
- */
-static inline int fast_get_data_ready(struct libxenvchan *ctrl, size_t request)
-{
-       int ready = raw_get_data_ready(ctrl);
-       if (ready >= request)
-               return ready;
-       /* We plan to consume all data; please tell us if you send more */
-       request_notify(ctrl, VCHAN_NOTIFY_WRITE);
-       /*
-        * If the writer moved rd_prod after our read but before request, we
-        * will not get notified even though the actual amount of data ready is
-        * above request. Reread rd_prod to cover this case.
-        */
-       return raw_get_data_ready(ctrl);
-}
-
-int libxenvchan_data_ready(struct libxenvchan *ctrl)
-{
-       /* Since this value is being used outside libxenvchan, request 
notification
-        * when it changes
-        */
-       request_notify(ctrl, VCHAN_NOTIFY_WRITE);
-       return raw_get_data_ready(ctrl);
-}
-
-/**
- * Get the amount of buffer space available, and do nothing
- * about notifications
- */
-static inline int raw_get_buffer_space(struct libxenvchan *ctrl)
-{
-       uint32_t ready = wr_ring_size(ctrl) - (wr_prod(ctrl) - wr_cons(ctrl));
-       xen_mb(); /* Ensure 'ready' is read only once. */
-       if (ready > wr_ring_size(ctrl))
-               /* We have no way to return errors.  Locking up the ring is
-                * better than the alternatives. */
-               return 0;
-       return ready;
-}
-
-/**
- * Get the amount of buffer space available and enable notifications if needed.
- */
-static inline int fast_get_buffer_space(struct libxenvchan *ctrl, size_t 
request)
-{
-       int ready = raw_get_buffer_space(ctrl);
-       if (ready >= request)
-               return ready;
-       /* We plan to fill the buffer; please tell us when you've read it */
-       request_notify(ctrl, VCHAN_NOTIFY_READ);
-       /*
-        * If the reader moved wr_cons after our read but before request, we
-        * will not get notified even though the actual amount of buffer space
-        * is above request. Reread wr_cons to cover this case.
-        */
-       return raw_get_buffer_space(ctrl);
-}
-
-int libxenvchan_buffer_space(struct libxenvchan *ctrl)
-{
-       /* Since this value is being used outside libxenvchan, request 
notification
-        * when it changes
-        */
-       request_notify(ctrl, VCHAN_NOTIFY_READ);
-       return raw_get_buffer_space(ctrl);
-}
-
-int libxenvchan_wait(struct libxenvchan *ctrl)
-{
-       int ret = xenevtchn_pending(ctrl->event);
-       if (ret < 0)
-               return -1;
-       xenevtchn_unmask(ctrl->event, ret);
-       return 0;
-}
-
-/**
- * returns -1 on error, or size on success
- *
- * caller must have checked that enough space is available
- */
-static int do_send(struct libxenvchan *ctrl, const void *data, size_t size)
-{
-       int real_idx = wr_prod(ctrl) & (wr_ring_size(ctrl) - 1);
-       int avail_contig = wr_ring_size(ctrl) - real_idx;
-       if (avail_contig > size)
-               avail_contig = size;
-       xen_mb(); /* read indexes /then/ write data */
-       memcpy(wr_ring(ctrl) + real_idx, data, avail_contig);
-       if (avail_contig < size)
-       {
-               // we rolled across the end of the ring
-               memcpy(wr_ring(ctrl), data + avail_contig, size - avail_contig);
-       }
-       xen_wmb(); /* write data /then/ notify */
-       wr_prod(ctrl) += size;
-       if (send_notify(ctrl, VCHAN_NOTIFY_WRITE))
-               return -1;
-       return size;
-}
-
-/**
- * returns 0 if no buffer space is available, -1 on error, or size on success
- */
-int libxenvchan_send(struct libxenvchan *ctrl, const void *data, size_t size)
-{
-       int avail;
-       while (1) {
-               if (!libxenvchan_is_open(ctrl))
-                       return -1;
-               avail = fast_get_buffer_space(ctrl, size);
-               if (size <= avail)
-                       return do_send(ctrl, data, size);
-               if (!ctrl->blocking)
-                       return 0;
-               if (size > wr_ring_size(ctrl))
-                       return -1;
-               if (libxenvchan_wait(ctrl))
-                       return -1;
-       }
-}
-
-int libxenvchan_write(struct libxenvchan *ctrl, const void *data, size_t size)
-{
-       int avail;
-       if (!libxenvchan_is_open(ctrl))
-               return -1;
-       if (ctrl->blocking) {
-               size_t pos = 0;
-               while (1) {
-                       avail = fast_get_buffer_space(ctrl, size - pos);
-                       if (pos + avail > size)
-                               avail = size - pos;
-                       if (avail)
-                               pos += do_send(ctrl, data + pos, avail);
-                       if (pos == size)
-                               return pos;
-                       if (libxenvchan_wait(ctrl))
-                               return -1;
-                       if (!libxenvchan_is_open(ctrl))
-                               return -1;
-               }
-       } else {
-               avail = fast_get_buffer_space(ctrl, size);
-               if (size > avail)
-                       size = avail;
-               if (size == 0)
-                       return 0;
-               return do_send(ctrl, data, size);
-       }
-}
-
-/**
- * returns -1 on error, or size on success
- *
- * caller must have checked that enough data is available
- */
-static int do_recv(struct libxenvchan *ctrl, void *data, size_t size)
-{
-       int real_idx = rd_cons(ctrl) & (rd_ring_size(ctrl) - 1);
-       int avail_contig = rd_ring_size(ctrl) - real_idx;
-       if (avail_contig > size)
-               avail_contig = size;
-       xen_rmb(); /* data read must happen /after/ rd_cons read */
-       memcpy(data, rd_ring(ctrl) + real_idx, avail_contig);
-       if (avail_contig < size)
-       {
-               // we rolled across the end of the ring
-               memcpy(data + avail_contig, rd_ring(ctrl), size - avail_contig);
-       }
-       xen_mb(); /* consume /then/ notify */
-       rd_cons(ctrl) += size;
-       if (send_notify(ctrl, VCHAN_NOTIFY_READ))
-               return -1;
-       return size;
-}
-
-/**
- * reads exactly size bytes from the vchan.
- * returns 0 if insufficient data is available, -1 on error, or size on success
- */
-int libxenvchan_recv(struct libxenvchan *ctrl, void *data, size_t size)
-{
-       while (1) {
-               int avail = fast_get_data_ready(ctrl, size);
-               if (size <= avail)
-                       return do_recv(ctrl, data, size);
-               if (!libxenvchan_is_open(ctrl))
-                       return -1;
-               if (!ctrl->blocking)
-                       return 0;
-               if (size > rd_ring_size(ctrl))
-                       return -1;
-               if (libxenvchan_wait(ctrl))
-                       return -1;
-       }
-}
-
-int libxenvchan_read(struct libxenvchan *ctrl, void *data, size_t size)
-{
-       while (1) {
-               int avail = fast_get_data_ready(ctrl, size);
-               if (avail && size > avail)
-                       size = avail;
-               if (avail)
-                       return do_recv(ctrl, data, size);
-               if (!libxenvchan_is_open(ctrl))
-                       return -1;
-               if (!ctrl->blocking)
-                       return 0;
-               if (libxenvchan_wait(ctrl))
-                       return -1;
-       }
-}
-
-int libxenvchan_is_open(struct libxenvchan* ctrl)
-{
-       if (ctrl->is_server)
-               return ctrl->server_persist ? 1 : ctrl->ring->cli_live;
-       else
-               return ctrl->ring->srv_live;
-}
-
-int libxenvchan_fd_for_select(struct libxenvchan *ctrl)
-{
-       return xenevtchn_fd(ctrl->event);
-}
-
-void libxenvchan_close(struct libxenvchan *ctrl)
-{
-       if (!ctrl)
-               return;
-       if (ctrl->read.order >= PAGE_SHIFT)
-               munmap(ctrl->read.buffer, 1 << ctrl->read.order);
-       if (ctrl->write.order >= PAGE_SHIFT)
-               munmap(ctrl->write.buffer, 1 << ctrl->write.order);
-       if (ctrl->ring) {
-               if (ctrl->is_server) {
-                       ctrl->ring->srv_live = 0;
-                       xengntshr_unshare(ctrl->gntshr, ctrl->ring, 1);
-               } else {
-                       ctrl->ring->cli_live = 0;
-                       xengnttab_unmap(ctrl->gnttab, ctrl->ring, 1);
-               }
-       }
-       if (ctrl->event) {
-               if (ctrl->ring)
-                       xenevtchn_notify(ctrl->event, ctrl->event_port);
-               xenevtchn_close(ctrl->event);
-       }
-       if (ctrl->is_server) {
-               if (ctrl->gntshr)
-                       xengntshr_close(ctrl->gntshr);
-       } else {
-               if (ctrl->gnttab)
-                       xengnttab_close(ctrl->gnttab);
-       }
-       free(ctrl);
-}
diff --git a/tools/libvchan/libxenvchan.h b/tools/libvchan/libxenvchan.h
deleted file mode 100644
index d6010b145d..0000000000
--- a/tools/libvchan/libxenvchan.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *
- *  Authors:
- *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- *
- * @section LICENSE
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; If not, see 
<http://www.gnu.org/licenses/>.
- *
- * @section DESCRIPTION
- *
- *  Originally borrowed from the Qubes OS Project, http://www.qubes-os.org,
- *  this code has been substantially rewritten to use the gntdev and gntalloc
- *  devices instead of raw MFNs and map_foreign_range.
- *
- *  This is a library for inter-domain communication.  A standard Xen ring
- *  buffer is used, with a datagram-based interface built on top.  The grant
- *  reference and event channels are shared in XenStore under the path
- *  /local/domain/<srv-id>/data/vchan/<cli-id>/<port>/{ring-ref,event-channel}
- *
- *  The ring.h macros define an asymmetric interface to a shared data structure
- *  that assumes all rings reside in a single contiguous memory space. This is
- *  not suitable for vchan because the interface to the ring is symmetric 
except
- *  for the setup. Unlike the producer-consumer rings defined in ring.h, the
- *  size of the rings used in vchan are determined at execution time instead of
- *  compile time, so the macros in ring.h cannot be used to access the rings.
- */
-
-#include <xen/io/libxenvchan.h>
-#include <xen/xen.h>
-#include <xen/sys/evtchn.h>
-#include <xenevtchn.h>
-#include <xengnttab.h>
-
-/* Callers who don't care don't need to #include <xentoollog.h> */
-struct xentoollog_logger;
-
-struct libxenvchan_ring {
-       /* Pointer into the shared page. Offsets into buffer. */
-       struct ring_shared* shr;
-       /* ring data; may be its own shared page(s) depending on order */
-       void* buffer;
-       /**
-        * The size of the ring is (1 << order); offsets wrap around when they
-        * exceed this. This copy is required because we can't trust the order
-        * in the shared page to remain constant.
-        */
-       int order;
-};
-
-/**
- * struct libxenvchan: control structure passed to all library calls
- */
-struct libxenvchan {
-       /* Mapping handle for shared ring page */
-       union {
-               xengntshr_handle *gntshr; /* for server */
-               xengnttab_handle *gnttab; /* for client */
-       };
-       /* Pointer to shared ring page */
-       struct vchan_interface *ring;
-       /* event channel interface */
-       xenevtchn_handle *event;
-       uint32_t event_port;
-       /* informative flags: are we acting as server? */
-       int is_server:1;
-       /* true if server remains active when client closes (allows 
reconnection) */
-       int server_persist:1;
-       /* true if operations should block instead of returning 0 */
-       int blocking:1;
-       /* communication rings */
-       struct libxenvchan_ring read, write;
-};
-
-/**
- * Set up a vchan, including granting pages
- * @param logger Logger for libxc errors
- * @param domain The peer domain that will be connecting
- * @param xs_path Base xenstore path for storing ring/event data
- * @param send_min The minimum size (in bytes) of the send ring (left)
- * @param recv_min The minimum size (in bytes) of the receive ring (right)
- * @return The structure, or NULL in case of an error
- */
-struct libxenvchan *libxenvchan_server_init(struct xentoollog_logger *logger,
-                                            int domain, const char* xs_path,
-                                            size_t read_min, size_t write_min);
-/**
- * Connect to an existing vchan. Note: you can reconnect to an existing vchan
- * safely, however no locking is performed, so you must prevent multiple 
clients
- * from connecting to a single server.
- *
- * @param logger Logger for libxc errors
- * @param domain The peer domain to connect to
- * @param xs_path Base xenstore path for storing ring/event data
- * @return The structure, or NULL in case of an error
- */
-struct libxenvchan *libxenvchan_client_init(struct xentoollog_logger *logger,
-                                            int domain, const char* xs_path);
-/**
- * Close a vchan. This deallocates the vchan and attempts to free its
- * resources. The other side is notified of the close, but can still read any
- * data pending prior to the close.
- */
-void libxenvchan_close(struct libxenvchan *ctrl);
-
-/**
- * Packet-based receive: always reads exactly $size bytes.
- * @param ctrl The vchan control structure
- * @param data Buffer for data that was read
- * @param size Size of the buffer and amount of data to read
- * @return -1 on error, 0 if nonblocking and insufficient data is available, 
or $size
- */
-int libxenvchan_recv(struct libxenvchan *ctrl, void *data, size_t size);
-/**
- * Stream-based receive: reads as much data as possible.
- * @param ctrl The vchan control structure
- * @param data Buffer for data that was read
- * @param size Size of the buffer
- * @return -1 on error, otherwise the amount of data read (which may be zero if
- *         the vchan is nonblocking)
- */
-int libxenvchan_read(struct libxenvchan *ctrl, void *data, size_t size);
-/**
- * Packet-based send: send entire buffer if possible
- * @param ctrl The vchan control structure
- * @param data Buffer for data to send
- * @param size Size of the buffer and amount of data to send
- * @return -1 on error, 0 if nonblocking and insufficient space is available, 
or $size
- */
-int libxenvchan_send(struct libxenvchan *ctrl, const void *data, size_t size);
-/**
- * Stream-based send: send as much data as possible.
- * @param ctrl The vchan control structure
- * @param data Buffer for data to send
- * @param size Size of the buffer
- * @return -1 on error, otherwise the amount of data sent (which may be zero if
- *         the vchan is nonblocking)
- */
-int libxenvchan_write(struct libxenvchan *ctrl, const void *data, size_t size);
-/**
- * Waits for reads or writes to unblock, or for a close
- */
-int libxenvchan_wait(struct libxenvchan *ctrl);
-/**
- * Returns the event file descriptor for this vchan. When this FD is readable,
- * libxenvchan_wait() will not block, and the state of the vchan has changed 
since
- * the last invocation of libxenvchan_wait().
- */
-int libxenvchan_fd_for_select(struct libxenvchan *ctrl);
-/**
- * Query the state of the vchan shared page:
- *  return 0 when one side has called libxenvchan_close() or crashed
- *  return 1 when both sides are open
- *  return 2 [server only] when no client has yet connected
- */
-int libxenvchan_is_open(struct libxenvchan* ctrl);
-/** Amount of data ready to read, in bytes */
-int libxenvchan_data_ready(struct libxenvchan *ctrl);
-/** Amount of data it is possible to send without blocking */
-int libxenvchan_buffer_space(struct libxenvchan *ctrl);
diff --git a/tools/libvchan/node-select.c b/tools/libvchan/node-select.c
deleted file mode 100644
index 039464427a..0000000000
--- a/tools/libvchan/node-select.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *
- *  Authors:
- *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- *
- * @section LICENSE
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; If not, see 
<http://www.gnu.org/licenses/>.
- *
- * @section DESCRIPTION
- *
- * This is a test program for libxenvchan.  Communications are bidirectional,
- * with either server (grant offeror) or client able to read and write.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-
-#include <libxenvchan.h>
-
-static void usage(char** argv)
-{
-       fprintf(stderr, "usage:\n"
-               "\t%s [client|server] domainid nodepath [rbufsiz wbufsiz]\n",
-               argv[0]);
-       exit(1);
-}
-
-#define BUFSIZE 5000
-char inbuf[BUFSIZE];
-char outbuf[BUFSIZE];
-int insiz = 0;
-int outsiz = 0;
-struct libxenvchan *ctrl = 0;
-
-static void vchan_wr(void) {
-       int ret;
-
-       if (!insiz)
-               return;
-       ret = libxenvchan_write(ctrl, inbuf, insiz);
-       if (ret < 0) {
-               fprintf(stderr, "vchan write failed\n");
-               exit(1);
-       }
-       if (ret > 0) {
-               insiz -= ret;
-               memmove(inbuf, inbuf + ret, insiz);
-       }
-}
-
-static void stdout_wr(void) {
-       int ret;
-
-       if (!outsiz)
-               return;
-       ret = write(1, outbuf, outsiz);
-       if (ret < 0 && errno != EAGAIN)
-               exit(1);
-       if (ret > 0) {
-               outsiz -= ret;
-               memmove(outbuf, outbuf + ret, outsiz);
-       }
-}
-
-static int set_nonblocking(int fd, int nonblocking) {
-       int flags = fcntl(fd, F_GETFL);
-       if (flags == -1)
-               return -1;
-
-       if (nonblocking)
-               flags |= O_NONBLOCK;
-       else
-               flags &= ~O_NONBLOCK;
-
-       if (fcntl(fd, F_SETFL, flags) == -1)
-               return -1;
-
-       return 0;
-}
-
-/**
-    Simple libxenvchan application, both client and server.
-       Both sides may write and read, both from the libxenvchan and from 
-       stdin/stdout (just like netcat).
-*/
-
-int main(int argc, char **argv)
-{
-       int ret;
-       int libxenvchan_fd;
-       if (argc < 4 || argv[3][0] != '/')
-               usage(argv);
-       if (!strcmp(argv[1], "server")) {
-               int rsiz = argc > 4 ? atoi(argv[4]) : 0;
-               int wsiz = argc > 5 ? atoi(argv[5]) : 0;
-               ctrl = libxenvchan_server_init(NULL, atoi(argv[2]), argv[3], 
rsiz, wsiz);
-       } else if (!strcmp(argv[1], "client"))
-               ctrl = libxenvchan_client_init(NULL, atoi(argv[2]), argv[3]);
-       else
-               usage(argv);
-       if (!ctrl) {
-               perror("libxenvchan_*_init");
-               exit(1);
-       }
-
-       if (set_nonblocking(0, 1) || set_nonblocking(1, 1)) {
-               perror("set_nonblocking");
-               exit(1);
-       }
-
-       libxenvchan_fd = libxenvchan_fd_for_select(ctrl);
-       for (;;) {
-               fd_set rfds;
-               fd_set wfds;
-               FD_ZERO(&rfds);
-               FD_ZERO(&wfds);
-               if (insiz != BUFSIZE)
-                       FD_SET(0, &rfds);
-               if (outsiz)
-                       FD_SET(1, &wfds);
-               FD_SET(libxenvchan_fd, &rfds);
-               ret = select(libxenvchan_fd + 1, &rfds, &wfds, NULL, NULL);
-               if (ret < 0) {
-                       perror("select");
-                       exit(1);
-               }
-               if (FD_ISSET(0, &rfds)) {
-                       ret = read(0, inbuf + insiz, BUFSIZE - insiz);
-                       if (ret < 0 && errno != EAGAIN)
-                               exit(1);
-                       if (ret == 0) {
-                               while (insiz) {
-                                       vchan_wr();
-                                       libxenvchan_wait(ctrl);
-                               }
-                               return 0;
-                       }
-                       if (ret)
-                               insiz += ret;
-                       vchan_wr();
-               }
-               if (FD_ISSET(libxenvchan_fd, &rfds)) {
-                       libxenvchan_wait(ctrl);
-                       vchan_wr();
-               }
-               if (FD_ISSET(1, &wfds))
-                       stdout_wr();
-               while (libxenvchan_data_ready(ctrl) && outsiz < BUFSIZE) {
-                       ret = libxenvchan_read(ctrl, outbuf + outsiz, BUFSIZE - 
outsiz);
-                       if (ret < 0)
-                               exit(1);
-                       outsiz += ret;
-                       stdout_wr();
-               }
-               if (!libxenvchan_is_open(ctrl)) {
-                       if (set_nonblocking(1, 0)) {
-                               perror("set_nonblocking");
-                               exit(1);
-                       }
-                       while (outsiz)
-                               stdout_wr();
-                       return 0;
-               }
-       }
-}
diff --git a/tools/libvchan/node.c b/tools/libvchan/node.c
deleted file mode 100644
index f1638f013d..0000000000
--- a/tools/libvchan/node.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *
- *  Authors:
- *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- *
- * @section LICENSE
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; If not, see 
<http://www.gnu.org/licenses/>.
- *
- * @section DESCRIPTION
- *
- * This is a test program for libxenvchan.  Communications are in one 
direction,
- * either server (grant offeror) to client or vice versa.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <libxenvchan.h>
-
-int libxenvchan_write_all(struct libxenvchan *ctrl, char *buf, int size)
-{
-       int written = 0;
-       int ret;
-       while (written < size) {
-               ret = libxenvchan_write(ctrl, buf + written, size - written);
-               if (ret <= 0) {
-                       perror("write");
-                       exit(1);
-               }
-               written += ret;
-       }
-       return size;
-}
-
-int write_all(int fd, char *buf, int size)
-{
-       int written = 0;
-       int ret;
-       while (written < size) {
-               ret = write(fd, buf + written, size - written);
-               if (ret <= 0) {
-                       perror("write");
-                       exit(1);
-               }
-               written += ret;
-       }
-       return size;
-}
-
-void usage(char** argv)
-{
-       fprintf(stderr, "usage:\n"
-               "%s [client|server] [read|write] domid nodepath\n", argv[0]);
-       exit(1);
-}
-
-#define BUFSIZE 5000
-char buf[BUFSIZE];
-void reader(struct libxenvchan *ctrl)
-{
-       int size;
-       for (;;) {
-               size = rand() % (BUFSIZE - 1) + 1;
-               size = libxenvchan_read(ctrl, buf, size);
-               fprintf(stderr, "#");
-               if (size < 0) {
-                       perror("read vchan");
-                       libxenvchan_close(ctrl);
-                       exit(1);
-               }
-               size = write_all(1, buf, size);
-               if (size < 0) {
-                       perror("stdout write");
-                       exit(1);
-               }
-               if (size == 0) {
-                       perror("write size=0?\n");
-                       exit(1);
-               }
-       }
-}
-
-void writer(struct libxenvchan *ctrl)
-{
-       int size;
-       for (;;) {
-               size = rand() % (BUFSIZE - 1) + 1;
-               size = read(0, buf, size);
-               if (size < 0) {
-                       perror("read stdin");
-                       libxenvchan_close(ctrl);
-                       exit(1);
-               }
-               if (size == 0)
-                       break;
-               size = libxenvchan_write_all(ctrl, buf, size);
-               fprintf(stderr, "#");
-               if (size < 0) {
-                       perror("vchan write");
-                       exit(1);
-               }
-               if (size == 0) {
-                       perror("write size=0?\n");
-                       exit(1);
-               }
-       }
-}
-
-
-/**
-       Simple libxenvchan application, both client and server.
-       One side does writing, the other side does reading; both from
-       standard input/output fds.
-*/
-int main(int argc, char **argv)
-{
-       int seed = time(0);
-       struct libxenvchan *ctrl = 0;
-       int wr = 0;
-       if (argc < 4)
-               usage(argv);
-       if (!strcmp(argv[2], "read"))
-               wr = 0;
-       else if (!strcmp(argv[2], "write"))
-               wr = 1;
-       else
-               usage(argv);
-       if (!strcmp(argv[1], "server"))
-               ctrl = libxenvchan_server_init(NULL, atoi(argv[3]), argv[4], 0, 
0);
-       else if (!strcmp(argv[1], "client"))
-               ctrl = libxenvchan_client_init(NULL, atoi(argv[3]), argv[4]);
-       else
-               usage(argv);
-       if (!ctrl) {
-               perror("libxenvchan_*_init");
-               exit(1);
-       }
-       ctrl->blocking = 1;
-
-       srand(seed);
-       fprintf(stderr, "seed=%d\n", seed);
-       if (wr)
-               writer(ctrl);
-       else
-               reader(ctrl);
-       libxenvchan_close(ctrl);
-       return 0;
-}
diff --git a/tools/libvchan/vchan-socket-proxy.c 
b/tools/libvchan/vchan-socket-proxy.c
deleted file mode 100644
index e1d959c6d1..0000000000
--- a/tools/libvchan/vchan-socket-proxy.c
+++ /dev/null
@@ -1,533 +0,0 @@
-/**
- * @file
- * @section AUTHORS
- *
- * Copyright (C) 2010  Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *
- *  Authors:
- *       Rafal Wojtczuk  <rafal@xxxxxxxxxxxxxxxxxxxxxx>
- *       Daniel De Graaf <dgdegra@xxxxxxxxxxxxx>
- *       Marek Marczykowski-Górecki  <marmarek@xxxxxxxxxxxxxxxxxxxxxx>
- *
- * @section LICENSE
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this program; If not, see 
<http://www.gnu.org/licenses/>.
- *
- * @section DESCRIPTION
- *
- * This is a vchan to unix socket proxy. Vchan server is set, and on client
- * connection, local socket connection is established. Communication is 
bidirectional.
- * One client is served at a time, clients needs to coordinate this themselves.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <getopt.h>
-
-#include <xenstore.h>
-#include <xenctrl.h>
-#include <libxenvchan.h>
-
-static void usage(char** argv)
-{
-    fprintf(stderr, "usage:\n"
-        "\t%s [options] domainid nodepath [socket-path|file-no|-]\n"
-        "\n"
-        "options:\n"
-        "\t-m, --mode=client|server - vchan connection mode (client by 
default)\n"
-        "\t-s, --state-path=path - xenstore path where write \"running\" to \n"
-        "\t                        at startup\n"
-        "\t-v, --verbose - verbose logging\n"
-        "\n"
-        "client: client of a vchan connection, fourth parameter can be:\n"
-        "\tsocket-path: listen on a UNIX socket at this path and connect to 
vchan\n"
-        "\t             whenever new connection is accepted;\n"
-        "\t             handle multiple _subsequent_ connections, until 
terminated\n"
-        "\n"
-        "\tfile-no:     except open FD of a socket in listen mode;\n"
-        "\t             otherwise similar to socket-path\n"
-        "\n"
-        "\t-:           open vchan connection immediately and pass the data\n"
-        "\t             from stdin/stdout; terminate when vchan connection\n"
-        "\t             is closed\n"
-        "\n"
-        "server: server of a vchan connection, fourth parameter can be:\n"
-        "\tsocket-path: connect to this UNIX socket when new vchan 
connection\n"
-        "\t             is accepted;\n"
-        "\t             handle multiple _subsequent_ connections, until 
terminated\n"
-        "\n"
-        "\tfile-no:     pass data to/from this FD; terminate when vchan 
connection\n"
-        "\t             is closed\n"
-        "\n"
-        "\t-:           pass data to/from stdin/stdout; terminate when vchan\n"
-        "\t             connection is closed\n",
-        argv[0]);
-    exit(1);
-}
-
-#define BUFSIZE 8192
-char inbuf[BUFSIZE];
-char outbuf[BUFSIZE];
-int insiz = 0;
-int outsiz = 0;
-int verbose = 0;
-
-struct vchan_proxy_state {
-    struct libxenvchan *ctrl;
-    int output_fd;
-    int input_fd;
-};
-
-static void vchan_wr(struct libxenvchan *ctrl) {
-    int ret;
-
-    if (!insiz)
-        return;
-    ret = libxenvchan_write(ctrl, inbuf, insiz);
-    if (ret < 0) {
-        fprintf(stderr, "vchan write failed\n");
-        exit(1);
-    }
-    if (verbose)
-        fprintf(stderr, "wrote %d bytes to vchan\n", ret);
-    if (ret > 0) {
-        insiz -= ret;
-        memmove(inbuf, inbuf + ret, insiz);
-    }
-}
-
-static void socket_wr(int output_fd) {
-    int ret;
-
-    if (!outsiz)
-        return;
-    ret = write(output_fd, outbuf, outsiz);
-    if (ret < 0 && errno != EAGAIN)
-        exit(1);
-    if (ret > 0) {
-        outsiz -= ret;
-        memmove(outbuf, outbuf + ret, outsiz);
-    }
-}
-
-static int set_nonblocking(int fd, int nonblocking) {
-    int flags = fcntl(fd, F_GETFL);
-    if (flags == -1)
-        return -1;
-
-    if (nonblocking)
-        flags |= O_NONBLOCK;
-    else
-        flags &= ~O_NONBLOCK;
-
-    if (fcntl(fd, F_SETFL, flags) == -1)
-        return -1;
-
-    return 0;
-}
-
-static int connect_socket(const char *path_or_fd) {
-    int fd;
-    char *endptr;
-    struct sockaddr_un addr;
-
-    fd = strtoll(path_or_fd, &endptr, 0);
-    if (*endptr == '\0') {
-        set_nonblocking(fd, 1);
-        return fd;
-    }
-
-    if (strlen(path_or_fd) >= sizeof(addr.sun_path)) {
-        fprintf(stderr, "UNIX socket path \"%s\" too long (%zd >= %zd)\n",
-                path_or_fd, strlen(path_or_fd), sizeof(addr.sun_path));
-        return -1;
-    }
-
-    fd = socket(AF_UNIX, SOCK_STREAM, 0);
-    if (fd == -1) {
-        perror("socket");
-        return -1;
-    }
-
-    addr.sun_family = AF_UNIX;
-    strcpy(addr.sun_path, path_or_fd);
-    if (connect(fd, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        perror("connect");
-        close(fd);
-        return -1;
-    }
-
-    set_nonblocking(fd, 1);
-
-    return fd;
-}
-
-static int listen_socket(const char *path_or_fd) {
-    int fd;
-    char *endptr;
-    struct sockaddr_un addr;
-
-    fd = strtoll(path_or_fd, &endptr, 0);
-    if (*endptr == '\0') {
-        return fd;
-    }
-
-    if (strlen(path_or_fd) >= sizeof(addr.sun_path)) {
-        fprintf(stderr, "UNIX socket path \"%s\" too long (%zd >= %zd)\n",
-                path_or_fd, strlen(path_or_fd), sizeof(addr.sun_path));
-        return -1;
-    }
-
-    /* if not a number, assume a socket path */
-    fd = socket(AF_UNIX, SOCK_STREAM, 0);
-    if (fd == -1) {
-        perror("socket");
-        return -1;
-    }
-
-    addr.sun_family = AF_UNIX;
-    strcpy(addr.sun_path, path_or_fd);
-    if (bind(fd, (const struct sockaddr *)&addr, sizeof(addr)) == -1) {
-        perror("bind");
-        close(fd);
-        return -1;
-    }
-    if (listen(fd, 5) != 0) {
-        perror("listen");
-        close(fd);
-        return -1;
-    }
-
-    return fd;
-}
-
-static struct libxenvchan *connect_vchan(int domid, const char *path) {
-    struct libxenvchan *ctrl = NULL;
-    struct xs_handle *xs = NULL;
-    xc_interface *xc = NULL;
-    xc_dominfo_t dominfo;
-    char **watch_ret;
-    unsigned int watch_num;
-    int ret;
-
-    xs = xs_open(XS_OPEN_READONLY);
-    if (!xs) {
-        perror("xs_open");
-        goto out;
-    }
-    xc = xc_interface_open(NULL, NULL, XC_OPENFLAG_NON_REENTRANT);
-    if (!xc) {
-        perror("xc_interface_open");
-        goto out;
-    }
-    /* wait for vchan server to create *path* */
-    if (!xs_watch(xs, path, "path")) {
-        fprintf(stderr, "xs_watch(%s) failed.\n", path);
-        goto out;
-    }
-    if (!xs_watch(xs, "@releaseDomain", "release")) {
-        fprintf(stderr, "xs_watch(@releaseDomain failed.\n");
-        goto out;
-    }
-
-    while ((watch_ret = xs_read_watch(xs, &watch_num))) {
-        /* don't care about exact which fired the watch */
-        free(watch_ret);
-        ctrl = libxenvchan_client_init(NULL, domid, path);
-        if (ctrl)
-            break;
-
-        ret = xc_domain_getinfo(xc, domid, 1, &dominfo);
-        /* break the loop if domain is definitely not there anymore, but
-         * continue if it is or the call failed (like EPERM) */
-        if (ret == -1 && errno == ESRCH)
-            break;
-        if (ret == 1 && (dominfo.domid != (uint32_t)domid || dominfo.dying))
-            break;
-    }
-
-out:
-    if (xc)
-        xc_interface_close(xc);
-    if (xs)
-        xs_close(xs);



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.