[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


 


Rackspace

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