All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries
@ 2015-06-10 11:36 Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library Ian Campbell
                   ` (10 more replies)
  0 siblings, 11 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel; +Cc: Ian Jackson, Roger Pau Monne, Wei Liu, Stefano Stabellini

In <1431963008.4944.80.camel@citrix.com> I proposed stabilising some
parts of the libxenctrl API/ABI by disaggregating into separate
libraries.

As a proof of concept these three intertangled series[0] splits out the
xentoollog and event channel device interfaces.

Still to come would be at least the grant table interfaces and a basic
hypercall making facility (including the buffers etc), followed by
libraries for specific out of tree purposes (device model, kexec).

The new libraries use linker version-scripts to hopefully make future
ABI changes be possible in a compatible way.

I decided to move the event channel functions into a new namespace
(xenevtchn_*) in order to provide a clean break from the old unstable
interfaces to the new stable ones. I've updated all the in tree callers
and qemu-trad and provided a compat shim in libxenctrl for other out of
tree users (which is used for qemu-upstream). My hope is that this can
be removed sooner rather than later. I intend to do the same for the
other interfaces. I haven't done this for the xentoollog stuff since it
already had a separate namespace.

I mulled over putting everything into tools/libs/FOO instead of
tools/libxenFOO, I didn't but I could if people think it is worthwhile.
Eventually I'd like to split libxc into libxenguest and libxenctrl to
cut down on the amount of strange cross talk...

As part of this change I've begun to get rid of the osdep interface
layer, since it is obsolete and just gets in the way. IIRC there were
some tricks being played to use this on rumpkernels to mix and match
facilities from xc_minios.c and xc_netbsd.c. Once the hypercall calling
and grant interfaces are in separate libraries are split this would
become easier since each library can independently choose the desired
backend.

The whole thing has been build tested on Linux and stubdoms, but not
FreeBSD, NetBSD or Solaris. It's certainly not impossible that I've not
got the #includes in the new files quite right.

Ian.

[0] There are 3 series, against xen.git, mini-os.git and
qemu-xen-trad.git. The patches against xen.git point to the patches in
the other two trees with instructions to update the relevant Config.mk
field. The perils of changing unstable interfaces...

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
@ 2015-06-10 11:36 ` Ian Campbell
  2015-06-11 11:20   ` Andrew Cooper
  2015-06-10 11:36 ` [PATCH RFC tools 2/6] tools: Link in-tree libvchan users against libxenvchan.so Ian Campbell
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

In attempting to disaggregate libxenctrl I found that many of the
pieces were going to want access to this library, so split it out (as
it probably should always have been).

Various build adjustments are needed. In particular things which use
xtl_* themselves now need to explicity link against the library.

This has a nice side effect which is that users of libxl no longer
need to link against libxenctrl just to create a logger.

The new library uses a version script to ensure that only expected
symbols are exported and to version them such that ABI guarantees can
be kept in the future.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>

---
Must be applied with:

- "qemu-xen-traditional: Use xentoollog as a separate library" and a
  corresponding QEMU_TAG update folded here.
- "mini-os: Include libxentoollog with libxc" and a corresponding bump
  to MINIOS_UPSTREAM_REVISION folded in here.
---
 .gitignore                               |    1 +
 stubdom/Makefile                         |   20 +++-
 stubdom/grub/Makefile                    |    1 +
 tools/Makefile                           |    3 +
 tools/Rules.mk                           |   15 ++-
 tools/libxc/Makefile                     |    7 +-
 tools/libxc/include/xentoollog.h         |  137 ---------------------
 tools/libxc/xtl_core.c                   |   84 -------------
 tools/libxc/xtl_logger_stdio.c           |  190 ------------------------------
 tools/libxentoollog/Makefile             |   59 ++++++++++
 tools/libxentoollog/include/xentoollog.h |  137 +++++++++++++++++++++
 tools/libxentoollog/libxentoollog.map    |   12 ++
 tools/libxentoollog/xtl_core.c           |   84 +++++++++++++
 tools/libxentoollog/xtl_logger_stdio.c   |  190 ++++++++++++++++++++++++++++++
 tools/libxl/Makefile                     |   15 +--
 tools/ocaml/Makefile.rules               |   26 ++--
 tools/ocaml/libs/xentoollog/Makefile     |    6 +-
 tools/ocaml/libs/xentoollog/genlevels.py |    2 +-
 tools/python/setup.py                    |    5 +-
 tools/xenpaging/Makefile                 |    2 +-
 20 files changed, 548 insertions(+), 448 deletions(-)
 delete mode 100644 tools/libxc/include/xentoollog.h
 delete mode 100644 tools/libxc/xtl_core.c
 delete mode 100644 tools/libxc/xtl_logger_stdio.c
 create mode 100644 tools/libxentoollog/Makefile
 create mode 100644 tools/libxentoollog/include/xentoollog.h
 create mode 100644 tools/libxentoollog/libxentoollog.map
 create mode 100644 tools/libxentoollog/xtl_core.c
 create mode 100644 tools/libxentoollog/xtl_logger_stdio.c

diff --git a/.gitignore b/.gitignore
index 3bc9cd9..49935f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -59,6 +59,7 @@ stubdom/gcc-*
 stubdom/include
 stubdom/ioemu
 stubdom/xenstore
+stubdom/libxentoollog-*
 stubdom/libxc-*
 stubdom/lwip-*
 stubdom/mini-os-*
diff --git a/stubdom/Makefile b/stubdom/Makefile
index faa7c21..b8b0d43 100644
--- a/stubdom/Makefile
+++ b/stubdom/Makefile
@@ -313,6 +313,11 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET)
 	  ln -sf $(wildcard $(XEN_ROOT)/tools/include/xen-foreign/*) include/xen-foreign/ && \
 	  $(MAKE) DESTDIR= -C include/xen-foreign/ && \
 	  ( [ -h include/xen/foreign ] || ln -sf ../xen-foreign include/xen/foreign )
+	mkdir -p libxentoollog-$(XEN_TARGET_ARCH)
+	[ -h libxentoollog-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxentoollog-$(XEN_TARGET_ARCH) && \
+	  ln -sf $(XEN_ROOT)/tools/libxentoollog/include/*.h . && \
+	  ln -sf $(XEN_ROOT)/tools/libxentoollog/*.c . && \
+	  ln -sf $(XEN_ROOT)/tools/libxentoollog/Makefile . )
 	mkdir -p libxc-$(XEN_TARGET_ARCH)
 	[ -h libxc-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxc-$(XEN_TARGET_ARCH) && \
 	  ln -sf $(XEN_ROOT)/tools/libxc/*.h . && \
@@ -336,12 +341,23 @@ $(TARGETS_MINIOS): mini-os-%:
 	done
 
 #######
+# libxentoollog
+#######
+
+.PHONY: libxentoollog
+libxentoollog: libxentoollog-$(XEN_TARGET_ARCH)/libxentoollog.a
+libxentoollog-$(XEN_TARGET_ARCH)/libxentoollog.a: $(NEWLIB_STAMPFILE)
+	$(MAKE) -C $(XEN_ROOT)/tools/include
+	$(MAKE) DESTDIR= -C $(MINI_OS) links
+	CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxentoollog-$(XEN_TARGET_ARCH)
+
+#######
 # libxc
 #######
 
 .PHONY: libxc
 libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a libxc-$(XEN_TARGET_ARCH)/libxenguest.a
-libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: cross-zlib
+libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog cross-zlib
 	$(MAKE) -C $(XEN_ROOT)/tools/include
 	$(MAKE) DESTDIR= -C $(MINI_OS) links
 	CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH)
@@ -519,6 +535,7 @@ clean:
 	$(MAKE) -C vtpmmgr clean
 	rm -fr grub-$(XEN_TARGET_ARCH)
 	rm -f $(STUBDOMPATH)
+	[ ! -e libxentoollog-$(XEN_TARGET_ARCH)/Makefile ] || $(MAKE) DESTDIR= -C libxentoollog-$(XEN_TARGET_ARCH) clean
 	[ ! -e libxc-$(XEN_TARGET_ARCH)/Makefile ] || $(MAKE) DESTDIR= -C libxc-$(XEN_TARGET_ARCH) clean
 	-[ ! -d ioemu ] || $(MAKE) DESTDIR= -C ioemu clean
 	-[ ! -d xenstore ] || $(MAKE) DESTDIR= -C xenstore clean
@@ -529,6 +546,7 @@ crossclean: clean
 	rm -fr $(CROSS_ROOT)
 	rm -fr newlib-$(XEN_TARGET_ARCH)
 	rm -fr zlib-$(XEN_TARGET_ARCH) pciutils-$(XEN_TARGET_ARCH)
+	rm -fr libxentoollog-$(XEN_TARGET_ARCH)
 	rm -fr libxc-$(XEN_TARGET_ARCH) ioemu xenstore
 	rm -fr gmp-$(XEN_TARGET_ARCH)
 	rm -fr polarssl-$(XEN_TARGET_ARCH)
diff --git a/stubdom/grub/Makefile b/stubdom/grub/Makefile
index 934cc4c..4969274 100644
--- a/stubdom/grub/Makefile
+++ b/stubdom/grub/Makefile
@@ -5,6 +5,7 @@ vpath %.c ../grub-upstream
 
 BOOT=$(OBJ_DIR)/boot-$(XEN_TARGET_ARCH).o
 
+DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libxentoollog/include
 DEF_CPPFLAGS += -I$(XEN_ROOT)/tools/libxc/include -I$(XEN_ROOT)/tools/include -I.
 DEF_CPPFLAGS += -I../grub-upstream/stage1
 DEF_CPPFLAGS += -I../grub-upstream/stage2
diff --git a/tools/Makefile b/tools/Makefile
index 45cb4b2..777591a 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -3,6 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 SUBDIRS-y :=
 SUBDIRS-y += include
+SUBDIRS-y += libxentoollog
 SUBDIRS-y += libxc
 SUBDIRS-$(FLASK_ENABLE) += flask
 SUBDIRS-y += xenstore
@@ -248,12 +249,14 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find
 		--includedir=$(LIBEXEC_INC) \
 		--source-path=$$source \
 		--extra-cflags="-I$(XEN_ROOT)/tools/include \
+		-I$(XEN_ROOT)/tools/libxentoollog/include \
 		-I$(XEN_ROOT)/tools/libxc/include \
 		-I$(XEN_ROOT)/tools/xenstore/include \
 		-I$(XEN_ROOT)/tools/xenstore/compat/include \
 		$(EXTRA_CFLAGS_QEMU_XEN)" \
 		--extra-ldflags="-L$(XEN_ROOT)/tools/libxc \
 		-L$(XEN_ROOT)/tools/xenstore \
+		-Wl,-rpath-link=$(XEN_ROOT)/tools/libxentoollog \
 		$(QEMU_UPSTREAM_RPATH)" \
 		--bindir=$(LIBEXEC_BIN) \
 		--datadir=$(SHAREDIR)/qemu-xen \
diff --git a/tools/Rules.mk b/tools/Rules.mk
index 3c29d07..bf85e5e 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -10,6 +10,7 @@ export _INSTALL := $(INSTALL)
 INSTALL = $(XEN_ROOT)/tools/cross-install
 
 XEN_INCLUDE        = $(XEN_ROOT)/tools/include
+XEN_LIBXENTOOLLOG  = $(XEN_ROOT)/tools/libxentoollog
 XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
 XEN_XENLIGHT       = $(XEN_ROOT)/tools/libxl
 XEN_XENSTORE       = $(XEN_ROOT)/tools/xenstore
@@ -34,9 +35,13 @@ INSTALL_SHLIB = : install-shlib-unsupported-fail
 SYMLINK_SHLIB = : symlink-shlib-unsupported-fail
 endif
 
-CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_xeninclude)
-LDLIBS_libxenctrl = $(XEN_LIBXC)/libxenctrl$(libextension)
-SHLIB_libxenctrl  = -Wl,-rpath-link=$(XEN_LIBXC)
+CFLAGS_libxentoollog = -I$(XEN_LIBXENTOOLLOG)/include $(CFLAGS_xeninclude)
+LDLIBS_libxentoollog = $(XEN_LIBXENTOOLLOG)/libxentoollog$(libextension)
+SHLIB_libxentoollog  = -Wl,-rpath-link=$(XEN_LIBXENTOOLLOG)
+
+CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude)
+LDLIBS_libxenctrl = $(SHLIB_libxentoollog) $(XEN_LIBXC)/libxenctrl$(libextension)
+SHLIB_libxenctrl  =  $(SHLIB_libxentoollog) -Wl,-rpath-link=$(XEN_LIBXC)
 
 CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_xeninclude)
 LDLIBS_libxenguest = $(XEN_LIBXC)/libxenguest$(libextension)
@@ -48,11 +53,11 @@ SHLIB_libxenstore  = -Wl,-rpath-link=$(XEN_XENSTORE)
 
 CFLAGS_libxenstat  = -I$(XEN_LIBXENSTAT)
 LDLIBS_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBXENSTAT)/libxenstat$(libextension)
-SHLIB_libxenstat  = -Wl,-rpath-link=$(XEN_LIBXENSTAT)
+SHLIB_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBXENSTAT)
 
 CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN)
 LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -L$(XEN_LIBVCHAN) -lxenvchan
-SHLIB_libxenvchan  = -Wl,-rpath-link=$(XEN_LIBVCHAN)
+SHLIB_libxenvchan  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBVCHAN)
 
 ifeq ($(debug),y)
 # Disable optimizations and enable debugging information for macros
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 55782c8..877ea62 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -39,8 +39,6 @@ CTRL_SRCS-y       += xc_memshr.c
 CTRL_SRCS-y       += xc_hcall_buf.c
 CTRL_SRCS-y       += xc_foreign_memory.c
 CTRL_SRCS-y       += xc_kexec.c
-CTRL_SRCS-y       += xtl_core.c
-CTRL_SRCS-y       += xtl_logger_stdio.c
 CTRL_SRCS-y       += xc_resource.c
 CTRL_SRCS-$(CONFIG_X86) += xc_psr.c
 CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
@@ -115,6 +113,7 @@ CFLAGS   += -I. -I./include $(CFLAGS_xeninclude)
 CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE
 
 CFLAGS	+= $(PTHREAD_CFLAGS)
+CFLAGS	+= $(CFLAGS_libxentoollog)
 
 CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
 CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y))
@@ -168,7 +167,7 @@ install: build
 	$(INSTALL_DATA) libxenctrl.a $(DESTDIR)$(libdir)
 	$(SYMLINK_SHLIB) libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenctrl.so.$(MAJOR)
 	$(SYMLINK_SHLIB) libxenctrl.so.$(MAJOR) $(DESTDIR)$(libdir)/libxenctrl.so
-	$(INSTALL_DATA) include/xenctrl.h include/xenctrlosdep.h include/xentoollog.h $(DESTDIR)$(includedir)
+	$(INSTALL_DATA) include/xenctrl.h include/xenctrlosdep.h $(DESTDIR)$(includedir)
 	$(INSTALL_SHLIB) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
 	$(INSTALL_DATA) libxenguest.a $(DESTDIR)$(libdir)
 	$(SYMLINK_SHLIB) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenguest.so.$(MAJOR)
@@ -211,7 +210,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
 	$(SYMLINK_SHLIB) $< $@
 
 libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
-	$(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
 
 # libxenguest
 
diff --git a/tools/libxc/include/xentoollog.h b/tools/libxc/include/xentoollog.h
deleted file mode 100644
index 85d3da9..0000000
--- a/tools/libxc/include/xentoollog.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * xentoollog.h
- *
- * Copyright (c) 2010 Citrix
- * Part of a generic logging interface used by various dom0 userland libraries.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifndef XENTOOLLOG_H
-#define XENTOOLLOG_H
-
-#include <stdio.h>
-#include <stdarg.h>
-
-
-/*---------- common declarations and types ----------*/
-
-typedef enum xentoollog_level {
-    XTL_NONE, /* sentinel etc, never used for logging */
-    XTL_DEBUG,
-    XTL_VERBOSE,
-    XTL_DETAIL,
-    XTL_PROGRESS, /* also used for "progress" messages */
-    XTL_INFO,
-    XTL_NOTICE,
-    XTL_WARN,
-    XTL_ERROR,
-    XTL_CRITICAL,
-    XTL_NUM_LEVELS
-} xentoollog_level;
-
-typedef struct xentoollog_logger xentoollog_logger;
-struct xentoollog_logger {
-    void (*vmessage)(struct xentoollog_logger *logger,
-                     xentoollog_level level,
-                     int errnoval /* or -1 */,
-                     const char *context /* eg "xc", "xl", may be 0 */,
-                     const char *format /* without level, context, \n */,
-                     va_list al)
-         __attribute__((format(printf,5,0)));
-    void (*progress)(struct xentoollog_logger *logger,
-                     const char *context /* see above */,
-                     const char *doing_what /* no \r,\n */,
-                     int percent, unsigned long done, unsigned long total)
-         /* null function pointer is ok.
-          * will always be called with done==0 for each new
-          * context/doing_what */;
-    void (*destroy)(struct xentoollog_logger *logger);
-    /* each logger can put its necessary data here */
-};
-
-
-/*---------- facilities for consuming log messages ----------*/
-
-#define XTL_STDIOSTREAM_SHOW_PID            001u
-#define XTL_STDIOSTREAM_SHOW_DATE           002u
-#define XTL_STDIOSTREAM_HIDE_PROGRESS       004u
-#define XTL_STDIOSTREAM_PROGRESS_USE_CR     010u /* default is to */
-#define XTL_STDIOSTREAM_PROGRESS_NO_CR      020u /* use \r to ttys */
-
-typedef struct xentoollog_logger_stdiostream  xentoollog_logger_stdiostream;
-
-xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
-        (FILE *f, xentoollog_level min_level, unsigned flags);
-    /* may return 0 if malloc fails, in which case error was logged */
-    /* destroy on this logger does not close the file */
-
-void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream*,
-                                  xentoollog_level min_level);
-void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream*,
-                                  unsigned set_flags, unsigned clear_flags);
-  /* if set_flags and clear_flags overlap, set_flags takes precedence */
-
-void xtl_logger_destroy(struct xentoollog_logger *logger /* 0 is ok */);
-
-
-/*---------- facilities for generating log messages ----------*/
-
-void xtl_logv(struct xentoollog_logger *logger,
-              xentoollog_level level,
-              int errnoval /* or -1 */,
-              const char *context /* eg "xc", "xenstore", "xl", may be 0 */,
-              const char *format /* does not contain \n */,
-              va_list) __attribute__((format(printf,5,0)));
-
-void xtl_log(struct xentoollog_logger *logger,
-             xentoollog_level level,
-             int errnoval /* or -1 */,
-             const char *context /* eg "xc", "xenstore", "xl" */,
-             const char *format /* does not contain \n */,
-             ...) __attribute__((format(printf,5,6)));
-
-void xtl_progress(struct xentoollog_logger *logger,
-                  const char *context /* see above, may be 0 */,
-                  const char *doing_what,
-                  unsigned long done, unsigned long total);
-
-
-/*---------- facilities for defining log message consumers ----------*/
-
-const char *xtl_level_to_string(xentoollog_level); /* never fails */
-
-
-#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
-    xentoollog_logger_##LOGGER *new_consumer;                           \
-                                                                        \
-    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
-    (buffer).vtable.progress = LOGGER##_progress;                       \
-    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
-                                                                        \
-    new_consumer = malloc(sizeof(*new_consumer));                       \
-    if (!new_consumer) {                                                \
-        xtl_log((xentoollog_logger*)&buffer,                            \
-                XTL_CRITICAL, errno, "xtl",                             \
-                "failed to allocate memory for new message logger");    \
-    } else {                                                            \
-        *new_consumer = buffer;                                         \
-    }                                                                   \
-                                                                        \
-    new_consumer;                                                       \
-});
-
-
-#endif /* XENTOOLLOG_H */
diff --git a/tools/libxc/xtl_core.c b/tools/libxc/xtl_core.c
deleted file mode 100644
index 73add92..0000000
--- a/tools/libxc/xtl_core.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * xtl_core.c
- *
- * core code including functions for generating log messages
- *
- * Copyright (c) 2010 Citrix
- * Part of a generic logging interface used by various dom0 userland libraries.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "xentoollog.h"
-
-#include <assert.h>
-#include <errno.h>
-#include <limits.h>
-
-static const char *level_strings[XTL_NUM_LEVELS]= {
-    "[BUG:XTL_NONE]",
-    "debug", "verbose", "detail",  /* normally off by default */
-    "progress", "info", "notice",  /* not a problem */
-    "warning", "error", "critical" /* problems and errors */
-};
-
-const char *xtl_level_to_string(xentoollog_level level) {
-    assert(level >= 0 && level < XTL_NUM_LEVELS);
-    return level_strings[level];
-}
-
-void xtl_logv(struct xentoollog_logger *logger,
-              xentoollog_level level,
-              int errnoval /* or -1 */,
-              const char *context /* eg "xc", "xenstore", "xl" */,
-              const char *format /* does not contain \n */,
-              va_list al) {
-    int errno_save = errno;
-    assert(level > XTL_NONE && level < XTL_NUM_LEVELS);
-    logger->vmessage(logger,level,errnoval,context,format,al);
-    errno = errno_save;
-}
-
-void xtl_log(struct xentoollog_logger *logger,
-             xentoollog_level level,
-             int errnoval /* or -1 */,
-             const char *context /* eg "xc", "xenstore", "xl" */,
-             const char *format /* does not contain \n */,
-             ...) {
-    va_list al;
-    va_start(al,format);
-    xtl_logv(logger,level,errnoval,context,format,al);
-    va_end(al);
-}
-
-void xtl_progress(struct xentoollog_logger *logger,
-                  const char *context, const char *doing_what,
-                  unsigned long done, unsigned long total) {
-    int percent = 0;
-
-    if (!logger->progress) return;
-
-    if ( total )
-        percent = (total < LONG_MAX/100)
-            ? (done * 100) / total
-            : done / ((total + 99) / 100);
-
-    logger->progress(logger, context, doing_what, percent, done, total);
-}
-
-void xtl_logger_destroy(struct xentoollog_logger *logger) {
-    if (!logger) return;
-    logger->destroy(logger);
-}
diff --git a/tools/libxc/xtl_logger_stdio.c b/tools/libxc/xtl_logger_stdio.c
deleted file mode 100644
index d8646e0..0000000
--- a/tools/libxc/xtl_logger_stdio.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * xtl_logger_stdio.c
- *
- * log message consumer that writes to stdio
- *
- * Copyright (c) 2010 Citrix
- * Part of a generic logging interface used by various dom0 userland libraries.
- *
- * 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;
- * version 2.1 of the License.
- *
- * 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include "xentoollog.h"
-
-#include <time.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <stdbool.h>
-
-struct xentoollog_logger_stdiostream {
-    xentoollog_logger vtable;
-    FILE *f;
-    xentoollog_level min_level;
-    unsigned flags;
-    int progress_erase_len, progress_last_percent;
-    bool progress_use_cr;
-};
-
-static void progress_erase(xentoollog_logger_stdiostream *lg) {
-    if (lg->progress_erase_len)
-        fprintf(lg->f, "\r%*s\r", lg->progress_erase_len, "");
-}
-
-static void stdiostream_vmessage(xentoollog_logger *logger_in,
-                                 xentoollog_level level,
-                                 int errnoval,
-                                 const char *context,
-                                 const char *format,
-                                 va_list al) {
-    xentoollog_logger_stdiostream *lg = (void*)logger_in;
-
-    if (level < lg->min_level)
-        return;
-
-    progress_erase(lg);
-
-    if (lg->flags & XTL_STDIOSTREAM_SHOW_DATE) {
-        struct tm lt_buf;
-        time_t now = time(0);
-        struct tm *lt= localtime_r(&now, &lt_buf);
-        fprintf(lg->f, "%04d-%02d-%02d %02d:%02d:%02d %s ",
-                lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday,
-                lt->tm_hour, lt->tm_min, lt->tm_sec,
-                tzname[!!lt->tm_isdst]);
-    }
-    if (lg->flags & XTL_STDIOSTREAM_SHOW_PID)
-        fprintf(lg->f, "[%lu] ", (unsigned long)getpid());
-
-    if (context)
-        fprintf(lg->f, "%s: ", context);
-
-    fprintf(lg->f, "%s: ", xtl_level_to_string(level));
-
-    vfprintf(lg->f, format, al);
-
-    if (errnoval >= 0)
-        fprintf(lg->f, ": %s", strerror(errnoval));
-
-    putc('\n', lg->f);
-    fflush(lg->f);
-}
-
-static void stdiostream_message(struct xentoollog_logger *logger_in,
-                                xentoollog_level level,
-                                const char *context,
-                                const char *format, ...)
-{
-    va_list al;
-    va_start(al,format);
-    stdiostream_vmessage(logger_in, level, -1, context, format, al);
-    va_end(al);
-}
-
-static void stdiostream_progress(struct xentoollog_logger *logger_in,
-                                 const char *context,
-                                 const char *doing_what, int percent,
-                                 unsigned long done, unsigned long total) {
-    xentoollog_logger_stdiostream *lg = (void*)logger_in;
-    int newpel, extra_erase;
-    xentoollog_level this_level;
-
-    if (lg->flags & XTL_STDIOSTREAM_HIDE_PROGRESS)
-        return;
-
-    if (percent < lg->progress_last_percent) {
-        this_level = XTL_PROGRESS;
-    } else if (percent == lg->progress_last_percent) {
-        return;
-    } else if (percent < lg->progress_last_percent + 5) {
-        this_level = XTL_DETAIL;
-    } else {
-        this_level = XTL_PROGRESS;
-    }
-
-    if (this_level < lg->min_level)
-        return;
-
-    lg->progress_last_percent = percent;
-
-    if (!lg->progress_use_cr) {
-        stdiostream_message(logger_in, this_level, context,
-                            "%s: %lu/%lu  %3d%%",
-                            doing_what, done, total, percent);
-        return;
-    }
-
-    if (lg->progress_erase_len)
-        putc('\r', lg->f);
-
-    newpel = fprintf(lg->f, "%s%s" "%s: %lu/%lu  %3d%%%s",
-                     context?context:"", context?": ":"",
-                     doing_what, done, total, percent,
-		     done == total ? "\n" : "");
-
-    extra_erase = lg->progress_erase_len - newpel;
-    if (extra_erase > 0)
-        fprintf(lg->f, "%*s\r", extra_erase, "");
-
-    lg->progress_erase_len = newpel;
-}
-
-static void stdiostream_destroy(struct xentoollog_logger *logger_in) {
-    xentoollog_logger_stdiostream *lg = (void*)logger_in;
-    progress_erase(lg);
-    free(lg);
-}
-
-void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream *lg,
-                                  xentoollog_level min_level) {
-    lg->min_level = min_level;
-}
-
-void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream *lg,
-                                  unsigned set_flags, unsigned clear_flags) {
-    unsigned new_flags = (lg->flags & ~clear_flags) | set_flags;
-    if (new_flags & XTL_STDIOSTREAM_HIDE_PROGRESS)
-        progress_erase(lg);
-    lg->flags = new_flags;
-}
-
-xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
-        (FILE *f, xentoollog_level min_level, unsigned flags) {
-    xentoollog_logger_stdiostream newlogger;
-
-    newlogger.f = f;
-    newlogger.min_level = min_level;
-    newlogger.flags = flags;
-
-    switch (flags & (XTL_STDIOSTREAM_PROGRESS_USE_CR |
-                     XTL_STDIOSTREAM_PROGRESS_NO_CR)) {
-    case XTL_STDIOSTREAM_PROGRESS_USE_CR: newlogger.progress_use_cr = 1; break;
-    case XTL_STDIOSTREAM_PROGRESS_NO_CR:  newlogger.progress_use_cr = 0; break;
-    case 0:
-        newlogger.progress_use_cr = isatty(fileno(newlogger.f)) > 0;
-        break;
-    default:
-        errno = EINVAL;
-        return 0;
-    }
-
-    if (newlogger.flags & XTL_STDIOSTREAM_SHOW_DATE) tzset();
-
-    newlogger.progress_erase_len = 0;
-    newlogger.progress_last_percent = 0;
-
-    return XTL_NEW_LOGGER(stdiostream, newlogger);
-}
diff --git a/tools/libxentoollog/Makefile b/tools/libxentoollog/Makefile
new file mode 100644
index 0000000..dcb1e88
--- /dev/null
+++ b/tools/libxentoollog/Makefile
@@ -0,0 +1,59 @@
+XEN_ROOT = $(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+MAJOR	= 1
+MINOR	= 0
+SHLIB_LDFLAGS += -Wl,--version-script=libxentoollog.map
+
+CFLAGS	+= -Werror -Wmissing-prototypes
+CFLAGS	+= -I./include
+
+SRCS-y	+= xtl_core.c
+SRCS-y	+= xtl_logger_stdio.c
+
+LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y))
+PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y))
+
+LIB := libxentoollog.a
+ifneq ($(nosharedlibs),y)
+LIB += libxentoollog.so
+endif
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build:
+	$(MAKE) libs
+
+.PHONY: libs
+libs: $(LIB)
+
+libxentoollog.a: $(LIB_OBJS)
+	$(AR) rc $@ $^
+
+libxentoollog.so: libxentoollog.so.$(MAJOR)
+	$(SYMLINK_SHLIB) $< $@
+libxentoollog.so.$(MAJOR): libxentoollog.so.$(MAJOR).$(MINOR)
+	$(SYMLINK_SHLIB) $< $@
+
+libxentoollog.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxentoollog.map
+	$(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxentoollog.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(APPEND_LDFLAGS)
+
+.PHONY: install
+install: build
+	$(INSTALL_DIR) $(DESTDIR)$(libdir)
+	$(INSTALL_DIR) $(DESTDIR)$(includedir)
+	$(INSTALL_SHLIB) libxentoollog.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
+	$(INSTALL_DATA) libxentoollog.a $(DESTDIR)$(libdir)
+	$(SYMLINK_SHLIB) libxentoollog.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxentoollog.so.$(MAJOR)
+	$(SYMLINK_SHLIB) libxentoollog.so.$(MAJOR) $(DESTDIR)$(libdir)/libxentoollog.so
+	$(INSTALL_DATA) include/xentoollog.h $(DESTDIR)$(includedir)
+
+.PHONY: TAGS
+TAGS:
+	etags -t *.c *.h
+
+.PHONY: clean
+clean:
+	rm -rf *.rpm $(LIB) *~ $(DEPS) $(LIB_OBJS) $(PIC_OBJS)
diff --git a/tools/libxentoollog/include/xentoollog.h b/tools/libxentoollog/include/xentoollog.h
new file mode 100644
index 0000000..85d3da9
--- /dev/null
+++ b/tools/libxentoollog/include/xentoollog.h
@@ -0,0 +1,137 @@
+/*
+ * xentoollog.h
+ *
+ * Copyright (c) 2010 Citrix
+ * Part of a generic logging interface used by various dom0 userland libraries.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef XENTOOLLOG_H
+#define XENTOOLLOG_H
+
+#include <stdio.h>
+#include <stdarg.h>
+
+
+/*---------- common declarations and types ----------*/
+
+typedef enum xentoollog_level {
+    XTL_NONE, /* sentinel etc, never used for logging */
+    XTL_DEBUG,
+    XTL_VERBOSE,
+    XTL_DETAIL,
+    XTL_PROGRESS, /* also used for "progress" messages */
+    XTL_INFO,
+    XTL_NOTICE,
+    XTL_WARN,
+    XTL_ERROR,
+    XTL_CRITICAL,
+    XTL_NUM_LEVELS
+} xentoollog_level;
+
+typedef struct xentoollog_logger xentoollog_logger;
+struct xentoollog_logger {
+    void (*vmessage)(struct xentoollog_logger *logger,
+                     xentoollog_level level,
+                     int errnoval /* or -1 */,
+                     const char *context /* eg "xc", "xl", may be 0 */,
+                     const char *format /* without level, context, \n */,
+                     va_list al)
+         __attribute__((format(printf,5,0)));
+    void (*progress)(struct xentoollog_logger *logger,
+                     const char *context /* see above */,
+                     const char *doing_what /* no \r,\n */,
+                     int percent, unsigned long done, unsigned long total)
+         /* null function pointer is ok.
+          * will always be called with done==0 for each new
+          * context/doing_what */;
+    void (*destroy)(struct xentoollog_logger *logger);
+    /* each logger can put its necessary data here */
+};
+
+
+/*---------- facilities for consuming log messages ----------*/
+
+#define XTL_STDIOSTREAM_SHOW_PID            001u
+#define XTL_STDIOSTREAM_SHOW_DATE           002u
+#define XTL_STDIOSTREAM_HIDE_PROGRESS       004u
+#define XTL_STDIOSTREAM_PROGRESS_USE_CR     010u /* default is to */
+#define XTL_STDIOSTREAM_PROGRESS_NO_CR      020u /* use \r to ttys */
+
+typedef struct xentoollog_logger_stdiostream  xentoollog_logger_stdiostream;
+
+xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
+        (FILE *f, xentoollog_level min_level, unsigned flags);
+    /* may return 0 if malloc fails, in which case error was logged */
+    /* destroy on this logger does not close the file */
+
+void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream*,
+                                  xentoollog_level min_level);
+void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream*,
+                                  unsigned set_flags, unsigned clear_flags);
+  /* if set_flags and clear_flags overlap, set_flags takes precedence */
+
+void xtl_logger_destroy(struct xentoollog_logger *logger /* 0 is ok */);
+
+
+/*---------- facilities for generating log messages ----------*/
+
+void xtl_logv(struct xentoollog_logger *logger,
+              xentoollog_level level,
+              int errnoval /* or -1 */,
+              const char *context /* eg "xc", "xenstore", "xl", may be 0 */,
+              const char *format /* does not contain \n */,
+              va_list) __attribute__((format(printf,5,0)));
+
+void xtl_log(struct xentoollog_logger *logger,
+             xentoollog_level level,
+             int errnoval /* or -1 */,
+             const char *context /* eg "xc", "xenstore", "xl" */,
+             const char *format /* does not contain \n */,
+             ...) __attribute__((format(printf,5,6)));
+
+void xtl_progress(struct xentoollog_logger *logger,
+                  const char *context /* see above, may be 0 */,
+                  const char *doing_what,
+                  unsigned long done, unsigned long total);
+
+
+/*---------- facilities for defining log message consumers ----------*/
+
+const char *xtl_level_to_string(xentoollog_level); /* never fails */
+
+
+#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
+    xentoollog_logger_##LOGGER *new_consumer;                           \
+                                                                        \
+    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
+    (buffer).vtable.progress = LOGGER##_progress;                       \
+    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
+                                                                        \
+    new_consumer = malloc(sizeof(*new_consumer));                       \
+    if (!new_consumer) {                                                \
+        xtl_log((xentoollog_logger*)&buffer,                            \
+                XTL_CRITICAL, errno, "xtl",                             \
+                "failed to allocate memory for new message logger");    \
+    } else {                                                            \
+        *new_consumer = buffer;                                         \
+    }                                                                   \
+                                                                        \
+    new_consumer;                                                       \
+});
+
+
+#endif /* XENTOOLLOG_H */
diff --git a/tools/libxentoollog/libxentoollog.map b/tools/libxentoollog/libxentoollog.map
new file mode 100644
index 0000000..c183cf5
--- /dev/null
+++ b/tools/libxentoollog/libxentoollog.map
@@ -0,0 +1,12 @@
+VERS_1.0 {
+	global:
+		xtl_createlogger_stdiostream;
+		xtl_level_to_string;
+		xtl_log;
+		xtl_logger_destroy;
+		xtl_logv;
+		xtl_progress;
+		xtl_stdiostream_adjust_flags;
+		xtl_stdiostream_set_minlevel;
+	local: *; /* Do not expose anything by default */
+};
diff --git a/tools/libxentoollog/xtl_core.c b/tools/libxentoollog/xtl_core.c
new file mode 100644
index 0000000..73add92
--- /dev/null
+++ b/tools/libxentoollog/xtl_core.c
@@ -0,0 +1,84 @@
+/*
+ * xtl_core.c
+ *
+ * core code including functions for generating log messages
+ *
+ * Copyright (c) 2010 Citrix
+ * Part of a generic logging interface used by various dom0 userland libraries.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "xentoollog.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+
+static const char *level_strings[XTL_NUM_LEVELS]= {
+    "[BUG:XTL_NONE]",
+    "debug", "verbose", "detail",  /* normally off by default */
+    "progress", "info", "notice",  /* not a problem */
+    "warning", "error", "critical" /* problems and errors */
+};
+
+const char *xtl_level_to_string(xentoollog_level level) {
+    assert(level >= 0 && level < XTL_NUM_LEVELS);
+    return level_strings[level];
+}
+
+void xtl_logv(struct xentoollog_logger *logger,
+              xentoollog_level level,
+              int errnoval /* or -1 */,
+              const char *context /* eg "xc", "xenstore", "xl" */,
+              const char *format /* does not contain \n */,
+              va_list al) {
+    int errno_save = errno;
+    assert(level > XTL_NONE && level < XTL_NUM_LEVELS);
+    logger->vmessage(logger,level,errnoval,context,format,al);
+    errno = errno_save;
+}
+
+void xtl_log(struct xentoollog_logger *logger,
+             xentoollog_level level,
+             int errnoval /* or -1 */,
+             const char *context /* eg "xc", "xenstore", "xl" */,
+             const char *format /* does not contain \n */,
+             ...) {
+    va_list al;
+    va_start(al,format);
+    xtl_logv(logger,level,errnoval,context,format,al);
+    va_end(al);
+}
+
+void xtl_progress(struct xentoollog_logger *logger,
+                  const char *context, const char *doing_what,
+                  unsigned long done, unsigned long total) {
+    int percent = 0;
+
+    if (!logger->progress) return;
+
+    if ( total )
+        percent = (total < LONG_MAX/100)
+            ? (done * 100) / total
+            : done / ((total + 99) / 100);
+
+    logger->progress(logger, context, doing_what, percent, done, total);
+}
+
+void xtl_logger_destroy(struct xentoollog_logger *logger) {
+    if (!logger) return;
+    logger->destroy(logger);
+}
diff --git a/tools/libxentoollog/xtl_logger_stdio.c b/tools/libxentoollog/xtl_logger_stdio.c
new file mode 100644
index 0000000..d8646e0
--- /dev/null
+++ b/tools/libxentoollog/xtl_logger_stdio.c
@@ -0,0 +1,190 @@
+/*
+ * xtl_logger_stdio.c
+ *
+ * log message consumer that writes to stdio
+ *
+ * Copyright (c) 2010 Citrix
+ * Part of a generic logging interface used by various dom0 userland libraries.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "xentoollog.h"
+
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdbool.h>
+
+struct xentoollog_logger_stdiostream {
+    xentoollog_logger vtable;
+    FILE *f;
+    xentoollog_level min_level;
+    unsigned flags;
+    int progress_erase_len, progress_last_percent;
+    bool progress_use_cr;
+};
+
+static void progress_erase(xentoollog_logger_stdiostream *lg) {
+    if (lg->progress_erase_len)
+        fprintf(lg->f, "\r%*s\r", lg->progress_erase_len, "");
+}
+
+static void stdiostream_vmessage(xentoollog_logger *logger_in,
+                                 xentoollog_level level,
+                                 int errnoval,
+                                 const char *context,
+                                 const char *format,
+                                 va_list al) {
+    xentoollog_logger_stdiostream *lg = (void*)logger_in;
+
+    if (level < lg->min_level)
+        return;
+
+    progress_erase(lg);
+
+    if (lg->flags & XTL_STDIOSTREAM_SHOW_DATE) {
+        struct tm lt_buf;
+        time_t now = time(0);
+        struct tm *lt= localtime_r(&now, &lt_buf);
+        fprintf(lg->f, "%04d-%02d-%02d %02d:%02d:%02d %s ",
+                lt->tm_year+1900, lt->tm_mon+1, lt->tm_mday,
+                lt->tm_hour, lt->tm_min, lt->tm_sec,
+                tzname[!!lt->tm_isdst]);
+    }
+    if (lg->flags & XTL_STDIOSTREAM_SHOW_PID)
+        fprintf(lg->f, "[%lu] ", (unsigned long)getpid());
+
+    if (context)
+        fprintf(lg->f, "%s: ", context);
+
+    fprintf(lg->f, "%s: ", xtl_level_to_string(level));
+
+    vfprintf(lg->f, format, al);
+
+    if (errnoval >= 0)
+        fprintf(lg->f, ": %s", strerror(errnoval));
+
+    putc('\n', lg->f);
+    fflush(lg->f);
+}
+
+static void stdiostream_message(struct xentoollog_logger *logger_in,
+                                xentoollog_level level,
+                                const char *context,
+                                const char *format, ...)
+{
+    va_list al;
+    va_start(al,format);
+    stdiostream_vmessage(logger_in, level, -1, context, format, al);
+    va_end(al);
+}
+
+static void stdiostream_progress(struct xentoollog_logger *logger_in,
+                                 const char *context,
+                                 const char *doing_what, int percent,
+                                 unsigned long done, unsigned long total) {
+    xentoollog_logger_stdiostream *lg = (void*)logger_in;
+    int newpel, extra_erase;
+    xentoollog_level this_level;
+
+    if (lg->flags & XTL_STDIOSTREAM_HIDE_PROGRESS)
+        return;
+
+    if (percent < lg->progress_last_percent) {
+        this_level = XTL_PROGRESS;
+    } else if (percent == lg->progress_last_percent) {
+        return;
+    } else if (percent < lg->progress_last_percent + 5) {
+        this_level = XTL_DETAIL;
+    } else {
+        this_level = XTL_PROGRESS;
+    }
+
+    if (this_level < lg->min_level)
+        return;
+
+    lg->progress_last_percent = percent;
+
+    if (!lg->progress_use_cr) {
+        stdiostream_message(logger_in, this_level, context,
+                            "%s: %lu/%lu  %3d%%",
+                            doing_what, done, total, percent);
+        return;
+    }
+
+    if (lg->progress_erase_len)
+        putc('\r', lg->f);
+
+    newpel = fprintf(lg->f, "%s%s" "%s: %lu/%lu  %3d%%%s",
+                     context?context:"", context?": ":"",
+                     doing_what, done, total, percent,
+		     done == total ? "\n" : "");
+
+    extra_erase = lg->progress_erase_len - newpel;
+    if (extra_erase > 0)
+        fprintf(lg->f, "%*s\r", extra_erase, "");
+
+    lg->progress_erase_len = newpel;
+}
+
+static void stdiostream_destroy(struct xentoollog_logger *logger_in) {
+    xentoollog_logger_stdiostream *lg = (void*)logger_in;
+    progress_erase(lg);
+    free(lg);
+}
+
+void xtl_stdiostream_set_minlevel(xentoollog_logger_stdiostream *lg,
+                                  xentoollog_level min_level) {
+    lg->min_level = min_level;
+}
+
+void xtl_stdiostream_adjust_flags(xentoollog_logger_stdiostream *lg,
+                                  unsigned set_flags, unsigned clear_flags) {
+    unsigned new_flags = (lg->flags & ~clear_flags) | set_flags;
+    if (new_flags & XTL_STDIOSTREAM_HIDE_PROGRESS)
+        progress_erase(lg);
+    lg->flags = new_flags;
+}
+
+xentoollog_logger_stdiostream *xtl_createlogger_stdiostream
+        (FILE *f, xentoollog_level min_level, unsigned flags) {
+    xentoollog_logger_stdiostream newlogger;
+
+    newlogger.f = f;
+    newlogger.min_level = min_level;
+    newlogger.flags = flags;
+
+    switch (flags & (XTL_STDIOSTREAM_PROGRESS_USE_CR |
+                     XTL_STDIOSTREAM_PROGRESS_NO_CR)) {
+    case XTL_STDIOSTREAM_PROGRESS_USE_CR: newlogger.progress_use_cr = 1; break;
+    case XTL_STDIOSTREAM_PROGRESS_NO_CR:  newlogger.progress_use_cr = 0; break;
+    case 0:
+        newlogger.progress_use_cr = isatty(fileno(newlogger.f)) > 0;
+        break;
+    default:
+        errno = EINVAL;
+        return 0;
+    }
+
+    if (newlogger.flags & XTL_STDIOSTREAM_SHOW_DATE) tzset();
+
+    newlogger.progress_erase_len = 0;
+    newlogger.progress_last_percent = 0;
+
+    return XTL_NEW_LOGGER(stdiostream, newlogger);
+}
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index cc9c152..387dc91 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -20,11 +20,12 @@ LIBUUID_LIBS += -luuid
 endif
 
 LIBXL_LIBS =
-LIBXL_LIBS = $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS)
+LIBXL_LIBS = $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS)
 ifeq ($(CONFIG_REMUS_NETBUF),y)
 LIBXL_LIBS += $(LIBNL3_LIBS)
 endif
 
+CFLAGS_LIBXL += $(CFLAGS_libxentoollog)
 CFLAGS_LIBXL += $(CFLAGS_libxenctrl)
 CFLAGS_LIBXL += $(CFLAGS_libxenguest)
 CFLAGS_LIBXL += $(CFLAGS_libxenstore)
@@ -132,7 +133,7 @@ CFLAGS_XL += -Wshadow
 
 XL_OBJS = xl.o xl_cmdimpl.o xl_cmdtable.o xl_sxp.o
 $(XL_OBJS) $(TEST_PROG_OBJS) _libxl.api-for-check: \
-            CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h
+            CFLAGS += $(CFLAGS_libxentoollog)
 $(XL_OBJS): CFLAGS += $(CFLAGS_XL)
 $(XL_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h # libxl_json.h needs it.
 
@@ -236,19 +237,19 @@ libxlutil.a: $(LIBXLU_OBJS)
 	$(AR) rcs libxlutil.a $^
 
 xl: $(XL_OBJS) libxlutil.so libxenlight.so
-	$(CC) $(LDFLAGS) -o $@ $(XL_OBJS) libxlutil.so $(LDLIBS_libxenlight) $(LDLIBS_libxenctrl) -lyajl $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $(XL_OBJS) libxlutil.so $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) -lyajl $(APPEND_LDFLAGS)
 
 xen-init-dom0: $(XEN_INIT_DOM0_OBJS) libxenlight.so
-	$(CC) $(LDFLAGS) -o $@ $(XEN_INIT_DOM0_OBJS) $(LDLIBS_libxenstore) $(LDLIBS_libxenlight) $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $(XEN_INIT_DOM0_OBJS) $(LDLIBS_libxenstore) $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(APPEND_LDFLAGS)
 
 test_%: test_%.o test_common.o libxlutil.so libxenlight_test.so
-	$(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxenctrl) -lyajl $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $^ $(filter-out %libxenlight.so, $(LDLIBS_libxenlight)) $(LDLIBS_libxentoollog) -lyajl $(APPEND_LDFLAGS)
 
 libxl-save-helper: $(SAVE_HELPER_OBJS) libxenlight.so
-	$(CC) $(LDFLAGS) -o $@ $(SAVE_HELPER_OBJS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $(SAVE_HELPER_OBJS) $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
 
 testidl: testidl.o libxlutil.so libxenlight.so
-	$(CC) $(LDFLAGS) -o $@ testidl.o libxlutil.so $(LDLIBS_libxenlight) $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ testidl.o libxlutil.so $(LDLIBS_libxenlight) $(LDLIBS_libxentoollog) $(APPEND_LDFLAGS)
 
 $(PKG_CONFIG): % : %.in Makefile
 	@sed -e 's/@@version@@/$(MAJOR).$(MINOR)/g' < $< > $@.new
diff --git a/tools/ocaml/Makefile.rules b/tools/ocaml/Makefile.rules
index 1796060..45e71f2 100644
--- a/tools/ocaml/Makefile.rules
+++ b/tools/ocaml/Makefile.rules
@@ -1,18 +1,18 @@
-ifdef V
-  ifeq ("$(origin V)", "command line")
-    BUILD_VERBOSE = $(V)
-  endif
-endif
-ifndef BUILD_VERBOSE
-  BUILD_VERBOSE = 0
-endif
-ifeq ($(BUILD_VERBOSE),1)
+#ifdef V
+#  ifeq ("$(origin V)", "command line")
+#    BUILD_VERBOSE = $(V)
+#  endif
+#endif
+#ifndef BUILD_VERBOSE
+#  BUILD_VERBOSE = 0
+#endif
+#ifeq ($(BUILD_VERBOSE),1)
   E = @true
   Q =
-else
-  E = @echo
-  Q = @
-endif
+#else
+#  E = @echo
+#  Q = @
+#endif
 
 .NOTPARALLEL:
 
diff --git a/tools/ocaml/libs/xentoollog/Makefile b/tools/ocaml/libs/xentoollog/Makefile
index 666eb66..084a3f4 100644
--- a/tools/ocaml/libs/xentoollog/Makefile
+++ b/tools/ocaml/libs/xentoollog/Makefile
@@ -5,7 +5,7 @@ include $(TOPLEVEL)/common.make
 # allow mixed declarations and code
 CFLAGS += -Wno-declaration-after-statement
 
-CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest)
+CFLAGS += $(CFLAGS_libxentoollog)
 CFLAGS += $(APPEND_CFLAGS)
 OCAMLINCLUDE +=
 
@@ -13,7 +13,7 @@ OBJS = xentoollog
 INTF = xentoollog.cmi
 LIBS = xentoollog.cma xentoollog.cmxa
 
-LIBS_xentoollog = $(LDLIBS_libxenctrl)
+LIBS_xentoollog = $(LDLIBS_libxentoollog)
 
 xentoollog_OBJS = $(OBJS)
 xentoollog_C_OBJS = xentoollog_stubs
@@ -49,7 +49,7 @@ xentoollog.mli: xentoollog.mli.in _xtl_levels.mli.in
 
 libs: $(LIBS)
 
-_xtl_levels.ml.in _xtl_levels.mli.in _xtl_levels.inc: genlevels.py $(XEN_ROOT)/tools/libxc/include/xentoollog.h
+_xtl_levels.ml.in _xtl_levels.mli.in _xtl_levels.inc: genlevels.py $(XEN_ROOT)/tools/libxentoollog/include/xentoollog.h
 	$(PYTHON) genlevels.py _xtl_levels.mli.in _xtl_levels.ml.in _xtl_levels.inc
 
 .PHONY: install
diff --git a/tools/ocaml/libs/xentoollog/genlevels.py b/tools/ocaml/libs/xentoollog/genlevels.py
index 65d334f..4de4fb1 100755
--- a/tools/ocaml/libs/xentoollog/genlevels.py
+++ b/tools/ocaml/libs/xentoollog/genlevels.py
@@ -3,7 +3,7 @@
 import sys
 
 def read_levels():
-	f = open('../../../libxc/include/xentoollog.h', 'r')
+	f = open('../../../libxentoollog/include/xentoollog.h', 'r')
 
 	levels = []
 	record = False
diff --git a/tools/python/setup.py b/tools/python/setup.py
index 439c429..e55ee01 100644
--- a/tools/python/setup.py
+++ b/tools/python/setup.py
@@ -7,16 +7,17 @@ XEN_ROOT = "../.."
 extra_compile_args  = [ "-fno-strict-aliasing", "-Werror" ]
 
 PATH_XEN      = XEN_ROOT + "/tools/include"
+PATH_LIBXENTOOLLOG = XEN_ROOT + "/tools/libxentoollog"
 PATH_LIBXC    = XEN_ROOT + "/tools/libxc"
 PATH_LIBXL    = XEN_ROOT + "/tools/libxl"
 PATH_XENSTORE = XEN_ROOT + "/tools/xenstore"
 
 xc = Extension("xc",
                extra_compile_args = extra_compile_args,
-               include_dirs       = [ PATH_XEN, PATH_LIBXC + "/include", "xen/lowlevel/xc" ],
+               include_dirs       = [ PATH_XEN, PATH_LIBXENTOOLLOG + "/include", PATH_LIBXC + "/include", "xen/lowlevel/xc" ],
                library_dirs       = [ PATH_LIBXC ],
                libraries          = [ "xenctrl", "xenguest" ],
-               depends            = [ PATH_LIBXC + "/libxenctrl.so", PATH_LIBXC + "/libxenguest.so" ],
+               depends            = [ PATH_LIBXC + "/libxenctrl.so", PATH_LIBXC + "/libxenguest.so",  "-Wl,-rpath-link="+PATH_LIBXENTOOLLOG ],
                sources            = [ "xen/lowlevel/xc/xc.c" ])
 
 xs = Extension("xs",
diff --git a/tools/xenpaging/Makefile b/tools/xenpaging/Makefile
index 2407a30..e63d894 100644
--- a/tools/xenpaging/Makefile
+++ b/tools/xenpaging/Makefile
@@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 # xenpaging.c and file_ops.c incorrectly use libxc internals
 CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc
-LDLIBS += $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS)
+LDLIBS += $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS)
 LDFLAGS += $(PTHREAD_LDFLAGS)
 
 POLICY    = default
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC tools 2/6] tools: Link in-tree libvchan users against libxenvchan.so
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library Ian Campbell
@ 2015-06-10 11:36 ` Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 3/6] tools: Do not add top-level tools dir to include path Ian Campbell
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

As with other in-tree users avoid -L + -l.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/Rules.mk |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/Rules.mk b/tools/Rules.mk
index bf85e5e..b8b8559 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -56,7 +56,7 @@ LDLIBS_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBXENSTAT)/
 SHLIB_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBXENSTAT)
 
 CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN)
-LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -L$(XEN_LIBVCHAN) -lxenvchan
+LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBVCHAN)/libxenvchan$(libextension)
 SHLIB_libxenvchan  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBVCHAN)
 
 ifeq ($(debug),y)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC tools 3/6] tools: Do not add top-level tools dir to include path
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 2/6] tools: Link in-tree libvchan users against libxenvchan.so Ian Campbell
@ 2015-06-10 11:36 ` Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 4/6] tools/libxc: Remove osdep indirection for xc_evtchn Ian Campbell
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

Instead switch to an explicit -include $(XEN_ROOT)/tools/config.h to
pickup config.h.

Most places already do this, fixup the rest.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libfsimage/ext2fs-lib/Makefile     |    4 ++--
 tools/libfsimage/ext2fs-lib/ext2fs-lib.c |    3 ---
 tools/misc/Makefile                      |    4 +++-
 tools/misc/gtraceview.c                  |    3 ---
 tools/ocaml/xenstored/Makefile           |    3 ++-
 tools/ocaml/xenstored/systemd_stubs.c    |    1 -
 tools/xenstat/xentop/Makefile            |    4 ++--
 tools/xenstat/xentop/xentop.c            |    3 ---
 tools/xenstore/Makefile                  |    3 ++-
 tools/xenstore/xenstored_core.c          |    1 -
 10 files changed, 11 insertions(+), 18 deletions(-)

diff --git a/tools/libfsimage/ext2fs-lib/Makefile b/tools/libfsimage/ext2fs-lib/Makefile
index 671fbff..0e00fde 100644
--- a/tools/libfsimage/ext2fs-lib/Makefile
+++ b/tools/libfsimage/ext2fs-lib/Makefile
@@ -6,8 +6,8 @@ FS = ext2fs-lib
 
 FS_LIBDEPS = $(EXTFS_LIBS)
 
-# Include configure output (config.h) to headers search path
-CFLAGS += -I$(XEN_ROOT)/tools
+# Include configure output (config.h)
+CFLAGS += -include $(XEN_ROOT)/tools/config.h
 
 .PHONY: all
 all: fs-all
diff --git a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c
index ed47146..84b6d1e 100644
--- a/tools/libfsimage/ext2fs-lib/ext2fs-lib.c
+++ b/tools/libfsimage/ext2fs-lib/ext2fs-lib.c
@@ -21,9 +21,6 @@
  * Use is subject to license terms.
  */
 
