[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 23 of 25] libxc: add abitility to dynamically load osdep
# 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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |