[PATCH v2 039/113] commands: introduce new findmnt command

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Mar 4 10:59:24 PST 2024


EFI loader support will need to map barebox VFS paths to fs_device and
back. Make development easier by providing a findmnt command to test
the mapping.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 commands/Kconfig   |  15 +++++++
 commands/Makefile  |   1 +
 commands/findmnt.c | 108 +++++++++++++++++++++++++++++++++++++++++++++
 fs/fs.c            |   4 +-
 include/driver.h   |   5 +++
 include/fs.h       |   2 +
 6 files changed, 132 insertions(+), 3 deletions(-)
 create mode 100644 commands/findmnt.c

diff --git a/commands/Kconfig b/commands/Kconfig
index 04bfc85a951d..9df3c67d930d 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -655,6 +655,21 @@ config CMD_MOUNT
 		  -o OPTIONS	set file system OPTIONS
 		  -v		verbose
 
+config CMD_FINDMNT
+	tristate
+	prompt "findmnt"
+	help
+	  Find a file system
+
+	  Usage: findmnt [ DEVICE | -T FILE ]
+
+	  findmnt will list all mounted filesystems or search
+	  for a filesystem when given the mountpoint or the
+	  source device as an argument
+
+	  Options:
+		-T		mount target file path
+
 config CMD_PARTED
 	tristate
 	depends on PARTITION
diff --git a/commands/Makefile b/commands/Makefile
index 8fdff75a72a6..19c006101dc6 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_CMD_RM)		+= rm.o
 obj-$(CONFIG_CMD_CAT)		+= cat.o
 obj-$(CONFIG_CMD_MOUNT)		+= mount.o
 obj-$(CONFIG_CMD_UMOUNT)	+= umount.o
+obj-$(CONFIG_CMD_FINDMNT)	+= findmnt.o
 obj-$(CONFIG_CMD_REGINFO)	+= reginfo.o
 obj-$(CONFIG_CMD_CRC)		+= crc.o
 obj-$(CONFIG_CMD_CLEAR)		+= clear.o
diff --git a/commands/findmnt.c b/commands/findmnt.c
new file mode 100644
index 000000000000..da8f58835f28
--- /dev/null
+++ b/commands/findmnt.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// SPDX-FileCopyrightText: © 2022 Ahmad Fatoum, Pengutronix
+
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <errno.h>
+#include <getopt.h>
+
+static void print_header(bool *header_printed)
+{
+	if (*header_printed)
+		return;
+	printf("%-20s%-25s%-10s%-20s\n", "TARGET", "SOURCE", "FSTYPE", "OPTIONS");
+	*header_printed = true;
+}
+
+static void report_findmnt(const struct fs_device *fsdev)
+{
+	const char *backingstore;
+
+	backingstore = fsdev->backingstore ?: cdev_name(fsdev->cdev) ?: "none";
+
+	printf("%-20s%-25s%-10s%-20s\n", fsdev->path, backingstore,
+	       fsdev->driver->drv.name, fsdev->options);
+}
+
+static int do_findmnt(int argc, char *argv[])
+{
+	bool header_printed = false;
+	struct fs_device *target = NULL;
+	char *device = NULL;
+	int opt, dirfd = AT_FDCWD;
+
+	while ((opt = getopt(argc, argv, "T:")) > 0) {
+		switch(opt) {
+		case 'T':
+			target = get_fsdevice_by_path(dirfd, optarg);
+			if (!target)
+				return COMMAND_ERROR;
+			break;
+		default:
+			return COMMAND_ERROR_USAGE;
+		}
+	}
+
+	argv += optind;
+	argc -= optind;
+
+	if ((target && argc > 0) || (!target && argc > 1))
+		return COMMAND_ERROR_USAGE;
+
+	if (target) {
+		print_header(&header_printed);
+		report_findmnt(target);
+		return 0;
+	}
+
+	if (argv[0]) {
+		device = canonicalize_path(dirfd, argv[0]);
+		if (!device)
+			return COMMAND_ERROR;
+	}
+
+	for_each_fs_device(target) {
+		if (!device || streq_ptr(target->path, device) ||
+		    streq_ptr(target->backingstore, device)) {
+			print_header(&header_printed);
+			report_findmnt(target);
+		} else {
+			const char *backingstore;
+			struct cdev *cdev;
+
+			cdev = cdev_by_name(devpath_to_name(device));
+			if (!cdev)
+				continue;
+
+			backingstore = target->backingstore;
+			backingstore += str_has_prefix(backingstore, "/dev/");
+
+			if (streq_ptr(backingstore, cdev->name)) {
+				print_header(&header_printed);
+				report_findmnt(target);
+			}
+		}
+	}
+
+	free(device);
+
+	return header_printed ? 0 : COMMAND_ERROR;
+}
+
+BAREBOX_CMD_HELP_START(findmnt)
+BAREBOX_CMD_HELP_TEXT("findmnt will list all mounted filesystems or search")
+BAREBOX_CMD_HELP_TEXT("for a filesystem when given the mountpoint or the")
+BAREBOX_CMD_HELP_TEXT("source device as an argument")
+BAREBOX_CMD_HELP_TEXT("")
+BAREBOX_CMD_HELP_TEXT("Options:")
+BAREBOX_CMD_HELP_OPT ("-T",  "mount target file path")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(findmnt)
+	.cmd		= do_findmnt,
+	BAREBOX_CMD_DESC("find a file system")
+	BAREBOX_CMD_OPTS("[ DEVICE | -T FILE ]")
+	BAREBOX_CMD_GROUP(CMD_GRP_FILE)
+	BAREBOX_CMD_HELP(cmd_findmnt_help)
+BAREBOX_CMD_END
diff --git a/fs/fs.c b/fs/fs.c
index 9b876fe1f9be..0ff7f1b6f947 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -130,8 +130,6 @@ void cdev_print(const struct cdev *cdev)
 }
 EXPORT_SYMBOL(cdev_print);
 
-static struct fs_device *get_fsdevice_by_path(int dirfd, const char *path);
-
 void stat_print(const char *filename, const struct stat *st)
 {
 	int dirfd = AT_FDCWD;
@@ -2383,7 +2381,7 @@ static int filename_lookup(int dirfd, struct filename *name, unsigned flags,
 	return err;
 }
 
-static struct fs_device *get_fsdevice_by_path(int dirfd, const char *pathname)
+struct fs_device *get_fsdevice_by_path(int dirfd, const char *pathname)
 {
 	struct fs_device *fsdev;
 	struct path path;
diff --git a/include/driver.h b/include/driver.h
index 54b30d9921e0..7ff65d63946d 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -590,6 +590,11 @@ static inline void cdev_set_of_node(struct cdev *cdev, struct device_node *np)
 		cdev->device_node = np;
 }
 
+static inline const char *cdev_name(struct cdev *cdev)
+{
+	return cdev ? cdev->name : NULL;
+}
+
 int devfs_create(struct cdev *);
 int devfs_create_link(struct cdev *, const char *name);
 int devfs_remove(struct cdev *);
diff --git a/include/fs.h b/include/fs.h
index c4af8659b0d3..020761692cad 100644
--- a/include/fs.h
+++ b/include/fs.h
@@ -152,6 +152,8 @@ void cdev_print(const struct cdev *cdev);
 
 char *canonicalize_path(int dirfd, const char *pathname);
 
+struct fs_device *get_fsdevice_by_path(int dirfd, const char *path);
+
 char *get_mounted_path(const char *path);
 
 struct cdev *get_cdev_by_mountpath(const char *path);
-- 
2.39.2




More information about the barebox mailing list