-/* Include output from configure */
-#include <config.h>
-
 #include <fsimage_plugin.h>
 #include INCLUDE_EXTFS_H
 #include <errno.h>
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index 82c361f..c4490f3 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -1,7 +1,9 @@
 XEN_ROOT=$(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
-CFLAGS += -Werror -I$(XEN_ROOT)/tools
+CFLAGS += -Werror
+# Include configure output (config.h)
+CFLAGS += -include $(XEN_ROOT)/tools/config.h
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += $(CFLAGS_xeninclude)
 CFLAGS += $(CFLAGS_libxenstore)
diff --git a/tools/misc/gtraceview.c b/tools/misc/gtraceview.c
index 501f86a..d9f1185 100644
--- a/tools/misc/gtraceview.c
+++ b/tools/misc/gtraceview.c
@@ -16,9 +16,6 @@
  * Place - Suite 330, Boston, MA 02111-1307 USA.
  */
 
-/* Include output from configure */
-#include <config.h>
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/tools/ocaml/xenstored/Makefile b/tools/ocaml/xenstored/Makefile
index bcf09d4..d861f11 100644
--- a/tools/ocaml/xenstored/Makefile
+++ b/tools/ocaml/xenstored/Makefile
@@ -2,7 +2,8 @@ XEN_ROOT = $(CURDIR)/../../..
 OCAML_TOPLEVEL = $(CURDIR)/..
 include $(OCAML_TOPLEVEL)/common.make
 
-CFLAGS += -I$(XEN_ROOT)/tools/
+# Include configure output (config.h)
+CFLAGS += -include $(XEN_ROOT)/tools/config.h
 CFLAGS-$(CONFIG_SYSTEMD)  += $(SYSTEMD_CFLAGS)
 LDFLAGS-$(CONFIG_SYSTEMD) += $(SYSTEMD_LIBS)
 
diff --git a/tools/ocaml/xenstored/systemd_stubs.c b/tools/ocaml/xenstored/systemd_stubs.c
index 623592c..d924ff1 100644
--- a/tools/ocaml/xenstored/systemd_stubs.c
+++ b/tools/ocaml/xenstored/systemd_stubs.c
@@ -22,7 +22,6 @@
 #include <caml/custom.h>
 #include <caml/signals.h>
 #include <caml/fail.h>
-#include <config.h>
 
 #if defined(HAVE_SYSTEMD)
 
diff --git a/tools/xenstat/xentop/Makefile b/tools/xenstat/xentop/Makefile
index 97950b9..e67c9ab 100644
--- a/tools/xenstat/xentop/Makefile
+++ b/tools/xenstat/xentop/Makefile
@@ -22,8 +22,8 @@ CFLAGS += -DGCC_PRINTF -Werror $(CFLAGS_libxenstat)
 LDLIBS += $(LDLIBS_libxenstat) $(CURSES_LIBS) $(TINFO_LIBS) $(SOCKET_LIBS) -lm -lyajl
 CFLAGS += -DHOST_$(XEN_OS)
 
-# Include configure output (config.h) to headers search path
-CFLAGS += -I$(XEN_ROOT)/tools
+# Include configure output (config.h)
+CFLAGS += -include $(XEN_ROOT)/tools/config.h
 LDFLAGS += $(APPEND_LDFLAGS)
 
 .PHONY: all
diff --git a/tools/xenstat/xentop/xentop.c b/tools/xenstat/xentop/xentop.c
index 23b57f1..8173886 100644
--- a/tools/xenstat/xentop/xentop.c
+++ b/tools/xenstat/xentop/xentop.c
@@ -19,9 +19,6 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* Include output from configure */
-#include <config.h>
-
 /* get curses header from configure */
 #include INCLUDE_CURSES_H
 
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile
index 30f3b46..1b4a494 100644
--- a/tools/xenstore/Makefile
+++ b/tools/xenstore/Makefile
@@ -6,7 +6,8 @@ MINOR = 3
 
 CFLAGS += -Werror
 CFLAGS += -I.
-CFLAGS += -I$(XEN_ROOT)/tools/
+# Include configure output (config.h)
+CFLAGS += -include $(XEN_ROOT)/tools/config.h
 CFLAGS += -I./include
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += -DXEN_LIB_STORED="\"$(XEN_LIB_STORED)\""
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index 3fd9a20..b18000d 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -40,7 +40,6 @@
 #include <signal.h>
 #include <assert.h>
 #include <setjmp.h>
-#include <config.h>
 
 #include "utils.h"
 #include "list.h"
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC tools 4/6] tools/libxc: Remove osdep indirection for xc_evtchn
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (2 preceding siblings ...)
  2015-06-10 11:36 ` [PATCH RFC tools 3/6] tools: Do not add top-level tools dir to include path Ian Campbell
@ 2015-06-10 11:36 ` Ian Campbell
  2015-06-10 11:36 ` [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn Ian Campbell
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

The alternative backend (a xen-api/xapi shim) is no longer around and
so this stuff is now just baggage which is getting in the way of
refactoring libxenctrl.

Note that the intention is to move this into a separate library
shortly.

Nested virt probably suffices for this use case now.

For now only evtchn is done as a PoC, other sub-APIs will follow.

One incorrect instance of using xc_interface where xc_evtchn (in ocaml
stubs) is removed, this used to work because they were typedefs to the
same struct, but is no longer permitted.

Build tested for Linux and stubdom, but not FreeBSd, NetBSD or
Solaris.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxc/include/xenctrl.h                 |    2 +-
 tools/libxc/include/xenctrlosdep.h            |   16 -----
 tools/libxc/xc_evtchn.c                       |   45 -------------
 tools/libxc/xc_freebsd_osdep.c                |   79 ++++++++--------------
 tools/libxc/xc_linux_osdep.c                  |   76 ++++++++-------------
 tools/libxc/xc_minios.c                       |   63 +++++++-----------
 tools/libxc/xc_netbsd.c                       |   72 ++++++++------------
 tools/libxc/xc_private.c                      |   37 +++++++++--
 tools/libxc/xc_private.h                      |   17 +++++
 tools/libxc/xc_solaris.c                      |   71 ++++++++------------
 tools/libxc/xenctrl_osdep_ENOSYS.c            |   87 -------------------------
 tools/ocaml/libs/eventchn/xeneventchn_stubs.c |    4 +-
 12 files changed, 180 insertions(+), 389 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 50fa9e7..f7b6533 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -118,7 +118,7 @@
  */
 
 typedef struct xc_interface_core xc_interface;
-typedef struct xc_interface_core xc_evtchn;
+typedef struct xenevtchn_handle xc_evtchn;
 typedef struct xc_interface_core xc_gnttab;
 typedef struct xc_interface_core xc_gntshr;
 
diff --git a/tools/libxc/include/xenctrlosdep.h b/tools/libxc/include/xenctrlosdep.h
index e97944b..a8b27ae 100644
--- a/tools/libxc/include/xenctrlosdep.h
+++ b/tools/libxc/include/xenctrlosdep.h
@@ -52,7 +52,6 @@
 
 enum xc_osdep_type {
     XC_OSDEP_PRIVCMD,
-    XC_OSDEP_EVTCHN,
     XC_OSDEP_GNTTAB,
     XC_OSDEP_GNTSHR,
 };
@@ -91,21 +90,6 @@ struct xc_osdep_ops
                                         int nentries);
         } privcmd;
         struct {
-            int (*fd)(xc_evtchn *xce, xc_osdep_handle h);
-
-            int (*notify)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port);
-
-            evtchn_port_or_error_t (*bind_unbound_port)(xc_evtchn *xce, xc_osdep_handle h, int domid);
-            evtchn_port_or_error_t (*bind_interdomain)(xc_evtchn *xce, xc_osdep_handle h, int domid,
-                                                       evtchn_port_t remote_port);
-            evtchn_port_or_error_t (*bind_virq)(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq);
-
-            int (*unbind)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port);
-
-            evtchn_port_or_error_t (*pending)(xc_evtchn *xce, xc_osdep_handle h);
-            int (*unmask)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port);
-        } evtchn;
-        struct {
 #define XC_GRANT_MAP_SINGLE_DOMAIN 0x1
             void *(*grant_map)(xc_gnttab *xcg, xc_osdep_handle h,
                                uint32_t count, int flags, int prot,
diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c
index 2e0679e..e6bd25c 100644
--- a/tools/libxc/xc_evtchn.c
+++ b/tools/libxc/xc_evtchn.c
@@ -78,51 +78,6 @@ int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status)
                         sizeof(*status), 1);
 }
 
-int xc_evtchn_fd(xc_evtchn *xce)
-{
-    return xce->ops->u.evtchn.fd(xce, xce->ops_handle);
-}
-
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
-{
-    return xce->ops->u.evtchn.notify(xce, xce->ops_handle, port);
-}
-
-evtchn_port_or_error_t
-xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
-{
-    return xce->ops->u.evtchn.bind_unbound_port(xce, xce->ops_handle, domid);
-}
-
-evtchn_port_or_error_t
-xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
-                           evtchn_port_t remote_port)
-{
-    return xce->ops->u.evtchn.bind_interdomain(xce, xce->ops_handle, domid, remote_port);
-}
-
-evtchn_port_or_error_t
-xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
-{
-    return xce->ops->u.evtchn.bind_virq(xce, xce->ops_handle, virq);
-}
-
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
-{
-    return xce->ops->u.evtchn.unbind(xce, xce->ops_handle, port);
-}
-
-evtchn_port_or_error_t
-xc_evtchn_pending(xc_evtchn *xce)
-{
-    return xce->ops->u.evtchn.pending(xce, xce->ops_handle);
-}
-
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
-{
-    return xce->ops->u.evtchn.unmask(xce, xce->ops_handle, port);
-}
-
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_freebsd_osdep.c b/tools/libxc/xc_freebsd_osdep.c
index e6613ef..7274274 100644
--- a/tools/libxc/xc_freebsd_osdep.c
+++ b/tools/libxc/xc_freebsd_osdep.c
@@ -253,34 +253,32 @@ static struct xc_osdep_ops freebsd_privcmd_ops = {
 };
 
 /*-------------------------- Evtchn device interface -------------------------*/
-static xc_osdep_handle
-freebsd_evtchn_open(xc_evtchn *xce)
+int osdep_evtchn_open(xc_evtchn *xce)
 {
     int fd = open(EVTCHN_DEV, O_RDWR);
     if ( fd == -1 )
-        return XC_OSDEP_OPEN_ERROR;
-
-    return (xc_osdep_handle)fd;
+        return -1;
+    xce->fd = fd;
+    return 0;
 }
 
-static int
-freebsd_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
+int osdep_evtchn_close(xc_evtchn *xce)
 {
-    int fd = (int)h;
-    return close(fd);
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
 }
 
-static int
-freebsd_evtchn_fd(xc_evtchn *xce, xc_osdep_handle h)
+int xc_evtchn_fd(xc_evtchn *xce)
 {
-    return (int)h;
+    return xce->fd;
 }
 
 /*------------------------------ Evtchn interface ----------------------------*/
-static int
-freebsd_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_notify notify;
 
     notify.port = port;
@@ -288,10 +286,9 @@ freebsd_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
     return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
-static evtchn_port_or_error_t
-freebsd_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
+evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
 {
-    int ret, fd = (int)h;
+    int ret, fd = xce->fd;
     struct ioctl_evtchn_bind_unbound_port bind;
 
     bind.remote_domain = domid;
@@ -300,11 +297,10 @@ freebsd_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
     return ( ret == 0 ) ? bind.port : ret;
 }
 
-static evtchn_port_or_error_t
-freebsd_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
-                                evtchn_port_t remote_port)
+evtchn_port_or_error_t
+xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, evtchn_port_t remote_port)
 {
-    int ret, fd = (int)h;
+    int ret, fd = xce->fd;
     struct ioctl_evtchn_bind_interdomain bind;
 
     bind.remote_domain = domid;
@@ -314,10 +310,9 @@ freebsd_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
     return ( ret == 0 ) ? bind.port : ret;
 }
 
-static evtchn_port_or_error_t
-freebsd_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
+evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
 {
-    int ret, fd = (int)h;
+    int ret, fd = xce->fd;
     struct ioctl_evtchn_bind_virq bind;
 
     bind.virq = virq;
@@ -326,10 +321,9 @@ freebsd_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
     return ( ret == 0 ) ? bind.port : ret;
 }
 
-static int
-freebsd_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_unbind unbind;
 
     unbind.port = port;
@@ -337,10 +331,9 @@ freebsd_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
     return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
 }
 
-static evtchn_port_or_error_t
-freebsd_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
+evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     evtchn_port_t port;
 
     if ( read(fd, &port, sizeof(port)) != sizeof(port) )
@@ -349,33 +342,15 @@ freebsd_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
     return port;
 }
 
-static int
-freebsd_evtchn_unmask(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
 
     if ( write(fd, &port, sizeof(port)) != sizeof(port) )
         return -1;
     return 0;
 }
 
-/*----------------------------- Evtchn handlers ------------------------------*/
-static struct xc_osdep_ops freebsd_evtchn_ops = {
-    .open = &freebsd_evtchn_open,
-    .close = &freebsd_evtchn_close,
-
-    .u.evtchn = {
-        .fd = &freebsd_evtchn_fd,
-        .notify = &freebsd_evtchn_notify,
-        .bind_unbound_port = &freebsd_evtchn_bind_unbound_port,
-        .bind_interdomain = &freebsd_evtchn_bind_interdomain,
-        .bind_virq = &freebsd_evtchn_bind_virq,
-        .unbind = &freebsd_evtchn_unbind,
-        .pending = &freebsd_evtchn_pending,
-        .unmask = &freebsd_evtchn_unmask,
-    },
-};
-
 /*---------------------------- FreeBSD interface -----------------------------*/
 static struct xc_osdep_ops *
 freebsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
@@ -384,8 +359,6 @@ freebsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
     {
     case XC_OSDEP_PRIVCMD:
         return &freebsd_privcmd_ops;
-    case XC_OSDEP_EVTCHN:
-        return &freebsd_evtchn_ops;
     default:
         return NULL;
     }
diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c
index 2687424..3c96c76 100644
--- a/tools/libxc/xc_linux_osdep.c
+++ b/tools/libxc/xc_linux_osdep.c
@@ -39,10 +39,9 @@
 #include "xenctrl.h"
 #include "xenctrlosdep.h"
 
+#include "xc_private.h"
+
 #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
-#define ERROR(_m, _a...)  xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m , ## _a )
-#define PERROR(_m, _a...) xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m \
-                  " (%d = %s)", ## _a , errno, xc_strerror(xch, errno))
 
 static xc_osdep_handle linux_privcmd_open(xc_interface *xch)
 {
@@ -457,29 +456,31 @@ static struct xc_osdep_ops linux_privcmd_ops = {
 
 #define DEVXEN "/dev/xen/"
 
-static xc_osdep_handle linux_evtchn_open(xc_evtchn *xce)
+int osdep_evtchn_open(xc_evtchn *xce)
 {
     int fd = open(DEVXEN "evtchn", O_RDWR);
     if ( fd == -1 )
-        return XC_OSDEP_OPEN_ERROR;
-
-    return (xc_osdep_handle)fd;
+        return -1;
+    xce->fd = fd;
+    return 0;
 }
 
-static int linux_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
+int osdep_evtchn_close(xc_evtchn *xce)
 {
-    int fd = (int)h;
-    return close(fd);
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
 }
 
-static int linux_evtchn_fd(xc_evtchn *xce, xc_osdep_handle h)
+int xc_evtchn_fd(xc_evtchn *xce)
 {
-    return (int)h;
+    return xce->fd;
 }
 
-static int linux_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_notify notify;
 
     notify.port = port;
@@ -487,10 +488,9 @@ static int linux_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t
     return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
-static evtchn_port_or_error_t
-linux_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
+evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_unbound_port bind;
 
     bind.remote_domain = domid;
@@ -498,11 +498,10 @@ linux_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
     return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
 }
 
-static evtchn_port_or_error_t
-linux_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
-                              evtchn_port_t remote_port)
+evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
+                                                  evtchn_port_t remote_port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_interdomain bind;
 
     bind.remote_domain = domid;
@@ -511,10 +510,9 @@ linux_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
     return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
 }
 
-static evtchn_port_or_error_t
-linux_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
+evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_virq bind;
 
     bind.virq = virq;
@@ -522,9 +520,9 @@ linux_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
     return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
 }
 
-static int linux_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_unbind unbind;
 
     unbind.port = port;
@@ -532,9 +530,9 @@ static int linux_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t
     return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
 }
 
-static evtchn_port_or_error_t linux_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
+evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     evtchn_port_t port;
 
     if ( read(fd, &port, sizeof(port)) != sizeof(port) )
@@ -543,31 +541,15 @@ static evtchn_port_or_error_t linux_evtchn_pending(xc_evtchn *xce, xc_osdep_hand
     return port;
 }
 
-static int linux_evtchn_unmask(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
 
     if ( write(fd, &port, sizeof(port)) != sizeof(port) )
         return -1;
     return 0;
 }
 
-static struct xc_osdep_ops linux_evtchn_ops = {
-    .open = &linux_evtchn_open,
-    .close = &linux_evtchn_close,
-
-    .u.evtchn = {
-        .fd = &linux_evtchn_fd,
-        .notify = &linux_evtchn_notify,
-        .bind_unbound_port = &linux_evtchn_bind_unbound_port,
-        .bind_interdomain = &linux_evtchn_bind_interdomain,
-        .bind_virq = &linux_evtchn_bind_virq,
-        .unbind = &linux_evtchn_unbind,
-        .pending = &linux_evtchn_pending,
-        .unmask = &linux_evtchn_unmask,
-    },
-};
-
 static xc_osdep_handle linux_gnttab_open(xc_gnttab *xcg)
 {
     int fd = open(DEVXEN "gntdev", O_RDWR);
@@ -871,8 +853,6 @@ static struct xc_osdep_ops *linux_osdep_init(xc_interface *xch, enum xc_osdep_ty
     {
     case XC_OSDEP_PRIVCMD:
         return &linux_privcmd_ops;
-    case XC_OSDEP_EVTCHN:
-        return &linux_evtchn_ops;
     case XC_OSDEP_GNTTAB:
         return &linux_gnttab_ops;
     case XC_OSDEP_GNTSHR:
diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c
index e703684..e9c4d8b 100644
--- a/tools/libxc/xc_minios.c
+++ b/tools/libxc/xc_minios.c
@@ -220,20 +220,23 @@ static void port_dealloc(struct evtchn_port_info *port_info) {
     free(port_info);
 }
 
-static xc_osdep_handle minios_evtchn_open(xc_evtchn *xce)
+int osdep_evtchn_open(xc_evtchn *xce)
 {
     int fd = alloc_fd(FTYPE_EVTCHN);
     if ( fd == -1 )
-        return XC_OSDEP_OPEN_ERROR;
+        return -1;
     LIST_INIT(&files[fd].evtchn.ports);
+    xce->fd = fd;
     printf("evtchn_open() -> %d\n", fd);
-    return (xc_osdep_handle)fd;
+    return 0;
 }
 
-static int minios_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
+int osdep_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
 {
-    int fd = (int)h;
-    return close(fd);
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
 }
 
 void minios_evtchn_close_fd(int fd)
@@ -245,12 +248,12 @@ void minios_evtchn_close_fd(int fd)
     files[fd].type = FTYPE_NONE;
 }
 
-static int minios_evtchn_fd(xc_evtchn *xce, xc_osdep_handle h)
+int xc_evtchn_fd(xc_evtchn *xce)
 {
-    return (int)h;
+    return xce->fd;
 }
 
-static int minios_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
 {
     int ret;
 
@@ -282,9 +285,9 @@ static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
     wake_up(&event_queue);
 }
 
-static evtchn_port_or_error_t minios_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
+evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct evtchn_port_info *port_info;
     int ret;
     evtchn_port_t port;
@@ -309,10 +312,10 @@ static evtchn_port_or_error_t minios_evtchn_bind_unbound_port(xc_evtchn *xce, xc
     return port;
 }
 
-static evtchn_port_or_error_t minios_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
-    evtchn_port_t remote_port)
+evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
+                                                  evtchn_port_t remote_port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct evtchn_port_info *port_info;
     evtchn_port_t local_port;
     int ret;
@@ -337,9 +340,9 @@ static evtchn_port_or_error_t minios_evtchn_bind_interdomain(xc_evtchn *xce, xc_
     return local_port;
 }
 
-static int minios_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct evtchn_port_info *port_info;
 
     LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
@@ -353,9 +356,9 @@ static int minios_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t
     return -1;
 }
 
-static evtchn_port_or_error_t minios_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
+evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct evtchn_port_info *port_info;
     evtchn_port_t port;
 
@@ -378,9 +381,9 @@ static evtchn_port_or_error_t minios_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_h
     return port;
 }
 
-static evtchn_port_or_error_t minios_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
+evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct evtchn_port_info *port_info;
     unsigned long flags;
     evtchn_port_t ret = -1;
@@ -403,28 +406,12 @@ static evtchn_port_or_error_t minios_evtchn_pending(xc_evtchn *xce, xc_osdep_han
     return ret;
 }
 
-static int minios_evtchn_unmask(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
 {
     unmask_evtchn(port);
     return 0;
 }
 
-static struct xc_osdep_ops minios_evtchn_ops = {
-    .open = &minios_evtchn_open,
-    .close = &minios_evtchn_close,
-
-    .u.evtchn = {
-        .fd = &minios_evtchn_fd,
-        .notify = &minios_evtchn_notify,
-        .bind_unbound_port = &minios_evtchn_bind_unbound_port,
-        .bind_interdomain = &minios_evtchn_bind_interdomain,
-        .bind_virq = &minios_evtchn_bind_virq,
-        .unbind = &minios_evtchn_unbind,
-        .pending = &minios_evtchn_pending,
-        .unmask = &minios_evtchn_unmask,
-   },
-};
-
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush)
 {
@@ -524,8 +511,6 @@ static struct xc_osdep_ops *minios_osdep_init(xc_interface *xch, enum xc_osdep_t
     {
     case XC_OSDEP_PRIVCMD:
         return &minios_privcmd_ops;
-    case XC_OSDEP_EVTCHN:
-        return &minios_evtchn_ops;
     case XC_OSDEP_GNTTAB:
         return &minios_gnttab_ops;
     default:
diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c
index 8a90ef3..f9bc100 100644
--- a/tools/libxc/xc_netbsd.c
+++ b/tools/libxc/xc_netbsd.c
@@ -226,29 +226,31 @@ static struct xc_osdep_ops netbsd_privcmd_ops = {
 
 #define EVTCHN_DEV_NAME  "/dev/xenevt"
 
-static xc_osdep_handle netbsd_evtchn_open(xc_evtchn *xce)
+int osdep_evtchn_open(xc_evtchn *xce)
 {
     int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
     if ( fd == -1 )
-        return XC_OSDEP_OPEN_ERROR;
-
-    return (xc_osdep_handle)fd;
+        return -1;
+    xce->fd = fd;
+    return 0;
 }
 
-static int netbsd_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
+int osdep_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
 {
-    int fd = (int)h;
-    return close(fd);
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
 }
 
-static int netbsd_evtchn_fd(xc_evtchn *xce, xc_osdep_handle h)
+int xc_evtchn_fd(xc_evtchn *xce)
 {
-    return (int)h;
+    return xce->fd;
 }
 
-static int netbsd_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_notify notify;
 
     notify.port = port;
@@ -256,10 +258,9 @@ static int netbsd_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t
     return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
-static evtchn_port_or_error_t
-netbsd_evtchn_bind_unbound_port(xc_evtchn * xce, xc_osdep_handle h, int domid)
+evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn * xce, int domid)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_unbound_port bind;
     int ret;
 
@@ -272,11 +273,10 @@ netbsd_evtchn_bind_unbound_port(xc_evtchn * xce, xc_osdep_handle h, int domid)
 	return -1;
 }
 
-static evtchn_port_or_error_t
-netbsd_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
-                               evtchn_port_t remote_port)
+evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
+                                                  evtchn_port_t remote_port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_interdomain bind;
     int ret;
 
@@ -290,9 +290,9 @@ netbsd_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
 	return -1;
 }
 
-static int netbsd_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_unbind unbind;
 
     unbind.port = port;
@@ -300,10 +300,9 @@ static int netbsd_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t
     return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
 }
 
-static evtchn_port_or_error_t
-netbsd_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
+evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_virq bind;
     int err;
 
@@ -316,10 +315,9 @@ netbsd_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
 	return bind.port;
 }
 
-static evtchn_port_or_error_t
-netbsd_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
+evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     evtchn_port_t port;
 
     if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 )
@@ -328,28 +326,12 @@ netbsd_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
     return port;
 }
 
-static int netbsd_evtchn_unmask(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     return write_exact(fd, (char *)&port, sizeof(port));
 }
 
-static struct xc_osdep_ops netbsd_evtchn_ops = {
-    .open = &netbsd_evtchn_open,
-    .close = &netbsd_evtchn_close,
-
-    .u.evtchn = {
-         .fd = &netbsd_evtchn_fd,
-         .notify = &netbsd_evtchn_notify,
-         .bind_unbound_port = &netbsd_evtchn_bind_unbound_port,
-         .bind_interdomain = &netbsd_evtchn_bind_interdomain,
-         .bind_virq = &netbsd_evtchn_bind_virq,
-         .unbind = &netbsd_evtchn_unbind,
-         .pending = &netbsd_evtchn_pending,
-         .unmask = &netbsd_evtchn_unmask,
-    },
-};
-
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
@@ -396,8 +378,6 @@ static struct xc_osdep_ops *netbsd_osdep_init(xc_interface *xch, enum xc_osdep_t
     {
     case XC_OSDEP_PRIVCMD:
         return &netbsd_privcmd_ops;
-    case XC_OSDEP_EVTCHN:
-        return &netbsd_evtchn_ops;
     default:
         return NULL;
     }
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index 2ffebd9..9f0ada7 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -120,7 +120,6 @@ static const char *xc_osdep_type_name(enum xc_osdep_type type)
     switch ( type )
     {
     case XC_OSDEP_PRIVCMD: return "privcmd";
-    case XC_OSDEP_EVTCHN:  return "evtchn";
     case XC_OSDEP_GNTTAB:  return "gnttab";
     case XC_OSDEP_GNTSHR:  return "gntshr";
     }
@@ -253,20 +252,44 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
     return xch->ops->u.privcmd.hypercall(xch, xch->ops_handle, hypercall);
 }
 
-xc_evtchn *xc_evtchn_open(xentoollog_logger *logger,
-                             unsigned open_flags)
+xc_evtchn *xc_evtchn_open(xentoollog_logger *logger, unsigned open_flags)
 {
-    xc_evtchn *xce;
+    xc_evtchn *xce = malloc(sizeof(*xce));
+    int rc;
+
+    if (!xce) return NULL;
+
+    xce->fd = -1;
+    xce->logger = logger;
+    xce->logger_tofree  = NULL;
 
-    xce = xc_interface_open_common(logger, NULL, open_flags,
-                                   XC_OSDEP_EVTCHN);
+    if (!xce->logger) {
+        xce->logger = xce->logger_tofree =
+            (xentoollog_logger*)
+            xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
+        if (!xce->logger) goto err;
+    }
+
+    rc = osdep_evtchn_open(xce);
+    if ( rc  < 0 ) goto err;
 
     return xce;
+
+err:
+    osdep_evtchn_close(xce);
+    xtl_logger_destroy(xce->logger_tofree);
+    free(xce);
+    return NULL;
 }
 
 int xc_evtchn_close(xc_evtchn *xce)
 {
-    return xc_interface_close_common(xce);
+    int rc;
+
+    rc = osdep_evtchn_close(xce);
+    xtl_logger_destroy(xce->logger_tofree);
+    free(xce);
+    return rc;
 }
 
 xc_gnttab *xc_gnttab_open(xentoollog_logger *logger,
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 247a408..4c66766 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -124,6 +124,13 @@ struct xc_interface_core {
     xc_osdep_handle  ops_handle; /* opaque data for xc_osdep_ops */
 };
 
+struct xenevtchn_handle {
+    xentoollog_logger *logger, *logger_tofree;
+    int fd;
+};
+int osdep_evtchn_open(xc_evtchn *xce);
+int osdep_evtchn_close(xc_evtchn *xce);
+
 void xc_report_error(xc_interface *xch, int code, const char *fmt, ...)
     __attribute__((format(printf,3,4)));
 void xc_reportv(xc_interface *xch, xentoollog_logger *lg, xentoollog_level,
@@ -447,3 +454,13 @@ void *xc_vm_event_enable(xc_interface *xch, domid_t domain_id, int param,
                          uint32_t *port);
 
 #endif /* __XC_PRIVATE_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c
index 7257a54..8867d97 100644
--- a/tools/libxc/xc_solaris.c
+++ b/tools/libxc/xc_solaris.c
@@ -195,33 +195,36 @@ static struct xc_osdep_ops solaris_privcmd_ops = {
     },
 };
 
-static xc_osdep_handle solaris_evtchn_open(xc_evtchn *xce)
+int osdep_evtchn_open(xc_evtchn *xce)
 {
     int fd;
 
     if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 )
     {
         PERROR("Could not open event channel interface");
-        return XC_OSDEP_OPEN_ERROR;
+        return -1;
     }
 
-    return (xc_osdep_handle)fd;
+    xce->fd = fd;
+    return 0;
 }
 
-static int solaris_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
+int osdep_evtchn_close(xc_evtchn *xce)
 {
-    int fd = (int)h;
-    return close(fd);
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
 }
 
-static int solaris_evtchn_fd(xc_evtchn *xce, xc_osdep_handle h)
+int xc_evtchn_fd(xc_evtchn *xce)
 {
-    return (int)h;
+    return xce->fd;
 }
 
-static int solaris_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_notify notify;
 
     notify.port = port;
@@ -229,10 +232,9 @@ static int solaris_evtchn_notify(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_
     return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
 }
 
-static evtchn_port_or_error_t
-solaris_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
+evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_unbound_port bind;
 
     bind.remote_domain = domid;
@@ -240,11 +242,10 @@ solaris_evtchn_bind_unbound_port(xc_evtchn *xce, xc_osdep_handle h, int domid)
     return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
 }
 
-evtchn_port_or_error_t
-solaris_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
-                           evtchn_port_t remote_port)
+evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
+                                                  evtchn_port_t remote_port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_interdomain bind;
 
     bind.remote_domain = domid;
@@ -253,10 +254,9 @@ solaris_evtchn_bind_interdomain(xc_evtchn *xce, xc_osdep_handle h, int domid,
     return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
 }
 
-static evtchn_port_or_error_t
-solaris_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
+evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_bind_virq bind;
 
     bind.virq = virq;
@@ -264,9 +264,9 @@ solaris_evtchn_bind_virq(xc_evtchn *xce, xc_osdep_handle h, unsigned int virq)
     return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
 }
 
-static int solaris_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port)
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     struct ioctl_evtchn_unbind unbind;
 
     unbind.port = port;
@@ -274,10 +274,9 @@ static int solaris_evtchn_unbind(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_
     return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
 }
 
-static evtchn_port_or_error_t
-solaris_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
+evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     evtchn_port_t port;
 
     if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 )
@@ -286,28 +285,12 @@ solaris_evtchn_pending(xc_evtchn *xce, xc_osdep_handle h)
     return port;
 }
 
-static int solaris_evtchn_unmask(xc_evtchn *xce, xc_osdep_handle h,evtchn_port_t port)
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
 {
-    int fd = (int)h;
+    int fd = xce->fd;
     return write_exact(fd, (char *)&port, sizeof(port));
 }
 
-static struct xc_osdep_ops solaris_evtchn_ops = {
-    .open = &solaris_evtchn_open,
-    .close = &solaris_evtchn_close,
-
-    .u.evtchn = {
-        .fd = &solaris_evtchn_fd,
-        .notify = &solaris_evtchn_notify,
-        .bind_unbound_port = &solaris_evtchn_bind_unbound_port,
-        .bind_interdomain = &solaris_evtchn_bind_interdomain,
-        .bind_virq = &solaris_evtchn_bind_virq,
-        .unbind = &solaris_evtchn_unbind,
-        .pending = &solaris_evtchn_pending,
-        .unmask = &solaris_evtchn_unmask,
-    },
-};
-
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
@@ -325,8 +308,6 @@ static struct xc_osdep_ops *solaris_osdep_init(xc_interface *xch, enum xc_osdep_
     {
     case XC_OSDEP_PRIVCMD:
         return &solaris_privcmd_ops;
-    case XC_OSDEP_EVTCHN:
-        return &solaris_evtchn_ops;
     default:
         return NULL;
     }
diff --git a/tools/libxc/xenctrl_osdep_ENOSYS.c b/tools/libxc/xenctrl_osdep_ENOSYS.c
index dd59dcd..5182532 100644
--- a/tools/libxc/xenctrl_osdep_ENOSYS.c
+++ b/tools/libxc/xenctrl_osdep_ENOSYS.c
@@ -81,90 +81,6 @@ static struct xc_osdep_ops ENOSYS_privcmd_ops =
     }
 };
 
-static xc_osdep_handle ENOSYS_evtchn_open(xc_interface *xce)
-{
-    IPRINTF(xce, "ENOSYS_evtchn: opening handle %p\n", (void *)1);
-    return (xc_osdep_handle)2; /*dummy*/
-}
-
-static int ENOSYS_evtchn_close(xc_interface *xce, xc_osdep_handle h)
-{
-    IPRINTF(xce, "ENOSYS_evtchn: closing handle %lx\n", h);
-    return 0;
-}
-
-static int ENOSYS_evtchn_fd(xc_interface *xce, xc_osdep_handle h)
-{
-    IPRINTF(xce, "ENOSYS_fd %lx fd\n", h);
-    return (int)h;
-}
-
-static int ENOSYS_evtchn_notify(xc_interface *xce, xc_osdep_handle h, evtchn_port_t port)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx notify: %d\n", h, port);
-    return -ENOSYS;
-}
-
-static int ENOSYS_evtchn_bind_unbound_port(xc_interface *xce, xc_osdep_handle h, int domid)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx bind_unbound_port: dom%d\n", h, domid);
-    return -ENOSYS;
-}
-
-
-static int ENOSYS_evtchn_bind_interdomain(xc_interface *xce, xc_osdep_handle h, int domid, evtchn_port_t remote_port)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx bind_interdomain: dmo%d %d\n", h, domid, remote_port);
-    return -ENOSYS;
-}
-
-
-static int ENOSYS_evtchn_bind_virq(xc_interface *xce, xc_osdep_handle h, unsigned int virq)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx bind_virq: %d\n", h, virq);
-    return -ENOSYS;
-}
-
-
-static int ENOSYS_evtchn_unbind(xc_interface *xce, xc_osdep_handle h, evtchn_port_t port)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx unbind: %d\n", h, port);
-    return -ENOSYS;
-}
-
-
-static evtchn_port_or_error_t ENOSYS_evtchn_pending(xc_interface *xce, xc_osdep_handle h)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx pending\n", h);
-    return -ENOSYS;
-}
-
-static int ENOSYS_evtchn_unmask(xc_interface *xce, xc_osdep_handle h, evtchn_port_t port)
-{
-    IPRINTF(xce, "ENOSYS_evtchn %lx unmask: %d\n", h, port);
-    return -ENOSYS;
-}
-
-static struct xc_osdep_ops ENOSYS_evtchn_ops = {
-    .open = &ENOSYS_evtchn_open,
-    .close = &ENOSYS_evtchn_close,
-
-    .u.evtchn = {
-        .fd = &ENOSYS_evtchn_fd,
-
-        .notify = &ENOSYS_evtchn_notify,
-
-        .bind_unbound_port = &ENOSYS_evtchn_bind_unbound_port,
-        .bind_interdomain = &ENOSYS_evtchn_bind_interdomain,
-        .bind_virq = &ENOSYS_evtchn_bind_virq,
-
-        .unbind = &ENOSYS_evtchn_unbind,
-
-        .pending = &ENOSYS_evtchn_pending,
-        .unmask = &ENOSYS_evtchn_unmask,
-    },
-};
-
 static struct xc_osdep_ops * ENOSYS_osdep_init(xc_interface *xch, enum xc_osdep_type type)
 {
     struct xc_osdep_ops *ops;
@@ -180,9 +96,6 @@ static struct xc_osdep_ops * ENOSYS_osdep_init(xc_interface *xch, enum xc_osdep_
     case XC_OSDEP_PRIVCMD:
         ops = &ENOSYS_privcmd_ops;
         break;
-    case XC_OSDEP_EVTCHN:
-        ops = &ENOSYS_evtchn_ops;
-        break;
     default:
         ops = NULL;
         break;
diff --git a/tools/ocaml/libs/eventchn/xeneventchn_stubs.c b/tools/ocaml/libs/eventchn/xeneventchn_stubs.c
index abefd6b..5939e7c 100644
--- a/tools/ocaml/libs/eventchn/xeneventchn_stubs.c
+++ b/tools/ocaml/libs/eventchn/xeneventchn_stubs.c
@@ -34,14 +34,14 @@
 #include <caml/callback.h>
 #include <caml/fail.h>
 
-#define _H(__h) ((xc_interface *)(__h))
+#define _H(__h) ((xc_evtchn *)(__h))
 
 CAMLprim value stub_eventchn_init(void)
 {
 	CAMLparam0();
 	CAMLlocal1(result);
 
-	xc_interface *xce = xc_evtchn_open(NULL, XC_OPENFLAG_NON_REENTRANT);
+	xc_evtchn *xce = xc_evtchn_open(NULL, XC_OPENFLAG_NON_REENTRANT);
 	if (xce == NULL)
 		caml_failwith("open failed");
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (3 preceding siblings ...)
  2015-06-10 11:36 ` [PATCH RFC tools 4/6] tools/libxc: Remove osdep indirection for xc_evtchn Ian Campbell
