From: Karel Zak Date: Wed, 19 Nov 2025 12:32:25 +0000 (+0100) Subject: mountpoint: add --show option to print mountpoint path X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f7facbb928a908ff4453891e45f124669f8318f1;p=thirdparty%2Futil-linux.git mountpoint: add --show option to print mountpoint path Add a new --show option that prints the actual mountpoint path for a given directory or file. This is useful for: - Resolving any path to its containing mountpoint - Finding the canonical mountpoint path when symlinks are involved - Determining the mountpoint from paths within filesystems The option requires kernel support for statmount(2) (Linux 6.8+). On older kernels without statmount support, the option fails with an error message, as the /proc/self/mountinfo fallback cannot resolve arbitrary paths to their containing mountpoint. Example usage: $ mountpoint --show / / $ mountpoint --show /home/user/file.txt /home The --show option always returns EXIT_SUCCESS (0) when it successfully finds the mountpoint, regardless of whether the given path itself is a mountpoint or not. Addresses: https://github.com/util-linux/util-linux/issues/3806 Signed-off-by: Karel Zak --- diff --git a/sys-utils/mountpoint.1.adoc b/sys-utils/mountpoint.1.adoc index 0e1252c72..250f6d1a9 100644 --- a/sys-utils/mountpoint.1.adoc +++ b/sys-utils/mountpoint.1.adoc @@ -34,6 +34,9 @@ Do not follow symbolic link if it the last element of the _directory_ path. *-x*, *--devno*:: Show the major/minor numbers of the given blockdevice on standard output. +*--show*:: +Print the mountpoint path for the given path. This resolves the given directory or file to its actual mountpoint, which is useful with bind mounts, symlinks, or paths within filesystems. This option requires kernel support for the *statmount*(2) system call (Linux 6.8 and newer). On older kernels, this option will fail with an error message. + include::man-common/help-version.adoc[] == EXIT STATUS diff --git a/sys-utils/mountpoint.c b/sys-utils/mountpoint.c index 8a114b5bb..aed1f0fef 100644 --- a/sys-utils/mountpoint.c +++ b/sys-utils/mountpoint.c @@ -37,12 +37,14 @@ struct mountpoint_control { char *path; + char *mnt_target; dev_t dev; struct stat st; bool dev_devno, fs_devno, nofollow, - quiet; + quiet, + show; }; #ifdef HAVE_STATMOUNT_API @@ -84,6 +86,9 @@ static int dir_to_device_statmount(struct mountpoint_control *ctl) goto done; } + if (ctl->show) + ctl->mnt_target = xstrdup(mnt_target); + if (strcmp(mnt_target, cn ? cn : ctl->path) != 0) rc = 1; /* not a mountpoint */ else { @@ -118,6 +123,9 @@ static int dir_to_device(struct mountpoint_control *ctl) /* * Fallback for older kernels without statmount() support */ + if (ctl->show) + errx(EXIT_FAILURE, _("--show is not supported on this system")); + tb = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO); if (!tb) { /* @@ -190,7 +198,8 @@ static void __attribute__((__noreturn__)) usage(void) fputs(_(" -q, --quiet quiet mode - don't print anything\n" " --nofollow do not follow symlink\n" " -d, --fs-devno print maj:min device number of the filesystem\n" - " -x, --devno print maj:min device number of the block device\n"), out); + " -x, --devno print maj:min device number of the block device\n" + " --show print mountpoint for given path\n"), out); fputs(USAGE_SEPARATOR, out); fprintf(out, USAGE_HELP_OPTIONS(20)); fprintf(out, USAGE_MAN_TAIL("mountpoint(1)")); @@ -204,7 +213,8 @@ int main(int argc, char **argv) struct mountpoint_control ctl = { NULL }; enum { - OPT_NOFOLLOW = CHAR_MAX + 1 + OPT_NOFOLLOW = CHAR_MAX + 1, + OPT_SHOW }; static const struct option longopts[] = { @@ -212,6 +222,7 @@ int main(int argc, char **argv) { "nofollow", no_argument, NULL, OPT_NOFOLLOW }, { "fs-devno", no_argument, NULL, 'd' }, { "devno", no_argument, NULL, 'x' }, + { "show", no_argument, NULL, OPT_SHOW }, { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } @@ -239,6 +250,9 @@ int main(int argc, char **argv) case 'x': ctl.dev_devno = 1; break; + case OPT_SHOW: + ctl.show = 1; + break; case 'h': usage(); @@ -281,6 +295,13 @@ int main(int argc, char **argv) } return EXIT_FAILURE; } + + if (ctl.show) { + printf("%s\n", ctl.mnt_target); + free(ctl.mnt_target); + return EXIT_SUCCESS; + } + if (rc == 1) { if (!ctl.quiet) printf(_("%s is not a mountpoint\n"), ctl.path);