]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
tools: add basic libxendevicemodel with _open and _close.
authorIan Campbell <ian.campbell@citrix.com>
Thu, 28 Jan 2016 11:10:15 +0000 (11:10 +0000)
committerIan Campbell <ian.campbell@citrix.com>
Wed, 10 Feb 2016 12:45:24 +0000 (12:45 +0000)
This library is intended to be a stable interface which device models
(specifically QEMU upstream, it probably isn't worth porting
qemu-traditional over) can rely on in order to avoid a link time
dependency on libxenctrl (which implies needing to rebuild QEMU when
Xen is updated to a new release, which is a pain for distros)

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
.gitignore
tools/Makefile
tools/libs/Makefile
tools/libs/devicemodel/Makefile [new file with mode: 0644]
tools/libs/devicemodel/core.c [new file with mode: 0644]
tools/libs/devicemodel/include/xendevicemodel.h [new file with mode: 0644]
tools/libs/devicemodel/libxendevicemodel.map [new file with mode: 0644]
tools/libs/devicemodel/private.h [new file with mode: 0644]

index 91f690cedab4b5a500ee064f8626d71fc0c458d5..e26aa3d6c2aa0283864421f3da9499e73e1fd6e8 100644 (file)
@@ -91,6 +91,7 @@ config/Tools.mk
 config/Stubdom.mk
 config/Docs.mk
 tools/libs/toollog/headers.chk
+tools/libs/devicemodel/headers.chk
 tools/libs/evtchn/headers.chk
 tools/libs/gnttab/headers.chk
 tools/libs/call/headers.chk
index 7556079961435e6a8c6d1b1f02bec974a9cbc32e..2896e668759306dede38190a9c27c8e0c8d097a8 100644 (file)
@@ -262,6 +262,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find
                -I$(XEN_ROOT)/tools/libs/evtchn/include \
                -I$(XEN_ROOT)/tools/libs/gnttab/include \
                -I$(XEN_ROOT)/tools/libs/foreignmemory/include \
+               -I$(XEN_ROOT)/tools/libs/devicemodel/include \
                -I$(XEN_ROOT)/tools/libxc/include \
                -I$(XEN_ROOT)/tools/xenstore/include \
                -I$(XEN_ROOT)/tools/xenstore/compat/include \
@@ -271,6 +272,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find
                -L$(XEN_ROOT)/tools/libs/evtchn \
                -L$(XEN_ROOT)/tools/libs/gnttab \
                -L$(XEN_ROOT)/tools/libs/foreignmemory \
+               -L$(XEN_ROOT)/tools/libs/devicemodel \
                -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/toollog \
                -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/evtchn \
                -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/gnttab \
index dc5726d00ab8fa2a100536137e64a61c4a832e1a..deae4aee78f5dbcabd66713112efb648b98ec7c7 100644 (file)
@@ -7,5 +7,6 @@ SUBDIRS-y += evtchn
 SUBDIRS-y += gnttab
 SUBDIRS-y += call
 SUBDIRS-y += foreignmemory
+SUBDIRS-y += devicemodel
 
 all clean install distclean: %: subdirs-%