@ 2015-06-10 11:36 ` Ian Campbell
  2015-06-10 16:29   ` David Vrabel
  2015-06-10 17:16   ` Andrew Cooper
  2015-06-10 11:36 ` [PATCH RFC tools 6/6] Cleanup SHLIBDEPS Ian Campbell
                   ` (5 subsequent siblings)
  10 siblings, 2 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

libxenevtchn will provide a stable API and ABI for accessing the
evtchn device.

The functions are moved into the xenevtchn namespace to make a clean
break from libxc and avoid ambiguity regarding which interfaces are
stable.

All in-tree users are updated to use the new names.

Upon request (via #define XC_WANT_COMPAT_EVTCHN_API) libxenctrl will
provide a compat API for the old names, which is used by qemu-xen for
the time being.

The dynamic osdep mechanism from libxc is not preserved, the
alternative backend (a xen-api/xapi shim) is no longer around. (Nested
virt probably suffices for this use case now).

This leaves a few event channel related functions which go via privcmd
(EVTCHNOP) rather than ioctls on the /dev/xen/evtchn device in
libxenctrl. Specifically:

 - xc_evtchn_alloc_unbound
 - xc_evtchn_reset
 - xc_evtchn_status

These functions do not appear to be needed by qemu-dm, qemu-pv
(provision of device model to HVM guests and PV backends respectively)
or by libvchan suggesting they are not needed by non-toolstack uses of
event channels. QEMU does use these in hw/xenpv/xen_domainbuild.c but
that is a "toolstack use".

The new library uses a version script to ensure that only expected
symbols are exported and to version them such that ABI guarantees can
be kept in the future.

Build tested with Linux and mini-os/stubdom, but not FreeBSD, NetBSD
or Solaris.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---

Must be applied with:

 - "qemu-xen-traditional: Use libxenevtchn" and a corresponding
   QEMU_TAG update folded here.
 - "mini-os: Include libxenevtchn with libxc"" and a corresponding
   bump to MINIOS_UPSTREAM_REVISION folded in here.
---
 .gitignore                                    |    1 +
 docs/misc/libxenctrl-functions.pandoc         |    9 +-
 stubdom/Makefile                              |   19 +-
 tools/Makefile                                |    6 +-
 tools/Rules.mk                                |   19 +-
 tools/console/Makefile                        |    2 +
 tools/console/daemon/io.c                     |   43 +++--
 tools/libvchan/Makefile                       |    6 +-
 tools/libvchan/init.c                         |   20 +-
 tools/libvchan/io.c                           |   12 +-
 tools/libvchan/libxenvchan.h                  |    3 +-
 tools/libxc/Makefile                          |    8 +-
 tools/libxc/include/xenctrl.h                 |   99 +---------
 tools/libxc/include/xenctrl_compat.h          |   48 +++++
 tools/libxc/include/xenguest.h                |   10 +-
 tools/libxc/xc_evtchn_compat.c                |   75 ++++++++
 tools/libxc/xc_freebsd_osdep.c                |  101 ----------
 tools/libxc/xc_linux_osdep.c                  |   95 ---------
 tools/libxc/xc_minios.c                       |  221 ---------------------
 tools/libxc/xc_netbsd.c                       |  109 -----------
 tools/libxc/xc_private.c                      |   40 ----
 tools/libxc/xc_private.h                      |    7 -
 tools/libxc/xc_solaris.c                      |   97 ----------
 tools/libxc/xc_suspend.c                      |   18 +-
 tools/libxenevtchn/Makefile                   |   65 +++++++
 tools/libxenevtchn/core.c                     |   60 ++++++
 tools/libxenevtchn/freebsd.c                  |  122 ++++++++++++
 tools/libxenevtchn/include/xenevtchn.h        |  154 +++++++++++++++
 tools/libxenevtchn/libxenevtchn.map           |   14 ++
 tools/libxenevtchn/linux.c                    |  133 +++++++++++++
 tools/libxenevtchn/minios.c                   |  257 +++++++++++++++++++++++++
 tools/libxenevtchn/netbsd.c                   |  132 +++++++++++++
 tools/libxenevtchn/private.h                  |   15 ++
 tools/libxenevtchn/solaris.c                  |  120 ++++++++++++
 tools/libxl/Makefile                          |    5 +-
 tools/libxl/libxl.c                           |    2 +-
 tools/libxl/libxl_dom.c                       |    4 +-
 tools/libxl/libxl_event.c                     |   14 +-
 tools/libxl/libxl_internal.h                  |    5 +-
 tools/misc/Makefile                           |    7 +-
 tools/misc/xen-hptool.c                       |   13 +-
 tools/misc/xen-lowmemd.c                      |   15 +-
 tools/ocaml/libs/eventchn/Makefile            |    4 +-
 tools/ocaml/libs/eventchn/xeneventchn_stubs.c |   20 +-
 tools/python/setup.py                         |    7 +-
 tools/tests/xen-access/xen-access.c           |    2 +-
 tools/xcutils/Makefile                        |    4 +-
 tools/xenmon/Makefile                         |    2 +
 tools/xenmon/xenbaked.c                       |   13 +-
 tools/xenpaging/Makefile                      |    4 +-
 tools/xenpaging/xenpaging.c                   |   18 +-
 tools/xenpaging/xenpaging.h                   |    3 +-
 tools/xenstore/Makefile                       |    5 +-
 tools/xenstore/xenstored_core.c               |    6 +-
 tools/xenstore/xenstored_domain.c             |   25 +--
 tools/xentrace/Makefile                       |    2 +
 tools/xentrace/xentrace.c                     |   13 +-
 57 files changed, 1413 insertions(+), 920 deletions(-)
 create mode 100644 tools/libxc/include/xenctrl_compat.h
 create mode 100644 tools/libxc/xc_evtchn_compat.c
 create mode 100644 tools/libxenevtchn/Makefile
 create mode 100644 tools/libxenevtchn/core.c
 create mode 100644 tools/libxenevtchn/freebsd.c
 create mode 100644 tools/libxenevtchn/include/xenevtchn.h
 create mode 100644 tools/libxenevtchn/libxenevtchn.map
 create mode 100644 tools/libxenevtchn/linux.c
 create mode 100644 tools/libxenevtchn/minios.c
 create mode 100644 tools/libxenevtchn/netbsd.c
 create mode 100644 tools/libxenevtchn/private.h
 create mode 100644 tools/libxenevtchn/solaris.c

diff --git a/.gitignore b/.gitignore
index 49935f2..24fab66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -60,6 +60,7 @@ stubdom/include
 stubdom/ioemu
 stubdom/xenstore
 stubdom/libxentoollog-*
+stubdom/libxenevtchn-*
 stubdom/libxc-*
 stubdom/lwip-*
 stubdom/mini-os-*
diff --git a/docs/misc/libxenctrl-functions.pandoc b/docs/misc/libxenctrl-functions.pandoc
index 60aa6fb..5d09e62 100644
--- a/docs/misc/libxenctrl-functions.pandoc
+++ b/docs/misc/libxenctrl-functions.pandoc
@@ -1009,9 +1009,6 @@ Gathered by:
     - xc_pfn_to_mfn
     - xc_query_page_offline_status
     - xc_read_image
-    - xc_suspend_evtchn_init_exclusive
-    - xc_suspend_evtchn_init_sane
-    - xc_suspend_evtchn_release
     - xc_try_bzip2_decode
     - xc_try_lz4_decode
     - _xc_try_lzma_decode
@@ -1019,6 +1016,12 @@ Gathered by:
     - xc_try_lzo1x_decode
     - xc_try_xz_decode
 
+Use privcmd and evtchn device handles:
+
+    - xc_suspend_evtchn_init_exclusive. Used by xen-hptool and libxl.
+    - xc_suspend_evtchn_init_sane. Unused
+    - xc_suspend_evtchn_release. Used by xen-hptool and libxl.
+
 # Symbols used by qemu
 
     $ nm tools/qemu-xen-dir-remote/i386-softmmu/qemu-system-i386 | grep \\bU.xc_
diff --git a/stubdom/Makefile b/stubdom/Makefile
index b8b0d43..b4dd39a 100644
--- a/stubdom/Makefile
+++ b/stubdom/Makefile
@@ -318,6 +318,12 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET)
 	  ln -sf $(XEN_ROOT)/tools/libxentoollog/include/*.h . && \
 	  ln -sf $(XEN_ROOT)/tools/libxentoollog/*.c . && \
 	  ln -sf $(XEN_ROOT)/tools/libxentoollog/Makefile . )
+	mkdir -p libxenevtchn-$(XEN_TARGET_ARCH)/include
+	[ -h libxenevtchn-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxenevtchn-$(XEN_TARGET_ARCH) && \
+	  ln -sf $(XEN_ROOT)/tools/libxenevtchn/*.h . && \
+	  ln -sf $(XEN_ROOT)/tools/libxenevtchn/include/*.h include/ && \
+	  ln -sf $(XEN_ROOT)/tools/libxenevtchn/*.c . && \
+	  ln -sf $(XEN_ROOT)/tools/libxenevtchn/Makefile . )
 	mkdir -p libxc-$(XEN_TARGET_ARCH)
 	[ -h libxc-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxc-$(XEN_TARGET_ARCH) && \
 	  ln -sf $(XEN_ROOT)/tools/libxc/*.h . && \
@@ -352,12 +358,23 @@ libxentoollog-$(XEN_TARGET_ARCH)/libxentoollog.a: $(NEWLIB_STAMPFILE)
 	CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxentoollog-$(XEN_TARGET_ARCH)
 
 #######
+# libxenevtchn
+#######
+
+.PHONY: libxenevtchn
+libxenevtchn: libxenevtchn-$(XEN_TARGET_ARCH)/libxenevtchn.a
+libxenevtchn-$(XEN_TARGET_ARCH)/libxenevtchn.a: $(NEWLIB_STAMPFILE)
+	$(MAKE) -C $(XEN_ROOT)/tools/include
+	$(MAKE) DESTDIR= -C $(MINI_OS) links
+	CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxenevtchn-$(XEN_TARGET_ARCH)
+
+#######
 # libxc
 #######
 
 .PHONY: libxc
 libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a libxc-$(XEN_TARGET_ARCH)/libxenguest.a
-libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog cross-zlib
+libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog libxenevtchn cross-zlib
 	$(MAKE) -C $(XEN_ROOT)/tools/include
 	$(MAKE) DESTDIR= -C $(MINI_OS) links
 	CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH)
diff --git a/tools/Makefile b/tools/Makefile
index 777591a..3497c53 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -4,6 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 SUBDIRS-y :=
 SUBDIRS-y += include
 SUBDIRS-y += libxentoollog
+SUBDIRS-y += libxenevtchn
 SUBDIRS-y += libxc
 SUBDIRS-$(FLASK_ENABLE) += flask
 SUBDIRS-y += xenstore
@@ -248,8 +249,10 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find
 		--libdir=$(LIBEXEC_LIB) \
 		--includedir=$(LIBEXEC_INC) \
 		--source-path=$$source \
-		--extra-cflags="-I$(XEN_ROOT)/tools/include \
+		--extra-cflags="-DXC_WANT_COMPAT_EVTCHN_API=1 \
+		-I$(XEN_ROOT)/tools/include \
 		-I$(XEN_ROOT)/tools/libxentoollog/include \
+		-I$(XEN_ROOT)/tools/libxenevtchn/include \
 		-I$(XEN_ROOT)/tools/libxc/include \
 		-I$(XEN_ROOT)/tools/xenstore/include \
 		-I$(XEN_ROOT)/tools/xenstore/compat/include \
@@ -257,6 +260,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find
 		--extra-ldflags="-L$(XEN_ROOT)/tools/libxc \
 		-L$(XEN_ROOT)/tools/xenstore \
 		-Wl,-rpath-link=$(XEN_ROOT)/tools/libxentoollog \
+		-Wl,-rpath-link=$(XEN_ROOT)/tools/libxenevtchn \
 		$(QEMU_UPSTREAM_RPATH)" \
 		--bindir=$(LIBEXEC_BIN) \
 		--datadir=$(SHAREDIR)/qemu-xen \
diff --git a/tools/Rules.mk b/tools/Rules.mk
index b8b8559..fd3a7db 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -11,6 +11,7 @@ INSTALL = $(XEN_ROOT)/tools/cross-install
 
 XEN_INCLUDE        = $(XEN_ROOT)/tools/include
 XEN_LIBXENTOOLLOG  = $(XEN_ROOT)/tools/libxentoollog
+XEN_LIBXENEVTCHN   = $(XEN_ROOT)/tools/libxenevtchn
 XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
 XEN_XENLIGHT       = $(XEN_ROOT)/tools/libxl
 XEN_XENSTORE       = $(XEN_ROOT)/tools/xenstore
@@ -39,13 +40,17 @@ CFLAGS_libxentoollog = -I$(XEN_LIBXENTOOLLOG)/include $(CFLAGS_xeninclude)
 LDLIBS_libxentoollog = $(XEN_LIBXENTOOLLOG)/libxentoollog$(libextension)
 SHLIB_libxentoollog  = -Wl,-rpath-link=$(XEN_LIBXENTOOLLOG)
 
+CFLAGS_libxenevtchn = -I$(XEN_LIBXENEVTCHN)/include $(CFLAGS_xeninclude)
+LDLIBS_libxenevtchn = $(XEN_LIBXENEVTCHN)/libxenevtchn$(libextension)
+SHLIB_libxenevtchn  = -Wl,-rpath-link=$(XEN_LIBXENEVTCHN)
+
 CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude)
-LDLIBS_libxenctrl = $(SHLIB_libxentoollog) $(XEN_LIBXC)/libxenctrl$(libextension)
-SHLIB_libxenctrl  =  $(SHLIB_libxentoollog) -Wl,-rpath-link=$(XEN_LIBXC)
+LDLIBS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) $(XEN_LIBXC)/libxenctrl$(libextension)
+SHLIB_libxenctrl  =  $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) -Wl,-rpath-link=$(XEN_LIBXC)
 
-CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_xeninclude)
-LDLIBS_libxenguest = $(XEN_LIBXC)/libxenguest$(libextension)
-SHLIB_libxenguest  = -Wl,-rpath-link=L$(XEN_LIBXC)
+CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_libxenevtchn) $(CFLAGS_xeninclude)
+LDLIBS_libxenguest = $(SHLIB_libxenevtchn) $(XEN_LIBXC)/libxenguest$(libextension)
+SHLIB_libxenguest  = $(SHLIB_libxenevtchn) -Wl,-rpath-link=L$(XEN_LIBXC)
 
 CFLAGS_libxenstore = -I$(XEN_XENSTORE)/include $(CFLAGS_xeninclude)
 LDLIBS_libxenstore = $(XEN_XENSTORE)/libxenstore$(libextension)
@@ -56,8 +61,8 @@ LDLIBS_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBXENSTAT)/
 SHLIB_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBXENSTAT)
 
 CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN)
-LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBVCHAN)/libxenvchan$(libextension)
-SHLIB_libxenvchan  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBVCHAN)
+LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) $(XEN_LIBVCHAN)/libxenvchan$(libextension)
+SHLIB_libxenvchan  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) -Wl,-rpath-link=$(XEN_LIBVCHAN)
 
 ifeq ($(debug),y)
 # Disable optimizations and enable debugging information for macros
diff --git a/tools/console/Makefile b/tools/console/Makefile
index 71f8088..0141d7f 100644
--- a/tools/console/Makefile
+++ b/tools/console/Makefile
@@ -3,8 +3,10 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 CFLAGS  += -Werror
 
+CFLAGS  += $(CFLAGS_libxenevtchn)
 CFLAGS  += $(CFLAGS_libxenctrl)
 CFLAGS  += $(CFLAGS_libxenstore)
+LDLIBS += $(LDLIBS_libxenevtchn)
 LDLIBS += $(LDLIBS_libxenctrl)
 LDLIBS += $(LDLIBS_libxenstore)
 LDLIBS += $(SOCKET_LIBS)
diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c
index ac08b5b..3842362 100644
--- a/tools/console/daemon/io.c
+++ b/tools/console/daemon/io.c
@@ -22,6 +22,7 @@
 
 #include "utils.h"
 #include "io.h"
+#include <xenevtchn.h>
 #include <xenstore.h>
 #include <xen/io/console.h>
 #include <xen/grant_table.h>
@@ -102,7 +103,7 @@ struct domain {
 	int ring_ref;
 	evtchn_port_or_error_t local_port;
 	evtchn_port_or_error_t remote_port;
-	xc_evtchn *xce_handle;
+	xenevtchn_handle *xce_handle;
 	int xce_pollfd_idx;
 	struct xencons_interface *interface;
 	int event_count;
@@ -186,7 +187,7 @@ static void buffer_append(struct domain *dom)
 
 	xen_mb();
 	intf->out_cons = cons;
-	xc_evtchn_notify(dom->xce_handle, dom->local_port);
+	xenevtchn_notify(dom->xce_handle, dom->local_port);
 
 	/* Get the data to the logfile as early as possible because if
 	 * no one is listening on the console pty then it will fill up
@@ -585,22 +586,22 @@ static int domain_create_ring(struct domain *dom)
 	dom->local_port = -1;
 	dom->remote_port = -1;
 	if (dom->xce_handle != NULL)
-		xc_evtchn_close(dom->xce_handle);
+		xenevtchn_close(dom->xce_handle);
 
 	/* Opening evtchn independently for each console is a bit
 	 * wasteful, but that's how the code is structured... */
-	dom->xce_handle = xc_evtchn_open(NULL, 0);
+	dom->xce_handle = xenevtchn_open(NULL, 0);
 	if (dom->xce_handle == NULL) {
 		err = errno;
 		goto out;
 	}
  
-	rc = xc_evtchn_bind_interdomain(dom->xce_handle,
+	rc = xenevtchn_bind_interdomain(dom->xce_handle,
 		dom->domid, remote_port);
 
 	if (rc == -1) {
 		err = errno;
-		xc_evtchn_close(dom->xce_handle);
+		xenevtchn_close(dom->xce_handle);
 		dom->xce_handle = NULL;
 		goto out;
 	}
@@ -610,7 +611,7 @@ static int domain_create_ring(struct domain *dom)
 	if (dom->master_fd == -1) {
 		if (!domain_create_tty(dom)) {
 			err = errno;
-			xc_evtchn_close(dom->xce_handle);
+			xenevtchn_close(dom->xce_handle);
 			dom->xce_handle = NULL;
 			dom->local_port = -1;
 			dom->remote_port = -1;
@@ -750,7 +751,7 @@ static void shutdown_domain(struct domain *d)
 	watch_domain(d, false);
 	domain_unmap_interface(d);
 	if (d->xce_handle != NULL)
-		xc_evtchn_close(d->xce_handle);
+		xenevtchn_close(d->xce_handle);
 	d->xce_handle = NULL;
 }
 
@@ -840,7 +841,7 @@ static void handle_tty_read(struct domain *dom)
 		}
 		xen_wmb();
 		intf->in_prod = prod;
-		xc_evtchn_notify(dom->xce_handle, dom->local_port);
+		xenevtchn_notify(dom->xce_handle, dom->local_port);
 	} else {
 		domain_close_tty(dom);
 		shutdown_domain(dom);
@@ -872,7 +873,7 @@ static void handle_ring_read(struct domain *dom)
 	if (dom->is_dead)
 		return;
 
-	if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
+	if ((port = xenevtchn_pending(dom->xce_handle)) == -1)
 		return;
 
 	dom->event_count++;
@@ -880,7 +881,7 @@ static void handle_ring_read(struct domain *dom)
 	buffer_append(dom);
 
 	if (dom->event_count < RATE_LIMIT_ALLOWANCE)
-		(void)xc_evtchn_unmask(dom->xce_handle, port);
+		(void)xenevtchn_unmask(dom->xce_handle, port);
 }
 
 static void handle_xs(void)
@@ -907,7 +908,7 @@ static void handle_xs(void)
 	free(vec);
 }
 
-static void handle_hv_logs(xc_evtchn *xce_handle, bool force)
+static void handle_hv_logs(xenevtchn_handle *xce_handle, bool force)
 {
 	static char buffer[1024*16];
 	char *bufptr = buffer;
@@ -915,7 +916,7 @@ static void handle_hv_logs(xc_evtchn *xce_handle, bool force)
 	static uint32_t index = 0;
 	evtchn_port_or_error_t port = -1;
 
-	if (!force && ((port = xc_evtchn_pending(xce_handle)) == -1))
+	if (!force && ((port = xenevtchn_pending(xce_handle)) == -1))
 		return;
 
 	do
@@ -939,7 +940,7 @@ static void handle_hv_logs(xc_evtchn *xce_handle, bool force)
 	} while (size == sizeof(buffer));
 
 	if (port != -1)
-		(void)xc_evtchn_unmask(xce_handle, port);
+		(void)xenevtchn_unmask(xce_handle, port);
 }
 
 static void handle_log_reload(void)
@@ -1007,10 +1008,10 @@ void handle_io(void)
 	evtchn_port_or_error_t log_hv_evtchn = -1;
 	int xce_pollfd_idx = -1;
 	int xs_pollfd_idx = -1;
-	xc_evtchn *xce_handle = NULL;
+	xenevtchn_handle *xce_handle = NULL;
 
 	if (log_hv) {
-		xce_handle = xc_evtchn_open(NULL, 0);
+		xce_handle = xenevtchn_open(NULL, 0);
 		if (xce_handle == NULL) {
 			dolog(LOG_ERR, "Failed to open xce handle: %d (%s)",
 			      errno, strerror(errno));
@@ -1019,7 +1020,7 @@ void handle_io(void)
 		log_hv_fd = create_hv_log();
 		if (log_hv_fd == -1)
 			goto out;
-		log_hv_evtchn = xc_evtchn_bind_virq(xce_handle, VIRQ_CON_RING);
+		log_hv_evtchn = xenevtchn_bind_virq(xce_handle, VIRQ_CON_RING);
 		if (log_hv_evtchn == -1) {
 			dolog(LOG_ERR, "Failed to bind to VIRQ_CON_RING: "
 			      "%d (%s)", errno, strerror(errno));
@@ -1048,7 +1049,7 @@ void handle_io(void)
 		xs_pollfd_idx = set_fds(xs_fileno(xs), POLLIN|POLLPRI);
 
 		if (log_hv)
-			xce_pollfd_idx = set_fds(xc_evtchn_fd(xce_handle),
+			xce_pollfd_idx = set_fds(xenevtchn_fd(xce_handle),
 						 POLLIN|POLLPRI);
 
 		if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0)
@@ -1067,7 +1068,7 @@ void handle_io(void)
 			if ((now+5) > d->next_period) {
 				d->next_period = now + RATE_LIMIT_PERIOD;
 				if (d->event_count >= RATE_LIMIT_ALLOWANCE) {
-					(void)xc_evtchn_unmask(d->xce_handle, d->local_port);
+					(void)xenevtchn_unmask(d->xce_handle, d->local_port);
 				}
 				d->event_count = 0;
 			}
@@ -1083,7 +1084,7 @@ void handle_io(void)
 				if (discard_overflowed_data ||
 				    !d->buffer.max_capacity ||
 				    d->buffer.size < d->buffer.max_capacity) {
-					int evtchn_fd = xc_evtchn_fd(d->xce_handle);
+					int evtchn_fd = xenevtchn_fd(d->xce_handle);
 					d->xce_pollfd_idx = set_fds(evtchn_fd,
 								    POLLIN|POLLPRI);
 				}
@@ -1203,7 +1204,7 @@ void handle_io(void)
 		log_hv_fd = -1;
 	}
 	if (xce_handle != NULL) {
-		xc_evtchn_close(xce_handle);
+		xenevtchn_close(xce_handle);
 		xce_handle = NULL;
 	}
 	if (xcg_handle != NULL) {
diff --git a/tools/libvchan/Makefile b/tools/libvchan/Makefile
index 3c50fe6..84128a3 100644
--- a/tools/libvchan/Makefile
+++ b/tools/libvchan/Makefile
@@ -10,9 +10,9 @@ NODE_OBJS = node.o
 NODE2_OBJS = node-select.o
 
 LIBVCHAN_PIC_OBJS = $(patsubst %.o,%.opic,$(LIBVCHAN_OBJS))
-LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl)
-$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxenctrl)
-$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxenctrl)
+LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl) $(LDLIBS_libxenevtchn)
+$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn)
+$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn)
 
 MAJOR = 1.0
 MINOR = 0
diff --git a/tools/libvchan/init.c b/tools/libvchan/init.c
index de10817..fef6c8d 100644
--- a/tools/libvchan/init.c
+++ b/tools/libvchan/init.c
@@ -217,25 +217,25 @@ static int init_evt_srv(struct libxenvchan *ctrl, int domain, xentoollog_logger
 {
 	evtchn_port_or_error_t port;
 
-	ctrl->event = xc_evtchn_open(logger, 0);
+	ctrl->event = xenevtchn_open(logger, 0);
 	if (!ctrl->event)
 		return -1;
 
-	port = xc_evtchn_bind_unbound_port(ctrl->event, domain);
+	port = xenevtchn_bind_unbound_port(ctrl->event, domain);
 	if (port < 0)
 		goto fail;
 	ctrl->event_port = port;
 
-	if (xc_evtchn_unmask(ctrl->event, ctrl->event_port))
+	if (xenevtchn_unmask(ctrl->event, ctrl->event_port))
 		goto fail;
 
 	return 0;
 
 fail:
 	if (port >= 0)
-		xc_evtchn_unbind(ctrl->event, port);
+		xenevtchn_unbind(ctrl->event, port);
 
-	xc_evtchn_close(ctrl->event);
+	xenevtchn_close(ctrl->event);
 	ctrl->event = NULL;
 
 	return -1;
@@ -347,26 +347,26 @@ static int init_evt_cli(struct libxenvchan *ctrl, int domain, xentoollog_logger
 {
 	evtchn_port_or_error_t port;
 
-	ctrl->event = xc_evtchn_open(logger, 0);
+	ctrl->event = xenevtchn_open(logger, 0);
 	if (!ctrl->event)
 		return -1;
 
-	port = xc_evtchn_bind_interdomain(ctrl->event,
+	port = xenevtchn_bind_interdomain(ctrl->event,
 		domain, ctrl->event_port);
 	if (port < 0)
 		goto fail;
 	ctrl->event_port = port;
 
-	if (xc_evtchn_unmask(ctrl->event, ctrl->event_port))
+	if (xenevtchn_unmask(ctrl->event, ctrl->event_port))
 		goto fail;
 
 	return 0;
 
 fail:
 	if (port >= 0)
-		xc_evtchn_unbind(ctrl->event, port);
+		xenevtchn_unbind(ctrl->event, port);
 
-	xc_evtchn_close(ctrl->event);
+	xenevtchn_close(ctrl->event);
 	ctrl->event = NULL;
 
 	return -1;
diff --git a/tools/libvchan/io.c b/tools/libvchan/io.c
index e66bc4e..4bd15ed 100644
--- a/tools/libvchan/io.c
+++ b/tools/libvchan/io.c
@@ -106,7 +106,7 @@ static inline int send_notify(struct libxenvchan *ctrl, uint8_t bit)
 	notify = ctrl->is_server ? &ctrl->ring->srv_notify : &ctrl->ring->cli_notify;
 	prev = __sync_fetch_and_and(notify, ~bit);
 	if (prev & bit)
-		return xc_evtchn_notify(ctrl->event, ctrl->event_port);
+		return xenevtchn_notify(ctrl->event, ctrl->event_port);
 	else
 		return 0;
 }
@@ -195,10 +195,10 @@ int libxenvchan_buffer_space(struct libxenvchan *ctrl)
 
 int libxenvchan_wait(struct libxenvchan *ctrl)
 {
-	int ret = xc_evtchn_pending(ctrl->event);
+	int ret = xenevtchn_pending(ctrl->event);
 	if (ret < 0)
 		return -1;
-	xc_evtchn_unmask(ctrl->event, ret);
+	xenevtchn_unmask(ctrl->event, ret);
 	return 0;
 }
 
@@ -351,7 +351,7 @@ int libxenvchan_is_open(struct libxenvchan* ctrl)
 
 int libxenvchan_fd_for_select(struct libxenvchan *ctrl)
 {
-	return xc_evtchn_fd(ctrl->event);
+	return xenevtchn_fd(ctrl->event);
 }
 
 void libxenvchan_close(struct libxenvchan *ctrl)
@@ -373,8 +373,8 @@ void libxenvchan_close(struct libxenvchan *ctrl)
 	}
 	if (ctrl->event) {
 		if (ctrl->ring)
-			xc_evtchn_notify(ctrl->event, ctrl->event_port);
-		xc_evtchn_close(ctrl->event);
+			xenevtchn_notify(ctrl->event, ctrl->event_port);
+		xenevtchn_close(ctrl->event);
 	}
 	if (ctrl->is_server) {
 		if (ctrl->gntshr)
diff --git a/tools/libvchan/libxenvchan.h b/tools/libvchan/libxenvchan.h
index 6365d36..0517dda 100644
--- a/tools/libvchan/libxenvchan.h
+++ b/tools/libvchan/libxenvchan.h
@@ -45,6 +45,7 @@
 
 #include <xen/io/libxenvchan.h>
 #include <xen/sys/evtchn.h>
+#include <xenevtchn.h>
 #include <xenctrl.h>
 
 struct libxenvchan_ring {
@@ -72,7 +73,7 @@ struct libxenvchan {
 	/* Pointer to shared ring page */
 	struct vchan_interface *ring;
 	/* event channel interface */
-	xc_evtchn *event;
+	xenevtchn_handle *event;
 	uint32_t event_port;
 	/* informative flags: are we acting as server? */
 	int is_server:1;
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 877ea62..8b69f93 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -47,6 +47,7 @@ CTRL_SRCS-$(CONFIG_FreeBSD) += xc_freebsd.c xc_freebsd_osdep.c
 CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
 CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c
 CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c
+CTRL_SRCS-y       += xc_evtchn_compat.c
 
 GUEST_SRCS-y :=
 GUEST_SRCS-y += xg_private.c xc_suspend.c
@@ -114,6 +115,7 @@ CFLAGS-$(CONFIG_Linux) += -D_GNU_SOURCE
 
 CFLAGS	+= $(PTHREAD_CFLAGS)
 CFLAGS	+= $(CFLAGS_libxentoollog)
+CFLAGS	+= $(CFLAGS_libxenevtchn)
 
 CTRL_LIB_OBJS := $(patsubst %.c,%.o,$(CTRL_SRCS-y))
 CTRL_PIC_OBJS := $(patsubst %.c,%.opic,$(CTRL_SRCS-y))
@@ -167,7 +169,7 @@ install: build
 	$(INSTALL_DATA) libxenctrl.a $(DESTDIR)$(libdir)
 	$(SYMLINK_SHLIB) libxenctrl.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenctrl.so.$(MAJOR)
 	$(SYMLINK_SHLIB) libxenctrl.so.$(MAJOR) $(DESTDIR)$(libdir)/libxenctrl.so
-	$(INSTALL_DATA) include/xenctrl.h include/xenctrlosdep.h $(DESTDIR)$(includedir)
+	$(INSTALL_DATA) include/xenctrl.h include/xenctrl_compat.h include/xenctrlosdep.h $(DESTDIR)$(includedir)
 	$(INSTALL_SHLIB) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
 	$(INSTALL_DATA) libxenguest.a $(DESTDIR)$(libdir)
 	$(SYMLINK_SHLIB) libxenguest.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenguest.so.$(MAJOR)
@@ -210,7 +212,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
 	$(SYMLINK_SHLIB) $< $@
 
 libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
-	$(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
 
 # libxenguest
 
@@ -233,7 +235,7 @@ xc_dom_bzimageloader.opic: CFLAGS += $(call zlib-options,D)
 
 libxenguest.so.$(MAJOR).$(MINOR): COMPRESSION_LIBS = $(call zlib-options,l)
 libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
-	$(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS) $(COMPRESSION_LIBS) -lz $(LDLIBS_libxenctrl) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenguest.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS) $(COMPRESSION_LIBS) -lz $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
 
 xenctrl_osdep_ENOSYS.so: $(OSDEP_PIC_OBJS) libxenctrl.so
 	$(CC) $(LDFLAGS) $(SHLIB_LDFLAGS) -o $@ $(OSDEP_PIC_OBJS) $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index f7b6533..90649a9 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -118,7 +118,6 @@
  */
 
 typedef struct xc_interface_core xc_interface;
-typedef struct xenevtchn_handle xc_evtchn;
 typedef struct xc_interface_core xc_gnttab;
 typedef struct xc_interface_core xc_gntshr;
 
@@ -1106,7 +1105,6 @@ int xc_cpupool_movedomain(xc_interface *xch,
  */
 xc_cpumap_t xc_cpupool_freeinfo(xc_interface *xch);
 
-
 /*
  * EVENT CHANNEL FUNCTIONS
  *
@@ -1141,101 +1139,7 @@ int xc_evtchn_reset(xc_interface *xch,
 typedef struct evtchn_status xc_evtchn_status_t;
 int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status);
 
-/*
- * Return a handle to the event channel driver, or NULL on failure, in
- * which case errno will be set appropriately.
- *
- * Note:
- * After fork a child process must not use any opened xc evtchn
- * handle inherited from their parent. They must open a new handle if
- * they want to interact with xc.
- *
- * Before Xen pre-4.1 this function would sometimes report errors with perror.
- */
-xc_evtchn *xc_evtchn_open(xentoollog_logger *logger,
-                             unsigned open_flags);
 
-/*
- * Close a handle previously allocated with xc_evtchn_open().
- */
-int xc_evtchn_close(xc_evtchn *xce);
-
-/*
- * Return an fd that can be select()ed on.
- *
- * Note that due to bugs, setting this fd to non blocking may not
- * work: you would hope that it would result in xc_evtchn_pending
- * failing with EWOULDBLOCK if there are no events signaled, but in
- * fact it may block.  (Bug is present in at least Linux 3.12, and
- * perhaps on other platforms or later version.)
- *
- * To be safe, you must use poll() or select() before each call to
- * xc_evtchn_pending.  If you have multiple threads (or processes)
- * sharing a single xce handle this will not work, and there is no
- * straightforward workaround.  Please design your program some other
- * way.
- */
-int xc_evtchn_fd(xc_evtchn *xce);
-
-/*
- * Notify the given event channel. Returns -1 on failure, in which case
- * errno will be set appropriately.
- */
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port);
-
-/*
- * Returns a new event port awaiting interdomain connection from the given
- * domain ID, or -1 on failure, in which case errno will be set appropriately.
- */
-evtchn_port_or_error_t
-xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid);
-
-/*
- * Returns a new event port bound to the remote port for the given domain ID,
- * or -1 on failure, in which case errno will be set appropriately.
- */
-evtchn_port_or_error_t
-xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
-                           evtchn_port_t remote_port);
-
-/*
- * Bind an event channel to the given VIRQ. Returns the event channel bound to
- * the VIRQ, or -1 on failure, in which case errno will be set appropriately.
- */
-evtchn_port_or_error_t
-xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq);
-
-/*
- * Unbind the given event channel. Returns -1 on failure, in which case errno
- * will be set appropriately.
- */
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port);
-
-/*
- * Return the next event channel to become pending, or -1 on failure, in which
- * case errno will be set appropriately.
- *
- * At the hypervisor level the event channel will have been masked,
- * and then cleared, by the underlying machinery (evtchn kernel
- * driver, or equivalent).  So if the event channel is signaled again
- * after it is returned here, it will be queued up, and delivered
- * again after you unmask it.  (See the documentation in the Xen
- * public header event_channel.h.)
- *
- * On receiving the notification from xc_evtchn_pending, you should
- * normally: check (by other means) what work needs doing; do the
- * necessary work (if any); unmask the event channel with
- * xc_evtchn_unmask (if you want to receive any further
- * notifications).
- */
-evtchn_port_or_error_t
-xc_evtchn_pending(xc_evtchn *xce);
-
-/*
- * Unmask the given event channel. Returns -1 on failure, in which case errno
- * will be set appropriately.
- */
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port);
 
 int xc_physdev_pci_access_modify(xc_interface *xch,
                                  uint32_t domid,
@@ -2785,6 +2689,9 @@ int xc_psr_cmt_get_data(xc_interface *xch, uint32_t rmid, uint32_t cpu,
 int xc_psr_cmt_enabled(xc_interface *xch);
 #endif
 
+/* Compat shims */
+#include "xenctrl_compat.h"
+
 #endif /* XENCTRL_H */
 
 /*
diff --git a/tools/libxc/include/xenctrl_compat.h b/tools/libxc/include/xenctrl_compat.h
new file mode 100644
index 0000000..48daeb2
--- /dev/null
+++ b/tools/libxc/include/xenctrl_compat.h
@@ -0,0 +1,48 @@
+/*
+ * Compat shims for use of 3rd party consumers of libxenctrl
+ * functionality which has been split into separate libraries.
+ *
+ * New code should use the separate libraries.
+ *
+ * Each interface must be opted-into separately by defining:
+ *
+ * XC_WANT_COMPAT_EVTCHN_API
+ *  - Functions relating to /dev/xen/evtchn
+ */
+#ifndef XENCTRL_COMPAT_H
+#define XENCTRL_COMPAT_H
+
+#ifdef XC_WANT_COMPAT_EVTCHN_API
+
+typedef struct xenevtchn_handle xc_evtchn;
+
+xc_evtchn *xc_evtchn_open(xentoollog_logger *logger,
+                             unsigned open_flags);
+int xc_evtchn_close(xc_evtchn *xce);
+int xc_evtchn_fd(xc_evtchn *xce);
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port);
+evtchn_port_or_error_t
+xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid);
+evtchn_port_or_error_t
+xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
+                           evtchn_port_t remote_port);
+evtchn_port_or_error_t
+xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq);
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port);
+evtchn_port_or_error_t
+xc_evtchn_pending(xc_evtchn *xce);
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port);
+
+#endif /* XC_WANT_COMPAT_EVTCHN_API */
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 7581263..6fcdb4f 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -23,6 +23,8 @@
 #ifndef XENGUEST_H
 #define XENGUEST_H
 
+#include <xenevtchn.h>
+
 #define XC_NUMA_NO_NODE   (~0U)
 
 #define XCFLAGS_LIVE      (1 << 0)
@@ -281,18 +283,18 @@ int xc_hvm_build_target_mem(xc_interface *xch,
  * Sets *lockfd to -1.
  * Has deallocated everything even on error.
  */
-int xc_suspend_evtchn_release(xc_interface *xch, xc_evtchn *xce, int domid, int suspend_evtchn, int *lockfd);
+int xc_suspend_evtchn_release(xc_interface *xch, xenevtchn_handle *xce, int domid, int suspend_evtchn, int *lockfd);
 
 /**
  * This function eats the initial notification.
  * xce must not be used for anything else
  * See xc_suspend_evtchn_init_sane re lockfd.
  */
-int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xc_evtchn *xce,
+int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xenevtchn_handle *xce,
                                      int domid, int port, int *lockfd);
 
 /* xce must not be used for anything else */
-int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn);
+int xc_await_suspend(xc_interface *xch, xenevtchn_handle *xce, int suspend_evtchn);
 
 /**
  * The port will be signaled immediately after this call
@@ -301,7 +303,7 @@ int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn);
  * and fed to xc_suspend_evtchn_release.  (On error *lockfd is
  * undefined and xc_suspend_evtchn_release is not allowed.)
  */
-int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce,
+int xc_suspend_evtchn_init_sane(xc_interface *xch, xenevtchn_handle *xce,
                                 int domid, int port, int *lockfd);
 
 int xc_get_bit_size(xc_interface *xch,
diff --git a/tools/libxc/xc_evtchn_compat.c b/tools/libxc/xc_evtchn_compat.c
new file mode 100644
index 0000000..5d3e4ba
--- /dev/null
+++ b/tools/libxc/xc_evtchn_compat.c
@@ -0,0 +1,75 @@
+/*
+ * Compat shims for use of 3rd party consumers of libxenctrl xc_evtchn
+ * functionality which has been split into separate libraries.
+ */
+
+#include <xenevtchn.h>
+
+#define XC_WANT_COMPAT_EVTCHN_API
+#include "xenctrl.h"
+
+xc_evtchn *xc_evtchn_open(xentoollog_logger *logger,
+                          unsigned open_flags)
+{
+    return xenevtchn_open(logger, open_flags);
+}
+
+int xc_evtchn_close(xc_evtchn *xce)
+{
+    return xenevtchn_close(xce);
+}
+
+int xc_evtchn_fd(xc_evtchn *xce)
+{
+    return xenevtchn_fd(xce);
+}
+
+int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
+{
+    return xenevtchn_notify(xce, port);
+}
+
+evtchn_port_or_error_t
+xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
+{
+    return xenevtchn_bind_unbound_port(xce, domid);
+}
+
+evtchn_port_or_error_t
+xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
+                           evtchn_port_t remote_port)
+{
+    return xenevtchn_bind_interdomain(xce, domid, remote_port);
+}
+
+evtchn_port_or_error_t
+xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
+{
+    return xenevtchn_bind_virq(xce, virq);
+}
+
+int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
+{
+    return xenevtchn_unbind(xce, port);
+}
+
+evtchn_port_or_error_t
+xc_evtchn_pending(xc_evtchn *xce)
+{
+    return xenevtchn_pending(xce);
+}
+
+int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
+{
+    return xenevtchn_unmask(xce, port);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxc/xc_freebsd_osdep.c b/tools/libxc/xc_freebsd_osdep.c
index 7274274..57a7d89 100644
--- a/tools/libxc/xc_freebsd_osdep.c
+++ b/tools/libxc/xc_freebsd_osdep.c
@@ -32,13 +32,11 @@
 #include <sys/ioctl.h>
 
 #include <xen/memory.h>
-#include <xen/sys/evtchn.h>
 
 #include "xenctrl.h"
 #include "xenctrlosdep.h"
 
 #define PRIVCMD_DEV     "/dev/xen/privcmd"
-#define EVTCHN_DEV      "/dev/xen/evtchn"
 
 #define PERROR(_m, _a...) xc_osdep_log(xch,XTL_ERROR,XC_INTERNAL_ERROR,_m \
                   " (%d = %s)", ## _a , errno, xc_strerror(xch, errno))
@@ -252,105 +250,6 @@ static struct xc_osdep_ops freebsd_privcmd_ops = {
     },
 };
 
-/*-------------------------- Evtchn device interface -------------------------*/
-int osdep_evtchn_open(xc_evtchn *xce)
-{
-    int fd = open(EVTCHN_DEV, O_RDWR);
-    if ( fd == -1 )
-        return -1;
-    xce->fd = fd;
-    return 0;
-}
-
-int osdep_evtchn_close(xc_evtchn *xce)
-{
-    if ( xce->fd == -1 )
-        return 0;
-
-    return close(xce->fd);
-}
-
-int xc_evtchn_fd(xc_evtchn *xce)
-{
-    return xce->fd;
-}
-
-/*------------------------------ Evtchn interface ----------------------------*/
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_notify notify;
-
-    notify.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
-{
-    int ret, fd = xce->fd;
-    struct ioctl_evtchn_bind_unbound_port bind;
-
-    bind.remote_domain = domid;
-
-    ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
-    return ( ret == 0 ) ? bind.port : ret;
-}
-
-evtchn_port_or_error_t
-xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid, evtchn_port_t remote_port)
-{
-    int ret, fd = xce->fd;
-    struct ioctl_evtchn_bind_interdomain bind;
-
-    bind.remote_domain = domid;
-    bind.remote_port = remote_port;
-
-    ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
-    return ( ret == 0 ) ? bind.port : ret;
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
-{
-    int ret, fd = xce->fd;
-    struct ioctl_evtchn_bind_virq bind;
-
-    bind.virq = virq;
-
-    ret = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
-    return ( ret == 0 ) ? bind.port : ret;
-}
-
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_unbind unbind;
-
-    unbind.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
-}
-
-evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
-{
-    int fd = xce->fd;
-    evtchn_port_t port;
-
-    if ( read(fd, &port, sizeof(port)) != sizeof(port) )
-        return -1;
-
-    return port;
-}
-
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-
-    if ( write(fd, &port, sizeof(port)) != sizeof(port) )
-        return -1;
-    return 0;
-}
-
 /*---------------------------- FreeBSD interface -----------------------------*/
 static struct xc_osdep_ops *
 freebsd_osdep_init(xc_interface *xch, enum xc_osdep_type type)
diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c
index 3c96c76..2230e44 100644
--- a/tools/libxc/xc_linux_osdep.c
+++ b/tools/libxc/xc_linux_osdep.c
@@ -32,7 +32,6 @@
 #include <sys/ioctl.h>
 
 #include <xen/memory.h>
-#include <xen/sys/evtchn.h>
 #include <xen/sys/gntdev.h>
 #include <xen/sys/gntalloc.h>
 
@@ -456,100 +455,6 @@ static struct xc_osdep_ops linux_privcmd_ops = {
 
 #define DEVXEN "/dev/xen/"
 
-int osdep_evtchn_open(xc_evtchn *xce)
-{
-    int fd = open(DEVXEN "evtchn", O_RDWR);
-    if ( fd == -1 )
-        return -1;
-    xce->fd = fd;
-    return 0;
-}
-
-int osdep_evtchn_close(xc_evtchn *xce)
-{
-    if ( xce->fd == -1 )
-        return 0;
-
-    return close(xce->fd);
-}
-
-int xc_evtchn_fd(xc_evtchn *xce)
-{
-    return xce->fd;
-}
-
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_notify notify;
-
-    notify.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_unbound_port bind;
-
-    bind.remote_domain = domid;
-
-    return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
-                                                  evtchn_port_t remote_port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_interdomain bind;
-
-    bind.remote_domain = domid;
-    bind.remote_port = remote_port;
-
-    return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_virq bind;
-
-    bind.virq = virq;
-
-    return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
-}
-
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_unbind unbind;
-
-    unbind.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
-}
-
-evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
-{
-    int fd = xce->fd;
-    evtchn_port_t port;
-
-    if ( read(fd, &port, sizeof(port)) != sizeof(port) )
-        return -1;
-
-    return port;
-}
-
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-
-    if ( write(fd, &port, sizeof(port)) != sizeof(port) )
-        return -1;
-    return 0;
-}
-
 static xc_osdep_handle linux_gnttab_open(xc_gnttab *xcg)
 {
     int fd = open(DEVXEN "gntdev", O_RDWR);
diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c
index e9c4d8b..7878cfa 100644
--- a/tools/libxc/xc_minios.c
+++ b/tools/libxc/xc_minios.c
@@ -20,14 +20,11 @@
  */
 
 #undef NDEBUG
-#include "xen-external/bsd-sys-queue.h"
 #include <mini-os/types.h>
 #include <mini-os/os.h>
 #include <mini-os/mm.h>
 #include <mini-os/lib.h>
 #include <mini-os/gntmap.h>
-#include <mini-os/events.h>
-#include <mini-os/wait.h>
 #include <sys/mman.h>
 
 #include <xen/memory.h>
@@ -42,13 +39,9 @@
 #include "xc_private.h"
 
 void minios_interface_close_fd(int fd);
-void minios_evtchn_close_fd(int fd);
 void minios_gnttab_close_fd(int fd);
 
 extern void minios_interface_close_fd(int fd);
-extern void minios_evtchn_close_fd(int fd);
-
-extern struct wait_queue_head event_queue;
 
 static xc_osdep_handle minios_privcmd_open(xc_interface *xch)
 {
@@ -198,220 +191,6 @@ static struct xc_osdep_ops minios_privcmd_ops = {
     },
 };
 
-
-/* XXX Note: This is not threadsafe */
-static struct evtchn_port_info* port_alloc(int fd) {
-    struct evtchn_port_info *port_info;
-    port_info = malloc(sizeof(struct evtchn_port_info));
-    if (port_info == NULL)
-        return NULL;
-    port_info->pending = 0;
-    port_info->port = -1;
-    port_info->bound = 0;
-
-    LIST_INSERT_HEAD(&files[fd].evtchn.ports, port_info, list);
-    return port_info;
-}
-
-static void port_dealloc(struct evtchn_port_info *port_info) {
-    if (port_info->bound)
-        unbind_evtchn(port_info->port);
-    LIST_REMOVE(port_info, list);
-    free(port_info);
-}
-
-int osdep_evtchn_open(xc_evtchn *xce)
-{
-    int fd = alloc_fd(FTYPE_EVTCHN);
-    if ( fd == -1 )
-        return -1;
-    LIST_INIT(&files[fd].evtchn.ports);
-    xce->fd = fd;
-    printf("evtchn_open() -> %d\n", fd);
-    return 0;
-}
-
-int osdep_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
-{
-    if ( xce->fd == -1 )
-        return 0;
-
-    return close(xce->fd);
-}
-
-void minios_evtchn_close_fd(int fd)
-{
-    struct evtchn_port_info *port_info, *tmp;
-    LIST_FOREACH_SAFE(port_info, &files[fd].evtchn.ports, list, tmp)
-        port_dealloc(port_info);
-
-    files[fd].type = FTYPE_NONE;
-}
-
-int xc_evtchn_fd(xc_evtchn *xce)
-{
-    return xce->fd;
-}
-
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
-{
-    int ret;
-
-    ret = notify_remote_via_evtchn(port);
-
-    if (ret < 0) {
-	errno = -ret;
-	ret = -1;
-    }
-    return ret;
-}
-
-static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
-{
-    int fd = (int)(intptr_t)data;
-    struct evtchn_port_info *port_info;
-    assert(files[fd].type == FTYPE_EVTCHN);
-    mask_evtchn(port);
-    LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
-        if (port_info->port == port)
-            goto found;
-    }
-    printk("Unknown port for handle %d\n", fd);
-    return;
-
- found:
-    port_info->pending = 1;
-    files[fd].read = 1;
-    wake_up(&event_queue);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
-{
-    int fd = xce->fd;
-    struct evtchn_port_info *port_info;
-    int ret;
-    evtchn_port_t port;
-
-    assert(get_current() == main_thread);
-    port_info = port_alloc(fd);
-    if (port_info == NULL)
-	return -1;
-
-    printf("xc_evtchn_bind_unbound_port(%d)", domid);
-    ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)fd, &port);
-    printf(" = %d\n", ret);
-
-    if (ret < 0) {
-	port_dealloc(port_info);
-	errno = -ret;
-	return -1;
-    }
-    port_info->bound = 1;
-    port_info->port = port;
-    unmask_evtchn(port);
-    return port;
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
-                                                  evtchn_port_t remote_port)
-{
-    int fd = xce->fd;
-    struct evtchn_port_info *port_info;
-    evtchn_port_t local_port;
-    int ret;
-
-    assert(get_current() == main_thread);
-    port_info = port_alloc(fd);
-    if (port_info == NULL)
-	return -1;
-
-    printf("xc_evtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
-    ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)fd, &local_port);
-    printf(" = %d\n", ret);
-
-    if (ret < 0) {
-	port_dealloc(port_info);
-	errno = -ret;
-	return -1;
-    }
-    port_info->bound = 1;
-    port_info->port = local_port;
-    unmask_evtchn(local_port);
-    return local_port;
-}
-
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct evtchn_port_info *port_info;
-
-    LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
-        if (port_info->port == port) {
-            port_dealloc(port_info);
-            return 0;
-        }
-    }
-    printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, fd);
-    errno = EINVAL;
-    return -1;
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
-{
-    int fd = xce->fd;
-    struct evtchn_port_info *port_info;
-    evtchn_port_t port;
-
-    assert(get_current() == main_thread);
-    port_info = port_alloc(fd);
-    if (port_info == NULL)
-	return -1;
-
-    printf("xc_evtchn_bind_virq(%d)", virq);
-    port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)fd);
-
-    if (port < 0) {
-	port_dealloc(port_info);
-	errno = -port;
-	return -1;
-    }
-    port_info->bound = 1;
-    port_info->port = port;
-    unmask_evtchn(port);
-    return port;
-}
-
-evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
-{
-    int fd = xce->fd;
-    struct evtchn_port_info *port_info;
-    unsigned long flags;
-    evtchn_port_t ret = -1;
-
-    local_irq_save(flags);
-    files[fd].read = 0;
-
-    LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
-        if (port_info->port != -1 && port_info->pending) {
-            if (ret == -1) {
-                ret = port_info->port;
-                port_info->pending = 0;
-            } else {
-                files[fd].read = 1;
-                break;
-            }
-        }
-    }
-    local_irq_restore(flags);
-    return ret;
-}
-
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
-{
-    unmask_evtchn(port);
-    return 0;
-}
-
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush)
 {
diff --git a/tools/libxc/xc_netbsd.c b/tools/libxc/xc_netbsd.c
index f9bc100..48fd5d7 100644
--- a/tools/libxc/xc_netbsd.c
+++ b/tools/libxc/xc_netbsd.c
@@ -20,7 +20,6 @@
 
 #include "xc_private.h"
 
-#include <xen/sys/evtchn.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <malloc.h>
@@ -224,114 +223,6 @@ static struct xc_osdep_ops netbsd_privcmd_ops = {
     },
 };
 
-#define EVTCHN_DEV_NAME  "/dev/xenevt"
-
-int osdep_evtchn_open(xc_evtchn *xce)
-{
-    int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
-    if ( fd == -1 )
-        return -1;
-    xce->fd = fd;
-    return 0;
-}
-
-int osdep_evtchn_close(xc_evtchn *xce, xc_osdep_handle h)
-{
-    if ( xce->fd == -1 )
-        return 0;
-
-    return close(xce->fd);
-}
-
-int xc_evtchn_fd(xc_evtchn *xce)
-{
-    return xce->fd;
-}
-
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_notify notify;
-
-    notify.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn * xce, int domid)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_unbound_port bind;
-    int ret;
-
-    bind.remote_domain = domid;
-
-    ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
-    if (ret == 0)
-	return bind.port;
-    else
-	return -1;
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
-                                                  evtchn_port_t remote_port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_interdomain bind;
-    int ret;
-
-    bind.remote_domain = domid;
-    bind.remote_port = remote_port;
-
-    ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
-    if (ret == 0)
-	return bind.port;
-    else
-	return -1;
-}
-
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_unbind unbind;
-
-    unbind.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_virq bind;
-    int err;
-
-    bind.virq = virq;
-
-    err = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
-    if (err)
-	return -1;
-    else
-	return bind.port;
-}
-
-evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
-{
-    int fd = xce->fd;
-    evtchn_port_t port;
-
-    if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 )
-        return -1;
-
-    return port;
-}
-
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    return write_exact(fd, (char *)&port, sizeof(port));
-}
-
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index 9f0ada7..375430c 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -252,46 +252,6 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
     return xch->ops->u.privcmd.hypercall(xch, xch->ops_handle, hypercall);
 }
 
-xc_evtchn *xc_evtchn_open(xentoollog_logger *logger, unsigned open_flags)
-{
-    xc_evtchn *xce = malloc(sizeof(*xce));
-    int rc;
-
-    if (!xce) return NULL;
-
-    xce->fd = -1;
-    xce->logger = logger;
-    xce->logger_tofree  = NULL;
-
-    if (!xce->logger) {
-        xce->logger = xce->logger_tofree =
-            (xentoollog_logger*)
-            xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
-        if (!xce->logger) goto err;
-    }
-
-    rc = osdep_evtchn_open(xce);
-    if ( rc  < 0 ) goto err;
-
-    return xce;
-
-err:
-    osdep_evtchn_close(xce);
-    xtl_logger_destroy(xce->logger_tofree);
-    free(xce);
-    return NULL;
-}
-
-int xc_evtchn_close(xc_evtchn *xce)
-{
-    int rc;
-
-    rc = osdep_evtchn_close(xce);
-    xtl_logger_destroy(xce->logger_tofree);
-    free(xce);
-    return rc;
-}
-
 xc_gnttab *xc_gnttab_open(xentoollog_logger *logger,
                              unsigned open_flags)
 {
diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h
index 4c66766..61f2f45 100644
--- a/tools/libxc/xc_private.h
+++ b/tools/libxc/xc_private.h
@@ -124,13 +124,6 @@ struct xc_interface_core {
     xc_osdep_handle  ops_handle; /* opaque data for xc_osdep_ops */
 };
 
-struct xenevtchn_handle {
-    xentoollog_logger *logger, *logger_tofree;
-    int fd;
-};
-int osdep_evtchn_open(xc_evtchn *xce);
-int osdep_evtchn_close(xc_evtchn *xce);
-
 void xc_report_error(xc_interface *xch, int code, const char *fmt, ...)
     __attribute__((format(printf,3,4)));
 void xc_reportv(xc_interface *xch, xentoollog_logger *lg, xentoollog_level,
diff --git a/tools/libxc/xc_solaris.c b/tools/libxc/xc_solaris.c
index 8867d97..182bd7d 100644
--- a/tools/libxc/xc_solaris.c
+++ b/tools/libxc/xc_solaris.c
@@ -21,7 +21,6 @@
 #include "xc_private.h"
 
 #include <xen/memory.h>
-#include <xen/sys/evtchn.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <malloc.h>
@@ -195,102 +194,6 @@ static struct xc_osdep_ops solaris_privcmd_ops = {
     },
 };
 
-int osdep_evtchn_open(xc_evtchn *xce)
-{
-    int fd;
-
-    if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 )
-    {
-        PERROR("Could not open event channel interface");
-        return -1;
-    }
-
-    xce->fd = fd;
-    return 0;
-}
-
-int osdep_evtchn_close(xc_evtchn *xce)
-{
-    if ( xce->fd == -1 )
-        return 0;
-
-    return close(xce->fd);
-}
-
-int xc_evtchn_fd(xc_evtchn *xce)
-{
-    return xce->fd;
-}
-
-int xc_evtchn_notify(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_notify notify;
-
-    notify.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_unbound_port(xc_evtchn *xce, int domid)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_unbound_port bind;
-
-    bind.remote_domain = domid;
-
-    return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_interdomain(xc_evtchn *xce, int domid,
-                                                  evtchn_port_t remote_port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_interdomain bind;
-
-    bind.remote_domain = domid;
-    bind.remote_port = remote_port;
-
-    return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
-}
-
-evtchn_port_or_error_t xc_evtchn_bind_virq(xc_evtchn *xce, unsigned int virq)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_bind_virq bind;
-
-    bind.virq = virq;
-
-    return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
-}
-
-int xc_evtchn_unbind(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    struct ioctl_evtchn_unbind unbind;
-
-    unbind.port = port;
-
-    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
-}
-
-evtchn_port_or_error_t xc_evtchn_pending(xc_evtchn *xce)
-{
-    int fd = xce->fd;
-    evtchn_port_t port;
-
-    if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 )
-        return -1;
-
-    return port;
-}
-
-int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port)
-{
-    int fd = xce->fd;
-    return write_exact(fd, (char *)&port, sizeof(port));
-}
-
 /* Optionally flush file to disk and discard page cache */
 void discard_file_cache(xc_interface *xch, int fd, int flush) 
 {
diff --git a/tools/libxc/xc_suspend.c b/tools/libxc/xc_suspend.c
index e22f4ac..139edb4 100644
--- a/tools/libxc/xc_suspend.c
+++ b/tools/libxc/xc_suspend.c
@@ -17,6 +17,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <xenevtchn.h>
+
 #include "xc_private.h"
 #include "xenguest.h"
 
@@ -125,12 +127,12 @@ static int unlock_suspend_event(xc_interface *xch, int domid, int *lockfd)
     return -1;
 }
 
-int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn)
+int xc_await_suspend(xc_interface *xch, xenevtchn_handle *xce, int suspend_evtchn)
 {
     int rc;
 
     do {
-        rc = xc_evtchn_pending(xce);
+        rc = xenevtchn_pending(xce);
         if (rc < 0) {
             ERROR("error polling suspend notification channel: %d", rc);
             return -1;
@@ -138,7 +140,7 @@ int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn)
     } while (rc != suspend_evtchn);
 
     /* harmless for one-off suspend */
-    if (xc_evtchn_unmask(xce, suspend_evtchn) < 0)
+    if (xenevtchn_unmask(xce, suspend_evtchn) < 0)
         ERROR("failed to unmask suspend notification channel: %d", rc);
 
     return 0;
@@ -146,16 +148,16 @@ int xc_await_suspend(xc_interface *xch, xc_evtchn *xce, int suspend_evtchn)
 
 /* Internal callers are allowed to call this with suspend_evtchn<0
  * but *lockfd>0. */
-int xc_suspend_evtchn_release(xc_interface *xch, xc_evtchn *xce,
+int xc_suspend_evtchn_release(xc_interface *xch, xenevtchn_handle *xce,
                               int domid, int suspend_evtchn, int *lockfd)
 {
     if (suspend_evtchn >= 0)
-        xc_evtchn_unbind(xce, suspend_evtchn);
+        xenevtchn_unbind(xce, suspend_evtchn);
 
     return unlock_suspend_event(xch, domid, lockfd);
 }
 
-int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce,
+int xc_suspend_evtchn_init_sane(xc_interface *xch, xenevtchn_handle *xce,
                                 int domid, int port, int *lockfd)
 {
     int rc, suspend_evtchn = -1;
@@ -165,7 +167,7 @@ int xc_suspend_evtchn_init_sane(xc_interface *xch, xc_evtchn *xce,
         goto cleanup;
     }
 
-    suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port);
+    suspend_evtchn = xenevtchn_bind_interdomain(xce, domid, port);
     if (suspend_evtchn < 0) {
         ERROR("failed to bind suspend event channel: %d", suspend_evtchn);
         goto cleanup;
@@ -185,7 +187,7 @@ cleanup:
     return -1;
 }
 
-int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xc_evtchn *xce,
+int xc_suspend_evtchn_init_exclusive(xc_interface *xch, xenevtchn_handle *xce,
                                      int domid, int port, int *lockfd)
 {
     int suspend_evtchn;
diff --git a/tools/libxenevtchn/Makefile b/tools/libxenevtchn/Makefile
new file mode 100644
index 0000000..b968b36
--- /dev/null
+++ b/tools/libxenevtchn/Makefile
@@ -0,0 +1,65 @@
+XEN_ROOT = $(CURDIR)/../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+MAJOR    = 1
+MINOR    = 0
+SHLIB_LDFLAGS += -Wl,--version-script=libxenevtchn.map
+
+CFLAGS   += -Werror -Wmissing-prototypes
+CFLAGS   += -I./include $(CFLAGS_xeninclude)
+CFLAGS   += $(CFLAGS_libxentoollog)
+
+SRCS-y                 += core.c
+SRCS-$(CONFIG_Linux)   += linux.c
+SRCS-$(CONFIG_FreeBSD) += freebsd.c
+SRCS-$(CONFIG_SunOS)   += solaris.c
+SRCS-$(CONFIG_NetBSD)  += netbsd.c
+SRCS-$(CONFIG_MiniOS)  += minios.c
+
+LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y))
+PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y))
+
+LIB := libxenevtchn.a
+ifneq ($(nosharedlibs),y)
+LIB += libxenevtchn.so
+endif
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build:
+	$(MAKE) libs
+
+.PHONY: libs
+libs: $(LIB)
+
+
+libxenevtchn.a: $(LIB_OBJS)
+	$(AR) rc $@ $^
+
+libxenevtchn.so: libxenevtchn.so.$(MAJOR)
+	$(SYMLINK_SHLIB) $< $@
+libxenevtchn.so.$(MAJOR): libxenevtchn.so.$(MAJOR).$(MINOR)
+	$(SYMLINK_SHLIB) $< $@
+
+libxenevtchn.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxenevtchn.map
+	$(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenevtchn.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(APPEND_LDFLAGS)
+
+.PHONY: install
+install: build
+	$(INSTALL_DIR) $(DESTDIR)$(libdir)
+	$(INSTALL_DIR) $(DESTDIR)$(includedir)
+	$(INSTALL_SHLIB) libxenevtchn.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
+	$(INSTALL_DATA) libxenevtchn.a $(DESTDIR)$(libdir)
+	$(SYMLINK_SHLIB) libxenevtchn.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxenevtchn.so.$(MAJOR)
+	$(SYMLINK_SHLIB) libxenevtchn.so.$(MAJOR) $(DESTDIR)$(libdir)/libxenevtchn.so
+	$(INSTALL_DATA) include/xenevtchn.h $(DESTDIR)$(includedir)
+
+.PHONY: TAGS
+TAGS:
+	etags -t *.c *.h
+
+.PHONY: clean
+clean:
+	rm -rf *.rpm $(LIB) *~ $(DEPS) $(LIB_OBJS) $(PIC_OBJS)
diff --git a/tools/libxenevtchn/core.c b/tools/libxenevtchn/core.c
new file mode 100644
index 0000000..89b41c9
--- /dev/null
+++ b/tools/libxenevtchn/core.c
@@ -0,0 +1,60 @@
+/*
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+
+#include "private.h"
+
+xenevtchn_handle *xenevtchn_open(xentoollog_logger *logger, unsigned open_flags)
+{
+    xenevtchn_handle *xce = malloc(sizeof(*xce));
+    int rc;
+
+    if (!xce) return NULL;
+
+    xce->fd = -1;
+    xce->logger = logger;
+    xce->logger_tofree  = NULL;
+
+    if (!xce->logger) {
+        xce->logger = xce->logger_tofree =
+            (xentoollog_logger*)
+            xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
+        if (!xce->logger) goto err;
+    }
+
+    rc = osdep_evtchn_open(xce);
+    if ( rc  < 0 ) goto err;
+
+    return xce;
+
+err:
+    osdep_evtchn_close(xce);
+    xtl_logger_destroy(xce->logger_tofree);
+    free(xce);
+    return NULL;
+}
+
+int xenevtchn_close(xenevtchn_handle *xce)
+{
+    int rc;
+
+    rc = osdep_evtchn_close(xce);
+    xtl_logger_destroy(xce->logger_tofree);
+    free(xce);
+    return rc;
+}
diff --git a/tools/libxenevtchn/freebsd.c b/tools/libxenevtchn/freebsd.c
new file mode 100644
index 0000000..e1fb38e
--- /dev/null
+++ b/tools/libxenevtchn/freebsd.c
@@ -0,0 +1,122 @@
+ /******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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.
+ *
+ * Split off from xc_freebsd_osdep.c
+ */
+
+#include <fcntl.h>
+
+#include <xen/sys/evtchn.h>
+
+#include "private.h"
+
+#define EVTCHN_DEV      "/dev/xen/evtchn"
+
+int osdep_evtchn_open(xenevtchn_handle *xce)
+{
+    int fd = open(EVTCHN_DEV, O_RDWR);
+    if ( fd == -1 )
+        return -1;
+    xce->fd = fd;
+    return 0;
+}
+
+int osdep_evtchn_close(xenevtchn_handle *xce)
+{
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
+}
+
+int xenevtchn_fd(xenevtchn_handle *xce)
+{
+    return xce->fd;
+}
+
+int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_notify notify;
+
+    notify.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid)
+{
+    int ret, fd = xce->fd;
+    struct ioctl_evtchn_bind_unbound_port bind;
+
+    bind.remote_domain = domid;
+
+    ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+    return ( ret == 0 ) ? bind.port : ret;
+}
+
+evtchn_port_or_error_t
+xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid, evtchn_port_t remote_port)
+{
+    int ret, fd = xce->fd;
+    struct ioctl_evtchn_bind_interdomain bind;
+
+    bind.remote_domain = domid;
+    bind.remote_port = remote_port;
+
+    ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+    return ( ret == 0 ) ? bind.port : ret;
+}
+
+evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq)
+{
+    int ret, fd = xce->fd;
+    struct ioctl_evtchn_bind_virq bind;
+
+    bind.virq = virq;
+
+    ret = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+    return ( ret == 0 ) ? bind.port : ret;
+}
+
+int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_unbind unbind;
+
+    unbind.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
+}
+
+evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
+{
+    int fd = xce->fd;
+    evtchn_port_t port;
+
+    if ( read(fd, &port, sizeof(port)) != sizeof(port) )
+        return -1;
+
+    return port;
+}
+
+int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+
+    if ( write(fd, &port, sizeof(port)) != sizeof(port) )
+        return -1;
+    return 0;
+}
diff --git a/tools/libxenevtchn/include/xenevtchn.h b/tools/libxenevtchn/include/xenevtchn.h
new file mode 100644
index 0000000..d969994
--- /dev/null
+++ b/tools/libxenevtchn/include/xenevtchn.h
@@ -0,0 +1,154 @@
+/*
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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.
+ *
+ * Split off from:
+ * xenctrl.h
+ *
+ * A library for low-level access to the Xen control interfaces.
+ *
+ * Copyright (c) 2003-2004, K A Fraser.
+ */
+
+#ifndef XENEVTCHN_H
+#define XENEVTCHN_H
+
+#include <stdint.h>
+
+#include <xen/event_channel.h>
+
+/* A port identifier is guaranteed to fit in 31 bits. */
+typedef int evtchn_port_or_error_t;
+
+typedef struct xenevtchn_handle xenevtchn_handle;
+
+/* Callers who don't care don't need to #include <xentoollog.h> */
+typedef struct xentoollog_logger xentoollog_logger;
+
+/*
+ * EVENT CHANNEL FUNCTIONS
+ *
+ * None of these do any logging.
+ */
+
+/*
+ * Return a handle to the event channel driver, or NULL on failure, in
+ * which case errno will be set appropriately.
+ *
+ * Note:
+ * After fork a child process must not use any opened xc evtchn
+ * handle inherited from their parent. They must open a new handle if
+ * they want to interact with xc.
+ *
+ * Before Xen pre-4.1 this function would sometimes report errors with perror.
+ */
+/* Currently no flags are defined */
+xenevtchn_handle *xenevtchn_open(xentoollog_logger *logger, unsigned open_flags);
+
+/*
+ * Close a handle previously allocated with xenevtchn_open().
+ */
+int xenevtchn_close(xenevtchn_handle *xce);
+
+/*
+ * Return an fd that can be select()ed on.
+ *
+ * Note that due to bugs, setting this fd to non blocking may not
+ * work: you would hope that it would result in xenevtchn_pending
+ * failing with EWOULDBLOCK if there are no events signaled, but in
+ * fact it may block.  (Bug is present in at least Linux 3.12, and
+ * perhaps on other platforms or later version.)
+ *
+ * To be safe, you must use poll() or select() before each call to
+ * xenevtchn_pending.  If you have multiple threads (or processes)
+ * sharing a single xce handle this will not work, and there is no
+ * straightforward workaround.  Please design your program some other
+ * way.
+ */
+int xenevtchn_fd(xenevtchn_handle *xce);
+
+/*
+ * Notify the given event channel. Returns -1 on failure, in which case
+ * errno will be set appropriately.
+ */
+int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port);
+
+/*
+ * Returns a new event port awaiting interdomain connection from the given
+ * domain ID, or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_or_error_t
+xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid);
+
+/*
+ * Returns a new event port bound to the remote port for the given domain ID,
+ * or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_or_error_t
+xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid,
+                           evtchn_port_t remote_port);
+
+/*
+ * Bind an event channel to the given VIRQ. Returns the event channel bound to
+ * the VIRQ, or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_or_error_t
+xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq);
+
+/*
+ * Unbind the given event channel. Returns -1 on failure, in which case errno
+ * will be set appropriately.
+ */
+int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port);
+
+/*
+ * Return the next event channel to become pending, or -1 on failure, in which
+ * case errno will be set appropriately.
+ *
+ * At the hypervisor level the event channel will have been masked,
+ * and then cleared, by the underlying machinery (evtchn kernel
+ * driver, or equivalent).  So if the event channel is signaled again
+ * after it is returned here, it will be queued up, and delivered
+ * again after you unmask it.  (See the documentation in the Xen
+ * public header event_channel.h.)
+ *
+ * On receiving the notification from xenevtchn_pending, you should
+ * normally: check (by other means) what work needs doing; do the
+ * necessary work (if any); unmask the event channel with
+ * xenevtchn_unmask (if you want to receive any further
+ * notifications).
+ */
+evtchn_port_or_error_t
+xenevtchn_pending(xenevtchn_handle *xce);
+
+/*
+ * Unmask the given event channel. Returns -1 on failure, in which case errno
+ * will be set appropriately.
+ */
+int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port);
+
+#ifdef XENEVTCHN_XC_COMPAT
+typedef struct xc_interface_core xc_evtchn;
+
+
+#endif
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
+
diff --git a/tools/libxenevtchn/libxenevtchn.map b/tools/libxenevtchn/libxenevtchn.map
new file mode 100644
index 0000000..1437940
--- /dev/null
+++ b/tools/libxenevtchn/libxenevtchn.map
@@ -0,0 +1,14 @@
+VERS_1.0 {
+	global:
+		xenevtchn_fd;
+		xenevtchn_bind_unbound_port;
+		xenevtchn_unbind;
+		xenevtchn_unmask;
+		xenevtchn_notify;
+		xenevtchn_bind_interdomain;
+		xenevtchn_bind_virq;
+		xenevtchn_open;
+		xenevtchn_close;
+		xenevtchn_pending;
+	local: *; /* Do not expose anything by default */
+};
diff --git a/tools/libxenevtchn/linux.c b/tools/libxenevtchn/linux.c
new file mode 100644
index 0000000..185244c
--- /dev/null
+++ b/tools/libxenevtchn/linux.c
@@ -0,0 +1,133 @@
+/*
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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.
+ *
+ * Split out from xc_linus_osdep.c:
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+#include <sys/ioctl.h>
+
+#include <xen/sys/evtchn.h>
+
+#include "private.h"
+
+int osdep_evtchn_open(xenevtchn_handle *xce)
+{
+    int fd = open("/dev/xen/evtchn", O_RDWR);
+    if ( fd == -1 )
+        return -1;
+    xce->fd = fd;
+    return 0;
+}
+
+int osdep_evtchn_close(xenevtchn_handle *xce)
+{
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
+}
+
+int xenevtchn_fd(xenevtchn_handle *xce)
+{
+    return xce->fd;
+}
+
+int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_notify notify;
+
+    notify.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce,
+                                                   int domid)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_unbound_port bind;
+
+    bind.remote_domain = domid;
+
+    return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce,
+                                                  int domid,
+                                                  evtchn_port_t remote_port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_interdomain bind;
+
+    bind.remote_domain = domid;
+    bind.remote_port = remote_port;
+
+    return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce,
+                                           unsigned int virq)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_virq bind;
+
+    bind.virq = virq;
+
+    return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+}
+
+int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_unbind unbind;
+
+    unbind.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
+}
+
+evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
+{
+    int fd = xce->fd;
+    evtchn_port_t port;
+
+    if ( read(fd, &port, sizeof(port)) != sizeof(port) )
+        return -1;
+
+    return port;
+}
+
+int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+
+    if ( write(fd, &port, sizeof(port)) != sizeof(port) )
+        return -1;
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxenevtchn/minios.c b/tools/libxenevtchn/minios.c
new file mode 100644
index 0000000..c776822
--- /dev/null
+++ b/tools/libxenevtchn/minios.c
@@ -0,0 +1,257 @@
+/******************************************************************************
+ *
+ * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>.
+ * All rights reserved.
+ * Use is subject to license terms.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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.
+ *
+ * Split off from xc_minios.c
+ */
+
+#include "xen-external/bsd-sys-queue.h"
+#include <mini-os/types.h>
+#include <mini-os/os.h>
+#include <mini-os/lib.h>
+#include <mini-os/events.h>
+#include <mini-os/wait.h>
+
+#include <sys/socket.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <malloc.h>
+
+#include "private.h"
+
+extern void minios_evtchn_close_fd(int fd);
+
+extern struct wait_queue_head event_queue;
+
+//void minios_evtchn_close_fd(int fd);
+
+/* XXX Note: This is not threadsafe */
+static struct evtchn_port_info* port_alloc(int fd) {
+    struct evtchn_port_info *port_info;
+    port_info = malloc(sizeof(struct evtchn_port_info));
+    if (port_info == NULL)
+        return NULL;
+    port_info->pending = 0;
+    port_info->port = -1;
+    port_info->bound = 0;
+
+    LIST_INSERT_HEAD(&files[fd].evtchn.ports, port_info, list);
+    return port_info;
+}
+
+static void port_dealloc(struct evtchn_port_info *port_info) {
+    if (port_info->bound)
+        unbind_evtchn(port_info->port);
+    LIST_REMOVE(port_info, list);
+    free(port_info);
+}
+
+int osdep_evtchn_open(xenevtchn_handle *xce)
+{
+    int fd = alloc_fd(FTYPE_EVTCHN);
+    if ( fd == -1 )
+        return -1;
+    LIST_INIT(&files[fd].evtchn.ports);
+    xce->fd = fd;
+    printf("evtchn_open() -> %d\n", fd);
+    return 0;
+}
+
+int osdep_evtchn_close(xenevtchn_handle *xce)
+{
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
+}
+
+void minios_evtchn_close_fd(int fd)
+{
+    struct evtchn_port_info *port_info, *tmp;
+    LIST_FOREACH_SAFE(port_info, &files[fd].evtchn.ports, list, tmp)
+        port_dealloc(port_info);
+
+    files[fd].type = FTYPE_NONE;
+}
+
+int xenevtchn_fd(xenevtchn_handle *xce)
+{
+    return xce->fd;
+}
+
+int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int ret;
+
+    ret = notify_remote_via_evtchn(port);
+
+    if (ret < 0) {
+	errno = -ret;
+	ret = -1;
+    }
+    return ret;
+}
+
+static void evtchn_handler(evtchn_port_t port, struct pt_regs *regs, void *data)
+{
+    int fd = (int)(intptr_t)data;
+    struct evtchn_port_info *port_info;
+    assert(files[fd].type == FTYPE_EVTCHN);
+    mask_evtchn(port);
+    LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
+        if (port_info->port == port)
+            goto found;
+    }
+    printk("Unknown port for handle %d\n", fd);
+    return;
+
+ found:
+    port_info->pending = 1;
+    files[fd].read = 1;
+    wake_up(&event_queue);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid)
+{
+    int fd = xce->fd;
+    struct evtchn_port_info *port_info;
+    int ret;
+    evtchn_port_t port;
+
+    assert(get_current() == main_thread);
+    port_info = port_alloc(fd);
+    if (port_info == NULL)
+	return -1;
+
+    printf("xenevtchn_bind_unbound_port(%d)", domid);
+    ret = evtchn_alloc_unbound(domid, evtchn_handler, (void*)(intptr_t)fd, &port);
+    printf(" = %d\n", ret);
+
+    if (ret < 0) {
+	port_dealloc(port_info);
+	errno = -ret;
+	return -1;
+    }
+    port_info->bound = 1;
+    port_info->port = port;
+    unmask_evtchn(port);
+    return port;
+}
+
+evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid,
+                                                  evtchn_port_t remote_port)
+{
+    int fd = xce->fd;
+    struct evtchn_port_info *port_info;
+    evtchn_port_t local_port;
+    int ret;
+
+    assert(get_current() == main_thread);
+    port_info = port_alloc(fd);
+    if (port_info == NULL)
+	return -1;
+
+    printf("xenevtchn_bind_interdomain(%d, %"PRId32")", domid, remote_port);
+    ret = evtchn_bind_interdomain(domid, remote_port, evtchn_handler, (void*)(intptr_t)fd, &local_port);
+    printf(" = %d\n", ret);
+
+    if (ret < 0) {
+	port_dealloc(port_info);
+	errno = -ret;
+	return -1;
+    }
+    port_info->bound = 1;
+    port_info->port = local_port;
+    unmask_evtchn(local_port);
+    return local_port;
+}
+
+int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct evtchn_port_info *port_info;
+
+    LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
+        if (port_info->port == port) {
+            port_dealloc(port_info);
+            return 0;
+        }
+    }
+    printf("Warning: couldn't find port %"PRId32" for xc handle %x\n", port, fd);
+    errno = EINVAL;
+    return -1;
+}
+
+evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq)
+{
+    int fd = xce->fd;
+    struct evtchn_port_info *port_info;
+    evtchn_port_t port;
+
+    assert(get_current() == main_thread);
+    port_info = port_alloc(fd);
+    if (port_info == NULL)
+	return -1;
+
+    printf("xenevtchn_bind_virq(%d)", virq);
+    port = bind_virq(virq, evtchn_handler, (void*)(intptr_t)fd);
+
+    if (port < 0) {
+	port_dealloc(port_info);
+	errno = -port;
+	return -1;
+    }
+    port_info->bound = 1;
+    port_info->port = port;
+    unmask_evtchn(port);
+    return port;
+}
+
+evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
+{
+    int fd = xce->fd;
+    struct evtchn_port_info *port_info;
+    unsigned long flags;
+    evtchn_port_t ret = -1;
+
+    local_irq_save(flags);
+    files[fd].read = 0;
+
+    LIST_FOREACH(port_info, &files[fd].evtchn.ports, list) {
+        if (port_info->port != -1 && port_info->pending) {
+            if (ret == -1) {
+                ret = port_info->port;
+                port_info->pending = 0;
+            } else {
+                files[fd].read = 1;
+                break;
+            }
+        }
+    }
+    local_irq_restore(flags);
+    return ret;
+}
+
+int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    unmask_evtchn(port);
+    return 0;
+}
+
diff --git a/tools/libxenevtchn/netbsd.c b/tools/libxenevtchn/netbsd.c
new file mode 100644
index 0000000..c99d138
--- /dev/null
+++ b/tools/libxenevtchn/netbsd.c
@@ -0,0 +1,132 @@
+/******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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.
+ *
+ * Split out from xc_netbsd.c
+ */
+
+#include <fcntl.h>
+
+#include <xen/sys/evtchn.h>
+
+#include "private.h"
+
+#define EVTCHN_DEV_NAME  "/dev/xenevt"
+
+int osdep_evtchn_open(xenevtchn_handle *xce)
+{
+    int fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
+    if ( fd == -1 )
+        return -1;
+    xce->fd = fd;
+    return 0;
+}
+
+int osdep_evtchn_close(xenevtchn_handle *xce, xc_osdep_handle h)
+{
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
+}
+
+int xenevtchn_fd(xenevtchn_handle *xce)
+{
+    return xce->fd;
+}
+
+int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_notify notify;
+
+    notify.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle * xce, int domid)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_unbound_port bind;
+    int ret;
+
+    bind.remote_domain = domid;
+
+    ret = ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+    if (ret == 0)
+	return bind.port;
+    else
+	return -1;
+}
+
+evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid,
+                                                  evtchn_port_t remote_port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_interdomain bind;
+    int ret;
+
+    bind.remote_domain = domid;
+    bind.remote_port = remote_port;
+
+    ret = ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+    if (ret == 0)
+	return bind.port;
+    else
+	return -1;
+}
+
+int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_unbind unbind;
+
+    unbind.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_virq bind;
+    int err;
+
+    bind.virq = virq;
+
+    err = ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+    if (err)
+	return -1;
+    else
+	return bind.port;
+}
+
+evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
+{
+    int fd = xce->fd;
+    evtchn_port_t port;
+
+    if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 )
+        return -1;
+
+    return port;
+}
+
+int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    return write_exact(fd, (char *)&port, sizeof(port));
+}
+
diff --git a/tools/libxenevtchn/private.h b/tools/libxenevtchn/private.h
new file mode 100644
index 0000000..107c438
--- /dev/null
+++ b/tools/libxenevtchn/private.h
@@ -0,0 +1,15 @@
+#ifndef XENEVTCHN_PRIVATE_H
+#define XENEVTCHN_PRIVATE_H
+
+#include <xentoollog.h>
+#include <xenevtchn.h>
+
+struct xenevtchn_handle {
+    xentoollog_logger *logger, *logger_tofree;
+    int fd;
+};
+
+int osdep_evtchn_open(xenevtchn_handle *xce);
+int osdep_evtchn_close(xenevtchn_handle *xce);
+
+#endif
diff --git a/tools/libxenevtchn/solaris.c b/tools/libxenevtchn/solaris.c
new file mode 100644
index 0000000..dcd2632
--- /dev/null
+++ b/tools/libxenevtchn/solaris.c
@@ -0,0 +1,120 @@
+/******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * 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;
+ * version 2.1 of the License.
+ *
+ * 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.
+ *
+ * Split out from xc_solaris.c
+ */
+
+#include <fcntl.h>
+
+#include <xen/sys/evtchn.h>
+
+#include "private.h"
+
+int osdep_evtchn_open(xenevtchn_handle *xce)
+{
+    int fd;
+
+    if ( (fd = open("/dev/xen/evtchn", O_RDWR)) == -1 )
+    {
+        PERROR("Could not open event channel interface");
+        return -1;
+    }
+
+    xce->fd = fd;
+    return 0;
+}
+
+int osdep_evtchn_close(xenevtchn_handle *xce)
+{
+    if ( xce->fd == -1 )
+        return 0;
+
+    return close(xce->fd);
+}
+
+int xenevtchn_fd(xenevtchn_handle *xce)
+{
+    return xce->fd;
+}
+
+int xenevtchn_notify(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_notify notify;
+
+    notify.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_NOTIFY, &notify);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_unbound_port(xenevtchn_handle *xce, int domid)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_unbound_port bind;
+
+    bind.remote_domain = domid;
+
+    return ioctl(fd, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_interdomain(xenevtchn_handle *xce, int domid,
+                                                  evtchn_port_t remote_port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_interdomain bind;
+
+    bind.remote_domain = domid;
+    bind.remote_port = remote_port;
+
+    return ioctl(fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
+}
+
+evtchn_port_or_error_t xenevtchn_bind_virq(xenevtchn_handle *xce, unsigned int virq)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_bind_virq bind;
+
+    bind.virq = virq;
+
+    return ioctl(fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
+}
+
+int xenevtchn_unbind(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    struct ioctl_evtchn_unbind unbind;
+
+    unbind.port = port;
+
+    return ioctl(fd, IOCTL_EVTCHN_UNBIND, &unbind);
+}
+
+evtchn_port_or_error_t xenevtchn_pending(xenevtchn_handle *xce)
+{
+    int fd = xce->fd;
+    evtchn_port_t port;
+
+    if ( read_exact(fd, (char *)&port, sizeof(port)) == -1 )
+        return -1;
+
+    return port;
+}
+
+int xenevtchn_unmask(xenevtchn_handle *xce, evtchn_port_t port)
+{
+    int fd = xce->fd;
+    return write_exact(fd, (char *)&port, sizeof(port));
+}
+
diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index 387dc91..6183f5a 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -20,12 +20,13 @@ LIBUUID_LIBS += -luuid
 endif
 
 LIBXL_LIBS =
-LIBXL_LIBS = $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS)
+LIBXL_LIBS = $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(LDLIBS_libblktapctl) $(PTYFUNCS_LIBS) $(LIBUUID_LIBS)
 ifeq ($(CONFIG_REMUS_NETBUF),y)
 LIBXL_LIBS += $(LIBNL3_LIBS)
 endif
 
 CFLAGS_LIBXL += $(CFLAGS_libxentoollog)
+CFLAGS_LIBXL += $(CFLAGS_libxenevtchn)
 CFLAGS_LIBXL += $(CFLAGS_libxenctrl)
 CFLAGS_LIBXL += $(CFLAGS_libxenguest)
 CFLAGS_LIBXL += $(CFLAGS_libxenstore)
@@ -142,7 +143,7 @@ $(XEN_INIT_DOM0_OBJS): CFLAGS += $(CFLAGS_libxenctrl)
 $(XEN_INIT_DOM0_OBJS): CFLAGS += $(CFLAGS_libxenstore)
 
 SAVE_HELPER_OBJS = libxl_save_helper.o _libxl_save_msgs_helper.o
-$(SAVE_HELPER_OBJS): CFLAGS += $(CFLAGS_libxenctrl)
+$(SAVE_HELPER_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn)
 
 PKG_CONFIG = xenlight.pc xlutil.pc
 
diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c
index 9117b01..45a9493 100644
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -178,7 +178,7 @@ int libxl_ctx_free(libxl_ctx *ctx)
     if (ctx->xch) xc_interface_close(ctx->xch);
     libxl_version_info_dispose(&ctx->version_info);
     if (ctx->xsh) xs_daemon_close(ctx->xsh);
-    if (ctx->xce) xc_evtchn_close(ctx->xce);
+    if (ctx->xce) xenevtchn_close(ctx->xce);
 
     libxl__poller_dispose(&ctx->poller_app);
     assert(LIBXL_LIST_EMPTY(&ctx->pollers_event));
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 867172a..843741d 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1424,9 +1424,9 @@ static void domain_suspend_callback_common(libxl__egc *egc,
     if ((hvm_s_state == 0) && (dss->guest_evtchn.port >= 0)) {
         LOG(DEBUG, "issuing %s suspend request via event channel",
             dss->hvm ? "PVHVM" : "PV");
-        ret = xc_evtchn_notify(CTX->xce, dss->guest_evtchn.port);
+        ret = xenevtchn_notify(CTX->xce, dss->guest_evtchn.port);
         if (ret < 0) {
-            LOG(ERROR, "xc_evtchn_notify failed ret=%d", ret);
+            LOG(ERROR, "xenevtchn_notify failed ret=%d", ret);
             goto err;
         }
 
diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 9ff4e78..0e842bf 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -705,7 +705,7 @@ static void evtchn_fd_callback(libxl__egc *egc, libxl__ev_fd *ev,
         /* OK, that's that workaround done.  We can actually check for
          * work for us to do: */
 
-        port = xc_evtchn_pending(CTX->xce);
+        port = xenevtchn_pending(CTX->xce);
         if (port < 0) {
             if (errno == EAGAIN)
                 break;
@@ -731,20 +731,20 @@ static void evtchn_fd_callback(libxl__egc *egc, libxl__ev_fd *ev,
 }
 
 int libxl__ctx_evtchn_init(libxl__gc *gc) {
-    xc_evtchn *xce;
+    xenevtchn_handle *xce;
     int rc, fd;
 
     if (CTX->xce)
         return 0;
 
-    xce = xc_evtchn_open(CTX->lg, 0);
+    xce = xenevtchn_open(CTX->lg, 0);
     if (!xce) {
         LOGE(ERROR,"cannot open libxc evtchn handle");
         rc = ERROR_FAIL;
         goto out;
     }
 
-    fd = xc_evtchn_fd(xce);
+    fd = xenevtchn_fd(xce);
     assert(fd >= 0);
 
     rc = libxl_fd_set_nonblock(CTX, fd, 1);
@@ -754,7 +754,7 @@ int libxl__ctx_evtchn_init(libxl__gc *gc) {
     return 0;
 
  out:
-    xc_evtchn_close(xce);
+    xenevtchn_close(xce);
     return rc;
 }
 
@@ -776,14 +776,14 @@ int libxl__ev_evtchn_wait(libxl__gc *gc, libxl__ev_evtchn *evev)
 
     if (!libxl__ev_fd_isregistered(&CTX->evtchn_efd)) {
         rc = libxl__ev_fd_register(gc, &CTX->evtchn_efd, evtchn_fd_callback,
-                                   xc_evtchn_fd(CTX->xce), POLLIN);
+                                   xenevtchn_fd(CTX->xce), POLLIN);
         if (rc) goto out;
     }
 
     if (evev->waiting)
         return 0;
 
-    r = xc_evtchn_unmask(CTX->xce, evev->port);
+    r = xenevtchn_unmask(CTX->xce, evev->port);
     if (r) {
         LOGE(ERROR,"cannot unmask event channel %d",evev->port);
         rc = ERROR_FAIL;
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index bb3a5c7..f6ad21f 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -46,6 +46,7 @@
 #include <sys/file.h>
 #include <sys/ioctl.h>
 
+#include <xenevtchn.h>
 #include <xenstore.h>
 #include <xenctrl.h>
 #include <xenguest.h>
@@ -377,7 +378,7 @@ struct libxl__ctx {
     uint32_t watch_counter; /* helps disambiguate slot reuse */
     libxl__ev_fd watch_efd;
 
-    xc_evtchn *xce; /* waiting must be done only with libxl__ev_evtchn* */
+    xenevtchn_handle *xce; /* waiting must be done only with libxl__ev_evtchn* */
     LIBXL_LIST_HEAD(, libxl__ev_evtchn) evtchns_waiting;
     libxl__ev_fd evtchn_efd;
 
@@ -829,7 +830,7 @@ static inline int libxl__ev_xswatch_isregistered(const libxl__ev_xswatch *xw)
  * When the event is signaled then the callback will be made, once.
  * Then you must call libxl__ev_evtchn_wait again, if desired.
  *
- * You must NOT call xc_evtchn_unmask.  wait will do that for you.
+ * You must NOT call xenevtchn_unmask.  wait will do that for you.
  *
  * Calling libxl__ev_evtchn_cancel will arrange for libxl to disregard
  * future occurrences of event.  Both libxl__ev_evtchn_wait and
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index c4490f3..cf6a475 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -4,6 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 CFLAGS += -Werror
 # Include configure output (config.h)
 CFLAGS += -include $(XEN_ROOT)/tools/config.h
+CFLAGS += $(CFLAGS_libxenevtchn)
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += $(CFLAGS_xeninclude)
 CFLAGS += $(CFLAGS_libxenstore)
@@ -88,18 +89,18 @@ xenlockprof: xenlockprof.o
 # xen-hptool incorrectly uses libxc internals
 xen-hptool.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
 xen-hptool: xen-hptool.o
-	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
 
 # xen-mfndump incorrectly uses libxc internals
 xen-mfndump.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
 xen-mfndump: xen-mfndump.o
-	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
 
 xenwatchdogd: xenwatchdogd.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
 xen-lowmemd: xen-lowmemd.o
-	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
+	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
 
 gtraceview: gtraceview.o
 	$(CC) $(LDFLAGS) -o $@ $< $(CURSES_LIBS) $(TINFO_LIBS) $(APPEND_LDFLAGS)
diff --git a/tools/misc/xen-hptool.c b/tools/misc/xen-hptool.c
index c7561a9..ebcc9e8 100644
--- a/tools/misc/xen-hptool.c
+++ b/tools/misc/xen-hptool.c
@@ -1,3 +1,4 @@
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xc_private.h>
 #include <xc_core.h>
@@ -98,7 +99,7 @@ static int hp_mem_query_func(int argc, char *argv[])
     return ret;
 }
 
-static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid,
+static int suspend_guest(xc_interface *xch, xenevtchn_handle *xce, int domid,
                          int *evtchn, int *lockfd)
 {
     int port, rc, suspend_evtchn = -1;
@@ -123,7 +124,7 @@ static int suspend_guest(xc_interface *xch, xc_evtchn *xce, int domid,
     }
     *evtchn = suspend_evtchn;
 
-    rc = xc_evtchn_notify(xce, suspend_evtchn);
+    rc = xenevtchn_notify(xce, suspend_evtchn);
     if (rc < 0)
     {
         fprintf(stderr, "Failed to notify suspend channel: errno %d\n", rc);
@@ -198,8 +199,8 @@ static int hp_mem_offline_func(int argc, char *argv[])
                 else if (status & PG_OFFLINE_OWNED)
                 {
                     int result, suspend_evtchn = -1, suspend_lockfd = -1;
-                    xc_evtchn *xce;
-                    xce = xc_evtchn_open(NULL, 0);
+                    xenevtchn_handle *xce;
+                    xce = xenevtchn_open(NULL, 0);
 
                     if (xce == NULL)
                     {
@@ -214,7 +215,7 @@ static int hp_mem_offline_func(int argc, char *argv[])
                     {
                         fprintf(stderr, "Failed to suspend guest %d for"
                                 " mfn %lx\n", domid, mfn);
-                        xc_evtchn_close(xce);
+                        xenevtchn_close(xce);
                         return -1;
                     }
 
@@ -238,7 +239,7 @@ static int hp_mem_offline_func(int argc, char *argv[])
                     xc_domain_resume(xch, domid, 1);
                     xc_suspend_evtchn_release(xch, xce, domid,
                                               suspend_evtchn, &suspend_lockfd);
-                    xc_evtchn_close(xce);
+                    xenevtchn_close(xce);
                 }
                 break;
             }
diff --git a/tools/misc/xen-lowmemd.c b/tools/misc/xen-lowmemd.c
index 82ffd75..3200404 100644
--- a/tools/misc/xen-lowmemd.c
+++ b/tools/misc/xen-lowmemd.c
@@ -4,22 +4,23 @@
  */
 
 #include <stdio.h>
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xenstore.h>
 #include <stdlib.h>
 #include <string.h>
 
 static evtchn_port_t virq_port      = -1;
-static xc_evtchn *xce_handle        = NULL;
+static xenevtchn_handle *xce_handle = NULL;
 static xc_interface *xch            = NULL;
 static struct xs_handle *xs_handle  = NULL;
 
 void cleanup(void)
 {
     if (virq_port > -1)
-        xc_evtchn_unbind(xce_handle, virq_port);
+        xenevtchn_unbind(xce_handle, virq_port);
     if (xce_handle)
-        xc_evtchn_close(xce_handle);
+        xenevtchn_close(xce_handle);
     if (xch)
         xc_interface_close(xch);
     if (xs_handle)
@@ -94,7 +95,7 @@ int main(int argc, char *argv[])
         return 1;
     }
 
-	xce_handle = xc_evtchn_open(NULL, 0);
+	xce_handle = xenevtchn_open(NULL, 0);
 	if (xce_handle == NULL)
     {
         perror("Failed to open evtchn device");
@@ -108,7 +109,7 @@ int main(int argc, char *argv[])
         return 3;
     }
 
-	if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1)
+	if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_ENOMEM)) == -1)
     {
         perror("Failed to bind to domain exception virq port");
         return 4;
@@ -120,7 +121,7 @@ int main(int argc, char *argv[])
     {
         evtchn_port_t port;
 
-        if ((port = xc_evtchn_pending(xce_handle)) == -1)
+        if ((port = xenevtchn_pending(xce_handle)) == -1)
         {
             perror("Failed to listen for pending event channel");
             return 5;
@@ -134,7 +135,7 @@ int main(int argc, char *argv[])
             return 6;
         }
 
-        if (xc_evtchn_unmask(xce_handle, port) == -1)
+        if (xenevtchn_unmask(xce_handle, port) == -1)
         {
             perror("Failed to unmask port");
             return 7;
diff --git a/tools/ocaml/libs/eventchn/Makefile b/tools/ocaml/libs/eventchn/Makefile
index 2d8d618..154efd4 100644
--- a/tools/ocaml/libs/eventchn/Makefile
+++ b/tools/ocaml/libs/eventchn/Makefile
@@ -2,13 +2,13 @@ TOPLEVEL=$(CURDIR)/../..
 XEN_ROOT=$(TOPLEVEL)/../..
 include $(TOPLEVEL)/common.make
 
-CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_xeninclude)
+CFLAGS += $(CFLAGS_libxenevtchn) $(CFLAGS_xeninclude)
 
 OBJS = xeneventchn
 INTF = $(foreach obj, $(OBJS),$(obj).cmi)
 LIBS = xeneventchn.cma xeneventchn.cmxa
 
-LIBS_xeneventchn = $(LDLIBS_libxenctrl)
+LIBS_xeneventchn = $(LDLIBS_libxenevtchn)
 
 all: $(INTF) $(LIBS) $(PROGRAMS)
 
diff --git a/tools/ocaml/libs/eventchn/xeneventchn_stubs.c b/tools/ocaml/libs/eventchn/xeneventchn_stubs.c
index 5939e7c..c2d4737 100644
--- a/tools/ocaml/libs/eventchn/xeneventchn_stubs.c
+++ b/tools/ocaml/libs/eventchn/xeneventchn_stubs.c
@@ -24,7 +24,7 @@
 #include <xen/sysctl.h>
 #include <xen/xen.h>
 #include <xen/sys/evtchn.h>
-#include <xenctrl.h>
+#include <xenevtchn.h>
 
 #define CAML_NAME_SPACE
 #include <caml/mlvalues.h>
@@ -34,14 +34,14 @@
 #include <caml/callback.h>
 #include <caml/fail.h>
 
-#define _H(__h) ((xc_evtchn *)(__h))
+#define _H(__h) ((xenevtchn_handle *)(__h))
 
 CAMLprim value stub_eventchn_init(void)
 {
 	CAMLparam0();
 	CAMLlocal1(result);
 
-	xc_evtchn *xce = xc_evtchn_open(NULL, XC_OPENFLAG_NON_REENTRANT);
+	xenevtchn_handle *xce = xenevtchn_open(NULL, 0);
 	if (xce == NULL)
 		caml_failwith("open failed");
 
@@ -55,7 +55,7 @@ CAMLprim value stub_eventchn_fd(value xce)
 	CAMLlocal1(result);
 	int fd;
 
-	fd = xc_evtchn_fd(_H(xce));
+	fd = xenevtchn_fd(_H(xce));
 	if (fd == -1)
 		caml_failwith("evtchn fd failed");
 
@@ -69,7 +69,7 @@ CAMLprim value stub_eventchn_notify(value xce, value port)
 	CAMLparam2(xce, port);
 	int rc;
 
-	rc = xc_evtchn_notify(_H(xce), Int_val(port));
+	rc = xenevtchn_notify(_H(xce), Int_val(port));
 	if (rc == -1)
 		caml_failwith("evtchn notify failed");
 
@@ -83,7 +83,7 @@ CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid,
 	CAMLlocal1(port);
 	evtchn_port_or_error_t rc;
 
-	rc = xc_evtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port));
+	rc = xenevtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port));
 	if (rc == -1)
 		caml_failwith("evtchn bind_interdomain failed");
 	port = Val_int(rc);
@@ -97,7 +97,7 @@ CAMLprim value stub_eventchn_bind_dom_exc_virq(value xce)
 	CAMLlocal1(port);
 	evtchn_port_or_error_t rc;
 
-	rc = xc_evtchn_bind_virq(_H(xce), VIRQ_DOM_EXC);
+	rc = xenevtchn_bind_virq(_H(xce), VIRQ_DOM_EXC);
 	if (rc == -1)
 		caml_failwith("evtchn bind_dom_exc_virq failed");
 	port = Val_int(rc);
@@ -110,7 +110,7 @@ CAMLprim value stub_eventchn_unbind(value xce, value port)
 	CAMLparam2(xce, port);
 	int rc;
 
-	rc = xc_evtchn_unbind(_H(xce), Int_val(port));
+	rc = xenevtchn_unbind(_H(xce), Int_val(port));
 	if (rc == -1)
 		caml_failwith("evtchn unbind failed");
 
@@ -123,7 +123,7 @@ CAMLprim value stub_eventchn_pending(value xce)
 	CAMLlocal1(result);
 	evtchn_port_or_error_t port;
 
-	port = xc_evtchn_pending(_H(xce));
+	port = xenevtchn_pending(_H(xce));
 	if (port == -1)
 		caml_failwith("evtchn pending failed");
 	result = Val_int(port);
@@ -137,7 +137,7 @@ CAMLprim value stub_eventchn_unmask(value xce, value _port)
 	evtchn_port_t port;
 
 	port = Int_val(_port);
-	if (xc_evtchn_unmask(_H(xce), port))
+	if (xenevtchn_unmask(_H(xce), port))
 		caml_failwith("evtchn unmask failed");
 	CAMLreturn(Val_unit);
 }
diff --git a/tools/python/setup.py b/tools/python/setup.py
index e55ee01..906d880 100644
--- a/tools/python/setup.py
+++ b/tools/python/setup.py
@@ -8,13 +8,18 @@ extra_compile_args  = [ "-fno-strict-aliasing", "-Werror" ]
 
 PATH_XEN      = XEN_ROOT + "/tools/include"
 PATH_LIBXENTOOLLOG = XEN_ROOT + "/tools/libxentoollog"
+PATH_LIBXENEVTCHN = XEN_ROOT + "/tools/libxenevtchn"
 PATH_LIBXC    = XEN_ROOT + "/tools/libxc"
 PATH_LIBXL    = XEN_ROOT + "/tools/libxl"
 PATH_XENSTORE = XEN_ROOT + "/tools/xenstore"
 
 xc = Extension("xc",
                extra_compile_args = extra_compile_args,
-               include_dirs       = [ PATH_XEN, PATH_LIBXENTOOLLOG + "/include", PATH_LIBXC + "/include", "xen/lowlevel/xc" ],
+               include_dirs       = [ PATH_XEN,
+                                      PATH_LIBXENTOOLLOG + "/include",
+                                      PATH_LIBXENEVTCHN + "/include",
+                                      PATH_LIBXC + "/include",
+                                      "xen/lowlevel/xc" ],
                library_dirs       = [ PATH_LIBXC ],
                libraries          = [ "xenctrl", "xenguest" ],
                depends            = [ PATH_LIBXC + "/libxenctrl.so", PATH_LIBXC + "/libxenguest.so",  "-Wl,-rpath-link="+PATH_LIBXENTOOLLOG ],
diff --git a/tools/tests/xen-access/xen-access.c b/tools/tests/xen-access/xen-access.c
index 12ab921..d68ae84 100644
--- a/tools/tests/xen-access/xen-access.c
+++ b/tools/tests/xen-access/xen-access.c
@@ -79,7 +79,7 @@ static void close_handler(int sig)
 
 int xc_wait_for_event_or_timeout(xc_interface *xch, xc_evtchn *xce, unsigned long ms)
 {
-    struct pollfd fd = { .fd = xc_evtchn_fd(xce), .events = POLLIN | POLLERR };
+    struct pollfd fd = { .fd = xenevtchn_fd(xce), .events = POLLIN | POLLERR };
     int port;
     int rc;
 
diff --git a/tools/xcutils/Makefile b/tools/xcutils/Makefile
index fff519d..2d1f112 100644
--- a/tools/xcutils/Makefile
+++ b/tools/xcutils/Makefile
@@ -16,8 +16,8 @@ PROGRAMS = readnotes lsevtchn
 CFLAGS += -Werror
 
 # incorrectly uses libxc internals
-CFLAGS_readnotes.o  := $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -I$(XEN_ROOT)/tools/libxc
-CFLAGS_lsevtchn.o   := $(CFLAGS_libxenctrl)
+CFLAGS_readnotes.o  := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -I$(XEN_ROOT)/tools/libxc
+CFLAGS_lsevtchn.o   := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl)
 
 .PHONY: all
 all: build
diff --git a/tools/xenmon/Makefile b/tools/xenmon/Makefile
index 5095682..fa80983 100644
--- a/tools/xenmon/Makefile
+++ b/tools/xenmon/Makefile
@@ -14,8 +14,10 @@ XEN_ROOT=$(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 CFLAGS  += -Werror
+CFLAGS  += $(CFLAGS_libxenevtchn)
 CFLAGS  += $(CFLAGS_libxenctrl)
 LDLIBS  += $(LDLIBS_libxenctrl)
+LDLIBS  += $(LDLIBS_libxenevtchn)
 
 SCRIPTS = xenmon.py
 
diff --git a/tools/xenmon/xenbaked.c b/tools/xenmon/xenbaked.c
index dc61d14..f092aec 100644
--- a/tools/xenmon/xenbaked.c
+++ b/tools/xenmon/xenbaked.c
@@ -38,6 +38,7 @@
 #include <unistd.h>
 #include <errno.h>
 #include <signal.h>
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xen/xen.h>
 #include <string.h>
@@ -268,7 +269,7 @@ static void log_event(int event_id)
 }
 
 int virq_port;
-xc_evtchn *xce_handle = NULL;
+xenevtchn_handle *xce_handle = NULL;
 
 /* Returns the event channel handle. */
 /* Stolen from xenstore code */
@@ -280,12 +281,12 @@ static int eventchn_init(void)
     if (0)
         return -1;
   
-    xce_handle = xc_evtchn_open(NULL, 0);
+    xce_handle = xenevtchn_open(NULL, 0);
 
     if (xce_handle == NULL)
         perror("Failed to open evtchn device");
   
-    if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1)
+    if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1)
         perror("Failed to bind to domain exception virq port");
     virq_port = rc;
   
@@ -305,7 +306,7 @@ static void wait_for_event(void)
         return;
     }
 
-    evtchn_fd = xc_evtchn_fd(xce_handle);
+    evtchn_fd = xenevtchn_fd(xce_handle);
 
     FD_ZERO(&inset);
     FD_SET(evtchn_fd, &inset);
@@ -315,13 +316,13 @@ static void wait_for_event(void)
     ret = select(evtchn_fd+1, &inset, NULL, NULL, &tv);
   
     if ( (ret == 1) && FD_ISSET(evtchn_fd, &inset)) {
-        if ((port = xc_evtchn_pending(xce_handle)) == -1)
+        if ((port = xenevtchn_pending(xce_handle)) == -1)
             perror("Failed to read from event fd");
     
         //    if (port == virq_port)
         //      printf("got the event I was looking for\r\n");
 
-        if (xc_evtchn_unmask(xce_handle, port) == -1)
+        if (xenevtchn_unmask(xce_handle, port) == -1)
             perror("Failed to write to event fd");
     }
 }
diff --git a/tools/xenpaging/Makefile b/tools/xenpaging/Makefile
index e63d894..d491867 100644
--- a/tools/xenpaging/Makefile
+++ b/tools/xenpaging/Makefile
@@ -2,8 +2,8 @@ XEN_ROOT=$(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 # xenpaging.c and file_ops.c incorrectly use libxc internals
-CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc
-LDLIBS += $(LDLIBS_libxentoollog) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS)
+CFLAGS += $(CFLAGS_libxentoollog) $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc
+LDLIBS += $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS)
 LDFLAGS += $(PTHREAD_LDFLAGS)
 
 POLICY    = default
diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c
index 3f4c2e9..6776896 100644
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -74,7 +74,7 @@ static void xenpaging_mem_paging_flush_ioemu_cache(struct xenpaging *paging)
 static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging)
 {
     xc_interface *xch = paging->xc_handle;
-    xc_evtchn *xce = paging->vm_event.xce_handle;
+    xenevtchn_handle *xce = paging->vm_event.xce_handle;
     char **vec, *val;
     unsigned int num;
     struct pollfd fd[2];
@@ -83,7 +83,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging)
     int timeout;
 
     /* Wait for event channel and xenstore */
-    fd[0].fd = xc_evtchn_fd(xce);
+    fd[0].fd = xenevtchn_fd(xce);
     fd[0].events = POLLIN | POLLERR;
     fd[1].fd = xs_fileno(paging->xs_handle);
     fd[1].events = POLLIN | POLLERR;
@@ -147,7 +147,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging)
     if ( rc && fd[0].revents & POLLIN )
     {
         DPRINTF("Got event from evtchn\n");
-        port = xc_evtchn_pending(xce);
+        port = xenevtchn_pending(xce);
         if ( port == -1 )
         {
             PERROR("Failed to read port from event channel");
@@ -155,7 +155,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging)
             goto err;
         }
 
-        rc = xc_evtchn_unmask(xce, port);
+        rc = xenevtchn_unmask(xce, port);
         if ( rc < 0 )
         {
             PERROR("Failed to unmask event channel port");
@@ -394,7 +394,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
     }
 
     /* Open event channel */
-    paging->vm_event.xce_handle = xc_evtchn_open(NULL, 0);
+    paging->vm_event.xce_handle = xenevtchn_open(NULL, 0);
     if ( paging->vm_event.xce_handle == NULL )
     {
         PERROR("Failed to open event channel");
@@ -402,7 +402,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
     }
 
     /* Bind event notification */
-    rc = xc_evtchn_bind_interdomain(paging->vm_event.xce_handle,
+    rc = xenevtchn_bind_interdomain(paging->vm_event.xce_handle,
                                     paging->vm_event.domain_id,
                                     paging->vm_event.evtchn_port);
     if ( rc < 0 )
@@ -532,7 +532,7 @@ static void xenpaging_teardown(struct xenpaging *paging)
     }
 
     /* Unbind VIRQ */
-    rc = xc_evtchn_unbind(paging->vm_event.xce_handle, paging->vm_event.port);
+    rc = xenevtchn_unbind(paging->vm_event.xce_handle, paging->vm_event.port);
     if ( rc != 0 )
     {
         PERROR("Error unbinding event port");
@@ -540,7 +540,7 @@ static void xenpaging_teardown(struct xenpaging *paging)
     paging->vm_event.port = -1;
 
     /* Close event channel */
-    rc = xc_evtchn_close(paging->vm_event.xce_handle);
+    rc = xenevtchn_close(paging->vm_event.xce_handle);
     if ( rc != 0 )
     {
         PERROR("Error closing event channel");
@@ -693,7 +693,7 @@ static int xenpaging_resume_page(struct xenpaging *paging, vm_event_response_t *
     }
 
     /* Tell Xen page is ready */
-    return xc_evtchn_notify(paging->vm_event.xce_handle, paging->vm_event.port);
+    return xenevtchn_notify(paging->vm_event.xce_handle, paging->vm_event.port);
 }
 
 static int xenpaging_populate_page(struct xenpaging *paging, unsigned long gfn, int i)
diff --git a/tools/xenpaging/xenpaging.h b/tools/xenpaging/xenpaging.h
index 25d511d..6c12030 100644
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -25,6 +25,7 @@
 #define __XEN_PAGING2_H__
 
 
+#include <xenevtchn.h>
 #include <xc_private.h>
 #include <xen/event_channel.h>
 #include <xen/vm_event.h>
@@ -33,7 +34,7 @@
 
 struct vm_event {
     domid_t domain_id;
-    xc_evtchn *xce_handle;
+    xenevtchn_handle *xce_handle;
     int port;
     vm_event_back_ring_t back_ring;
     uint32_t evtchn_port;
diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile
index 1b4a494..c161046 100644
--- a/tools/xenstore/Makefile
+++ b/tools/xenstore/Makefile
@@ -9,6 +9,7 @@ CFLAGS += -I.
 # Include configure output (config.h)
 CFLAGS += -include $(XEN_ROOT)/tools/config.h
 CFLAGS += -I./include
+CFLAGS += $(CFLAGS_libxenevtchn)
 CFLAGS += $(CFLAGS_libxenctrl)
 CFLAGS += -DXEN_LIB_STORED="\"$(XEN_LIB_STORED)\""
 
@@ -75,10 +76,10 @@ endif
 init-xenstore-domain.o: CFLAGS += $(CFLAGS_libxenguest)
 
 init-xenstore-domain: init-xenstore-domain.o $(LIBXENSTORE)
-	$(CC) $^ $(LDFLAGS) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS)
+	$(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS)
 
 xenstored: $(XENSTORED_OBJS)
-	$(CC) $^ $(LDFLAGS) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
+	$(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS)
 
 xenstored.a: $(XENSTORED_OBJS)
 	$(AR) cr $@ $^
diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
index b18000d..7f1e489 100644
--- a/tools/xenstore/xenstored_core.c
+++ b/tools/xenstore/xenstored_core.c
@@ -41,6 +41,8 @@
 #include <assert.h>
 #include <setjmp.h>
 
+#include <xenevtchn.h>
+
 #include "utils.h"
 #include "list.h"
 #include "talloc.h"
@@ -64,7 +66,7 @@
 #include <systemd/sd-daemon.h>
 #endif
 
-extern xc_evtchn *xce_handle; /* in xenstored_domain.c */
+extern xenevtchn_handle *xce_handle; /* in xenstored_domain.c */
 static int xce_pollfd_idx = -1;
 static struct pollfd *fds;
 static unsigned int current_array_size;
@@ -373,7 +375,7 @@ static void initialize_fds(int sock, int *p_sock_pollfd_idx,
 			set_fd(reopen_log_pipe[0], POLLIN|POLLPRI);
 
 	if (xce_handle != NULL)
-		xce_pollfd_idx = set_fd(xc_evtchn_fd(xce_handle),
+		xce_pollfd_idx = set_fd(xenevtchn_fd(xce_handle),
 					POLLIN|POLLPRI);
 
 	list_for_each_entry(conn, &connections, list) {
diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
index 6d0394d..51959da 100644
--- a/tools/xenstore/xenstored_domain.c
+++ b/tools/xenstore/xenstored_domain.c
@@ -30,6 +30,7 @@
 #include "xenstored_transaction.h"
 #include "xenstored_watch.h"
 
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xen/grant_table.h>
 
@@ -37,7 +38,7 @@ static xc_interface **xc_handle;
 xc_gnttab **xcg_handle;
 static evtchn_port_t virq_port;
 
-xc_evtchn *xce_handle = NULL;
+xenevtchn_handle *xce_handle = NULL;
 
 struct domain
 {
@@ -129,7 +130,7 @@ static int writechn(struct connection *conn,
 	xen_mb();
 	intf->rsp_prod += len;
 
-	xc_evtchn_notify(xce_handle, conn->domain->port);
+	xenevtchn_notify(xce_handle, conn->domain->port);
 
 	return len;
 }
@@ -159,7 +160,7 @@ static int readchn(struct connection *conn, void *data, unsigned int len)
 	xen_mb();
 	intf->req_cons += len;
 
-	xc_evtchn_notify(xce_handle, conn->domain->port);
+	xenevtchn_notify(xce_handle, conn->domain->port);
 
 	return len;
 }
@@ -191,7 +192,7 @@ static int destroy_domain(void *_domain)
 	list_del(&domain->list);
 
 	if (domain->port) {
-		if (xc_evtchn_unbind(xce_handle, domain->port) == -1)
+		if (xenevtchn_unbind(xce_handle, domain->port) == -1)
 			eprintf("> Unbinding port %i failed!\n", domain->port);
 	}
 
@@ -240,13 +241,13 @@ void handle_event(void)
 {
 	evtchn_port_t port;
 
-	if ((port = xc_evtchn_pending(xce_handle)) == -1)
+	if ((port = xenevtchn_pending(xce_handle)) == -1)
 		barf_perror("Failed to read from event fd");
 
 	if (port == virq_port)
 		domain_cleanup();
 
-	if (xc_evtchn_unmask(xce_handle, port) == -1)
+	if (xenevtchn_unmask(xce_handle, port) == -1)
 		barf_perror("Failed to write to event fd");
 }
 
@@ -288,7 +289,7 @@ static struct domain *new_domain(void *context, unsigned int domid,
 	talloc_set_destructor(domain, destroy_domain);
 
 	/* Tell kernel we're interested in this event. */
-	rc = xc_evtchn_bind_interdomain(xce_handle, domid, port);
+	rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
 	if (rc == -1)
 	    return NULL;
 	domain->port = rc;
@@ -393,8 +394,8 @@ void do_introduce(struct connection *conn, struct buffered_data *in)
 	} else if ((domain->mfn == mfn) && (domain->conn != conn)) {
 		/* Use XS_INTRODUCE for recreating the xenbus event-channel. */
 		if (domain->port)
-			xc_evtchn_unbind(xce_handle, domain->port);
-		rc = xc_evtchn_bind_interdomain(xce_handle, domid, port);
+			xenevtchn_unbind(xce_handle, domain->port);
+		rc = xenevtchn_bind_interdomain(xce_handle, domid, port);
 		domain->port = (rc == -1) ? 0 : rc;
 		domain->remote_port = port;
 	} else {
@@ -615,7 +616,7 @@ static int dom0_init(void)
 
 	talloc_steal(dom0->conn, dom0); 
 
-	xc_evtchn_notify(xce_handle, dom0->port); 
+	xenevtchn_notify(xce_handle, dom0->port); 
 
 	return 0; 
 }
@@ -644,7 +645,7 @@ void domain_init(void)
 	else
 		talloc_set_destructor(xcg_handle, close_xcg_handle);
 
-	xce_handle = xc_evtchn_open(NULL, 0);
+	xce_handle = xenevtchn_open(NULL, 0);
 
 	if (xce_handle == NULL)
 		barf_perror("Failed to open evtchn device");
@@ -652,7 +653,7 @@ void domain_init(void)
 	if (dom0_init() != 0) 
 		barf_perror("Failed to initialize dom0 state"); 
 
-	if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1)
+	if ((rc = xenevtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1)
 		barf_perror("Failed to bind to domain exception virq port");
 	virq_port = rc;
 }
diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile
index 5360960..fc94e04 100644
--- a/tools/xentrace/Makefile
+++ b/tools/xentrace/Makefile
@@ -3,7 +3,9 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 CFLAGS += -Werror
 
+CFLAGS += $(CFLAGS_libxenevtchn)
 CFLAGS += $(CFLAGS_libxenctrl)
+LDLIBS += $(LDLIBS_libxenevtchn)
 LDLIBS += $(LDLIBS_libxenctrl)
 
 BIN      =
diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c
index 4ee1458..c970d42 100644
--- a/tools/xentrace/xentrace.c
+++ b/tools/xentrace/xentrace.c
@@ -30,6 +30,7 @@
 #include <xen/xen.h>
 #include <xen/trace.h>
 
+#include <xenevtchn.h>
 #include <xenctrl.h>
 
 #define PERROR(_m, _a...)                                       \
@@ -74,7 +75,7 @@ settings_t opts;
 int interrupted = 0; /* gets set if we get a SIGHUP */
 
 static xc_interface *xc_handle;
-static xc_evtchn *xce_handle = NULL;
+static xenevtchn_handle *xce_handle = NULL;
 static int virq_port = -1;
 static int outfd = 1;
 
@@ -602,13 +603,13 @@ static void event_init(void)
 {
     int rc;
 
-    xce_handle = xc_evtchn_open(NULL, 0);
+    xce_handle = xenevtchn_open(NULL, 0);
     if (xce_handle == NULL) {
         perror("event channel open");
         exit(EXIT_FAILURE);
     }
 
-    rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF);
+    rc = xenevtchn_bind_virq(xce_handle, VIRQ_TBUF);
     if (rc == -1) {
         PERROR("failed to bind to VIRQ port");
         exit(EXIT_FAILURE);
@@ -623,7 +624,7 @@ static void event_init(void)
 static void wait_for_event_or_timeout(unsigned long milliseconds)
 {
     int rc;
-    struct pollfd fd = { .fd = xc_evtchn_fd(xce_handle),
+    struct pollfd fd = { .fd = xenevtchn_fd(xce_handle),
                          .events = POLLIN | POLLERR };
     int port;
 
@@ -636,7 +637,7 @@ static void wait_for_event_or_timeout(unsigned long milliseconds)
     }
 
     if (rc == 1) {
-        port = xc_evtchn_pending(xce_handle);
+        port = xenevtchn_pending(xce_handle);
         if (port == -1) {
             PERROR("failed to read port from evtchn");
             exit(EXIT_FAILURE);
@@ -647,7 +648,7 @@ static void wait_for_event_or_timeout(unsigned long milliseconds)
                     port, virq_port);
             exit(EXIT_FAILURE);
         }
-        rc = xc_evtchn_unmask(xce_handle, port);
+        rc = xenevtchn_unmask(xce_handle, port);
         if (rc == -1) {
             PERROR("failed to write port to evtchn");
             exit(EXIT_FAILURE);
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC tools 6/6] Cleanup SHLIBDEPS
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (4 preceding siblings ...)
  2015-06-10 11:36 ` [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn Ian Campbell
@ 2015-06-10 11:36 ` Ian Campbell
  2015-06-10 11:37 ` [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library Ian Campbell
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:36 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

---
 tools/Rules.mk |   25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/tools/Rules.mk b/tools/Rules.mk
index fd3a7db..fbb0fb4 100644
--- a/tools/Rules.mk
+++ b/tools/Rules.mk
@@ -45,24 +45,28 @@ LDLIBS_libxenevtchn = $(XEN_LIBXENEVTCHN)/libxenevtchn$(libextension)
 SHLIB_libxenevtchn  = -Wl,-rpath-link=$(XEN_LIBXENEVTCHN)
 
 CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude)
-LDLIBS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) $(XEN_LIBXC)/libxenctrl$(libextension)
-SHLIB_libxenctrl  =  $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) -Wl,-rpath-link=$(XEN_LIBXC)
+SHDEPS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn)
+LDLIBS_libxenctrl = $(SHDEPS_libxenctrl) $(XEN_LIBXC)/libxenctrl$(libextension)
+SHLIB_libxenctrl  = $(SHDEPS_libxenctrl) -Wl,-rpath-link=$(XEN_LIBXC)
 
 CFLAGS_libxenguest = -I$(XEN_LIBXC)/include $(CFLAGS_libxenevtchn) $(CFLAGS_xeninclude)
-LDLIBS_libxenguest = $(SHLIB_libxenevtchn) $(XEN_LIBXC)/libxenguest$(libextension)
-SHLIB_libxenguest  = $(SHLIB_libxenevtchn) -Wl,-rpath-link=L$(XEN_LIBXC)
+SHDEPS_libxenguest = $(SHLIB_libxenevtchn)
+LDLIBS_libxenguest = $(SHDEPS_libxenguest) $(XEN_LIBXC)/libxenguest$(libextension)
+SHLIB_libxenguest  = $(SHDEPS_libxenguest) -Wl,-rpath-link=L$(XEN_LIBXC)
 
 CFLAGS_libxenstore = -I$(XEN_XENSTORE)/include $(CFLAGS_xeninclude)
 LDLIBS_libxenstore = $(XEN_XENSTORE)/libxenstore$(libextension)
 SHLIB_libxenstore  = -Wl,-rpath-link=$(XEN_XENSTORE)
 
 CFLAGS_libxenstat  = -I$(XEN_LIBXENSTAT)
-LDLIBS_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(XEN_LIBXENSTAT)/libxenstat$(libextension)
-SHLIB_libxenstat  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) -Wl,-rpath-link=$(XEN_LIBXENSTAT)
+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_LIBVCHAN)
-LDLIBS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) $(XEN_LIBVCHAN)/libxenvchan$(libextension)
-SHLIB_libxenvchan  = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) -Wl,-rpath-link=$(XEN_LIBVCHAN)
+SHDEPS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn)
+LDLIBS_libxenvchan = $(SHDEPS_libxenvchan) $(XEN_LIBVCHAN)/libxenvchan$(libextension)
+SHLIB_libxenvchan  = $(SHDEPS_libxenvchan) -Wl,-rpath-link=$(XEN_LIBVCHAN)
 
 ifeq ($(debug),y)
 # Disable optimizations and enable debugging information for macros
