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@citrix.com>
Signed-off-by: Ian Jackson <ian.jackson.citrix.com>
This commit is contained in:
Ian Campbell committed 2010-12-03 09:36:47 +00:00
1 parent 0ccceacd05
commit c89c726db9
4 files changed
+291 -2

No files matched your search

+8 -1
View File
@@ -92,6 +92,10 @@ ifneq ($(stubdom),y)
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.$(MAJOR).$(MINOR)
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): COMPRESSION_LIBS = $(call zlib-options,l)
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)
+62 -1
View File
@@ -27,10 +27,22 @@
#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
* -1 - on error
@@ -38,16 +50,65 @@
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,
+206
View File
@@ -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:
*/
+15
View File
@@ -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;
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.