# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1291369007 0
# Node ID a4d3be2e38ea883d3d2404078adc94960692d022
# Parent fd025a5043072ae2684f55e5c4ffdb86f6cda042
libxc: add abitility to dynamically load osdep.
Add a dummy backend which always returns ENOSYS. Mainly as a compile
time testbed rather than because it is a useful backend.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
diff -r fd025a504307 -r a4d3be2e38ea tools/libxc/Makefile
--- a/tools/libxc/Makefile Fri Dec 03 09:36:47 2010 +0000
+++ b/tools/libxc/Makefile Fri Dec 03 09:36:47 2010 +0000
@@ -92,6 +92,10 @@ LIB += libxenguest.so libxenguest.so.$(M
LIB += libxenguest.so libxenguest.so.$(MAJOR) libxenguest.so.$(MAJOR).$(MINOR)
endif
+ifneq ($(stubdom),y)
+LIB += xenctrl_osdep_ENOSYS.so
+endif
+
.PHONY: all
all: build
@@ -148,7 +152,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(
ln -sf $< $@
libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
- $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG)
-Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(PTHREAD_LIBS)
+ $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG)
-Wl,libxenctrl.so.$(MAJOR) -ldl $(SHLIB_LDFLAGS) -o $@ $^ $(PTHREAD_LIBS)
# libxenguest
@@ -186,5 +190,8 @@ libxenguest.so.$(MAJOR).$(MINOR): $(GUES
libxenguest.so.$(MAJOR).$(MINOR): $(GUEST_PIC_OBJS) libxenctrl.so
$(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG)
-Wl,libxenguest.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(GUEST_PIC_OBJS)
$(COMPRESSION_LIBS) -lz -lxenctrl $(PTHREAD_LIBS)
+xenctrl_osdep_ENOSYS.so: xenctrl_osdep_ENOSYS.o libxenctrl.so
+ $(CC) -g $(CFLAGS) $(LDFLAGS) $(SHLIB_LDFLAGS) -o $@
xenctrl_osdep_ENOSYS.o -lxenctrl
+
-include $(DEPS)
diff -r fd025a504307 -r a4d3be2e38ea tools/libxc/xc_private.c
--- a/tools/libxc/xc_private.c Fri Dec 03 09:36:47 2010 +0000
+++ b/tools/libxc/xc_private.c Fri Dec 03 09:36:47 2010 +0000
@@ -27,9 +27,21 @@
#include <pthread.h>
#include <assert.h>
+#ifndef __MINIOS__
+#include <dlfcn.h>
+#endif
+
+#define XENCTRL_OSDEP "XENCTRL_OSDEP"
+
/*
* Returns a (shallow) copy of the xc_osdep_info_t for the
* active OS interface.
+ *
+ * On success a handle to the relevant library is opened. The user
+ * must subsequently call xc_osdep_put_info() when it is
+ * finished with the library.
+ *
+ * Logs IFF xch != NULL.
*
* Returns:
* 0 - on success
@@ -38,16 +50,65 @@ static int xc_osdep_get_info(xc_interfac
static int xc_osdep_get_info(xc_interface *xch, xc_osdep_info_t *info)
{
int rc = -1;
+#ifndef __MINIOS__
+ const char *lib = getenv(XENCTRL_OSDEP);
+ xc_osdep_info_t *pinfo;
+ void *dl_handle = NULL;
- *info = xc_osdep_info;
+ if ( lib != NULL )
+ {
+ if ( getuid() != geteuid() )
+ {
+ if ( xch ) ERROR("cannot use %s=%s with setuid application",
XENCTRL_OSDEP, lib);
+ abort();
+ }
+ if ( getgid() != getegid() )
+ {
+ if ( xch ) ERROR("cannot use %s=%s with setgid application",
XENCTRL_OSDEP, lib);
+ abort();
+ }
+
+ dl_handle = dlopen(lib, RTLD_LAZY|RTLD_LOCAL);
+ if ( !dl_handle )
+ {
+ if ( xch ) ERROR("unable to open osdep library %s: %s", lib,
dlerror());
+ goto out;
+ }
+
+ pinfo = dlsym(dl_handle, "xc_osdep_info");
+ if ( !pinfo )
+ {
+ if ( xch ) ERROR("unable to find xc_osinteface_info in %s: %s",
lib, dlerror());
+ goto out;
+ }
+
+ *info = *pinfo;
+ info->dl_handle = dl_handle;
+ }
+ else
+#endif
+ {
+ *info = xc_osdep_info;
+ info->dl_handle = NULL;
+ }
rc = 0;
+
+#ifndef __MINIOS__
+out:
+ if ( dl_handle && rc == -1 )
+ dlclose(dl_handle);
+#endif
return rc;
}
static void xc_osdep_put(xc_osdep_info_t *info)
{
+#ifndef __MINIOS__
+ if ( info->dl_handle )
+ dlclose(info->dl_handle);
+#endif
}
static struct xc_interface_core *xc_interface_open_common(xentoollog_logger
*logger,
diff -r fd025a504307 -r a4d3be2e38ea tools/libxc/xenctrl_osdep_ENOSYS.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/libxc/xenctrl_osdep_ENOSYS.c Fri Dec 03 09:36:47 2010 +0000
@@ -0,0 +1,206 @@
+/* Dummy backend which just logs and returns ENOSYS. */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <stdlib.h>
+
+#include "xenctrl.h"
+#include "xenctrlosdep.h"
+
+#define IPRINTF(_x, _f, _a...) xc_osdep_log(_x,XTL_INFO,0, _f , ## _a)
+
+#define ERROR(_x, _m, _a...) xc_osdep_log(_x,XTL_ERROR,XC_INTERNAL_ERROR,_m ,
## _a )
+#define PERROR(_x, _m, _a...) xc_osdep_log(_x,XTL_ERROR,XC_INTERNAL_ERROR,_m \
+ " (%d = %s)", ## _a , errno, xc_strerror(xch, errno))
+
+static xc_osdep_handle ENOSYS_privcmd_open(xc_interface *xch)
+{
+ IPRINTF(xch, "ENOSYS_privcmd: opening handle %p\n", (void *)1);
+ return (xc_osdep_handle)1; /*dummy*/
+}
+
+static int ENOSYS_privcmd_close(xc_interface *xch, xc_osdep_handle h)
+{
+ IPRINTF(xch, "ENOSYS_privcmd: closing handle %p\n", h);
+ return 0;
+}
+
+static int ENOSYS_privcmd_hypercall(xc_interface *xch, xc_osdep_handle h,
privcmd_hypercall_t *hypercall)
+{
+ IPRINTF(xch, "ENOSYS_privcmd %p: hypercall:
%02lld(%#llx,%#llx,%#llx,%#llx,%#llx,%#llx)\n",
+ h, hypercall->op,
+ hypercall->arg[0], hypercall->arg[1], hypercall->arg[2],
+ hypercall->arg[3], hypercall->arg[4], hypercall->arg[5]);
+ return -ENOSYS;
+}
+
+static void *ENOSYS_privcmd_map_foreign_batch(xc_interface *xch,
xc_osdep_handle h, uint32_t dom, int prot,
+ xen_pfn_t *arr, int num)
+{
+ IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_batch: dom%d prot %#x arr %p
num %d\n", h, dom, prot, arr, num);
+ return MAP_FAILED;
+}
+
+static void *ENOSYS_privcmd_map_foreign_bulk(xc_interface *xch,
xc_osdep_handle h, uint32_t dom, int prot,
+ const xen_pfn_t *arr, int *err, unsigned
int num)
+{
+ IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_buld: dom%d prot %#x arr %p
err %p num %d\n", h, dom, prot, arr, err, num);
+ return MAP_FAILED;
+}
+
+static void *ENOSYS_privcmd_map_foreign_range(xc_interface *xch,
xc_osdep_handle h, uint32_t dom, int size, int prot,
+ unsigned long mfn)
+{
+ IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_range: dom%d size %#x prot
%#x mfn %ld\n", h, dom, size, prot, mfn);
+ return MAP_FAILED;
+}
+
+static void *ENOSYS_privcmd_map_foreign_ranges(xc_interface *xch,
xc_osdep_handle h, uint32_t dom, size_t size, int prot,
+ size_t chunksize, privcmd_mmap_entry_t
entries[],
+ int nentries)
+{
+ IPRINTF(xch, "ENOSYS_privcmd %p: map_foreign_ranges: dom%d size %zd prot
%#x chunksize %zd entries %p num %d\n", h, dom, size, prot, chunksize, entries,
nentries);
+ return MAP_FAILED;
+}
+
+static struct xc_osdep_ops ENOSYS_privcmd_ops =
+{
+ .open = &ENOSYS_privcmd_open,
+ .close = &ENOSYS_privcmd_close,
+ .u.privcmd = {
+ .hypercall = &ENOSYS_privcmd_hypercall,
+
+ .map_foreign_batch = &ENOSYS_privcmd_map_foreign_batch,
+ .map_foreign_bulk = &ENOSYS_privcmd_map_foreign_bulk,
+ .map_foreign_range = &ENOSYS_privcmd_map_foreign_range,
+ .map_foreign_ranges = &ENOSYS_privcmd_map_foreign_ranges,
+ }
+};
+
+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 %p\n", h);
+ return 0;
+}
+
+static int ENOSYS_evtchn_fd(xc_interface *xce, xc_osdep_handle h)
+{
+ IPRINTF(xce, "ENOSYS_fd %p: 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 %p: 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 %p: 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 %p: 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 %p: 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 %p: 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 %p: 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 %p: 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;
+
+ if (getenv("ENOSYS") == NULL)
+ {
+ PERROR(xch, "ENOSYS: not configured\n");
+ return NULL;
+ }
+
+ switch ( type )
+ {
+ case XC_OSDEP_PRIVCMD:
+ ops = &ENOSYS_privcmd_ops;
+ break;
+ case XC_OSDEP_EVTCHN:
+ ops = &ENOSYS_evtchn_ops;
+ break;
+ default:
+ ops = NULL;
+ break;
+ }
+
+ IPRINTF(xch, "ENOSYS_osdep_init: initialising handle ops at %p\n", ops);
+
+ return ops;
+}
+
+xc_osdep_info_t xc_osdep_info = {
+ .name = "Pessimistic ENOSYS OS interface",
+ .init = &ENOSYS_osdep_init,
+ .fake = 1,
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r fd025a504307 -r a4d3be2e38ea tools/libxc/xenctrlosdep.h
--- a/tools/libxc/xenctrlosdep.h Fri Dec 03 09:36:47 2010 +0000
+++ b/tools/libxc/xenctrlosdep.h Fri Dec 03 09:36:47 2010 +0000
@@ -23,6 +23,18 @@
* This interface defines the interactions between the Xen control
* libraries and the OS facilities used to communicate with the
* hypervisor.
+ *
+ * It is possible to override the default (native) implementation by
+ * setting the XENCTRL_OSDEP environment variable to point to a
+ * plugin library. Userspace can use this facility to intercept
+ * hypervisor operations. This can be used e.g. to implement a
+ * userspace simulator for Xen hypercalls.
+ *
+ * The plugin must contain a data structure:
+ * xc_osdep_info_t xc_osdep_info;
+ *
+ * xc_osdep_init:
+ * Must return a suitable struct xc_osdep_ops pointer or NULL on failure.
*/
#ifndef XC_OSDEP_H
@@ -125,6 +137,9 @@ struct xc_osdep_info
/* True if this interface backs onto a fake Xen. */
int fake;
+
+ /* For internal use by loader. */
+ void *dl_handle;
};
typedef struct xc_osdep_info xc_osdep_info_t;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|