@@ -84,8 +88,9 @@ SHLIB_libblktapctl  =
 endif
 
 CFLAGS_libxenlight = -I$(XEN_XENLIGHT) $(CFLAGS_libxenctrl) $(CFLAGS_xeninclude)
-LDLIBS_libxenlight = $(XEN_XENLIGHT)/libxenlight$(libextension) $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libblktapctl)
-SHLIB_libxenlight  = -Wl,-rpath-link=$(XEN_XENLIGHT)
+SHDEPS_libxenlight = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libblktapctl)
+LDLIBS_libxenlight = $(SHDEPS_libxenlight) $(XEN_XENLIGHT)/libxenlight$(libextension)
+SHLIB_libxenlight  = $(SHDEPS_libxenlight) -Wl,-rpath-link=$(XEN_XENLIGHT)
 
 CFLAGS += -D__XEN_TOOLS__
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (5 preceding siblings ...)
  2015-06-10 11:36 ` [PATCH RFC tools 6/6] Cleanup SHLIBDEPS Ian Campbell
@ 2015-06-10 11:37 ` Ian Campbell
  2015-06-10 15:57   ` Ian Jackson
  2015-06-10 11:37 ` [PATCH RFC qemu-trad 2/2] qemu-xen-traditional: Use libxenevtchn Ian Campbell
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:37 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

