From 0009f510cb4bafabbec0d26acd7385436c3e7c8b Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Thu, 19 Mar 2015 12:08:30 +0100 Subject: [PATCH] findmnt: add --mountpoint command line option The current --target implementation check the elements in reverse order to get the mountpoint. The feature may be inwanted in some cases when we really want to check for mountpoint specified by the . The new option "--mountpoint " allows to be strict. Signed-off-by: Karel Zak --- misc-utils/findmnt.8 | 25 +++++++++++++++++-------- misc-utils/findmnt.c | 21 +++++++++++++++++---- tests/ts/mount/fstab-broken | 4 ++-- tests/ts/mount/fstab-none | 4 ++-- tests/ts/mount/move | 4 ++-- tests/ts/mount/remount | 2 +- tests/ts/mount/shared-subtree | 16 ++++++++-------- 7 files changed, 49 insertions(+), 27 deletions(-) diff --git a/misc-utils/findmnt.8 b/misc-utils/findmnt.8 index 31c614ae1f..620e422de5 100644 --- a/misc-utils/findmnt.8 +++ b/misc-utils/findmnt.8 @@ -13,7 +13,7 @@ findmnt \- find a filesystem [options] .RB [ \-\-source ] .IR device -.RB [ \-\-target ] +.RB [ \-\-target | \-\-mountpoint ] .IR mountpoint .SH DESCRIPTION .B findmnt @@ -31,9 +31,13 @@ or is not given, all filesystems are shown. .PP The device may be specified by device name, maj:min, filesystem LABEL or UUID, -or partition PARTUUID or PARTLABEL. Note that a device name may be interpreted -as a mountpoint (and vice versa) if the \fB--target\fR or \fB--source\fR options -are not specified. +or partition PARTUUID or PARTLABEL. Note that +.B findmnt +follows +.BR mount (8) +behavior where a device name may be interpreted +as a mountpoint (and vice versa) if the \fB--target\fR, \fB--mountpoint\fR or +\fB--source\fR options are not specified. .PP The command prints all mounted filesystems in the tree-like format by default. .SH OPTIONS @@ -96,6 +100,9 @@ output is restricted by the \fB\-t\fP, \fB\-O\fP, \fB\-S\fP or \fB\-T\fP option and the option \fB\-\-submounts\fP is not used or if more that one source file (the option \fB\-F\fP) is specified. .TP +.BR \-M , " \-\-mountpoint \fIpath\fP" +Explicitly define the mountpoint file or directory. See also \fB\-\-target\fP. +.TP .BR \-m , " \-\-mtab" Search in .IR /etc/mtab . @@ -186,11 +193,13 @@ Search in The output is in the list format (see \fB--list\fR). .TP .BR \-T , " \-\-target \fIpath\fP" -Explicitly define the mount target (mountpoint directory). If the \fIpath\fR +Define the mount target. If the \fIpath\fR is not a mountpoint file or directory than .B findmnt checks \fIpath\fR elements in reverse order for get the mountpoint (this feature is -supported only if search in kernel files and unsupported for \fB\-\-fstab\fP). +supported only if search in kernel files and unsupported for \fB\-\-fstab\fP). It's +recommended to use the option \fB--mountpoint\fR when checks \fIpath\fR elements is +unwanted and \fIpath\fR is strictly specified mountpoint. .TP .BR \-t , " \-\-types \fIlist\fP" Limit the set of printed filesystems. More than one type may be @@ -239,9 +248,9 @@ Prints all filesystems and converts LABEL= and UUID= tags to the real device names. .IP "\fBfindmnt -n --raw --evaluate --output=target LABEL=/boot\fP" Prints only the mountpoint where the filesystem with label "/boot" is mounted. -.IP "\fBfindmnt --poll --target /mnt/foo\fP" +.IP "\fBfindmnt --poll --mountpoint /mnt/foo\fP" Monitors mount, unmount, remount and move on /mnt/foo. -.IP "\fBfindmnt --poll=umount --first-only --target /mnt/foo\fP" +.IP "\fBfindmnt --poll=umount --first-only --mountpoint /mnt/foo\fP" Waits for /mnt/foo unmount. .IP "\fBfindmnt --poll=remount -t ext3 -O ro\fP" Monitors remounts to read-only mode on all ext3 filesystems. diff --git a/misc-utils/findmnt.c b/misc-utils/findmnt.c index 1adc231240..f76ac2e041 100644 --- a/misc-utils/findmnt.c +++ b/misc-utils/findmnt.c @@ -62,6 +62,7 @@ enum { FL_UNIQ = (1 << 12), FL_BYTES = (1 << 13), FL_NOCACHE = (1 << 14), + FL_STRICTTARGET = (1 << 15), /* basic table settings */ FL_ASCII = (1 << 20), @@ -259,7 +260,12 @@ static void set_source_match(const char *data) set_match(COL_SOURCE, data); } -/* @tb has to be from kernel (so no fstab or so)! */ +/* + * Extra functionality for --target . The function mnt_table_find_mountpoint() + * also checks parents (path elements in reverse order) to get mountpoint. + * + * @tb has to be from kernel (so no fstab or so)! + */ static void enable_extra_target_match(struct libmnt_table *tb) { char *cn = NULL; @@ -1201,7 +1207,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out) " %1$s [options]\n" " %1$s [options] | \n" " %1$s [options] \n" - " %1$s [options] [--source ] [--target ]\n"), + " %1$s [options] [--source ] [--target | --mountpoint ]\n"), program_invocation_short_name); fputs(USAGE_SEPARATOR, out); @@ -1239,7 +1245,8 @@ static void __attribute__((__noreturn__)) usage(FILE *out) fputs(_(" -r, --raw use raw output format\n"), out); fputs(_(" -S, --source the device to mount (by name, maj:min, \n" " LABEL=, UUID=, PARTUUID=, PARTLABEL=)\n"), out); - fputs(_(" -T, --target the mountpoint to use\n"), out); + fputs(_(" -T, --target the path to the filesystem to use\n"), out); + fputs(_(" -M, --mountpoint the mountpoint directory\n"), out); fputs(_(" -t, --types limit the set of filesystems by FS types\n"), out); fputs(_(" -U, --uniq ignore filesystems with duplicate target\n"), out); fputs(_(" -u, --notruncate don't truncate text in columns\n"), out); @@ -1284,6 +1291,7 @@ int main(int argc, char *argv[]) { "invert", 0, 0, 'i' }, { "kernel", 0, 0, 'k' }, { "list", 0, 0, 'l' }, + { "mountpoint", 1, 0, 'M' }, { "mtab", 0, 0, 'm' }, { "noheadings", 0, 0, 'n' }, { "notruncate", 0, 0, 'u' }, @@ -1310,6 +1318,7 @@ int main(int argc, char *argv[]) static const ul_excl_t excl[] = { /* rows and cols in in ASCII order */ { 'C', 'c'}, /* [no]canonicalize */ { 'C', 'e' }, /* nocanonicalize, evaluate */ + { 'M', 'T' }, /* mountpoint, target */ { 'N','k','m','s' }, /* task,kernel,mtab,fstab */ { 'P','l','r' }, /* pairs,list,raw */ { 'm','p','s' }, /* mtab,poll,fstab */ @@ -1326,7 +1335,7 @@ int main(int argc, char *argv[]) flags |= FL_TREE; while ((c = getopt_long(argc, argv, - "AabCcDd:ehifF:o:O:p::PklmnN:rst:uvRS:T:Uw:V", + "AabCcDd:ehifF:o:O:p::PklmM:nN:rst:uvRS:T:Uw:V", longopts, NULL)) != -1) { err_exclusive_options(c, longopts, excl, excl_st); @@ -1439,6 +1448,9 @@ int main(int argc, char *argv[]) set_source_match(optarg); flags |= FL_NOSWAPMATCH; break; + case 'M': + flags |= FL_STRICTTARGET; + /* fallthrough */ case 'T': set_match(COL_TARGET, optarg); flags |= FL_NOSWAPMATCH; @@ -1602,6 +1614,7 @@ int main(int argc, char *argv[]) if (rc != 0 && tabtype == TABTYPE_KERNEL && (flags & FL_NOSWAPMATCH) + && !(flags & FL_STRICTTARGET) && get_match(COL_TARGET)) { /* * Found nothing, maybe the --target is regular file, diff --git a/tests/ts/mount/fstab-broken b/tests/ts/mount/fstab-broken index 5934c22d37..2f0f63caeb 100755 --- a/tests/ts/mount/fstab-broken +++ b/tests/ts/mount/fstab-broken @@ -39,7 +39,7 @@ ts_fstab_close ts_init_subtest "mount" $TS_CMD_MOUNT $MNT &> /dev/null -$TS_CMD_FINDMNT --kernel --target "$MNT" &> /dev/null +$TS_CMD_FINDMNT --kernel --mountpoint "$MNT" &> /dev/null if [ "$?" != "0" ]; then ts_log "Cannot find $MNT in /proc/self/mountinfo" else @@ -51,7 +51,7 @@ ts_finalize_subtest ts_init_subtest "mount-all" $TS_CMD_MOUNT -a &> /dev/null -$TS_CMD_FINDMNT --kernel --target "$MNT" &> /dev/null +$TS_CMD_FINDMNT --kernel --mountpoint "$MNT" &> /dev/null if [ "$?" != "0" ]; then ts_log "Cannot find $MNT in /proc/self/mountinfo" else diff --git a/tests/ts/mount/fstab-none b/tests/ts/mount/fstab-none index 64eb48bbfb..f4684b11c0 100755 --- a/tests/ts/mount/fstab-none +++ b/tests/ts/mount/fstab-none @@ -20,10 +20,10 @@ mkdir -p $TS_MOUNTPOINT $TS_CMD_MOUNT $TS_MOUNTPOINT 2>&1 >> $TS_OUTPUT -$TS_CMD_FINDMNT --target "$TS_MOUNTPOINT" &> /dev/null +$TS_CMD_FINDMNT --mountpoint "$TS_MOUNTPOINT" &> /dev/null [ $? -eq 0 ] || ts_die "Not found target (mount failed?)" -$TS_CMD_FINDMNT --source "none" --target "$TS_MOUNTPOINT" &> /dev/null +$TS_CMD_FINDMNT --source "none" --mountpoint "$TS_MOUNTPOINT" &> /dev/null [ $? -eq 0 ] || ts_die "Not found source and target" $TS_CMD_UMOUNT $TS_MOUNTPOINT || ts_die "Cannot umount $TS_MOUNTPOINT" diff --git a/tests/ts/mount/move b/tests/ts/mount/move index 5244887773..1e50d01d4f 100755 --- a/tests/ts/mount/move +++ b/tests/ts/mount/move @@ -49,14 +49,14 @@ $TS_CMD_MOUNT --make-private $DIR_PRIVATE $TS_CMD_MOUNT --bind $DIR_SRC $DIR_A # check the bind -$TS_CMD_FINDMNT --kernel --target "$DIR_A" &> /dev/null +$TS_CMD_FINDMNT --kernel --mountpoint "$DIR_A" &> /dev/null [ "$?" == "0" ] || ts_die "Cannot find binded $DIR_A in /proc/self/mountinfo" # move $TS_CMD_MOUNT --move $DIR_A $DIR_B # check the move -$TS_CMD_FINDMNT --kernel --target "$DIR_B" &> /dev/null +$TS_CMD_FINDMNT --kernel --mountpoint "$DIR_B" &> /dev/null [ "$?" == "0" ] || ts_die "Cannot find binded $DIR_B in /proc/self/mountinfo" # clean up diff --git a/tests/ts/mount/remount b/tests/ts/mount/remount index 99ede4a75c..6814e313ee 100755 --- a/tests/ts/mount/remount +++ b/tests/ts/mount/remount @@ -48,7 +48,7 @@ $TS_CMD_MOUNT -o remount,ro $TS_MOUNTPOINT \ || ts_die "Cannot remount $TS_MOUNTPOINT" $DEVICE # check the remount -$TS_CMD_FINDMNT --kernel --target "$TS_MOUNTPOINT" --options "ro" &> /dev/null +$TS_CMD_FINDMNT --kernel --mountpoint "$TS_MOUNTPOINT" --options "ro" &> /dev/null [ "$?" == "0" ] || ts_die "Cannot find read-only in $TS_MOUNTPOINT in /proc/self/mountinfo" ts_device_deinit $DEVICE diff --git a/tests/ts/mount/shared-subtree b/tests/ts/mount/shared-subtree index 45154835d0..2f8f5b90a1 100755 --- a/tests/ts/mount/shared-subtree +++ b/tests/ts/mount/shared-subtree @@ -20,7 +20,7 @@ ts_check_losetup $TS_CMD_MOUNT --bind $TS_MOUNTPOINT $TS_MOUNTPOINT # check the bind -$TS_CMD_FINDMNT --kernel --target $TS_MOUNTPOINT &> /dev/null +$TS_CMD_FINDMNT --kernel --mountpoint $TS_MOUNTPOINT &> /dev/null [ "$?" == "0" ] || ts_die "Cannot find binded $TS_MOUNTPOINT in /proc/self/mountinfo" # use the same mounpoint for all sub-tests @@ -29,18 +29,18 @@ MOUNTPOINT="$TS_MOUNTPOINT" ts_init_subtest "make-shared" $TS_CMD_MOUNT --make-shared $MOUNTPOINT >> $TS_OUTPUT 2>&1 -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT ts_finalize_subtest ts_init_subtest "make-private" $TS_CMD_MOUNT --make-private $MOUNTPOINT >> $TS_OUTPUT 2>&1 -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT ts_finalize_subtest ts_init_subtest "make-unbindable" $TS_CMD_MOUNT --make-unbindable $MOUNTPOINT >> $TS_OUTPUT 2>&1 -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT ts_finalize_subtest # clean up @@ -50,7 +50,7 @@ $TS_CMD_UMOUNT $MOUNTPOINT ts_init_subtest "bind-shared" $TS_CMD_MOUNT --make-shared \ --bind $MOUNTPOINT $MOUNTPOINT >> $TS_OUTPUT 2>&1 -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT $TS_CMD_UMOUNT $MOUNTPOINT ts_finalize_subtest @@ -68,14 +68,14 @@ ts_device_has "TYPE" "ext3" $DEVICE || ts_die "Cannot find ext3 on $DEVICE" $DEV ts_init_subtest "mount-private" $TS_CMD_MOUNT --make-private --make-unbindable \ $DEVICE $MOUNTPOINT >> $TS_OUTPUT 2>&1 -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT $TS_CMD_UMOUNT $MOUNTPOINT ts_finalize_subtest ts_init_subtest "mount-private-ro" $TS_CMD_MOUNT $DEVICE $MOUNTPOINT -o ro,private >> $TS_OUTPUT 2>&1 -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT -$TS_CMD_FINDMNT -nr --target $MOUNTPOINT -o VFS-OPTIONS >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o PROPAGATION >> $TS_OUTPUT +$TS_CMD_FINDMNT -nr --mountpoint $MOUNTPOINT -o VFS-OPTIONS >> $TS_OUTPUT $TS_CMD_UMOUNT $MOUNTPOINT ts_finalize_subtest -- 2.47.2