From patchwork Wed Sep 11 06:19:57 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: 11140325 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 0F4581395 for ; Wed, 11 Sep 2019 06:21:48 +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 E83E021A4C for ; Wed, 11 Sep 2019 06:21:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E83E021A4C 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 1i7vzI-0003dk-0Q; Wed, 11 Sep 2019 06:20:20 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i7vzG-0003de-Q5 for xen-devel@lists.xenproject.org; Wed, 11 Sep 2019 06:20:18 +0000 X-Inumbo-ID: 3214bdbc-d45c-11e9-b299-bc764e2007e4 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 3214bdbc-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 CDDAEAF54; 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:57 +0200 Message-Id: <20190911062001.25931-2-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 1/5] docs: add feature document for Xen hypervisor sysfs-like support 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 , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" On the 2019 Xen developer summit there was agreement that the Xen hypervisor should gain support for a hierarchical name-value store similar to the Linux kernel's sysfs. In the beginning there should only be basic support: entries can be added from the hypervisor itself only, there is a simple hypercall interface to read the data. Add a feature document for setting the base of a discussion regarding the desired functionality and the entries to add. Signed-off-by: Juergen Gross --- docs/features/hypervisorfs.pandoc | 110 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docs/features/hypervisorfs.pandoc diff --git a/docs/features/hypervisorfs.pandoc b/docs/features/hypervisorfs.pandoc new file mode 100644 index 0000000000..e13a3c9b0a --- /dev/null +++ b/docs/features/hypervisorfs.pandoc @@ -0,0 +1,110 @@ +% Hypervisor FS +% Revision 1 + +\clearpage + +# Basics +---------------- --------------------- + Status: e.g. **Supported** + + Architectures: all + + Components: Hypervisor, toolstack +---------------- --------------------- + +# Overview + +The Hypervisor FS is a hierarchical name-value store for reporting +information to guests, especially dom0. It is similar to the Linux +kernel's sysfs, but without the functionality to directly alter +entries values. Entries and directories are created by the hypervisor, +while the toolstack is able to use a hypercall to query the entry +values. + +# User details + +With: + + xenfs --ls + +the user can list the entries of a specific path of the FS. Using: + + xenfs --cat + +the content of an entry can be retrieved. + +The FS structure is: + + / + buildinfo/ directory containing build-time data + config contents of .config file used to build Xen + cpu-bugs/ x86: directory of cpu bug information + l1tf "Vulnerable" or "Not vulnerable" + mds "Vulnerable" or "Not vulnerable" + meltdown "Vulnerable" or "Not vulnerable" + spec-store-bypass "Vulnerable" or "Not vulnerable" + spectre-v1 "Vulnerable" or "Not vulnerable" + spectre-v2 "Vulnerable" or "Not vulnerable" + mitigations/ directory of mitigation settings + bti-thunk "N/A", "RETPOLINE", "LFENCE" or "JMP" + spec-ctrl "No", "IBRS+" or IBRS-" + ibpb "No" or "Yes" + l1d-flush "No" or "Yes" + md-clear "No" or "VERW" + l1tf-barrier "No" or "Yes" + active-hvm/ directory for mitigations active in hvm doamins + msr-spec-ctrl "No" or "Yes" + rsb "No" or "Yes" + eager-fpu "No" or "Yes" + md-clear "No" or "Yes" + active-pv/ directory for mitigations active in pv doamins + msr-spec-ctrl "No" or "Yes" + rsb "No" or "Yes" + eager-fpu "No" or "Yes" + md-clear "No" or "Yes" + xpti "No" or list of "dom0", "domU", "PCID on" + l1tf-shadow "No" or list of "dom0", "domU" + parameters/ directory with hypervisor parameter values + (boot/runtime parameters) + +# Technical details + +Access to the hypervisor filesystem is done via the stable new hypercall +__HYPERVISOR_filesystem_op. + +* hypercall interface specification + * `xen/include/public/filesystem.h` +* hypervisor internal files + * `xen/include/xen/filesystem.h` + * `xen/common/filesystem.c` +* `libxenfs` + * `tools/libs/libxenfs/*` +* `xenfs` + * `tools/misc/xenfs.c` + +# Testing + +Any new parameters or hardware mitigations should be verified to show up +correctly in the filesystem. + +# Areas for improvement + +* More detailed access rights +* Entries per domain and/or per cpupool +* Possibility to modify values via filesystem access + +# Known issues + +* None + +# References + +* None + +# History + +------------------------------------------------------------------------ +Date Revision Version Notes +---------- -------- -------- ------------------------------------------- +2019-08-29 1 Xen 4.13 Document written +---------- -------- -------- ------------------------------------------- From patchwork Wed Sep 11 06:19:58 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: 11140335 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 DBFB614DB for ; Wed, 11 Sep 2019 06:22:26 +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 B660821A4C for ; Wed, 11 Sep 2019 06:22:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B660821A4C 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 1i7vzX-0003ii-6d; Wed, 11 Sep 2019 06:20:35 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i7vzV-0003iE-R0 for xen-devel@lists.xenproject.org; Wed, 11 Sep 2019 06:20:33 +0000 X-Inumbo-ID: 32145fa2-d45c-11e9-978d-bc764e2007e4 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 32145fa2-d45c-11e9-978d-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 DBA73AF5B; 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:58 +0200 Message-Id: <20190911062001.25931-3-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 2/5] xen: add basic hypervisor filesystem support 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 , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Jan Beulich , Volodymyr Babchuk , =?utf-8?q?Roger_Pau_Monn?= =?utf-8?q?=C3=A9?= MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the infrastructure for the hypervisor filesystem. This includes the hypercall interface and the base functions for entry creation, deletion and modification. Signed-off-by: Juergen Gross --- xen/arch/arm/traps.c | 1 + xen/arch/x86/hvm/hypercall.c | 1 + xen/arch/x86/hypercall.c | 1 + xen/arch/x86/pv/hypercall.c | 1 + xen/common/Makefile | 1 + xen/common/filesystem.c | 270 ++++++++++++++++++++++++++++++++++++++++ xen/include/public/errno.h | 1 + xen/include/public/filesystem.h | 98 +++++++++++++++ xen/include/public/xen.h | 1 + xen/include/xen/filesystem.h | 34 +++++ xen/include/xen/hypercall.h | 8 ++ 11 files changed, 417 insertions(+) create mode 100644 xen/common/filesystem.c create mode 100644 xen/include/public/filesystem.h create mode 100644 xen/include/xen/filesystem.h diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c index a3b961bd06..44b027951f 100644 --- a/xen/arch/arm/traps.c +++ b/xen/arch/arm/traps.c @@ -1401,6 +1401,7 @@ static arm_hypercall_t arm_hypercall_table[] = { #ifdef CONFIG_ARGO HYPERCALL(argo_op, 5), #endif + HYPERCALL(filesystem_op, 5), }; #ifndef NDEBUG diff --git a/xen/arch/x86/hvm/hypercall.c b/xen/arch/x86/hvm/hypercall.c index 33dd2d99d2..936ad10add 100644 --- a/xen/arch/x86/hvm/hypercall.c +++ b/xen/arch/x86/hvm/hypercall.c @@ -144,6 +144,7 @@ static const hypercall_table_t hvm_hypercall_table[] = { #endif HYPERCALL(xenpmu_op), COMPAT_CALL(dm_op), + HYPERCALL(filesystem_op), HYPERCALL(arch_1) }; diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c index d483dbaa6b..640347e514 100644 --- a/xen/arch/x86/hypercall.c +++ b/xen/arch/x86/hypercall.c @@ -73,6 +73,7 @@ const hypercall_args_t hypercall_args_table[NR_hypercalls] = ARGS(hvm_op, 2), ARGS(dm_op, 3), #endif + ARGS(filesystem_op, 5), ARGS(mca, 1), ARGS(arch_1, 1), }; diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c index 0c84c0b3a0..27c8e893c6 100644 --- a/xen/arch/x86/pv/hypercall.c +++ b/xen/arch/x86/pv/hypercall.c @@ -84,6 +84,7 @@ const hypercall_table_t pv_hypercall_table[] = { HYPERCALL(hvm_op), COMPAT_CALL(dm_op), #endif + HYPERCALL(filesystem_op), HYPERCALL(mca), HYPERCALL(arch_1), }; diff --git a/xen/common/Makefile b/xen/common/Makefile index 62b34e69e9..be43757dff 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -11,6 +11,7 @@ obj-y += domain.o obj-y += event_2l.o obj-y += event_channel.o obj-y += event_fifo.o +obj-y += filesystem.o obj-$(CONFIG_CRASH_DEBUG) += gdbstub.o obj-$(CONFIG_GRANT_TABLE) += grant_table.o obj-y += guestcopy.o diff --git a/xen/common/filesystem.c b/xen/common/filesystem.c new file mode 100644 index 0000000000..d833992ab1 --- /dev/null +++ b/xen/common/filesystem.c @@ -0,0 +1,270 @@ +/****************************************************************************** + * + * filesystem.c + * + * Simple sysfs-like file system for the hypervisor. + */ + +#include +#include +#include +#include +#include + +static DEFINE_SPINLOCK(fs_lock); + +struct fs_dir fs_root = { + .list = LIST_HEAD_INIT(fs_root.list), +}; + +static struct fs_entry fs_root_entry = { + .type = fs_type_dir, + .name = "", + .list = LIST_HEAD_INIT(fs_root_entry.list), + .parent = &fs_root, + .dir = &fs_root, +}; + +static int fs_add_entry(struct fs_dir *parent, struct fs_entry *new) +{ + int ret = -ENOENT; + struct list_head *l; + + if ( !new->content ) + return -EINVAL; + + spin_lock(&fs_lock); + + list_for_each ( l, &parent->list ) + { + struct fs_entry *e = list_entry(l, struct fs_entry, list); + int cmp = strcmp(e->name, new->name); + + if ( cmp < 0 ) + { + ret = 0; + list_add_tail(&new->list, l); + break; + } + if ( cmp == 0 ) + { + ret = -EEXIST; + break; + } + } + + if ( ret == -ENOENT ) + { + ret = 0; + list_add_tail(&new->list, &parent->list); + } + + if ( !ret ) + { + unsigned int sz = strlen(new->name) + 1; + + parent->content_size += sizeof(struct xen_fs_direntry) + ROUNDUP(sz, 4); + new->parent = parent; + } + + spin_unlock(&fs_lock); + + return ret; +} + +int fs_new_entry_any(struct fs_dir *parent, const char *name, + enum fs_entry_type type, void *content) +{ + int ret = -ENOMEM; + struct fs_entry *new = xzalloc(struct fs_entry); + + if ( !new ) + return ret; + + new->name = name; + new->type = type; + new->content = content; + + ret = fs_add_entry(parent, new); + + if ( ret ) + xfree(new); + + return ret; +} + +int fs_new_entry(struct fs_dir *parent, const char *name, const char *val) +{ + return fs_new_entry_any(parent, name, fs_type_string, (void *)val); +} + +int fs_new_dir(struct fs_dir *parent, const char *name, struct fs_dir *dir) +{ + if ( !dir ) + dir = xzalloc(struct fs_dir); + + return fs_new_entry_any(parent, name, fs_type_dir, dir); +} + +static int fs_get_path_user(char *buf, XEN_GUEST_HANDLE_PARAM(void) uaddr, + unsigned long len) +{ + if ( len > XEN_FS_MAX_PATHLEN ) + return -EINVAL; + + if ( copy_from_guest(buf, uaddr, len) ) + return -EFAULT; + + buf[len - 1] = 0; + + return 0; +} + +static struct fs_entry *fs_get_entry_rel(struct fs_entry *dir, char *path) +{ + char *slash; + struct fs_entry *entry; + struct list_head *l; + unsigned int name_len; + + if ( *path == 0 ) + return dir; + + if ( dir->type != fs_type_dir ) + return NULL; + + slash = strchr(path, '/'); + if ( !slash ) + slash = strchr(path, '\0'); + name_len = slash - path; + + list_for_each ( l, &dir->dir->list ) + { + int cmp; + + entry = list_entry(l, struct fs_entry, list); + cmp = strncmp(path, entry->name, name_len); + if ( cmp < 0 ) + return NULL; + if ( cmp > 0 ) + continue; + if ( strlen(entry->name) == name_len ) + return *slash ? fs_get_entry_rel(entry, slash + 1) : entry; + } + + return NULL; +} + +struct fs_entry *fs_get_entry(char *path) +{ + if ( path[0] != '/' ) + return NULL; + + return fs_get_entry_rel(&fs_root_entry, path + 1); +} + +long do_filesystem_op(unsigned int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg1, unsigned long arg2, + XEN_GUEST_HANDLE_PARAM(void) arg3, unsigned long arg4) +{ + int ret; + struct fs_entry *entry; + unsigned int len; + static char path[XEN_FS_MAX_PATHLEN]; + + if ( !is_control_domain(current->domain) && + !is_hardware_domain(current->domain) ) + return -EPERM; + + spin_lock(&fs_lock); + + ret = fs_get_path_user(path, arg1, arg2); + if ( ret ) + goto out; + + entry = fs_get_entry(path); + if ( !entry ) + { + ret = -ENOENT; + goto out; + } + + switch ( cmd ) + { + case XEN_FS_OP_read_contents: + if ( entry->type == fs_type_dir ) + { + ret = -EISDIR; + break; + } + + len = strlen(entry->val) + 1; + if ( len > arg4 ) + { + ret = len; + break; + } + + if ( copy_to_guest(arg3, entry->val, len) ) + ret = -EFAULT; + + break; + + case XEN_FS_OP_read_dir: + { + struct list_head *l; + + if ( entry->type != fs_type_dir ) + { + ret = -ENOTDIR; + break; + } + + len = entry->dir->content_size; + if ( len > arg4 ) + { + ret = len; + break; + } + + list_for_each ( l, &entry->dir->list ) + { + struct xen_fs_direntry direntry; + struct fs_entry *e = list_entry(l, struct fs_entry, list); + unsigned int e_len = strlen(e->name) + 1; + + e_len = sizeof(direntry) + ROUNDUP(e_len, 4); + direntry.flags = (e->type == fs_type_dir) ? XEN_FS_ISDIR : 0; + direntry.off_next = list_is_last(l, &entry->dir->list) ? 0 : e_len; + direntry.content_len = (e->type == fs_type_dir) + ? e->dir->content_size + : strlen(e->val) + 1; + if ( copy_to_guest(arg3, &direntry, 1) ) + { + ret = -EFAULT; + goto out; + } + + if ( copy_to_guest_offset(arg3, sizeof(direntry), e->name, + strlen(e->name) + 1) ) + { + ret = -EFAULT; + goto out; + } + + guest_handle_add_offset(arg3, e_len); + } + + break; + } + + default: + ret = -ENOSYS; + break; + } + + out: + spin_unlock(&fs_lock); + + return ret; +} diff --git a/xen/include/public/errno.h b/xen/include/public/errno.h index e1d02fcddf..5c53af6af9 100644 --- a/xen/include/public/errno.h +++ b/xen/include/public/errno.h @@ -78,6 +78,7 @@ XEN_ERRNO(EBUSY, 16) /* Device or resource busy */ XEN_ERRNO(EEXIST, 17) /* File exists */ XEN_ERRNO(EXDEV, 18) /* Cross-device link */ XEN_ERRNO(ENODEV, 19) /* No such device */ +XEN_ERRNO(ENOTDIR, 20) /* Not a directory */ XEN_ERRNO(EISDIR, 21) /* Is a directory */ XEN_ERRNO(EINVAL, 22) /* Invalid argument */ XEN_ERRNO(ENFILE, 23) /* File table overflow */ diff --git a/xen/include/public/filesystem.h b/xen/include/public/filesystem.h new file mode 100644 index 0000000000..cc790ae490 --- /dev/null +++ b/xen/include/public/filesystem.h @@ -0,0 +1,98 @@ +/****************************************************************************** + * Xen Hypervisor Filesystem + * + * Copyright (c) 2019, SUSE Software Solutions Germany GmbH + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __XEN_PUBLIC_FILESYSTEM_H__ +#define __XEN_PUBLIC_FILESYSTEM_H__ + +#include "xen.h" + +/* + * Definitions for the __HYPERVISOR_filesystem_op hypercall. + */ + +/* Maximum length of a path in the filesystem. */ +#define XEN_FS_MAX_PATHLEN 1024 + +struct xen_fs_direntry { + uint16_t flags; +#define XEN_FS_ISDIR 0x0001 + /* Offset in bytes to next entry (0 == this is the last entry). */ + uint16_t off_next; + uint32_t content_len; + char name[XEN_FLEX_ARRAY_DIM]; +}; + +/* + * Hypercall operations. + */ + +/* + * XEN_FS_OP_read_contents + * + * Read contents of a filesystem entry. + * + * Returns the contents of an entry in the buffer supplied by the caller. + * Only text data with a trailing zero byte is returned. + * + * arg1: XEN_GUEST_HANDLE(path name) + * arg2: length of path name (including trailing zero byte) + * arg3: XEN_GUEST_HANDLE(content buffer) + * arg4: content buffer size + * + * Possible return values: + * 0: success + * -EPERM: operation not permitted + * -ENOENT: entry not found + * -EACCESS: access to entry not permitted + * -EISDIR: entry is a directory + * -EINVAL: invalid parameter + * positive value: content buffer was too small, returned value is needed size + */ +#define XEN_FS_OP_read_contents 1 + +/* + * XEN_FS_OP_read_dir + * + * Read directory entries of a directory. + * + * Returns a struct xen_fs_direntry for each entry in a directory. + * + * arg1: XEN_GUEST_HANDLE(path name) + * arg2: length of path name (including trailing zero byte) + * arg3: XEN_GUEST_HANDLE(content buffer) + * arg4: content buffer size + * + * Possible return values: + * 0: success + * -EPERM: operation not permitted + * -ENOENT: entry not found + * -EACCESS: access to entry not permitted + * -ENOTDIR: entry is not a directory + * -EINVAL: invalid parameter + * positive value: content buffer was too small, returned value is needed size + */ +#define XEN_FS_OP_read_dir 2 + +#endif /* __XEN_PUBLIC_FILESYSTEM_H__ */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index cef65c38e7..232589a95b 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -130,6 +130,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_ulong_t); #define __HYPERVISOR_argo_op 39 #define __HYPERVISOR_xenpmu_op 40 #define __HYPERVISOR_dm_op 41 +#define __HYPERVISOR_filesystem_op 42 /* Architecture-specific hypercall definitions. */ #define __HYPERVISOR_arch_0 48 diff --git a/xen/include/xen/filesystem.h b/xen/include/xen/filesystem.h new file mode 100644 index 0000000000..24e0e2c62d --- /dev/null +++ b/xen/include/xen/filesystem.h @@ -0,0 +1,34 @@ +#ifndef __XEN_FILESYSTEM_H__ +#define __XEN_FILESYSTEM_H__ + +#include + +struct fs_dir { + unsigned int content_size; + struct list_head list; +}; + +enum fs_entry_type { + fs_type_dir, + fs_type_string +}; + +struct fs_entry { + enum fs_entry_type type; + const char *name; + struct list_head list; + struct fs_dir *parent; + union { + void *content; + struct fs_dir *dir; + const char *val; + }; +}; + +extern struct fs_dir fs_root; + +int fs_new_dir(struct fs_dir *parent, const char *name, struct fs_dir *dir); +int fs_new_entry(struct fs_dir *parent, const char *name, const char *val); +struct fs_entry *fs_get_entry(char *path); + +#endif /* __XEN_FILESYSTEM_H__ */ diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h index ad8ad27b23..56129ef82f 100644 --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -150,6 +150,14 @@ do_dm_op( unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(xen_dm_op_buf_t) bufs); +extern long +do_filesystem_op( + unsigned int cmd, + XEN_GUEST_HANDLE_PARAM(void) arg1, + unsigned long arg2, + XEN_GUEST_HANDLE_PARAM(void) arg3, + unsigned long arg4); + #ifdef CONFIG_COMPAT extern int 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 From patchwork Wed Sep 11 06:20:00 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: 11140331 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 0E8C814DB for ; Wed, 11 Sep 2019 06:22:18 +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 E804421A4C for ; Wed, 11 Sep 2019 06:22:17 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E804421A4C 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 1i7vzN-0003ep-Az; Wed, 11 Sep 2019 06:20:25 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i7vzL-0003eK-QY for xen-devel@lists.xenproject.org; Wed, 11 Sep 2019 06:20:23 +0000 X-Inumbo-ID: 3217d646-d45c-11e9-b299-bc764e2007e4 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 3217d646-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 2176DB60A; Wed, 11 Sep 2019 06:20:05 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Wed, 11 Sep 2019 08:20:00 +0200 Message-Id: <20190911062001.25931-5-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 4/5] tools: add xenfs tool 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 xenfs tool for accessing the hypervisor filesystem. Signed-off-by: Juergen Gross --- tools/misc/Makefile | 6 ++++ tools/misc/xenfs.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 tools/misc/xenfs.c diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 63947bfadc..9f3abd5bcf 100644 --- a/tools/misc/Makefile +++ b/tools/misc/Makefile @@ -24,6 +24,7 @@ INSTALL_SBIN-$(CONFIG_X86) += xen-lowmemd INSTALL_SBIN-$(CONFIG_X86) += xen-mfndump INSTALL_SBIN-$(CONFIG_X86) += xen-ucode INSTALL_SBIN += xencov +INSTALL_SBIN += xenfs INSTALL_SBIN += xenlockprof INSTALL_SBIN += xenperf INSTALL_SBIN += xenpm @@ -86,6 +87,9 @@ xenperf: xenperf.o xenpm: xenpm.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) +xenfs: xenfs.o + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenfs) $(APPEND_LDFLAGS) + xenlockprof: xenlockprof.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS) @@ -94,6 +98,8 @@ xen-hptool.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall) xen-hptool: xen-hptool.o $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS) +xenfs.o: CFLAGS += $(CFLAGS_libxenfs) + # xen-mfndump incorrectly uses libxc internals xen-mfndump.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall) xen-mfndump: xen-mfndump.o diff --git a/tools/misc/xenfs.c b/tools/misc/xenfs.c new file mode 100644 index 0000000000..ecaa4ccb0a --- /dev/null +++ b/tools/misc/xenfs.c @@ -0,0 +1,102 @@ +#define _GNU_SOURCE +#include +#include +#include +#include + +static struct xenfs_handle *hdl; + +static int xenfs_cat(char *path) +{ + int ret = 0; + char *result; + + result = xenfs_read(hdl, path); + if (!result) { + perror("could not read"); + ret = 3; + } else { + printf("%s\n", result); + free(result); + } + return ret; +} + +static int xenfs_ls(char *path) +{ + struct xenfs_dirent *ent; + unsigned int n, i; + int ret = 0; + + ent = xenfs_readdir(hdl, path, &n); + if (!ent) { + perror("could not read dir"); + ret = 3; + } else { + for (i = 0; i < n; i++) + printf("%c %s\n", ent[i].is_dir ? 'd' : '-', ent[i].name); + + free(ent); + } + return ret; +} + +static int xenfs_tree_sub(char *path, unsigned int depth) +{ + struct xenfs_dirent *ent; + unsigned int n, i; + int ret = 0; + char *p; + + ent = xenfs_readdir(hdl, path, &n); + if (!ent) + return 1; + + for (i = 0; i < n; i++) { + printf("%*s%s%s\n", depth * 2, "", ent[i].name, + ent[i].is_dir ? "/" : ""); + if (ent[i].is_dir) { + asprintf(&p, "%s%s%s", path, (depth == 1) ? "" : "/", ent[i].name); + if (xenfs_tree_sub(p, depth + 1)) + ret = 1; + } + } + + free(ent); + + return ret; +} + +static int xenfs_tree(void) +{ + printf("/\n"); + + return xenfs_tree_sub("/", 1); +} + +int main(int argc, char *argv[]) +{ + int ret; + + hdl = xenfs_open(NULL, 0); + + if (!hdl) { + fprintf(stderr, "Could not open libxenfs\n"); + ret = 2; + } else if (argc == 3 && !strcmp(argv[1], "--cat")) + ret = xenfs_cat(argv[2]); + else if (argc == 3 && !strcmp(argv[1], "--ls")) + ret = xenfs_ls(argv[2]); + else if (argc == 2 && !strcmp(argv[1], "--tree")) + ret = xenfs_tree(); + else { + fprintf(stderr, "usage: xenfs --ls \n"); + fprintf(stderr, " xenfs --cat \n"); + fprintf(stderr, " xenfs --tree\n"); + ret = 1; + } + + xenfs_close(hdl); + + return ret; +} From patchwork Wed Sep 11 06:20:01 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: 11140329 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 97A9114DB for ; Wed, 11 Sep 2019 06:21:54 +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 7CFE121A4C for ; Wed, 11 Sep 2019 06:21:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7CFE121A4C 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 1i7vzS-0003gh-Lo; Wed, 11 Sep 2019 06:20:30 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i7vzQ-0003g6-Q4 for xen-devel@lists.xenproject.org; Wed, 11 Sep 2019 06:20:28 +0000 X-Inumbo-ID: 3421c3ac-d45c-11e9-a337-bc764e2007e4 Received: from mx1.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 3421c3ac-d45c-11e9-a337-bc764e2007e4; Wed, 11 Sep 2019 06:20:09 +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 786CEAEBE; Wed, 11 Sep 2019 06:20:05 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Wed, 11 Sep 2019 08:20:01 +0200 Message-Id: <20190911062001.25931-6-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 5/5] xen: add /buildinfo/config entry to hypervisor filesystem 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 , Stefano Stabellini , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Tim Deegan , Julien Grall , Jan Beulich MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Add the /buildinfo/config entry to the hypervisor filesystem. This entry contains the .config file used to build the hypervisor. Signed-off-by: Juergen Gross --- .gitignore | 2 ++ xen/common/Makefile | 6 ++++++ xen/common/filesystem.c | 17 +++++++++++++++++ xen/include/xen/kernel.h | 2 ++ xen/tools/Makefile | 9 +++++++-- xen/tools/bin2c.c | 28 ++++++++++++++++++++++++++++ 6 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 xen/tools/bin2c.c diff --git a/.gitignore b/.gitignore index 3c947ac948..7150dd0548 100644 --- a/.gitignore +++ b/.gitignore @@ -295,6 +295,7 @@ xen/arch/*/efi/boot.c xen/arch/*/efi/compat.c xen/arch/*/efi/efi.h xen/arch/*/efi/runtime.c +xen/common/config_data.c xen/include/headers*.chk xen/include/asm xen/include/asm-*/asm-offsets.h @@ -312,6 +313,7 @@ xen/test/livepatch/xen_bye_world.livepatch xen/test/livepatch/xen_hello_world.livepatch xen/test/livepatch/xen_nop.livepatch xen/test/livepatch/xen_replace_world.livepatch +xen/tools/bin2c xen/tools/kconfig/.tmp_gtkcheck xen/tools/kconfig/.tmp_qtcheck xen/tools/symbols diff --git a/xen/common/Makefile b/xen/common/Makefile index be43757dff..9bce9db43b 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_ARGO) += argo.o obj-y += bitmap.o obj-y += bsearch.o +obj-y += config_data.o obj-$(CONFIG_CORE_PARKING) += core_parking.o obj-y += cpu.o obj-y += cpupool.o @@ -79,3 +80,8 @@ subdir-$(CONFIG_UBSAN) += ubsan subdir-$(CONFIG_NEEDS_LIBELF) += libelf subdir-$(CONFIG_HAS_DEVICE_TREE) += libfdt + +config_data.c: ../.config + ( echo "const char xen_config_data[] ="; \ + ../tools/bin2c <$<; \ + echo ";" ) > $@ diff --git a/xen/common/filesystem.c b/xen/common/filesystem.c index d833992ab1..4ab18eb82a 100644 --- a/xen/common/filesystem.c +++ b/xen/common/filesystem.c @@ -25,6 +25,10 @@ static struct fs_entry fs_root_entry = { .dir = &fs_root, }; +static struct fs_dir fs_buildinfo = { + .list = LIST_HEAD_INIT(fs_buildinfo.list), +}; + static int fs_add_entry(struct fs_dir *parent, struct fs_entry *new) { int ret = -ENOENT; @@ -268,3 +272,16 @@ long do_filesystem_op(unsigned int cmd, return ret; } + +static int __init fs_init(void) +{ + int ret; + + ret = fs_new_dir(&fs_root, "buildinfo", &fs_buildinfo); + BUG_ON(ret); + ret = fs_new_entry(&fs_buildinfo, "config", xen_config_data); + BUG_ON(ret); + + return 0; +} +__initcall(fs_init); diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h index 548b64da9f..00817d06c8 100644 --- a/xen/include/xen/kernel.h +++ b/xen/include/xen/kernel.h @@ -100,5 +100,7 @@ extern enum system_state { bool_t is_active_kernel_text(unsigned long addr); +extern const char xen_config_data[]; + #endif /* _LINUX_KERNEL_H */ diff --git a/xen/tools/Makefile b/xen/tools/Makefile index e940939d61..cd2bbbf647 100644 --- a/xen/tools/Makefile +++ b/xen/tools/Makefile @@ -1,13 +1,18 @@ include $(XEN_ROOT)/Config.mk +PROGS = symbols bin2c + .PHONY: default default: - $(MAKE) symbols + $(MAKE) $(PROGS) .PHONY: clean clean: - rm -f *.o symbols + rm -f *.o $(PROGS) symbols: symbols.c $(HOSTCC) $(HOSTCFLAGS) -o $@ $< + +bin2c: bin2c.c + $(HOSTCC) $(HOSTCFLAGS) -o $@ $< diff --git a/xen/tools/bin2c.c b/xen/tools/bin2c.c new file mode 100644 index 0000000000..c332399b70 --- /dev/null +++ b/xen/tools/bin2c.c @@ -0,0 +1,28 @@ +/* + * Unloved program to convert a binary on stdin to a C include on stdout + * + * Jan 1999 Matt Mackall + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + */ + +#include + +int main(int argc, char *argv[]) +{ + int ch, total = 0; + + do { + printf("\t\""); + while ((ch = getchar()) != EOF) { + total++; + printf("\\x%02x", ch); + if (total % 16 == 0) + break; + } + printf("\"\n"); + } while (ch != EOF); + + return 0; +}