This has been split out of libxenctrl, so the build needs to be able
to find the header and the library. QEMU does not use xtl_* itself so
-rpath-link is sufficient to allow linking to libxenctrl.so (which
links against libxentoollog).

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen-hooks.mak |    2 ++
 1 file changed, 2 insertions(+)

diff --git a/xen-hooks.mak b/xen-hooks.mak
index bc7f1f1..2e53c04 100644
--- a/xen-hooks.mak
+++ b/xen-hooks.mak
@@ -1,3 +1,4 @@
+CPPFLAGS+= -I$(XEN_ROOT)/tools/libxentoollog/include
 CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc/include
 CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore/include
 CPPFLAGS+= -I$(XEN_ROOT)/tools/include
@@ -19,6 +20,7 @@ CFLAGS += $(CMDLINE_CFLAGS)
 
 LIBS += -L$(XEN_ROOT)/tools/libxc -lxenctrl -lxenguest
 LIBS += -L$(XEN_ROOT)/tools/xenstore -lxenstore
+LIBS += -Wl,-rpath-link=$(XEN_ROOT)/tools/libxentoollog
 
 LDFLAGS := $(CFLAGS) $(LDFLAGS)
 
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC qemu-trad 2/2] qemu-xen-traditional: Use libxenevtchn
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (6 preceding siblings ...)
  2015-06-10 11:37 ` [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library Ian Campbell
@ 2015-06-10 11:37 ` Ian Campbell
  2015-06-10 11:37 ` [PATCH RFC mini-os 1/2] mini-os: Include libxentoollog with libxc Ian Campbell
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:37 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

/dev/xen/evtchn related wrappers have been moved out of libxenctrl
into their own library.

Note that i386-dm/helper2.c's xc_interface * was always really an
xc_evtchn *, it's just they used to be typedefs to the same thing...

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 hw/xen_backend.c  |   26 +++++++++++++-------------
 hw/xen_backend.h  |    2 +-
 hw/xen_common.h   |    1 +
 i386-dm/helper2.c |   19 ++++++++++---------
 xen-hooks.mak     |    2 ++
 5 files changed, 27 insertions(+), 23 deletions(-)

diff --git a/hw/xen_backend.c b/hw/xen_backend.c
index 92b3506..40f6887 100644
--- a/hw/xen_backend.c
+++ b/hw/xen_backend.c
@@ -208,19 +208,19 @@ static struct XenDevice *xen_be_get_xendev(const char *type, int dom, int dev,
     xendev->debug      = debug;
     xendev->local_port = -1;
 
-    xendev->evtchndev = xc_evtchn_open(NULL, 0);
+    xendev->evtchndev = xenevtchn_open(NULL, 0);
     if (xendev->evtchndev == NULL) {
 	xen_be_printf(NULL, 0, "can't open evtchn device\n");
 	qemu_free(xendev);
 	return NULL;
     }
-    fcntl(xc_evtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
+    fcntl(xenevtchn_fd(xendev->evtchndev), F_SETFD, FD_CLOEXEC);
 
     if (ops->flags & DEVOPS_FLAG_NEED_GNTDEV) {
 	xendev->gnttabdev = xc_gnttab_open(NULL, 0);
 	if (xendev->gnttabdev == NULL) {
 	    xen_be_printf(NULL, 0, "can't open gnttab device\n");
-	    xc_evtchn_close(xendev->evtchndev);
+	    xenevtchn_close(xendev->evtchndev);
 	    qemu_free(xendev);
 	    return NULL;
 	}
@@ -268,7 +268,7 @@ static struct XenDevice *xen_be_del_xendev(int dom, int dev)
 	}
 
 	if (xendev->evtchndev != NULL)
-	    xc_evtchn_close(xendev->evtchndev);
+	    xenevtchn_close(xendev->evtchndev);
 	if (xendev->gnttabdev != NULL)
 	    xc_gnttab_close(xendev->gnttabdev);
 
@@ -630,13 +630,13 @@ static void xen_be_evtchn_event(void *opaque)
     struct XenDevice *xendev = opaque;
     evtchn_port_t port;
 
-    port = xc_evtchn_pending(xendev->evtchndev);
+    port = xenevtchn_pending(xendev->evtchndev);
     if (port != xendev->local_port) {
-	xen_be_printf(xendev, 0, "xc_evtchn_pending returned %d (expected %d)\n",
+	xen_be_printf(xendev, 0, "xenevtchn_pending returned %d (expected %d)\n",
 		      port, xendev->local_port);
 	return;
     }
-    xc_evtchn_unmask(xendev->evtchndev, port);
+    xenevtchn_unmask(xendev->evtchndev, port);
 
     if (xendev->ops->event)
 	xendev->ops->event(xendev);
@@ -683,14 +683,14 @@ int xen_be_bind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port != -1)
 	return 0;
-    xendev->local_port = xc_evtchn_bind_interdomain
+    xendev->local_port = xenevtchn_bind_interdomain
 	(xendev->evtchndev, xendev->dom, xendev->remote_port);
     if (xendev->local_port == -1) {
-	xen_be_printf(xendev, 0, "xc_evtchn_bind_interdomain failed\n");
+	xen_be_printf(xendev, 0, "xenevtchn_bind_interdomain failed\n");
 	return -1;
     }
     xen_be_printf(xendev, 2, "bind evtchn port %d\n", xendev->local_port);
-    qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev),
+    qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev),
 			xen_be_evtchn_event, NULL, xendev);
     return 0;
 }
@@ -699,15 +699,15 @@ void xen_be_unbind_evtchn(struct XenDevice *xendev)
 {
     if (xendev->local_port == -1)
 	return;
-    qemu_set_fd_handler(xc_evtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
-    xc_evtchn_unbind(xendev->evtchndev, xendev->local_port);
+    qemu_set_fd_handler(xenevtchn_fd(xendev->evtchndev), NULL, NULL, NULL);
+    xenevtchn_unbind(xendev->evtchndev, xendev->local_port);
     xen_be_printf(xendev, 2, "unbind evtchn port %d\n", xendev->local_port);
     xendev->local_port = -1;
 }
 
 int xen_be_send_notify(struct XenDevice *xendev)
 {
-    return xc_evtchn_notify(xendev->evtchndev, xendev->local_port);
+    return xenevtchn_notify(xendev->evtchndev, xendev->local_port);
 }
 
 /*
diff --git a/hw/xen_backend.h b/hw/xen_backend.h
index e421391..60f18f8 100644
--- a/hw/xen_backend.h
+++ b/hw/xen_backend.h
@@ -44,7 +44,7 @@ struct XenDevice {
     int                remote_port;
     int                local_port;
 
-    xc_evtchn          *evtchndev;
+    xenevtchn_handle   *evtchndev;
     xc_gnttab          *gnttabdev;
 
     struct XenDevOps   *ops;
diff --git a/hw/xen_common.h b/hw/xen_common.h
index a615052..cee908f 100644
--- a/hw/xen_common.h
+++ b/hw/xen_common.h
@@ -4,6 +4,7 @@
 #include <stddef.h>
 #include <inttypes.h>
 
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xenstore.h>
 #include <xen/io/xenbus.h>
diff --git a/i386-dm/helper2.c b/i386-dm/helper2.c
index 63a938b..e4df0d7 100644
--- a/i386-dm/helper2.c
+++ b/i386-dm/helper2.c
@@ -48,6 +48,7 @@
 #include <limits.h>
 #include <fcntl.h>
 
+#include <xenevtchn.h>
 #include <xenctrl.h>
 #include <xen/hvm/ioreq.h>
 #include <xen/hvm/hvm_info_table.h>
@@ -104,7 +105,7 @@ buffered_iopage_t *buffered_io_page = NULL;
 QEMUTimer *buffered_io_timer;
 
 /* the evtchn fd for polling */
-xc_interface *xce_handle = NULL;
+xenevtchn_handle *xce_handle = NULL;
 
 /* which vcpu we are serving */
 int send_vcpu = 0;
@@ -141,7 +142,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 
         cpu_single_env = env;
 
-        xce_handle = xc_evtchn_open(NULL, 0);
+        xce_handle = xenevtchn_open(NULL, 0);
         if (xce_handle == NULL) {
             perror("open");
             return NULL;
@@ -149,7 +150,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
 
         /* FIXME: how about if we overflow the page here? */
         for (i = 0; i < vcpus; i++) {
-            rc = xc_evtchn_bind_interdomain(
+            rc = xenevtchn_bind_interdomain(
                 xce_handle, domid, shared_page->vcpu_ioreq[i].vp_eport);
             if (rc == -1) {
                 fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
@@ -164,7 +165,7 @@ CPUX86State *cpu_x86_init(const char *cpu_model)
                     errno);
             return NULL;
         }
-        rc = xc_evtchn_bind_interdomain(xce_handle, domid, (uint32_t)bufioreq_evtchn);
+        rc = xenevtchn_bind_interdomain(xce_handle, domid, (uint32_t)bufioreq_evtchn);
         if (rc == -1) {
             fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
             return NULL;
@@ -278,7 +279,7 @@ static ioreq_t *cpu_get_ioreq(void)
     int i;
     evtchn_port_t port;
 
-    port = xc_evtchn_pending(xce_handle);
+    port = xenevtchn_pending(xce_handle);
     if (port == bufioreq_local_port) {
         qemu_mod_timer(buffered_io_timer,
                 BUFFER_IO_MAX_DELAY + qemu_get_clock(rt_clock));
@@ -296,7 +297,7 @@ static ioreq_t *cpu_get_ioreq(void)
         }
 
         // unmask the wanted port again
-        xc_evtchn_unmask(xce_handle, port);
+        xenevtchn_unmask(xce_handle, port);
 
         //get the io packet from shared memory
         send_vcpu = i;
@@ -531,7 +532,7 @@ static void handle_buffered_io(void *opaque)
                 BUFFER_IO_MAX_DELAY + qemu_get_clock(rt_clock));
     } else {
         qemu_del_timer(buffered_io_timer);
-        xc_evtchn_unmask(xce_handle, bufioreq_local_port);
+        xenevtchn_unmask(xce_handle, bufioreq_local_port);
     }
 }
 
@@ -575,7 +576,7 @@ static void cpu_handle_ioreq(void *opaque)
 	}
 
         req->state = STATE_IORESP_READY;
-        xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
+        xenevtchn_notify(xce_handle, ioreq_local_port[send_vcpu]);
     }
 }
 
@@ -584,7 +585,7 @@ int xen_pause_requested;
 int main_loop(void)
 {
     CPUState *env = cpu_single_env;
-    int evtchn_fd = xce_handle == NULL ? -1 : xc_evtchn_fd(xce_handle);
+    int evtchn_fd = xce_handle == NULL ? -1 : xenevtchn_fd(xce_handle);
     char *qemu_file;
     fd_set fds;
 
diff --git a/xen-hooks.mak b/xen-hooks.mak
index 2e53c04..ec5fbab 100644
--- a/xen-hooks.mak
+++ b/xen-hooks.mak
@@ -1,4 +1,5 @@
 CPPFLAGS+= -I$(XEN_ROOT)/tools/libxentoollog/include
+CPPFLAGS+= -I$(XEN_ROOT)/tools/libxenevtchn/include
 CPPFLAGS+= -I$(XEN_ROOT)/tools/libxc/include
 CPPFLAGS+= -I$(XEN_ROOT)/tools/xenstore/include
 CPPFLAGS+= -I$(XEN_ROOT)/tools/include
@@ -18,6 +19,7 @@ endif
 
 CFLAGS += $(CMDLINE_CFLAGS)
 
+LIBS += -L$(XEN_ROOT)/tools/libxenevtchn -lxenevtchn
 LIBS += -L$(XEN_ROOT)/tools/libxc -lxenctrl -lxenguest
 LIBS += -L$(XEN_ROOT)/tools/xenstore -lxenstore
 LIBS += -Wl,-rpath-link=$(XEN_ROOT)/tools/libxentoollog
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC mini-os 1/2] mini-os: Include libxentoollog with libxc
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (7 preceding siblings ...)
  2015-06-10 11:37 ` [PATCH RFC qemu-trad 2/2] qemu-xen-traditional: Use libxenevtchn Ian Campbell
