diff options
author | Karel Zak | 2011-04-27 22:39:44 +0200 |
---|---|---|
committer | Karel Zak | 2011-04-27 22:59:00 +0200 |
commit | 582a5006d4ccac6131ad9e3eb3f391f4904bf4e3 (patch) | |
tree | 158e113fc07a4d9e4c31a99045a93c0824c54848 /misc-utils/findmnt.c | |
parent | findmnt: print OLD-* columns only when necessary (diff) | |
download | kernel-qcow2-util-linux-582a5006d4ccac6131ad9e3eb3f391f4904bf4e3.tar.gz kernel-qcow2-util-linux-582a5006d4ccac6131ad9e3eb3f391f4904bf4e3.tar.xz kernel-qcow2-util-linux-582a5006d4ccac6131ad9e3eb3f391f4904bf4e3.zip |
findmnt: filter filesystems and actions for --poll
The patch allows to filter by:
* actions name:
$ findmnt --poll=umount
* target, source, fstype, options:
$ findmnt --poll /mnt/test
$ findmnt --poll -O ro
$ findmnt --poll -t ext4
* --first-only option to wait only for the first matching change:
$ findmnt --poll=umount --first-only /mnt/test
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'misc-utils/findmnt.c')
-rw-r--r-- | misc-utils/findmnt.c | 98 |
1 files changed, 88 insertions, 10 deletions
diff --git a/misc-utils/findmnt.c b/misc-utils/findmnt.c index 71a44f001..4a2096982 100644 --- a/misc-utils/findmnt.c +++ b/misc-utils/findmnt.c @@ -102,6 +102,11 @@ int tt_flags = 0; 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; @@ -177,6 +182,39 @@ static int is_listall_mode(void) } /* + * 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> * * ... it works like "mount <devname|TAG=|mountpoint>" @@ -586,6 +624,30 @@ done: 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) { @@ -632,12 +694,12 @@ static int poll_table(struct libmnt_table *tb, const char *tabfile, 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; } @@ -649,10 +711,16 @@ static int poll_table(struct libmnt_table *tb, const char *tabfile, 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; @@ -660,9 +728,11 @@ static int poll_table(struct libmnt_table *tb, const char *tabfile, 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; @@ -671,6 +741,9 @@ static int poll_table(struct libmnt_table *tb, const char *tabfile, tt_remove_lines(tt); mnt_reset_table(tb_new); + + if (count && (flags & FL_FIRSTONLY)) + break; } rc = 0; @@ -700,7 +773,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out) " -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" @@ -771,7 +844,7 @@ int main(int argc, char *argv[]) { "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' }, @@ -793,7 +866,7 @@ int main(int argc, char *argv[]) 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; @@ -834,6 +907,11 @@ int main(int argc, char *argv[]) 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; |