From: David Howells <dhowells@redhat.com>
To: viro@zeniv.linux.org.uk
Cc: dhowells@redhat.com, raven@themaw.net, mszeredi@redhat.com,
christian@brauner.io, linux-api@vger.kernel.org,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 08/19] vfs: fsinfo sample: Mount listing program [ver #16]
Date: Tue, 18 Feb 2020 17:05:58 +0000 [thread overview]
Message-ID: <158204555855.3299825.16222565076194085551.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <158204549488.3299825.3783690177353088425.stgit@warthog.procyon.org.uk>
Implement a program to demonstrate mount listing using the new fsinfo()
syscall, for example:
# ./test-mntinfo -M 21
MOUNT MOUNT ID CHANGE# TYPE & DEVICE
------------------------------------- ---------- ---------- ---------------
21 21 8 sysfs 0:15
\_ kernel/security 24 0 securityfs 0:8
\_ fs/cgroup 28 16 tmpfs 0:19
| \_ unified 29 0 cgroup2 0:1a
| \_ systemd 30 0 cgroup 0:1b
| \_ freezer 34 0 cgroup 0:1f
| \_ cpu,cpuacct 35 0 cgroup 0:20
| \_ devices 36 0 cgroup 0:21
| \_ memory 37 0 cgroup 0:22
| \_ cpuset 38 0 cgroup 0:23
| \_ net_cls,net_prio 39 0 cgroup 0:24
| \_ hugetlb 40 0 cgroup 0:25
| \_ rdma 41 0 cgroup 0:26
| \_ blkio 42 0 cgroup 0:27
| \_ perf_event 43 0 cgroup 0:28
\_ fs/pstore 31 0 pstore 0:1c
\_ firmware/efi/efivars 32 0 efivarfs 0:1d
\_ fs/bpf 33 0 bpf 0:1e
\_ kernel/config 92 0 configfs 0:10
\_ fs/selinux 44 0 selinuxfs 0:12
\_ kernel/debug 48 0 debugfs 0:7
Signed-off-by: David Howells <dhowells@redhat.com>
---
samples/vfs/Makefile | 2
samples/vfs/test-mntinfo.c | 243 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 245 insertions(+)
create mode 100644 samples/vfs/test-mntinfo.c
diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
index 9159ad1d7fc5..19be60ab950e 100644
--- a/samples/vfs/Makefile
+++ b/samples/vfs/Makefile
@@ -4,12 +4,14 @@
hostprogs := \
test-fsinfo \
test-fsmount \
+ test-mntinfo \
test-statx
always-y := $(hostprogs)
HOSTCFLAGS_test-fsinfo.o += -I$(objtree)/usr/include
HOSTLDLIBS_test-fsinfo += -static -lm
+HOSTCFLAGS_test-mntinfo.o += -I$(objtree)/usr/include
HOSTCFLAGS_test-fsmount.o += -I$(objtree)/usr/include
HOSTCFLAGS_test-statx.o += -I$(objtree)/usr/include
diff --git a/samples/vfs/test-mntinfo.c b/samples/vfs/test-mntinfo.c
new file mode 100644
index 000000000000..f4d90d0671c5
--- /dev/null
+++ b/samples/vfs/test-mntinfo.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Test the fsinfo() system call
+ *
+ * Copyright (C) 2020 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ */
+
+#define _GNU_SOURCE
+#define _ATFILE_SOURCE
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <errno.h>
+#include <time.h>
+#include <math.h>
+#include <sys/syscall.h>
+#include <linux/fsinfo.h>
+#include <linux/socket.h>
+#include <linux/fcntl.h>
+#include <sys/stat.h>
+#include <arpa/inet.h>
+
+#ifndef __NR_fsinfo
+#define __NR_fsinfo -1
+#endif
+
+static __attribute__((unused))
+ssize_t fsinfo(int dfd, const char *filename, struct fsinfo_params *params,
+ void *buffer, size_t buf_size)
+{
+ return syscall(__NR_fsinfo, dfd, filename, params, buffer, buf_size);
+}
+
+static char tree_buf[4096];
+static char bar_buf[4096];
+
+/*
+ * Get an fsinfo attribute in a statically allocated buffer.
+ */
+static void get_attr(unsigned int mnt_id, unsigned int attr,
+ void *buf, size_t buf_size)
+{
+ struct fsinfo_params params = {
+ .flags = FSINFO_FLAGS_QUERY_MOUNT,
+ .request = attr,
+ };
+ char file[32];
+ long ret;
+
+ sprintf(file, "%u", mnt_id);
+
+ memset(buf, 0xbd, buf_size);
+
+ ret = fsinfo(AT_FDCWD, file, ¶ms, buf, buf_size);
+ if (ret == -1) {
+ fprintf(stderr, "mount-%s: %m\n", file);
+ exit(1);
+ }
+}
+
+/*
+ * Get an fsinfo attribute in a dynamically allocated buffer.
+ */
+static void *get_attr_alloc(unsigned int mnt_id, unsigned int attr,
+ unsigned int Nth, size_t *_size)
+{
+ struct fsinfo_params params = {
+ .flags = FSINFO_FLAGS_QUERY_MOUNT,
+ .request = attr,
+ .Nth = Nth,
+ };
+ size_t buf_size = 4096;
+ char file[32];
+ void *r;
+ long ret;
+
+ sprintf(file, "%u", mnt_id);
+
+ for (;;) {
+ r = malloc(buf_size);
+ if (!r) {
+ perror("malloc");
+ exit(1);
+ }
+ memset(r, 0xbd, buf_size);
+
+ ret = fsinfo(AT_FDCWD, file, ¶ms, r, buf_size);
+ if (ret == -1) {
+ fprintf(stderr, "mount-%s: %x,%x,%x %m\n",
+ file, params.request, params.Nth, params.Mth);
+ exit(1);
+ }
+
+ if (ret <= buf_size) {
+ *_size = ret;
+ break;
+ }
+ buf_size = (ret + 4096 - 1) & ~(4096 - 1);
+ }
+
+ return r;
+}
+
+/*
+ * Display a mount and then recurse through its children.
+ */
+static void display_mount(unsigned int mnt_id, unsigned int depth, char *path)
+{
+ struct fsinfo_mount_child *children;
+ struct fsinfo_mount_info info;
+ struct fsinfo_ids ids;
+ unsigned int d;
+ size_t ch_size, p_size;
+ char dev[64];
+ int i, n, s;
+
+ get_attr(mnt_id, FSINFO_ATTR_MOUNT_INFO, &info, sizeof(info));
+ get_attr(mnt_id, FSINFO_ATTR_IDS, &ids, sizeof(ids));
+ if (depth > 0)
+ printf("%s", tree_buf);
+
+ s = strlen(path);
+ printf("%s", !s ? "\"\"" : path);
+ if (!s)
+ s += 2;
+ s += depth;
+ if (s < 38)
+ s = 38 - s;
+ else
+ s = 1;
+ printf("%*.*s", s, s, "");
+
+ sprintf(dev, "%x:%x", ids.f_dev_major, ids.f_dev_minor);
+ printf("%10u %8x %2x %5s %s",
+ info.mnt_id, info.change_counter,
+ info.attr,
+ dev, ids.f_fs_name);
+ putchar('\n');
+
+ children = get_attr_alloc(mnt_id, FSINFO_ATTR_MOUNT_CHILDREN, 0, &ch_size);
+ n = ch_size / sizeof(children[0]) - 1;
+
+ bar_buf[depth + 1] = '|';
+ if (depth > 0) {
+ tree_buf[depth - 4 + 1] = bar_buf[depth - 4 + 1];
+ tree_buf[depth - 4 + 2] = ' ';
+ }
+
+ tree_buf[depth + 0] = ' ';
+ tree_buf[depth + 1] = '\\';
+ tree_buf[depth + 2] = '_';
+ tree_buf[depth + 3] = ' ';
+ tree_buf[depth + 4] = 0;
+ d = depth + 4;
+
+ for (i = 0; i < n; i++) {
+ if (i == n - 1)
+ bar_buf[depth + 1] = ' ';
+ path = get_attr_alloc(children[i].mnt_id, FSINFO_ATTR_MOUNT_POINT,
+ 0, &p_size);
+ display_mount(children[i].mnt_id, d, path + 1);
+ free(path);
+ }
+
+ free(children);
+ if (depth > 0) {
+ tree_buf[depth - 4 + 1] = '\\';
+ tree_buf[depth - 4 + 2] = '_';
+ }
+ tree_buf[depth] = 0;
+}
+
+/*
+ * Find the ID of whatever is at the nominated path.
+ */
+static unsigned int lookup_mnt_by_path(const char *path)
+{
+ struct fsinfo_mount_info mnt;
+ struct fsinfo_params params = {
+ .flags = FSINFO_FLAGS_QUERY_PATH,
+ .request = FSINFO_ATTR_MOUNT_INFO,
+ };
+
+ if (fsinfo(AT_FDCWD, path, ¶ms, &mnt, sizeof(mnt)) == -1) {
+ perror(path);
+ exit(1);
+ }
+
+ return mnt.mnt_id;
+}
+
+/*
+ *
+ */
+int main(int argc, char **argv)
+{
+ unsigned int mnt_id;
+ char *path;
+ bool use_mnt_id = false;
+ int opt;
+
+ while ((opt = getopt(argc, argv, "M"))) {
+ switch (opt) {
+ case 'M':
+ use_mnt_id = true;
+ continue;
+ }
+ break;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ switch (argc) {
+ case 0:
+ mnt_id = lookup_mnt_by_path("/");
+ path = "ROOT";
+ break;
+ case 1:
+ path = argv[0];
+ if (use_mnt_id) {
+ mnt_id = strtoul(argv[0], NULL, 0);
+ break;
+ }
+
+ mnt_id = lookup_mnt_by_path(argv[0]);
+ break;
+ default:
+ printf("Format: test-mntinfo\n");
+ printf("Format: test-mntinfo <path>\n");
+ printf("Format: test-mntinfo -M <mnt_id>\n");
+ exit(2);
+ }
+
+ printf("MOUNT MOUNT ID CHANGE# AT DEV TYPE\n");
+ printf("------------------------------------- ---------- -------- -- ----- --------\n");
+ display_mount(mnt_id, 0, path);
+ return 0;
+}
next prev parent reply other threads:[~2020-02-18 17:06 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-18 17:04 [PATCH 00/19] VFS: Filesystem information and notifications [ver #16] David Howells
2020-02-18 17:05 ` [PATCH 01/19] vfs: syscall: Add fsinfo() to query filesystem information " David Howells
2020-02-19 16:31 ` Darrick J. Wong
2020-02-19 20:07 ` Jann Horn
2020-02-20 10:34 ` David Howells
2020-02-20 15:48 ` Darrick J. Wong
2020-02-20 11:03 ` David Howells
2020-02-20 14:54 ` Jann Horn
2020-02-20 15:31 ` Darrick J. Wong
2020-02-18 17:05 ` [PATCH 02/19] fsinfo: Add syscalls to other arches " David Howells
2020-02-21 14:51 ` Christian Brauner
2020-02-21 18:10 ` Geert Uytterhoeven
2020-02-18 17:05 ` [PATCH 03/19] fsinfo: Provide a bitmap of supported features " David Howells
2020-02-19 16:37 ` Darrick J. Wong
2020-02-20 12:22 ` David Howells
2020-02-18 17:05 ` [PATCH 04/19] vfs: Add mount change counter " David Howells
2020-02-21 14:48 ` Christian Brauner
2020-02-18 17:05 ` [PATCH 05/19] vfs: Introduce a non-repeating system-unique superblock ID " David Howells
2020-02-19 16:53 ` Darrick J. Wong
2020-02-20 12:45 ` David Howells
2020-02-18 17:05 ` [PATCH 06/19] vfs: Allow fsinfo() to look up a mount object by " David Howells
2020-02-21 15:09 ` Christian Brauner
2020-02-18 17:05 ` [PATCH 07/19] vfs: Allow mount information to be queried by fsinfo() " David Howells
2020-02-18 17:05 ` David Howells [this message]
2020-02-18 17:06 ` [PATCH 09/19] fsinfo: Allow the mount topology propogation flags to be retrieved " David Howells
2020-02-18 17:06 ` [PATCH 10/19] fsinfo: Add API documentation " David Howells
2020-02-18 17:06 ` [PATCH 11/19] afs: Support fsinfo() " David Howells
2020-02-19 21:01 ` Jann Horn
2020-02-20 12:58 ` David Howells
2020-02-20 14:58 ` Jann Horn
2020-02-21 13:26 ` David Howells
2020-02-18 17:06 ` [PATCH 12/19] security: Add hooks to rule on setting a superblock or mount watch " David Howells
2020-02-18 17:06 ` [PATCH 13/19] vfs: Add a mount-notification facility " David Howells
2020-02-19 22:40 ` Jann Horn
2020-02-19 22:55 ` Jann Horn
2020-02-21 12:24 ` David Howells
2020-02-21 15:49 ` Jann Horn
2020-02-21 17:06 ` David Howells
2020-02-21 17:36 ` seq_lock and lockdep_is_held() assertions Jann Horn
2020-02-21 18:02 ` John Stultz
2020-02-18 17:06 ` [PATCH 14/19] notifications: sample: Display mount tree change notifications [ver #16] David Howells
2020-02-18 17:06 ` [PATCH 15/19] vfs: Add superblock " David Howells
2020-02-19 23:08 ` Jann Horn
2020-02-21 14:23 ` David Howells
2020-02-21 15:44 ` Jann Horn
2020-02-21 16:33 ` David Howells
2020-02-21 16:41 ` Jann Horn
2020-02-21 17:11 ` David Howells
2020-02-18 17:06 ` [PATCH 16/19] fsinfo: Provide superblock notification counter " David Howells
2020-02-18 17:07 ` [PATCH 17/19] notifications: sample: Display superblock notifications " David Howells
2020-02-18 17:07 ` [PATCH 18/19] ext4: Add example fsinfo information " David Howells
2020-02-19 17:04 ` Darrick J. Wong
2020-02-20 0:53 ` kbuild test robot
2020-02-21 14:43 ` David Howells
2020-02-21 16:26 ` Darrick J. Wong
2020-02-18 17:07 ` [PATCH 19/19] nfs: Add example filesystem " David Howells
2020-02-20 2:13 ` kbuild test robot
2020-02-20 2:20 ` kbuild test robot
2020-02-18 18:12 ` David Howells
2020-02-19 10:23 ` [PATCH 00/19] VFS: Filesystem information and notifications " Stefan Metzmacher
2020-02-19 14:46 ` Christian Brauner
2020-02-19 15:50 ` Darrick J. Wong
2020-02-20 4:42 ` Ian Kent
2020-02-20 9:09 ` Christian Brauner
2020-02-20 11:30 ` Ian Kent
2020-02-19 16:16 ` David Howells
2020-02-21 12:57 ` David Howells
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=158204555855.3299825.16222565076194085551.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=christian@brauner.io \
--cc=linux-api@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mszeredi@redhat.com \
--cc=raven@themaw.net \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).