diff options
author | Karel Zak | 2015-06-01 13:17:41 +0200 |
---|---|---|
committer | Karel Zak | 2015-06-01 13:17:41 +0200 |
commit | 08e193e1e468f3f570e686f7e495b21fa47ba661 (patch) | |
tree | 44e7dfbffbf36d98e5ac8ae87f305393fb0ac597 /libmount/src/monitor.c | |
parent | lsblk: use internally sysfs devnames (diff) | |
download | kernel-qcow2-util-linux-08e193e1e468f3f570e686f7e495b21fa47ba661.tar.gz kernel-qcow2-util-linux-08e193e1e468f3f570e686f7e495b21fa47ba661.tar.xz kernel-qcow2-util-linux-08e193e1e468f3f570e686f7e495b21fa47ba661.zip |
libmount: fix mnt_monitor_event_cleanup()
We have to call epoll to drain mountinfo events too. The problem is
visible if the monitor epoll FD is within another (top-level) epoll.
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libmount/src/monitor.c')
-rw-r--r-- | libmount/src/monitor.c | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/libmount/src/monitor.c b/libmount/src/monitor.c index 28064b896..34bdd767b 100644 --- a/libmount/src/monitor.c +++ b/libmount/src/monitor.c @@ -713,7 +713,7 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn, return -EINVAL; /* - * if we previously called epoll_wait() (e.g. mnt_monitor_waith()) then + * if we previously called epoll_wait() (e.g. mnt_monitor_wait()) then * info about unread change is already stored in monitor_entry. * * If we get nothing, then ask kernel. @@ -751,7 +751,7 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn, if (type) *type = me->type; - DBG(MONITOR, ul_debugobj(mn, " *** success")); + DBG(MONITOR, ul_debugobj(mn, " *** success [changed: %s]", me->path)); return 0; /* success */ } @@ -766,18 +766,13 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn, */ int mnt_monitor_event_cleanup(struct libmnt_monitor *mn) { - struct monitor_entry *me; - struct libmnt_iter itr; + int rc; if (!mn || mn->fd < 0) return -EINVAL; - mnt_reset_iter(&itr, MNT_ITER_FORWARD); - while (monitor_next_entry(mn, &itr, &me) == 0) { - if (me->opers->op_event_cleanup != NULL) - me->opers->op_event_cleanup(mn, me); - } - return 0; + while ((rc = mnt_monitor_next_change(mn, NULL, NULL)) == 0); + return rc < 0 ? rc : 0; } #ifdef TEST_PROGRAM @@ -821,7 +816,7 @@ err: /* * create a monitor and add the monitor fd to epoll */ -int test_epoll(struct libmnt_test *ts, int argc, char *argv[]) +int __test_epoll(struct libmnt_test *ts, int argc, char *argv[], int cleanup) { int fd, efd = -1, rc = -1; struct epoll_event ev; @@ -866,8 +861,12 @@ int test_epoll(struct libmnt_test *ts, int argc, char *argv[]) continue; printf(" top-level FD active\n"); - while (mnt_monitor_next_change(mn, &filename, NULL) == 0) - printf(" %s: change detected\n", filename); + if (cleanup) + mnt_monitor_event_cleanup(mn); + else { + while (mnt_monitor_next_change(mn, &filename, NULL) == 0) + printf(" %s: change detected\n", filename); + } } while (1); rc = 0; @@ -879,6 +878,19 @@ done: } /* + * create a monitor and add the monitor fd to epoll + */ +int test_epoll(struct libmnt_test *ts, int argc, char *argv[]) +{ + return __test_epoll(ts, argc, argv, 0); +} + +int test_epoll_cleanup(struct libmnt_test *ts, int argc, char *argv[]) +{ + return __test_epoll(ts, argc, argv, 1); +} + +/* * create a monitor and wait for a change */ int test_wait(struct libmnt_test *ts, int argc, char *argv[]) @@ -905,6 +917,7 @@ int main(int argc, char *argv[]) { struct libmnt_test tss[] = { { "--epoll", test_epoll, "<userspace kernel ...> monitor in epoll" }, + { "--epoll-clean", test_epoll_cleanup, "<userspace kernel ...> monitor in epoll and clean events" }, { "--wait", test_wait, "<userspace kernel ...> monitor wait function" }, { NULL } }; |