findmnt: add --mountpoint command line option

The current --target <path> implementation check the <path> 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 <path>. The new option "--mountpoint <path>" allows to be strict.

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2015-03-19 12:08:30 +01:00
parent 8ba3f35e07
commit 0009f510cb
7 changed files with 49 additions and 27 deletions

View File

@ -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.

View File

@ -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 <path>. 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] <device> | <mountpoint>\n"
" %1$s [options] <device> <mountpoint>\n"
" %1$s [options] [--source <device>] [--target <mountpoint>]\n"),
" %1$s [options] [--source <device>] [--target <path> | --mountpoint <dir>]\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 <string> the device to mount (by name, maj:min, \n"
" LABEL=, UUID=, PARTUUID=, PARTLABEL=)\n"), out);
fputs(_(" -T, --target <string> the mountpoint to use\n"), out);
fputs(_(" -T, --target <path> the path to the filesystem to use\n"), out);
fputs(_(" -M, --mountpoint <dir> the mountpoint directory\n"), out);
fputs(_(" -t, --types <list> 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,

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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