@ 2015-06-10 11:37 ` Ian Campbell
  2015-06-10 11:37 ` [PATCH RFC mini-os 2/2] mini-os: Include libxenevtchn " Ian Campbell
  2015-06-10 16:01 ` [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Jackson
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:37 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

libxentoollog has just been split out from libxc. From mini-os's point
of view we don't care about the distinction, so keep things simple by
just including libxentoollog if libxc is enabled.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 Makefile |    1 +
 1 file changed, 1 insertion(+)

diff --git a/Makefile b/Makefile
index 2cb5e51..757bd70 100644
--- a/Makefile
+++ b/Makefile
@@ -165,6 +165,7 @@ OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS))
 
 ifeq ($(libc),y)
 ifeq ($(CONFIG_XC),y)
+APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxentoollog-$(MINIOS_TARGET_ARCH) -whole-archive -lxentoollog -no-whole-archive
 APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc-$(MINIOS_TARGET_ARCH) -whole-archive -lxenguest -lxenctrl -no-whole-archive
 endif
 APP_LDLIBS += -lpci
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH RFC mini-os 2/2] mini-os: Include libxenevtchn with libxc
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (8 preceding siblings ...)
  2015-06-10 11:37 ` [PATCH RFC mini-os 1/2] mini-os: Include libxentoollog with libxc Ian Campbell
