[PATCH] vfs: tiny sample programs for open_tree() and move_mount()

From: Alan Jenkins
Date: Fri Oct 12 2018 - 06:11:13 EST


A couple of utility commands for fd-based mounts. They were useful to
reproduce three different issues, in the original implementation of the
system calls.

Also add .gitignore for all the vfs samples.

Signed-off-by: Alan Jenkins <alan.christopher.jenkins@xxxxxxxxx>
---
samples/vfs/.gitignore | 4 +++
samples/vfs/Makefile | 4 +++
samples/vfs/move_mount.c | 42 ++++++++++++++++++++++
samples/vfs/open_tree_clone.c | 65 +++++++++++++++++++++++++++++++++++
4 files changed, 115 insertions(+)
create mode 100644 samples/vfs/.gitignore
create mode 100644 samples/vfs/move_mount.c
create mode 100644 samples/vfs/open_tree_clone.c

diff --git a/samples/vfs/.gitignore b/samples/vfs/.gitignore
new file mode 100644
index 000000000000..242ed23f90d2
--- /dev/null
+++ b/samples/vfs/.gitignore
@@ -0,0 +1,4 @@
+open_tree_clone
+move_mount
+test-fsmount
+test-statx
diff --git a/samples/vfs/Makefile b/samples/vfs/Makefile
index 4ac9690fb3c4..3a5bb48d21a0 100644
--- a/samples/vfs/Makefile
+++ b/samples/vfs/Makefile
@@ -1,10 +1,14 @@
# List of programs to build
hostprogs-$(CONFIG_SAMPLE_VFS) := \
+ open_tree_clone \
+ move_mount \
test-fsmount \
test-statx

# Tell kbuild to always build the programs
always := $(hostprogs-y)

+HOSTCFLAGS_open_tree_clone.o += -I$(objtree)/usr/include
+HOSTCFLAGS_move_mount.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/move_mount.c b/samples/vfs/move_mount.c
new file mode 100644
index 000000000000..2cc9d876078a
--- /dev/null
+++ b/samples/vfs/move_mount.c
@@ -0,0 +1,42 @@
+/* fd-based mount utility.
+ *
+ * Copyright (C) 2018 Alan Jenkins (alan.christopher.jenkins@xxxxxxxxx).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+
+static inline int move_mount(int from_dfd, const char *from_pathname,
+ int to_dfd, const char *to_pathname,
+ unsigned int flags)
+{
+ return syscall(__NR_move_mount,
+ from_dfd, from_pathname,
+ to_dfd, to_pathname, flags);
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc != 1) {
+ fprintf(stderr, "Usage: move_mount 3</from/path 4</to/path\n");
+ exit(2);
+ }
+
+ if (move_mount(3, "", 4, "", MOVE_MOUNT_F_EMPTY_PATH |
+ MOVE_MOUNT_T_EMPTY_PATH) < 0) {
+ perror("move_mount");
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/samples/vfs/open_tree_clone.c b/samples/vfs/open_tree_clone.c
new file mode 100644
index 000000000000..3025d101addc
--- /dev/null
+++ b/samples/vfs/open_tree_clone.c
@@ -0,0 +1,65 @@
+/* fd-based mount utility.
+ *
+ * Inspired by http://skarnet.org/software/execline/redirfd.html etc.
+ *
+ * Copyright (C) 2018 Alan Jenkins (alan.christopher.jenkins@xxxxxxxxx).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/fs.h>
+#include <linux/unistd.h>
+
+#ifndef AT_RECURSIVE
+#define AT_RECURSIVE 0x8000
+#endif
+
+#define E(x) do { if ((x) == -1) { perror(#x); exit(1); } } while(0)
+
+static inline int open_tree(int dfd, const char *pathname, unsigned flags)
+{
+ return syscall(__NR_open_tree, dfd, pathname, flags);
+}
+
+int main(int argc, char *argv[])
+{
+ int fd_number;
+ char **command;
+ int mfd;
+
+ if (argc < 3 || !isdigit(argv[1][0])) {
+ fprintf(stderr, "Usage: 3</from/path open_tree_clone FD_NUMBER COMMAND...\n");
+ fprintf(stderr, "Clone the tree mounted at /from/path.\n");
+ fprintf(stderr, "Then execute COMMAND, passing the cloned tree as file FD_NUMBER.\n");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "hint: 3</from/path 4</to/path open_tree_clone 3 move_mount\n");
+ exit(2);
+ }
+ fd_number = atoi(argv[1]);
+ command = argv + 2;
+
+ mfd = open_tree(3, "", AT_EMPTY_PATH | OPEN_TREE_CLONE | AT_RECURSIVE);
+ if (mfd == -1) {
+ perror("open_tree");
+ exit(1);
+ }
+
+ if (fd_number != mfd) {
+ E( dup2(mfd, fd_number) );
+ E( close(mfd) );
+ }
+
+ execvp(command[0], command);
+ perror("exec");
+ exit(1);
+}
--
2.17.2


--------------F25C7A29E5A46BE6833D0F14--