or
.B \-\-raw
options are not specified.
-.IP "\fB\-p, \-\-poll\fP"
-Monitor changes in the /proc/self/mountinfo file. The standard columns always
-use the new version of the information from the mountinfo file, except the
-umount action which is based on the original information cached by
+.IP "\fB\-p, \-\-poll[=list]\fP"
+Monitor changes in the /proc/self/mountinfo file. Supported actions are: mount,
+umount, remount and move. More than one action may be specified in a
+comma-separated list. All actions are monitored by default.
+
+The time for which --poll will block could be restricted by \fB\-\-timeout\fP
+or \fB\-\-first-only\fP options.
+
+The standard columns always use the new version of the information from the
+mountinfo file, except the umount action which is based on the original
+information cached by
.BR findmnt (8) .
The poll mode allows to use extra columns:
.RS
Prints all
.IR /etc/fstab
filesystems and converts LABEL= and UUID= tags to the real device names.
-.IP "\fBfindmnt -n --raw --evaluate --output=target LABEL=/boot
+.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"
+Monitors mount, umount, remount and move on /mnt/foo.
+.IP "\fBfindmnt --poll=umount --first-only --target /mnt/foo\fP"
+Waits for /mnt/foo umount.
+.IP "\fBfindmnt --poll=remount -t ext3 -O ro\fP"
+Monitors remounts to read-only mode on all ext3 filesystems.
.SH AUTHORS
.nf
Karel Zak <kzak@redhat.com>
int columns[__NCOLUMNS];
int ncolumns;
+/* poll actions (parsed --poll=<list> */
+#define __NACTIONS 4 /* mount, umount, move, remount */
+int actions[__NACTIONS];
+int nactions;
+
/* libmount cache */
struct libmnt_cache *cache;
!get_match(COL_OPTIONS));
}
+/*
+ * Returns 1 if the @act is in the --poll=<list>
+ */
+static int has_poll_action(int act)
+{
+ int i;
+
+ if (!nactions)
+ return 1; /* all actions enabled */
+ for (i = 0; i < nactions; i++)
+ if (actions[i] == act)
+ return 1;
+ return 0;
+}
+
+static int poll_action_name_to_id(const char *name, size_t namesz)
+{
+ int id = -1;
+
+ if (strncasecmp(name, "move", namesz) == 0 && namesz == 4)
+ id = MNT_TABDIFF_MOVE;
+ else if (strncasecmp(name, "mount", namesz) == 0 && namesz == 5)
+ id = MNT_TABDIFF_MOUNT;
+ else if (strncasecmp(name, "umount", namesz) == 0 && namesz == 6)
+ id = MNT_TABDIFF_UMOUNT;
+ else if (strncasecmp(name, "remount", namesz) == 0 && namesz == 7)
+ id = MNT_TABDIFF_REMOUNT;
+ else
+ warnx(_("unknown action: %s"), name);
+
+ return id;
+}
+
/*
* findmnt --first-only <devname|TAG=|mountpoint>
*
return rc;
}
+static int poll_match(struct libmnt_fs *fs)
+{
+ int rc = match_func(fs, NULL);
+
+ if (rc == 0 && !(flags & FL_NOSWAPMATCH) &&
+ get_match(COL_SOURCE) && !get_match(COL_TARGET)) {
+ /*
+ * findmnt --poll /foo
+ * The '/foo' source as well as target.
+ */
+ const char *str = get_match(COL_SOURCE);
+
+ set_match(COL_TARGET, str); /* swap */
+ set_match(COL_SOURCE, NULL);
+
+ rc = match_func(fs, NULL);
+
+ set_match(COL_TARGET, NULL); /* restore */
+ set_match(COL_SOURCE, str);
+
+ }
+ return rc;
+}
+
static int poll_table(struct libmnt_table *tb, const char *tabfile,
int timeout, struct tt *tt, int direction)
{
while (1) {
struct libmnt_table *tmp;
struct libmnt_fs *old, *new;
- int change, x;
+ int change, count;
- x = poll(fds, 1, timeout);
- if (x == 0)
+ count = poll(fds, 1, timeout);
+ if (count == 0)
break; /* timeout */
- if (x < 0) {
+ if (count < 0) {
warn(_("poll() failed"));
goto done;
}
if (rc < 0)
goto done;
+ count = 0;
mnt_reset_iter(itr, direction);
while(mnt_tabdiff_next_change(
diff, itr, &old, &new, &change) == 0) {
+ if (!has_poll_action(change))
+ continue;
+ if (!poll_match(new ? new : old))
+ continue;
+ count++;
rc = !add_tabdiff_line(tt, new, old, change);
if (rc)
goto done;
break;
}
- rc = tt_print_table(tt);
- if (rc)
- goto done;
+ if (count) {
+ rc = tt_print_table(tt);
+ if (rc)
+ goto done;
+ }
/* swap tables */
tmp = tb;
tt_remove_lines(tt);
mnt_reset_table(tb_new);
+
+ if (count && (flags & FL_FIRSTONLY))
+ break;
}
rc = 0;
" -k, --kernel search in kernel table of mounted \n"
" filesystems (default)\n\n"
- " -p, --poll monitor changes in table of mounted filesystems\n"
+ " -p, --poll[=<list>] monitor changes in table of mounted filesystems\n"
" -w, --timeout <num> upper limit in millisecods which --poll will block\n\n"
" -c, --canonicalize canonicalize printed paths\n"
{ "notruncate", 0, 0, 'u' },
{ "options", 1, 0, 'O' },
{ "output", 1, 0, 'o' },
- { "poll", 0, 0, 'p' },
+ { "poll", 2, 0, 'p' },
{ "raw", 0, 0, 'r' },
{ "types", 1, 0, 't' },
{ "fsroot", 0, 0, 'v' },
tt_flags |= TT_FL_TREE;
while ((c = getopt_long(argc, argv,
- "acd:ehifo:O:pklmnrst:uvRS:T:w:", longopts, NULL)) != -1) {
+ "acd:ehifo:O:p::klmnrst:uvRS:T:w:", longopts, NULL)) != -1) {
switch(c) {
case 'a':
tt_flags |= TT_FL_ASCII;
set_match(COL_OPTIONS, optarg);
break;
case 'p':
+ if (optarg &&
+ tt_parse_columns_list(optarg, actions, &nactions,
+ poll_action_name_to_id))
+ exit(EXIT_FAILURE);
+
flags |= FL_POLL;
tt_flags &= ~TT_FL_TREE;
break;