From patchwork Tue May 19 07:21:00 2020 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: 11557095 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 852671391 for ; Tue, 19 May 2020 07:22:30 +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 6B49A20709 for ; Tue, 19 May 2020 07:22:30 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6B49A20709 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.com Authentication-Results: mail.kernel.org; spf=pass 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.92) (envelope-from ) id 1jawZ6-0004pB-1m; Tue, 19 May 2020 07:21:28 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1jawZ4-0004od-Dw for xen-devel@lists.xenproject.org; Tue, 19 May 2020 07:21:26 +0000 X-Inumbo-ID: 5101dcd6-99a1-11ea-b9cf-bc764e2007e4 Received: from mx2.suse.de (unknown [195.135.220.15]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 5101dcd6-99a1-11ea-b9cf-bc764e2007e4; Tue, 19 May 2020 07:21:12 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4061DB211; Tue, 19 May 2020 07:21:13 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Subject: [PATCH v10 06/12] tools: add xenfs tool Date: Tue, 19 May 2020 09:21:00 +0200 Message-Id: <20200519072106.26894-7-jgross@suse.com> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20200519072106.26894-1-jgross@suse.com> References: <20200519072106.26894-1-jgross@suse.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Juergen Gross , Stefano Stabellini , Julien Grall , Wei Liu , Andrew Cooper , Ian Jackson , George Dunlap , Jan Beulich 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 Acked-by: Wei Liu --- V1: - rename to xenhypfs - don't use "--" for subcommands - add write support V2: - escape non-printable characters per default with cat subcommand (Ian Jackson) - add -b option to cat subcommand (Ian Jackson) - add man page V3: - adapt to new hypfs interface V7: - added missing bool for ls output Signed-off-by: Juergen Gross --- .gitignore | 1 + docs/man/xenhypfs.1.pod | 61 +++++++++++++ tools/misc/Makefile | 6 ++ tools/misc/xenhypfs.c | 192 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 260 insertions(+) create mode 100644 docs/man/xenhypfs.1.pod create mode 100644 tools/misc/xenhypfs.c diff --git a/.gitignore b/.gitignore index 7bd292f64d..6171b3b43f 100644 --- a/.gitignore +++ b/.gitignore @@ -368,6 +368,7 @@ tools/libxl/test_timedereg tools/libxl/test_fdderegrace tools/firmware/etherboot/eb-roms.h tools/firmware/etherboot/gpxe-git-snapshot.tar.gz +tools/misc/xenhypfs tools/misc/xenwatchdogd tools/misc/xen-hvmcrash tools/misc/xen-lowmemd diff --git a/docs/man/xenhypfs.1.pod b/docs/man/xenhypfs.1.pod new file mode 100644 index 0000000000..37aa488fcc --- /dev/null +++ b/docs/man/xenhypfs.1.pod @@ -0,0 +1,61 @@ +=head1 NAME + +xenhypfs - Xen tool to access Xen hypervisor file system + +=head1 SYNOPSIS + +B I [I] [I] + +=head1 DESCRIPTION + +The B program is used to access the Xen hypervisor file system. +It can be used to show the available entries, to show their contents and +(if allowed) to modify their contents. + +=head1 SUBCOMMANDS + +=over 4 + +=item B I + +List the available entries below I. + +=item B [I<-b>] I + +Show the contents of the entry specified by I. Non-printable characters +other than white space characters (like tab, new line) will be shown as +B<\xnn> (B being a two digit hex number) unless the option B<-b> is +specified. + +=item B I I + +Set the contents of the entry specified by I to I. + +=item B + +Show all the entries of the file system as a tree. + +=back + +=head1 RETURN CODES + +=over 4 + +=item B<0> + +Success + +=item B<1> + +Invalid usage (e.g. unknown subcommand, unknown option, missing parameter). + +=item B<2> + +Entry not found while traversing the tree. + +=item B<3> + +Access right violation. + +=back + diff --git a/tools/misc/Makefile b/tools/misc/Makefile index 63947bfadc..9fdb13597f 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 += xenhypfs 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) +xenhypfs: xenhypfs.o + $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenhypfs) $(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) +xenhypfs.o: CFLAGS += $(CFLAGS_libxenhypfs) + # 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/xenhypfs.c b/tools/misc/xenhypfs.c new file mode 100644 index 0000000000..158b901f42 --- /dev/null +++ b/tools/misc/xenhypfs.c @@ -0,0 +1,192 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +static struct xenhypfs_handle *hdl; + +static int usage(void) +{ + fprintf(stderr, "usage: xenhypfs ls \n"); + fprintf(stderr, " xenhypfs cat [-b] \n"); + fprintf(stderr, " xenhypfs write \n"); + fprintf(stderr, " xenhypfs tree\n"); + + return 1; +} + +static void xenhypfs_print_escaped(char *string) +{ + char *c; + + for (c = string; *c; c++) { + if (isgraph(*c) || isspace(*c)) + printf("%c", *c); + else + printf("\\x%02x", *c); + } + printf("\n"); +} + +static int xenhypfs_cat(int argc, char *argv[]) +{ + int ret = 0; + char *result; + char *path; + bool bin = false; + + switch (argc) { + case 1: + path = argv[0]; + break; + + case 2: + if (strcmp(argv[0], "-b")) + return usage(); + bin = true; + path = argv[1]; + break; + + default: + return usage(); + } + + result = xenhypfs_read(hdl, path); + if (!result) { + perror("could not read"); + ret = 3; + } else { + if (!bin) + printf("%s\n", result); + else + xenhypfs_print_escaped(result); + free(result); + } + + return ret; +} + +static int xenhypfs_wr(char *path, char *val) +{ + int ret; + + ret = xenhypfs_write(hdl, path, val); + if (ret) { + perror("could not write"); + ret = 3; + } + + return ret; +} + +static char *xenhypfs_type(struct xenhypfs_dirent *ent) +{ + char *res; + + switch (ent->type) { + case xenhypfs_type_dir: + res = " "; + break; + case xenhypfs_type_blob: + res = " "; + break; + case xenhypfs_type_string: + res = ""; + break; + case xenhypfs_type_uint: + res = " "; + break; + case xenhypfs_type_int: + res = " "; + break; + case xenhypfs_type_bool: + res = " "; + break; + default: + res = "<\?\?\?> "; + break; + } + + return res; +} + +static int xenhypfs_ls(char *path) +{ + struct xenhypfs_dirent *ent; + unsigned int n, i; + int ret = 0; + + ent = xenhypfs_readdir(hdl, path, &n); + if (!ent) { + perror("could not read dir"); + ret = 3; + } else { + for (i = 0; i < n; i++) + printf("%s r%c %s\n", xenhypfs_type(ent + i), + ent[i].is_writable ? 'w' : '-', ent[i].name); + + free(ent); + } + + return ret; +} + +static int xenhypfs_tree_sub(char *path, unsigned int depth) +{ + struct xenhypfs_dirent *ent; + unsigned int n, i; + int ret = 0; + char *p; + + ent = xenhypfs_readdir(hdl, path, &n); + if (!ent) + return 2; + + for (i = 0; i < n; i++) { + printf("%*s%s%s\n", depth * 2, "", ent[i].name, + ent[i].type == xenhypfs_type_dir ? "/" : ""); + if (ent[i].type == xenhypfs_type_dir) { + asprintf(&p, "%s%s%s", path, (depth == 1) ? "" : "/", ent[i].name); + if (xenhypfs_tree_sub(p, depth + 1)) + ret = 2; + } + } + + free(ent); + + return ret; +} + +static int xenhypfs_tree(void) +{ + printf("/\n"); + + return xenhypfs_tree_sub("/", 1); +} + +int main(int argc, char *argv[]) +{ + int ret; + + hdl = xenhypfs_open(NULL, 0); + + if (!hdl) { + fprintf(stderr, "Could not open libxenhypfs\n"); + ret = 2; + } else if (argc >= 3 && !strcmp(argv[1], "cat")) + ret = xenhypfs_cat(argc - 2, argv + 2); + else if (argc == 3 && !strcmp(argv[1], "ls")) + ret = xenhypfs_ls(argv[2]); + else if (argc == 4 && !strcmp(argv[1], "write")) + ret = xenhypfs_wr(argv[2], argv[3]); + else if (argc == 2 && !strcmp(argv[1], "tree")) + ret = xenhypfs_tree(); + else + ret = usage(); + + xenhypfs_close(hdl); + + return ret; +}