From patchwork Wed Sep 11 06:19:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 11140333 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 09F891395 for ; Wed, 11 Sep 2019 06:22:19 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D70D621A4C for ; Wed, 11 Sep 2019 06:22:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D70D621A4C Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i7vzD-0003d2-NJ; Wed, 11 Sep 2019 06:20:15 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i7vzB-0003cw-Pk for xen-devel@lists.xenproject.org; Wed, 11 Sep 2019 06:20:13 +0000 X-Inumbo-ID: 3214ba24-d45c-11e9-b299-bc764e2007e4 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 3214ba24-d45c-11e9-b299-bc764e2007e4; Wed, 11 Sep 2019 06:20:05 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id EDCBEB062; Wed, 11 Sep 2019 06:20:04 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Wed, 11 Sep 2019 08:19:59 +0200 Message-Id: <20190911062001.25931-4-jgross@suse.com> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20190911062001.25931-1-jgross@suse.com> References: <20190911062001.25931-1-jgross@suse.com> Subject: [Xen-devel] [RFC PATCH 3/5] libs: add libxenfs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Ian Jackson , Wei Liu MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the new library libxenfs for access to the hypervisor filesystem. Signed-off-by: Juergen Gross --- tools/Rules.mk | 6 ++ tools/libs/Makefile | 1 + tools/libs/fs/Makefile | 14 +++ tools/libs/fs/core.c | 198 ++++++++++++++++++++++++++++++++++++++++++ tools/libs/fs/include/xenfs.h | 57 ++++++++++++ tools/libs/fs/libxenfs.map | 8 ++ tools/libs/fs/xenfs.pc.in | 10 +++ 7 files changed, 294 insertions(+) create mode 100644 tools/libs/fs/Makefile create mode 100644 tools/libs/fs/core.c create mode 100644 tools/libs/fs/include/xenfs.h create mode 100644 tools/libs/fs/libxenfs.map create mode 100644 tools/libs/fs/xenfs.pc.in diff --git a/tools/Rules.mk b/tools/Rules.mk index cf8935d6a3..60ab97e80f 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -19,6 +19,7 @@ XEN_LIBXENGNTTAB = $(XEN_ROOT)/tools/libs/gnttab XEN_LIBXENCALL = $(XEN_ROOT)/tools/libs/call XEN_LIBXENFOREIGNMEMORY = $(XEN_ROOT)/tools/libs/foreignmemory XEN_LIBXENDEVICEMODEL = $(XEN_ROOT)/tools/libs/devicemodel +XEN_LIBXENFS = $(XEN_ROOT)/tools/libs/fs XEN_LIBXC = $(XEN_ROOT)/tools/libxc XEN_XENLIGHT = $(XEN_ROOT)/tools/libxl # Currently libxlutil lives in the same directory as libxenlight @@ -134,6 +135,11 @@ SHDEPS_libxendevicemodel = $(SHLIB_libxentoollog) $(SHLIB_libxentoolcore) $(SHLI LDLIBS_libxendevicemodel = $(SHDEPS_libxendevicemodel) $(XEN_LIBXENDEVICEMODEL)/libxendevicemodel$(libextension) SHLIB_libxendevicemodel = $(SHDEPS_libxendevicemodel) -Wl,-rpath-link=$(XEN_LIBXENDEVICEMODEL) +CFLAGS_libxenfs = -I$(XEN_LIBXENFS)/include $(CFLAGS_xeninclude) +SHDEPS_libxenfs = $(SHLIB_libxentoollog) $(SHLIB_libxentoolcore) $(SHLIB_xencall) +LDLIBS_libxenfs = $(SHDEPS_libxenfs) $(XEN_LIBXENFS)/libxenfs$(libextension) +SHLIB_libxenfs = $(SHDEPS_libxenfs) -Wl,-rpath-link=$(XEN_LIBXENFS) + # code which compiles against libxenctrl get __XEN_TOOLS__ and # therefore sees the unstable hypercall interfaces. CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_libxenforeignmemory) $(CFLAGS_libxendevicemodel) $(CFLAGS_xeninclude) -D__XEN_TOOLS__ diff --git a/tools/libs/Makefile b/tools/libs/Makefile index 88901e7341..e21fd0516e 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -9,6 +9,7 @@ SUBDIRS-y += gnttab SUBDIRS-y += call SUBDIRS-y += foreignmemory SUBDIRS-y += devicemodel +SUBDIRS-y += fs ifeq ($(CONFIG_RUMP),y) SUBDIRS-y := toolcore diff --git a/tools/libs/fs/Makefile b/tools/libs/fs/Makefile new file mode 100644 index 0000000000..26ac677bcc --- /dev/null +++ b/tools/libs/fs/Makefile @@ -0,0 +1,14 @@ +XEN_ROOT = $(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +MAJOR = 1 +MINOR = 0 +LIBNAME := fs +USELIBS := toollog toolcore call + +SRCS-y += core.c + +include ../libs.mk + +$(PKG_CONFIG_LOCAL): PKG_CONFIG_INCDIR = $(XEN_LIBXENFS)/include +$(PKG_CONFIG_LOCAL): PKG_CONFIG_CFLAGS_LOCAL = $(CFLAGS_xeninclude) diff --git a/tools/libs/fs/core.c b/tools/libs/fs/core.c new file mode 100644 index 0000000000..f202a6bd99 --- /dev/null +++ b/tools/libs/fs/core.c @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2019 SUSE Software Solutions Germany GmbH + * + * 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 . + */ + +#define __XEN_TOOLS__ 1 + +#include +#include +#include + +#include +#include +#include + +#include + +struct xenfs_handle { + xentoollog_logger *logger, *logger_tofree; + unsigned int flags; + xencall_handle *xcall; +}; + +xenfs_handle *xenfs_open(xentoollog_logger *logger, + unsigned open_flags) +{ + xenfs_handle *fshdl = calloc(1, sizeof(*fshdl)); + + if (!fshdl) + return NULL; + + fshdl->flags = open_flags; + fshdl->logger = logger; + fshdl->logger_tofree = NULL; + + if (!fshdl->logger) { + fshdl->logger = fshdl->logger_tofree = + (xentoollog_logger*) + xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); + if (!fshdl->logger) + goto err; + } + + fshdl->xcall = xencall_open(fshdl->logger, 0); + if (!fshdl->xcall) + goto err; + + + return fshdl; + +err: + xtl_logger_destroy(fshdl->logger_tofree); + xencall_close(fshdl->xcall); + free(fshdl); + return NULL; +} + +int xenfs_close(xenfs_handle *fshdl) +{ + if (!fshdl) + return 0; + + xencall_close(fshdl->xcall); + xtl_logger_destroy(fshdl->logger_tofree); + free(fshdl); + return 0; +} + +static void *xenfs_read_any(xenfs_handle *fshdl, const char *path, + unsigned int cmd) +{ + char *buf = NULL, *path_buf = NULL; + int ret; + int sz, path_sz; + + if (!fshdl) { + errno = EBADF; + goto out; + } + + path_sz = strlen(path) + 1; + if (path_sz > XEN_FS_MAX_PATHLEN) + { + errno = ENAMETOOLONG; + goto out; + } + path_buf = xencall_alloc_buffer(fshdl->xcall, path_sz); + if (!path_buf) { + errno = ENOMEM; + goto out; + } + strcpy(path_buf, path); + + for (sz = 4096; sz > 0; sz = ret) { + if (buf) + xencall_free_buffer(fshdl->xcall, buf); + + buf = xencall_alloc_buffer(fshdl->xcall, sz); + if (!buf) { + errno = ENOMEM; + goto out; + } + + ret = xencall5(fshdl->xcall, __HYPERVISOR_filesystem_op, cmd, + (unsigned long)path_buf, path_sz, + (unsigned long)buf, sz); + } + + if (ret < 0) { + errno = -ret; + xencall_free_buffer(fshdl->xcall, buf); + buf = NULL; + goto out; + } + + out: + ret = errno; + xencall_free_buffer(fshdl->xcall, path_buf); + errno = ret; + + return buf; +} + +char *xenfs_read(xenfs_handle *fshdl, const char *path) +{ + char *buf, *ret_buf = NULL; + int ret; + + buf = xenfs_read_any(fshdl, path, XEN_FS_OP_read_contents); + if (buf) + ret_buf = strdup(buf); + + ret = errno; + xencall_free_buffer(fshdl->xcall, buf); + errno = ret; + + return ret_buf; +} + +struct xenfs_dirent *xenfs_readdir(xenfs_handle *fshdl, const char *path, + unsigned int *num_entries) +{ + void *buf, *curr; + int ret; + char *names; + struct xenfs_dirent *ret_buf = NULL; + unsigned int n, name_sz = 0; + struct xen_fs_direntry *entry; + + buf = xenfs_read_any(fshdl, path, XEN_FS_OP_read_dir); + if (!buf) + goto out; + + curr = buf; + for (n = 1;; n++) { + entry = curr; + name_sz += strlen(entry->name) + 1; + if (!entry->off_next) + break; + + curr += entry->off_next; + } + + ret_buf = malloc(n * sizeof(*ret_buf) + name_sz); + if (!ret_buf) + goto out; + + *num_entries = n; + names = (char *)(ret_buf + n); + curr = buf; + for (n = 0; n < *num_entries; n++) { + entry = curr; + ret_buf[n].name = names; + ret_buf[n].is_dir = entry->flags & XEN_FS_ISDIR; + strcpy(names, entry->name); + names += strlen(entry->name) + 1; + curr += entry->off_next; + } + + out: + ret = errno; + xencall_free_buffer(fshdl->xcall, buf); + errno = ret; + + return ret_buf; +} diff --git a/tools/libs/fs/include/xenfs.h b/tools/libs/fs/include/xenfs.h new file mode 100644 index 0000000000..000919ed5f --- /dev/null +++ b/tools/libs/fs/include/xenfs.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2019 SUSE Software Solutions Germany GmbH + * + * 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 XENFS_H +#define XENFS_H + +#include +#include + +#include +#include + +/* Callers who don't care don't need to #include */ +struct xentoollog_logger; + +typedef struct xenfs_handle xenfs_handle; + +struct xenfs_dirent { + char *name; + bool is_dir; +}; + +xenfs_handle *xenfs_open(struct xentoollog_logger *logger, + unsigned int open_flags); +int xenfs_close(xenfs_handle *fshdl); + +/* Returned buffer should be freed via free(). */ +char *xenfs_read(xenfs_handle *fshdl, const char *path); + +/* Returned buffer should be freed via free(). */ +struct xenfs_dirent *xenfs_readdir(xenfs_handle *fshdl, const char *path, + unsigned int *num_entries); + +#endif /* XENFS_H */ + +/* + * 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/fs/libxenfs.map b/tools/libs/fs/libxenfs.map new file mode 100644 index 0000000000..ac42d9163e --- /dev/null +++ b/tools/libs/fs/libxenfs.map @@ -0,0 +1,8 @@ +VERS_1.0 { + global: + xenfs_open; + xenfs_close; + xenfs_read; + xenfs_readdir; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libs/fs/xenfs.pc.in b/tools/libs/fs/xenfs.pc.in new file mode 100644 index 0000000000..ea3c17b253 --- /dev/null +++ b/tools/libs/fs/xenfs.pc.in @@ -0,0 +1,10 @@ +prefix=@@prefix@@ +includedir=@@incdir@@ +libdir=@@libdir@@ + +Name: Xenfs +Description: The Xenfs library for Xen hypervisor +Version: @@version@@ +Cflags: -I${includedir} @@cflagslocal@@ +Libs: @@libsflag@@${libdir} -lxenfs +Requires.private: xentoolcore,xentoollog,xencall