@ 2015-06-10 11:37 ` Ian Campbell
  2015-06-10 16:01 ` [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Jackson
  10 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-10 11:37 UTC (permalink / raw)
  To: xen-devel
  Cc: ian.jackson, roger.pau, wei.liu2, Ian Campbell, stefano.stabellini

libxenevtchn has just been split out from libxc. From mini-os's point
of view we don't care about the distinction, so keep things simple by
just including libxenevtchn if libxc is enabled.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 Makefile |    1 +
 1 file changed, 1 insertion(+)

diff --git a/Makefile b/Makefile
index 757bd70..66ed510 100644
--- a/Makefile
+++ b/Makefile
@@ -166,6 +166,7 @@ OBJS := $(filter-out $(OBJ_DIR)/lwip%.o $(LWO), $(OBJS))
 ifeq ($(libc),y)
 ifeq ($(CONFIG_XC),y)
 APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxentoollog-$(MINIOS_TARGET_ARCH) -whole-archive -lxentoollog -no-whole-archive
+APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxenevtchn-$(MINIOS_TARGET_ARCH) -whole-archive -lxenevtchn -no-whole-archive
 APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc-$(MINIOS_TARGET_ARCH) -whole-archive -lxenguest -lxenctrl -no-whole-archive
 endif
 APP_LDLIBS += -lpci
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library
  2015-06-10 11:37 ` [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library Ian Campbell
@ 2015-06-10 15:57   ` Ian Jackson
  2015-06-11  8:59     ` Ian Campbell
  0 siblings, 1 reply; 29+ messages in thread
From: Ian Jackson @ 2015-06-10 15:57 UTC (permalink / raw)
  To: Ian Campbell; +Cc: stefano.stabellini, wei.liu2, roger.pau, xen-devel

Ian Campbell writes ("[PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library"):
> This has been split out of libxenctrl, so the build needs to be able
> to find the header and the library. QEMU does not use xtl_* itself so
> -rpath-link is sufficient to allow linking to libxenctrl.so (which
> links against libxentoollog).

Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>

I guess this is harmless to apply right away ?

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries
  2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
                   ` (9 preceding siblings ...)
  2015-06-10 11:37 ` [PATCH RFC mini-os 2/2] mini-os: Include libxenevtchn " Ian Campbell
@ 2015-06-10 16:01 ` Ian Jackson
  2015-06-10 16:15   ` Wei Liu
  10 siblings, 1 reply; 29+ messages in thread
From: Ian Jackson @ 2015-06-10 16:01 UTC (permalink / raw)
  To: Ian Campbell; +Cc: Stefano Stabellini, Wei Liu, Roger Pau Monne, xen-devel

Ian Campbell writes ("[PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries"):
> [stuff]

Most of this looks good to me.

> As part of this change I've begun to get rid of the osdep interface
> layer, since it is obsolete and just gets in the way. IIRC there were
> some tricks being played to use this on rumpkernels to mix and match
> facilities from xc_minios.c and xc_netbsd.c.

Replacing those tricks with appropriate #ifdefs would be fine.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries
  2015-06-10 16:01 ` [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Jackson
@ 2015-06-10 16:15   ` Wei Liu
  2015-06-11 10:01     ` Antti Kantee
  0 siblings, 1 reply; 29+ messages in thread
From: Wei Liu @ 2015-06-10 16:15 UTC (permalink / raw)
  To: Ian Jackson
  Cc: Roger Pau Monne, Stefano Stabellini, Wei Liu, Ian Campbell, xen-devel

On Wed, Jun 10, 2015 at 05:01:27PM +0100, Ian Jackson wrote:
> Ian Campbell writes ("[PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries"):
> > [stuff]
> 
> Most of this looks good to me.
> 
> > As part of this change I've begun to get rid of the osdep interface
> > layer, since it is obsolete and just gets in the way. IIRC there were
> > some tricks being played to use this on rumpkernels to mix and match
> > facilities from xc_minios.c and xc_netbsd.c.
> 
> Replacing those tricks with appropriate #ifdefs would be fine.
> 

FYI I think I will write more glue code to make rump kernel to just use
netbsd code, because they don't want to expose underlying minios
functionalities to application level.

Wei.

> Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
  2015-06-10 11:36 ` [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn Ian Campbell
@ 2015-06-10 16:29   ` David Vrabel
  2015-06-11  8:58     ` Ian Campbell
  2015-06-10 17:16   ` Andrew Cooper
  1 sibling, 1 reply; 29+ messages in thread
From: David Vrabel @ 2015-06-10 16:29 UTC (permalink / raw)
  To: Ian Campbell, xen-devel
  Cc: wei.liu2, stefano.stabellini, ian.jackson, roger.pau

On 10/06/15 12:36, Ian Campbell wrote:
> libxenevtchn will provide a stable API and ABI for accessing the
> evtchn device.
> 
> The functions are moved into the xenevtchn namespace to make a clean
> break from libxc and avoid ambiguity regarding which interfaces are
> stable.
> 
> All in-tree users are updated to use the new names.
> 
> Upon request (via #define XC_WANT_COMPAT_EVTCHN_API) libxenctrl will
> provide a compat API for the old names, which is used by qemu-xen for
> the time being.
> 
> The dynamic osdep mechanism from libxc is not preserved, the
> alternative backend (a xen-api/xapi shim) is no longer around. (Nested
> virt probably suffices for this use case now).
> 
> This leaves a few event channel related functions which go via privcmd
> (EVTCHNOP) rather than ioctls on the /dev/xen/evtchn device in
> libxenctrl. Specifically:
> 
>  - xc_evtchn_alloc_unbound

I was about to complain that this is important functionality for this
new lib, but the library provides the more useful
xenevtchn_bind_unbound_port() instead.  Might be worth mentioning this
in the commit.

David

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
  2015-06-10 11:36 ` [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn Ian Campbell
  2015-06-10 16:29   ` David Vrabel
@ 2015-06-10 17:16   ` Andrew Cooper
  2015-06-11  9:03     ` Ian Campbell
  1 sibling, 1 reply; 29+ messages in thread
From: Andrew Cooper @ 2015-06-10 17:16 UTC (permalink / raw)
  To: Ian Campbell, xen-devel
  Cc: wei.liu2, stefano.stabellini, ian.jackson, roger.pau

On 10/06/15 12:36, Ian Campbell wrote:
> libxenevtchn will provide a stable API and ABI for accessing the
> evtchn device.
>
> The functions are moved into the xenevtchn namespace to make a clean
> break from libxc and avoid ambiguity regarding which interfaces are
> stable.
>
> All in-tree users are updated to use the new names.
>
> Upon request (via #define XC_WANT_COMPAT_EVTCHN_API) libxenctrl will
> provide a compat API for the old names, which is used by qemu-xen for
> the time being.
>
> The dynamic osdep mechanism from libxc is not preserved, the
> alternative backend (a xen-api/xapi shim) is no longer around. (Nested
> virt probably suffices for this use case now).
>
> This leaves a few event channel related functions which go via privcmd
> (EVTCHNOP) rather than ioctls on the /dev/xen/evtchn device in
> libxenctrl. Specifically:
>
>  - xc_evtchn_alloc_unbound
>  - xc_evtchn_reset
>  - xc_evtchn_status
>
> These functions do not appear to be needed by qemu-dm, qemu-pv
> (provision of device model to HVM guests and PV backends respectively)
> or by libvchan suggesting they are not needed by non-toolstack uses of
> event channels. QEMU does use these in hw/xenpv/xen_domainbuild.c but
> that is a "toolstack use".
>
> The new library uses a version script to ensure that only expected
> symbols are exported and to version them such that ABI guarantees can
> be kept in the future.
>
> Build tested with Linux and mini-os/stubdom, but not FreeBSD, NetBSD
> or Solaris.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> ---
>
> Must be applied with:
>
>  - "qemu-xen-traditional: Use libxenevtchn" and a corresponding
>    QEMU_TAG update folded here.
>  - "mini-os: Include libxenevtchn with libxc"" and a corresponding
>    bump to MINIOS_UPSTREAM_REVISION folded in here.
> ---

As we are taking the hit of updating all in-tree users, and providing a
compat shim, can we take the opportunity to make amends to the ABI.

For xenevtchn, it is never realistically going to gain logging.  It
seems like it would be a good idea to ditch all knowledge of xentoollog
from the new library, as the cost is just dropping one parameter in the
callsites.

~Andrew

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
  2015-06-10 16:29   ` David Vrabel
@ 2015-06-11  8:58     ` Ian Campbell
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-11  8:58 UTC (permalink / raw)
  To: David Vrabel
  Cc: wei.liu2, roger.pau, ian.jackson, stefano.stabellini, xen-devel

On Wed, 2015-06-10 at 17:29 +0100, David Vrabel wrote:
> On 10/06/15 12:36, Ian Campbell wrote:
> > libxenevtchn will provide a stable API and ABI for accessing the
> > evtchn device.
> > 
> > The functions are moved into the xenevtchn namespace to make a clean
> > break from libxc and avoid ambiguity regarding which interfaces are
> > stable.
> > 
> > All in-tree users are updated to use the new names.
> > 
> > Upon request (via #define XC_WANT_COMPAT_EVTCHN_API) libxenctrl will
> > provide a compat API for the old names, which is used by qemu-xen for
> > the time being.
> > 
> > The dynamic osdep mechanism from libxc is not preserved, the
> > alternative backend (a xen-api/xapi shim) is no longer around. (Nested
> > virt probably suffices for this use case now).
> > 
> > This leaves a few event channel related functions which go via privcmd
> > (EVTCHNOP) rather than ioctls on the /dev/xen/evtchn device in
> > libxenctrl. Specifically:
> > 
> >  - xc_evtchn_alloc_unbound
> 
> I was about to complain that this is important functionality for this
> new lib, but the library provides the more useful
> xenevtchn_bind_unbound_port() instead.  Might be worth mentioning this
> in the commit.

Yes, I hadn't realised the two were redundant in that way. I'll mention
it.

Perhaps we should even consider removing xc_evtchn_alloc_unbound? Other
then the language bindings I can't see an in tree user apart from the
language bindings. I suspect the user was xend.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library
  2015-06-10 15:57   ` Ian Jackson
@ 2015-06-11  8:59     ` Ian Campbell
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-11  8:59 UTC (permalink / raw)
  To: Ian Jackson; +Cc: stefano.stabellini, wei.liu2, roger.pau, xen-devel

On Wed, 2015-06-10 at 16:57 +0100, Ian Jackson wrote:
> Ian Campbell writes ("[PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library"):
> > This has been split out of libxenctrl, so the build needs to be able
> > to find the header and the library. QEMU does not use xtl_* itself so
> > -rpath-link is sufficient to allow linking to libxenctrl.so (which
> > links against libxentoollog).
> 
> Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
> 
> I guess this is harmless to apply right away ?

I suppose so, although the paths it references won't actually exist
until later

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn.
  2015-06-10 17:16   ` Andrew Cooper
@ 2015-06-11  9:03     ` Ian Campbell
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-11  9:03 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: wei.liu2, roger.pau, ian.jackson, stefano.stabellini, xen-devel

On Wed, 2015-06-10 at 18:16 +0100, Andrew Cooper wrote:
> On 10/06/15 12:36, Ian Campbell wrote:
> > libxenevtchn will provide a stable API and ABI for accessing the
> > evtchn device.
> >
> > The functions are moved into the xenevtchn namespace to make a clean
> > break from libxc and avoid ambiguity regarding which interfaces are
> > stable.
> >
> > All in-tree users are updated to use the new names.
> >
> > Upon request (via #define XC_WANT_COMPAT_EVTCHN_API) libxenctrl will
> > provide a compat API for the old names, which is used by qemu-xen for
> > the time being.
> >
> > The dynamic osdep mechanism from libxc is not preserved, the
> > alternative backend (a xen-api/xapi shim) is no longer around. (Nested
> > virt probably suffices for this use case now).
> >
> > This leaves a few event channel related functions which go via privcmd
> > (EVTCHNOP) rather than ioctls on the /dev/xen/evtchn device in
> > libxenctrl. Specifically:
> >
> >  - xc_evtchn_alloc_unbound
> >  - xc_evtchn_reset
> >  - xc_evtchn_status
> >
> > These functions do not appear to be needed by qemu-dm, qemu-pv
> > (provision of device model to HVM guests and PV backends respectively)
> > or by libvchan suggesting they are not needed by non-toolstack uses of
> > event channels. QEMU does use these in hw/xenpv/xen_domainbuild.c but
> > that is a "toolstack use".
> >
> > The new library uses a version script to ensure that only expected
> > symbols are exported and to version them such that ABI guarantees can
> > be kept in the future.
> >
> > Build tested with Linux and mini-os/stubdom, but not FreeBSD, NetBSD
> > or Solaris.
> >
> > Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> > ---
> >
> > Must be applied with:
> >
> >  - "qemu-xen-traditional: Use libxenevtchn" and a corresponding
> >    QEMU_TAG update folded here.
> >  - "mini-os: Include libxenevtchn with libxc"" and a corresponding
> >    bump to MINIOS_UPSTREAM_REVISION folded in here.
> > ---
> 
> As we are taking the hit of updating all in-tree users, and providing a
> compat shim, can we take the opportunity to make amends to the ABI.

Yes, we should in general take the opportunity.

In particular fixing the error reporting behaviour would be a very good
idea...

> For xenevtchn, it is never realistically going to gain logging.

I thought about this but I wasn't sure and at least the Solaris backend
does log (or tries to, who knows if it works!).

>   It
> seems like it would be a good idea to ditch all knowledge of xentoollog
> from the new library, as the cost is just dropping one parameter in the
> callsites.

I don't think the overhead of an extra NULL is worth it, and it's
possible something might want to log there in the future.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries
  2015-06-10 16:15   ` Wei Liu
@ 2015-06-11 10:01     ` Antti Kantee
  0 siblings, 0 replies; 29+ messages in thread
From: Antti Kantee @ 2015-06-11 10:01 UTC (permalink / raw)
  To: Wei Liu, Ian Jackson
  Cc: Stefano Stabellini, xen-devel, Ian Campbell, Roger Pau Monne

On 10/06/15 16:15, Wei Liu wrote:
> On Wed, Jun 10, 2015 at 05:01:27PM +0100, Ian Jackson wrote:
>> Ian Campbell writes ("[PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries"):
>>> [stuff]
>>
>> Most of this looks good to me.
>>
>>> As part of this change I've begun to get rid of the osdep interface
>>> layer, since it is obsolete and just gets in the way. IIRC there were
>>> some tricks being played to use this on rumpkernels to mix and match
>>> facilities from xc_minios.c and xc_netbsd.c.
>>
>> Replacing those tricks with appropriate #ifdefs would be fine.
>>
>
> FYI I think I will write more glue code to make rump kernel to just use
> netbsd code, because they don't want to expose underlying minios
> functionalities to application level.

It's not so much that we outright "don't want to" as "prefer not to". 
If there's a strong reason, e.g. a measurably significant performance 
improvement, then we can talk.  However, anything calling past the libc 
interface is dipping into internal interfaces.  We make no guarantee 
about internal interface stability.

One good summary of 8 years of rump kernel development would be "lack of 
compartmentalization always comes back to bite you", so IMO it's better 
to conceptually maintain separation even where not enforced by a MMU and 
just make everything go through the guaranteed-stable syscall interfaces.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-06-10 11:36 ` [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library Ian Campbell
@ 2015-06-11 11:20   ` Andrew Cooper
  2015-06-11 11:35     ` Ian Campbell
  2015-09-21 16:17     ` Ian Jackson
  0 siblings, 2 replies; 29+ messages in thread
From: Andrew Cooper @ 2015-06-11 11:20 UTC (permalink / raw)
  To: Ian Campbell, xen-devel
  Cc: wei.liu2, stefano.stabellini, ian.jackson, roger.pau

On 10/06/15 12:36, Ian Campbell wrote:
> +
> +#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
> +    xentoollog_logger_##LOGGER *new_consumer;                           \
> +                                                                        \
> +    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
> +    (buffer).vtable.progress = LOGGER##_progress;                       \
> +    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
> +                                                                        \
> +    new_consumer = malloc(sizeof(*new_consumer));                       \
> +    if (!new_consumer) {                                                \
> +        xtl_log((xentoollog_logger*)&buffer,                            \
> +                XTL_CRITICAL, errno, "xtl",                             \
> +                "failed to allocate memory for new message logger");    \
> +    } else {                                                            \
> +        *new_consumer = buffer;                                         \
> +    }                                                                   \
> +                                                                        \
> +    new_consumer;                                                       \
> +});

This macro should be ditched.

It is a gnu-ism which shouldn't be present in the public library header,
violates several principles of least supprise, and can literally only be
used by its sole user in xtl_logger_stdio.c because of its internal
expectations of xentoollog_logger_stdiostream.  (Its sole user could do
the above in a cleaner manner anyway.)

As part of the tidyup, we should choose a particular C standard (89,
probably) and ensure that the API/ABI complies with `gcc -std=c$VER
-pedantic`.  This will help to provide a consistent API on other
platforms (I seem to recall an effort to port libvchan to windows.)

As another thought, it would also be a good time to sort out a
consistent coding style, although that doesn't necessarily need to be
folded into the split-out patch.  The current source is very mixed when
it comes to coding style.

~Andrew

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-06-11 11:20   ` Andrew Cooper
@ 2015-06-11 11:35     ` Ian Campbell
  2015-06-11 12:06       ` Jan Beulich
  2015-09-21 16:17     ` Ian Jackson
  1 sibling, 1 reply; 29+ messages in thread
From: Ian Campbell @ 2015-06-11 11:35 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich
  Cc: wei.liu2, roger.pau, ian.jackson, stefano.stabellini, xen-devel

On Thu, 2015-06-11 at 12:20 +0100, Andrew Cooper wrote:
> On 10/06/15 12:36, Ian Campbell wrote:
> > +
> > +#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
> > +    xentoollog_logger_##LOGGER *new_consumer;                           \
> > +                                                                        \
> > +    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
> > +    (buffer).vtable.progress = LOGGER##_progress;                       \
> > +    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
> > +                                                                        \
> > +    new_consumer = malloc(sizeof(*new_consumer));                       \
> > +    if (!new_consumer) {                                                \
> > +        xtl_log((xentoollog_logger*)&buffer,                            \
> > +                XTL_CRITICAL, errno, "xtl",                             \
> > +                "failed to allocate memory for new message logger");    \
> > +    } else {                                                            \
> > +        *new_consumer = buffer;                                         \
> > +    }                                                                   \
> > +                                                                        \
> > +    new_consumer;                                                       \
> > +});
> 
> This macro should be ditched.
> 
> It is a gnu-ism which shouldn't be present in the public library header,
> violates several principles of least supprise, and can literally only be
> used by its sole user in xtl_logger_stdio.c because of its internal
> expectations of xentoollog_logger_stdiostream.  (Its sole user could do
> the above in a cleaner manner anyway.)

Ian? Do you agree?

> As part of the tidyup, we should choose a particular C standard (89,
> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
> -pedantic`.  This will help to provide a consistent API on other
> platforms (I seem to recall an effort to port libvchan to windows.)

Shall we just follow what we do for xen/include/public i.e.
        $(CC) -x c -ansi -Wall -Werror
? It seems sensible that the two should follow similar rules.

Or if not shall we change the requirements for xen/include/public to
match? (Jan CCd for comments)

> As another thought, it would also be a good time to sort out a
> consistent coding style, although that doesn't necessarily need to be
> folded into the split-out patch.  The current source is very mixed when
> it comes to coding style.

True, but this is already quite a big job, with lots of moving parts
already. If I find time I could do a pass, but I don't think it is super
ciritical

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-06-11 11:35     ` Ian Campbell
@ 2015-06-11 12:06       ` Jan Beulich
  2015-06-11 12:21         ` Ian Campbell
  0 siblings, 1 reply; 29+ messages in thread
From: Jan Beulich @ 2015-06-11 12:06 UTC (permalink / raw)
  To: Andrew Cooper, Ian Campbell
  Cc: ian.jackson, xen-devel, stefano.stabellini, wei.liu2, roger.pau

>>> On 11.06.15 at 13:35, <ian.campbell@citrix.com> wrote:
> On Thu, 2015-06-11 at 12:20 +0100, Andrew Cooper wrote:
>> As part of the tidyup, we should choose a particular C standard (89,
>> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
>> -pedantic`.  This will help to provide a consistent API on other
>> platforms (I seem to recall an effort to port libvchan to windows.)
> 
> Shall we just follow what we do for xen/include/public i.e.
>         $(CC) -x c -ansi -Wall -Werror
> ? It seems sensible that the two should follow similar rules.
> 
> Or if not shall we change the requirements for xen/include/public to
> match? (Jan CCd for comments)

We certainly shouldn't weaken what we do for the public headers.
How far standard compliance matters for the library interface
headers I really don't know.

Jan

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-06-11 12:06       ` Jan Beulich
@ 2015-06-11 12:21         ` Ian Campbell
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-06-11 12:21 UTC (permalink / raw)
  To: Jan Beulich
  Cc: wei.liu2, stefano.stabellini, Andrew Cooper, ian.jackson,
	xen-devel, roger.pau

On Thu, 2015-06-11 at 13:06 +0100, Jan Beulich wrote:
> >>> On 11.06.15 at 13:35, <ian.campbell@citrix.com> wrote:
> > On Thu, 2015-06-11 at 12:20 +0100, Andrew Cooper wrote:
> >> As part of the tidyup, we should choose a particular C standard (89,
> >> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
> >> -pedantic`.  This will help to provide a consistent API on other
> >> platforms (I seem to recall an effort to port libvchan to windows.)
> > 
> > Shall we just follow what we do for xen/include/public i.e.
> >         $(CC) -x c -ansi -Wall -Werror
> > ? It seems sensible that the two should follow similar rules.
> > 
> > Or if not shall we change the requirements for xen/include/public to
> > match? (Jan CCd for comments)
> 
> We certainly shouldn't weaken what we do for the public headers.
> How far standard compliance matters for the library interface
> headers I really don't know.

Actually, since -ansi is the same as -std=c89 I don't think there is a
practical difference between the two.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-06-11 11:20   ` Andrew Cooper
  2015-06-11 11:35     ` Ian Campbell
@ 2015-09-21 16:17     ` Ian Jackson
  2015-09-21 17:03       ` Andrew Cooper
  1 sibling, 1 reply; 29+ messages in thread
From: Ian Jackson @ 2015-09-21 16:17 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: roger.pau, wei.liu2, Ian Campbell, stefano.stabellini, xen-devel

Andrew Cooper writes ("Re: [Xen-devel] [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library"):
> On 10/06/15 12:36, Ian Campbell wrote:
> > +
> > +#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
> > +    xentoollog_logger_##LOGGER *new_consumer;                           \
> > +                                                                        \
> > +    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
> > +    (buffer).vtable.progress = LOGGER##_progress;                       \
> > +    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
> > +                                                                        \
> > +    new_consumer = malloc(sizeof(*new_consumer));                       \
> > +    if (!new_consumer) {                                                \
> > +        xtl_log((xentoollog_logger*)&buffer,                            \
> > +                XTL_CRITICAL, errno, "xtl",                             \
> > +                "failed to allocate memory for new message logger");    \
> > +    } else {                                                            \
> > +        *new_consumer = buffer;                                         \
> > +    }                                                                   \
> > +                                                                        \
> > +    new_consumer;                                                       \
> > +});

Ian Campbell just pointed me at this.

> This macro should be ditched.
> 
> It is a gnu-ism which shouldn't be present in the public library header,

Do you mean that statement expressions (originally a GNU extension)
should be avoided in tools code ?  A quick git-grep discovered that
xenctrl already contains numerous statement expressions.

> violates several principles of least supprise,

This is just invective.

> and can literally only be
> used by its sole user in xtl_logger_stdio.c because of its internal
> expectations of xentoollog_logger_stdiostream.  (Its sole user could do
> the above in a cleaner manner anyway.)

There is only one place in tree that calls this because there are only
two in-tree loggers and the other one
(tools/ocaml/libs/xentoollog/xentoollog_stubs.c) chose not to use it.
It seems to me that stub_xtl_create_logger could use this macro.

> As part of the tidyup, we should choose a particular C standard (89,
> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
> -pedantic`.  This will help to provide a consistent API on other
> platforms (I seem to recall an effort to port libvchan to windows.)

-pedantic is certainly a bad idea.

> As another thought, it would also be a good time to sort out a
> consistent coding style, although that doesn't necessarily need to be
> folded into the split-out patch.  The current source is very mixed when
> it comes to coding style.

This sounds like it's going to lead to a lot of bikeshedding.  If
there are components with internally inconsistent coding styles that
should be fixed.  But I don't think it is a good idea to go around
reformatting areas that are coherent to make them like other areas
which are differently coherent.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-09-21 16:17     ` Ian Jackson
@ 2015-09-21 17:03       ` Andrew Cooper
  2015-09-21 17:13         ` Ian Jackson
  0 siblings, 1 reply; 29+ messages in thread
From: Andrew Cooper @ 2015-09-21 17:03 UTC (permalink / raw)
  To: Ian Jackson
  Cc: roger.pau, wei.liu2, Ian Campbell, stefano.stabellini, xen-devel

On 21/09/15 17:17, Ian Jackson wrote:
> Andrew Cooper writes ("Re: [Xen-devel] [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library"):
>> On 10/06/15 12:36, Ian Campbell wrote:
>>> +
>>> +#define XTL_NEW_LOGGER(LOGGER,buffer) ({                                \
>>> +    xentoollog_logger_##LOGGER *new_consumer;                           \
>>> +                                                                        \
>>> +    (buffer).vtable.vmessage = LOGGER##_vmessage;                       \
>>> +    (buffer).vtable.progress = LOGGER##_progress;                       \
>>> +    (buffer).vtable.destroy  = LOGGER##_destroy;                        \
>>> +                                                                        \
>>> +    new_consumer = malloc(sizeof(*new_consumer));                       \
>>> +    if (!new_consumer) {                                                \
>>> +        xtl_log((xentoollog_logger*)&buffer,                            \
>>> +                XTL_CRITICAL, errno, "xtl",                             \
>>> +                "failed to allocate memory for new message logger");    \
>>> +    } else {                                                            \
>>> +        *new_consumer = buffer;                                         \
>>> +    }                                                                   \
>>> +                                                                        \
>>> +    new_consumer;                                                       \
>>> +});
> Ian Campbell just pointed me at this.
>
>> This macro should be ditched.
>>
>> It is a gnu-ism which shouldn't be present in the public library header,
> Do you mean that statement expressions (originally a GNU extension)
> should be avoided in tools code ?  A quick git-grep discovered that
> xenctrl already contains numerous statement expressions.

It is fine (in principle) to be used internally.  Not in a public header
for what is supposed to be a clean API.

>
>> violates several principles of least supprise,
> This is just invective.

/me googles and discovered a new word.  I stand by my statement.

It requires the user to embed one structure inside another structure
(with half a undocumented magic name), under a specific undocumented
field name, and have three functions (with half undocumented magic
names) in scope with undocumented types.  It also mandates an original
copy of the half-magically-named struct in scope to be partially
initialised, just to have another copy created in the heap.

The error handling is also broken;  It will follow a wild function
pointer, if vtable is not the first element in the structure (again
undocumented).

This macro is not fit for any purpose it attempts to perform.

https://github.com/xenserver/xen-4.5.pg/blob/master/master/xenguest.patch#L609
is the correct way to use a setup like this, even if it does require
embedding other data alongside it.

>
>> and can literally only be
>> used by its sole user in xtl_logger_stdio.c because of its internal
>> expectations of xentoollog_logger_stdiostream.  (Its sole user could do
>> the above in a cleaner manner anyway.)
> There is only one place in tree that calls this because there are only
> two in-tree loggers and the other one
> (tools/ocaml/libs/xentoollog/xentoollog_stubs.c) chose not to use it.
> It seems to me that stub_xtl_create_logger could use this macro.

Or better yet, ditch it completely.

All that needs to happen is for struct xentoollog_logger to have the
three function pointers filled in appropriately.  This in turn does not
mandate that the structure is allocated from the heap, or the prescribed
layout/naming scheme.

>
>> As part of the tidyup, we should choose a particular C standard (89,
>> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
>> -pedantic`.  This will help to provide a consistent API on other
>> platforms (I seem to recall an effort to port libvchan to windows.)
> -pedantic is certainly a bad idea.

Pedantic is absolutely the correct answer.  It will cause gcc to reject
any non C compliant statements.

The APIs of each of these new libraries should be just as usable on
windows systems as Linux systems.

~Andrew

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-09-21 17:03       ` Andrew Cooper
@ 2015-09-21 17:13         ` Ian Jackson
  2015-09-21 17:30           ` Andrew Cooper
  0 siblings, 1 reply; 29+ messages in thread
From: Ian Jackson @ 2015-09-21 17:13 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: roger.pau, wei.liu2, Ian Campbell, stefano.stabellini, xen-devel

Andrew Cooper writes ("Re: [Xen-devel] [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library"):
> On 21/09/15 17:17, Ian Jackson wrote:
> > Do you mean that statement expressions (originally a GNU extension)
> > should be avoided in tools code ?  A quick git-grep discovered that
> > xenctrl already contains numerous statement expressions.
> 
> It is fine (in principle) to be used internally.  Not in a public header
> for what is supposed to be a clean API.

I don't understand why this distinction is relevant.  Either the
compiler supports it, or it doesn't.

> >> violates several principles of least supprise,
> > This is just invective.
> 
> /me googles and discovered a new word.  I stand by my statement.

Well, if you feel so strongly, I won't object to a patch to remove it.

> >> As part of the tidyup, we should choose a particular C standard (89,
> >> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
> >> -pedantic`.  This will help to provide a consistent API on other
> >> platforms (I seem to recall an effort to port libvchan to windows.)
> > -pedantic is certainly a bad idea.
> 
> Pedantic is absolutely the correct answer.  It will cause gcc to reject
> any non C compliant statements.

No, that is not what -pedantic does.  Please RTFM.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-09-21 17:13         ` Ian Jackson
@ 2015-09-21 17:30           ` Andrew Cooper
  2015-09-22  8:39             ` Ian Campbell
  0 siblings, 1 reply; 29+ messages in thread
From: Andrew Cooper @ 2015-09-21 17:30 UTC (permalink / raw)
  To: Ian Jackson
  Cc: roger.pau, wei.liu2, Ian Campbell, stefano.stabellini, xen-devel

On 21/09/15 18:13, Ian Jackson wrote:
> Andrew Cooper writes ("Re: [Xen-devel] [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library"):
>> On 21/09/15 17:17, Ian Jackson wrote:
>>> Do you mean that statement expressions (originally a GNU extension)
>>> should be avoided in tools code ?  A quick git-grep discovered that
>>> xenctrl already contains numerous statement expressions.
>> It is fine (in principle) to be used internally.  Not in a public header
>> for what is supposed to be a clean API.
> I don't understand why this distinction is relevant.  Either the
> compiler supports it, or it doesn't.

There shouldn't be items in a public header which can't be used by all
compilers which might want to compile it.

GCC is not the only compiler liable to encounter this new header file.

>
>>>> violates several principles of least supprise,
>>> This is just invective.
>> /me googles and discovered a new word.  I stand by my statement.
> Well, if you feel so strongly, I won't object to a patch to remove it.

This is exactly why I raise the point now when the ABI is deliberately
changing.  Having said that, it was previously in libxc so anything
went.  I would be happy to submit a patch either to libxc now, or to
libxentoollog later.

>
>>>> As part of the tidyup, we should choose a particular C standard (89,
>>>> probably) and ensure that the API/ABI complies with `gcc -std=c$VER
>>>> -pedantic`.  This will help to provide a consistent API on other
>>>> platforms (I seem to recall an effort to port libvchan to windows.)
>>> -pedantic is certainly a bad idea.
>> Pedantic is absolutely the correct answer.  It will cause gcc to reject
>> any non C compliant statements.
> No, that is not what -pedantic does.  Please RTFM.

Please explain why you believe it to be unsuitable?  It is not perfect,
but is far better than nothing.

~Andrew

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library
  2015-09-21 17:30           ` Andrew Cooper
@ 2015-09-22  8:39             ` Ian Campbell
  0 siblings, 0 replies; 29+ messages in thread
From: Ian Campbell @ 2015-09-22  8:39 UTC (permalink / raw)
  To: Andrew Cooper, Ian Jackson
  Cc: roger.pau, wei.liu2, stefano.stabellini, xen-devel

On Mon, 2015-09-21 at 18:30 +0100, Andrew Cooper wrote:
> On 21/09/15 18:13, Ian Jackson wrote:
> > Andrew Cooper writes ("Re: [Xen-devel] [PATCH RFC tools 1/6] tools:
> > Refactor "xentoollog" into its own library"):
> > > On 21/09/15 17:17, Ian Jackson wrote:
> > > > Do you mean that statement expressions (originally a GNU extension)
> > > > should be avoided in tools code ?  A quick git-grep discovered that
> > > > xenctrl already contains numerous statement expressions.
> > > It is fine (in principle) to be used internally.  Not in a public
> > > header
> > > for what is supposed to be a clean API.
> > I don't understand why this distinction is relevant.  Either the
> > compiler supports it, or it doesn't.
> 
> There shouldn't be items in a public header which can't be used by all
> compilers which might want to compile it.
> 
> GCC is not the only compiler liable to encounter this new header file.
> 
[...]
> Please explain why you believe it to be unsuitable?  It is not perfect,
> but is far better than nothing.

It's a #define, so unless the including application actually uses it the
compiler proper (as opposed to cpp) will never see it.

Ian.

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2015-09-22  8:39 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-10 11:36 [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Campbell
2015-06-10 11:36 ` [PATCH RFC tools 1/6] tools: Refactor "xentoollog" into its own library Ian Campbell
2015-06-11 11:20   ` Andrew Cooper
2015-06-11 11:35     ` Ian Campbell
2015-06-11 12:06       ` Jan Beulich
2015-06-11 12:21         ` Ian Campbell
2015-09-21 16:17     ` Ian Jackson
2015-09-21 17:03       ` Andrew Cooper
2015-09-21 17:13         ` Ian Jackson
2015-09-21 17:30           ` Andrew Cooper
2015-09-22  8:39             ` Ian Campbell
2015-06-10 11:36 ` [PATCH RFC tools 2/6] tools: Link in-tree libvchan users against libxenvchan.so Ian Campbell
2015-06-10 11:36 ` [PATCH RFC tools 3/6] tools: Do not add top-level tools dir to include path Ian Campbell
2015-06-10 11:36 ` [PATCH RFC tools 4/6] tools/libxc: Remove osdep indirection for xc_evtchn Ian Campbell
2015-06-10 11:36 ` [PATCH RFC tools 5/6] tools: Refactor /dev/xen/evtchn wrappers into libxenevtchn Ian Campbell
2015-06-10 16:29   ` David Vrabel
2015-06-11  8:58     ` Ian Campbell
2015-06-10 17:16   ` Andrew Cooper
2015-06-11  9:03     ` Ian Campbell
2015-06-10 11:36 ` [PATCH RFC tools 6/6] Cleanup SHLIBDEPS Ian Campbell
2015-06-10 11:37 ` [PATCH RFC qemu-trad 1/2] qemu-xen-traditional: Use xentoollog as a separate library Ian Campbell
2015-06-10 15:57   ` Ian Jackson
2015-06-11  8:59     ` Ian Campbell
2015-06-10 11:37 ` [PATCH RFC qemu-trad 2/2] qemu-xen-traditional: Use libxenevtchn Ian Campbell
2015-06-10 11:37 ` [PATCH RFC mini-os 1/2] mini-os: Include libxentoollog with libxc Ian Campbell
2015-06-10 11:37 ` [PATCH RFC mini-os 2/2] mini-os: Include libxenevtchn " Ian Campbell
2015-06-10 16:01 ` [PATCH RFC 0/6+2+2] Begin to disentangle libxenctrl and provide some stable libraries Ian Jackson
2015-06-10 16:15   ` Wei Liu
2015-06-11 10:01     ` Antti Kantee

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.