From: Ian Campbell Date: Thu, 28 Jan 2016 11:10:15 +0000 (+0000) Subject: tools: add basic libxendevicemodel with _open and _close. X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=a209ae3747e1d8c809ec5adfeb148cb4fd142ed9;p=people%2Fliuw%2Flibxenctrl-split%2Fxen.git tools: add basic libxendevicemodel with _open and _close. 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 --- diff --git a/.gitignore b/.gitignore index 91f690ceda..e26aa3d6c2 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/tools/Makefile b/tools/Makefile index 7556079961..2896e66875 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -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 \ diff --git a/tools/libs/Makefile b/tools/libs/Makefile index dc5726d00a..deae4aee78 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -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 index 0000000000..07358fc906 --- /dev/null +++ b/tools/libs/devicemodel/Makefile @@ -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 index 0000000000..057ad219b5 --- /dev/null +++ b/tools/libs/devicemodel/core.c @@ -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 . + */ + +#include +#include +#include + +#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 index 0000000000..bcfba4174c --- /dev/null +++ b/tools/libs/devicemodel/include/xendevicemodel.h @@ -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 . + */ +#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 +#include +#include + +#include + +/* Callers who don't care don't need to #include */ +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 index 0000000000..980c429425 --- /dev/null +++ b/tools/libs/devicemodel/libxendevicemodel.map @@ -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 index 0000000000..b1f40c2861 --- /dev/null +++ b/tools/libs/devicemodel/private.h @@ -0,0 +1,33 @@ +#ifndef XENDEVICEMODEL_PRIVATE_H +#define XENDEVICEMODEL_PRIVATE_H + +#include + +#include +#include + +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: + */