diff --git a/tools/libs/devicemodel/Makefile b/tools/libs/devicemodel/Makefile
new file mode 100644 (file)
index 0000000..07358fc
--- /dev/null
@@ -0,0 +1,70 @@
+XEN_ROOT = $(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+MAJOR    = 1
+MINOR    = 0
+SHLIB_LDFLAGS += -Wl,--version-script=libxendevicemodel.map
+
+CFLAGS   += -Werror -Wmissing-prototypes
+CFLAGS   += -I./include $(CFLAGS_xeninclude)
+CFLAGS   += $(CFLAGS_libxentoollog)
+CFLAGS   += $(CFLAGS_libxencall)
+
+LDLIBS   += $(LDLIBS_libxentoollog)
+LDLIBS   += $(LDLIBS_libxencall)
+
+SRCS-y   += core.c
+
+LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y))
+PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y))
+
+LIB := libxendevicemodel.a
+ifneq ($(nosharedlibs),y)
+LIB += libxendevicemodel.so
+endif
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build:
+       $(MAKE) libs
+
+.PHONY: libs
+libs: headers.chk $(LIB)
+
+headers.chk: $(wildcard include/*.h)
+
+libxendevicemodel.a: $(LIB_OBJS)
+       $(AR) rc $@ $^
+
+libxendevicemodel.so: libxendevicemodel.so.$(MAJOR)
+       $(SYMLINK_SHLIB) $< $@
+libxendevicemodel.so.$(MAJOR): libxendevicemodel.so.$(MAJOR).$(MINOR)
+       $(SYMLINK_SHLIB) $< $@
+
+libxendevicemodel.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxendevicemodel.map
+       $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxendevicemodel.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(LDLIBS) $(APPEND_LDFLAGS)
+
+.PHONY: install
+install: build
+       $(INSTALL_DIR) $(DESTDIR)$(libdir)
+       $(INSTALL_DIR) $(DESTDIR)$(includedir)
+       $(INSTALL_SHLIB) libxendevicemodel.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
+       $(INSTALL_DATA) libxendevicemodel.a $(DESTDIR)$(libdir)
+       $(SYMLINK_SHLIB) libxendevicemodel.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxendevicemodel.so.$(MAJOR)
+       $(SYMLINK_SHLIB) libxendevicemodel.so.$(MAJOR) $(DESTDIR)$(libdir)/libxendevicemodel.so
+       $(INSTALL_DATA) include/xendevicemodel.h $(DESTDIR)$(includedir)
+
+.PHONY: TAGS
+TAGS:
+       etags -t *.c *.h
+
+.PHONY: clean
+clean:
+       rm -rf *.rpm $(LIB) *~ $(DEPS) $(LIB_OBJS) $(PIC_OBJS)
+       rm -f libxendevicemodel.so.$(MAJOR).$(MINOR) libxendevicemodel.so.$(MAJOR)
+       rm -f headers.chk
+
+.PHONY: distclean
+distclean: clean
diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
new file mode 100644 (file)
index 0000000..057ad21
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "private.h"
+
+xendevicemodel_handle *xendevicemodel_open(struct xentoollog_logger *logger,
+                                           domid_t domid,
+                                           unsigned open_flags,
+                                           int *r_restricted)
+{
+    xendevicemodel_handle *dm = malloc(sizeof(*dm));
+    int rc;
+    bool require_restricted = open_flags & XENDEVICEMODEL_OPENFLAG_RESTRICTED;
+
+    if (!dm) return NULL;
+
+    dm->domid = domid;
+
+    dm->logger = logger;
+    dm->logger_tofree = NULL;
+
+    if (!dm->logger) {
+        dm->logger = dm->logger_tofree =
+            (xentoollog_logger*)
+            xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
+        if (!dm->logger) goto err;
+    }
+
+    dm->call = xencall_open(dm->logger, 0);
+    if ( !dm->call )
+    {
+        LOGE(ERROR, "failed to open xencall handle");
+        goto err;
+    }
+
+       rc = xencall_restrict_target(dm->call, dm->domid);
+    if ( rc < 0 )
+    {
+        if ( require_restricted )
+            LOGE(ERROR, "fatal error restricting xencall handle");
+        else
+            LOGE(WARN, "unable to restrict xencall handle, continuing");
+        if ( require_restricted ) goto err;
+        if ( r_restricted ) *r_restricted = errno;
+    } else if ( r_restricted )
+        *r_restricted = 0;
+
+    return dm;
+
+err:
+    xencall_close(dm->call);
+    xtl_logger_destroy(dm->logger_tofree);
+    free(dm);
+    return NULL;
+}
+
+int xendevicemodel_close(xendevicemodel_handle *dm)
+{
+    int rc;
+
+    if ( !dm )
+        return 0;
+
+    rc = xencall_close(dm->call);
+    if ( rc )
+        LOGE(ERROR, "failed to close xencall handle");
+    xtl_logger_destroy(dm->logger_tofree);
+    free(dm);
+    return rc;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/devicemodel/include/xendevicemodel.h b/tools/libs/devicemodel/include/xendevicemodel.h
new file mode 100644 (file)
index 0000000..bcfba41
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef XENDEVICEMODEL_H
+#define XENDEVICEMODEL_H
+
+/*
+ * This library allows you to make arbitrary hypercalls (subject to
+ * sufficient permission for the process and the domain itself). Note
+ * that while the library interface is stable the hypercalls are
+ * subject to their own rules.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include <xen/xen.h>
+
+/* Callers who don't care don't need to #include <xentoollog.h> */
+struct xentoollog_logger;
+
+typedef struct xendevicemodel_handle xendevicemodel_handle;
+
+#define XENDEVICEMODEL_OPENFLAG_RESTRICTED (1U<<0)
+
+/*
+ * Return a handle onto the hypercall driver.  Logs errors.
+ *
+ * Returns NULL on failure and sets errno.
+ *
+ * The library will attempt to restrict any underlying interfaces such
+ * that they are only capable of operating on the target domain.
+ * These restrictions will be implemented by the platform in a way
+ * which cannot be circumvented by a userspace process. Further
+ * privilege drops (such as using setuid(2) etc) may also be required
+ * to prevent a compromised process from simply opening a second
+ * handle.
+ *
+ * If r_restricted is not NULL then on success *r_restricted will be
+ * set to indicate if the resulting handle was successfully limited to
+ * only operate on the given domain by setting it to 0 if the handle
+ * is restricted or to an errno value if it was not.
+ *
+ * If open_flags contains XENDEVICEMODEL_OPENFLAG_RESTRICTED then
+ * failure to restrict will be fatal. xendevicemodel_open() will
+ * return NULL setting errno to EPERM. In this case *r_restricted will
+ * not be updated.
+ */
+xendevicemodel_handle *xendevicemodel_open(struct xentoollog_logger *logger,
+                                           domid_t domid,
+                                           unsigned open_flags,
+                                           int *r_restricted);
+
+/*
+ * Close a handle previously allocated with xendevicemodel_open().
+ */
+int xendevicemodel_close(xendevicemodel_handle *dm);
+
+#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/libs/devicemodel/libxendevicemodel.map b/tools/libs/devicemodel/libxendevicemodel.map
new file mode 100644 (file)
index 0000000..980c429
--- /dev/null
@@ -0,0 +1,6 @@
+VERS_1.0 {
+       global:
+               xendevicemodel_open;
+               xendevicemodel_close;
+       local: *; /* Do not expose anything by default */
+};
diff --git a/tools/libs/devicemodel/private.h b/tools/libs/devicemodel/private.h
new file mode 100644 (file)
index 0000000..b1f40c2
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef XENDEVICEMODEL_PRIVATE_H
+#define XENDEVICEMODEL_PRIVATE_H
+
+#include <xentoollog.h>
+
+#include <xendevicemodel.h>
+#include <xencall.h>
+
+struct xendevicemodel_handle {
+    xentoollog_logger *logger, *logger_tofree;
+    unsigned flags;
+    domid_t domid;
+    xencall_handle *call;
+};
+
+/* requires xendevicemodel_handle *dm in scope. level omites the XTL_ prefix. */
+#define LOGEV(level, errnoval,fmt, ...)                     \
+    xtl_log(dm->logger, XTL_##level, errnoval, "xendevicemodel", \
+            "dom%u: " fmt, dm->domid, ##__VA_ARGS__)
+#define LOGE(level, fmt, ...) LOGEV(level, errno, fmt, ##__VA_ARGS__)
+#define LOG(level, fmt, ...)  LOGEV(level, -1, fmt, ##__VA_ARGS__)
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */