From: Karel Zak Date: Mon, 1 Jun 2015 11:17:41 +0000 (+0200) Subject: libmount: fix mnt_monitor_event_cleanup() X-Git-Tag: v2.27-rc1~182 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08e193e1e468f3f570e686f7e495b21fa47ba661;p=thirdparty%2Futil-linux.git 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 --- diff --git a/libmount/src/monitor.c b/libmount/src/monitor.c index 28064b8968..34bdd767b3 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; @@ -878,6 +877,19 @@ done: return rc; } +/* + * 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 */ @@ -905,6 +917,7 @@ int main(int argc, char *argv[]) { struct libmnt_test tss[] = { { "--epoll", test_epoll, " monitor in epoll" }, + { "--epoll-clean", test_epoll_cleanup, " monitor in epoll and clean events" }, { "--wait", test_wait, " monitor wait function" }, { NULL } };