[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