From: Karel Zak Date: Tue, 5 Aug 2025 13:39:53 +0000 (+0200) Subject: libmount: (monitor) add fanotify_next_fs() X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f744e6391b1af5bb68e79b6e6d59f842450c2526;p=thirdparty%2Futil-linux.git libmount: (monitor) add fanotify_next_fs() This function returns a unique filesystem ID to the caller. Signed-off-by: Karel Zak --- diff --git a/libmount/src/monitor.c b/libmount/src/monitor.c index 2202c712c..194817aac 100644 --- a/libmount/src/monitor.c +++ b/libmount/src/monitor.c @@ -449,7 +449,7 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn, if (type) *type = me->type; - DBG(MONITOR, ul_debugobj(mn, " *** success [changed: %s]", me->path)); + DBG(MONITOR, ul_debugobj(mn, " *** success [changed: %s, type=%d]", me->path, me->type)); return 0; } @@ -564,6 +564,7 @@ static int __test_epoll(struct libmnt_test *ts __attribute__((unused)), int fd, efd = -1, rc = -1; struct epoll_event ev; struct libmnt_monitor *mn = create_test_monitor(argc, argv); + struct libmnt_fs *fs = NULL; if (!mn) return -1; @@ -609,8 +610,25 @@ static int __test_epoll(struct libmnt_test *ts __attribute__((unused)), if (cleanup) mnt_monitor_event_cleanup(mn); else { - while (mnt_monitor_next_change(mn, &filename, NULL) == 0) + int type = 0; + + while (mnt_monitor_next_change(mn, &filename, &type) == 0) { printf(" %s: change detected\n", filename); + + if (type == MNT_MONITOR_TYPE_FANOTIFY) { + if (!fs) + fs = mnt_new_fs(); + while (mnt_monitor_event_next_fs(mn, fs) == 0) { + mnt_fs_fetch_statmount(fs, 0); + printf("ID=%ju (%s %s)\n", + mnt_fs_get_uniq_id(fs), + mnt_fs_get_target(fs), + mnt_fs_is_attached(fs) ? "ATTACHED" : + mnt_fs_is_detached(fs) ? "DETACHED" : + mnt_fs_is_moved(fs) ? "MOVED" : "???"); + } + } + } } } while (1); @@ -619,6 +637,7 @@ done: if (efd >= 0) close(efd); mnt_unref_monitor(mn); + mnt_unref_fs(fs); return rc; } diff --git a/libmount/src/monitor_fanotify.c b/libmount/src/monitor_fanotify.c index 6adb6e5af..7e6903beb 100644 --- a/libmount/src/monitor_fanotify.c +++ b/libmount/src/monitor_fanotify.c @@ -125,8 +125,8 @@ static int fanotify_process_event( struct monitor_entrydata *data; ssize_t len; - if (!mn || !me || me->fd < 0) - return 0; + if (!mn || !me || me->fd < 0 || !me->data) + return -EINVAL; DBG(MONITOR, ul_debugobj(mn, "reading fanotify event")); @@ -148,13 +148,72 @@ static int fanotify_process_event( } len = read(me->fd, data->buf, sizeof(data->buf)); - if (len < 0) + if (len <= 0) return 1; /* nothing */ data->remaining = (size_t) len; - DBG(MONITOR, ul_debugobj(mn, " fanotify event [len=%zu]", data->remaining)); + DBG(MONITOR, ul_debugobj(mn, " fanotify event [len=%zu %p]", + data->remaining, data->current)); + + return 0; +} + +/* Returns: <0 error; 0 success; 1 nothing */ +static int fanotify_next_fs(struct libmnt_monitor *mn, struct monitor_entry *me, + struct libmnt_fs *fs) +{ + struct monitor_entrydata *data; + size_t thislen; + + struct fanotify_event_metadata *meta; + struct fanotify_event_info_mnt *mnt; + + if (!mn || !me || me->fd < 0 || !me->data) + return -EINVAL; + + DBG(MONITOR, ul_debugobj(mn, "next fanotify fs")); + data = (struct monitor_entrydata *) me->data; + if (!fs || !data->remaining) + goto nothing; + else { + struct libmnt_statmnt *tmp = fs->stmnt; + fs->stmnt = NULL; + mnt_reset_fs(fs); + fs->stmnt = tmp; + } + + meta = (struct fanotify_event_metadata *) data->current; + + if (!FAN_EVENT_OK(meta, data->remaining) || + meta->vers != FANOTIFY_METADATA_VERSION) + goto nothing; + + thislen = meta->event_len - sizeof(*meta); + + mnt = (struct fanotify_event_info_mnt *) + (data->current + meta->event_len - thislen); + + + mnt_fs_set_uniq_id(fs, mnt->mnt_id); + + if (meta->mask & FAN_MNT_ATTACH) + fs->flags |= MNT_FS_STATUS_ATTACH; + if (meta->mask & FAN_MNT_DETACH) + fs->flags |= MNT_FS_STATUS_DETACH; + + DBG(MONITOR, ul_debugobj(mn, "fanotify fs id=%ju %s\n", + (uintmax_t) mnt_fs_get_uniq_id(fs), + mnt_fs_is_attached(fs) ? "ATTACHED" : + mnt_fs_is_detached(fs) ? "DETACHED" : + mnt_fs_is_moved(fs) ? "MOVED" : "???")); + + data->current = (char *) FAN_EVENT_NEXT(meta, data->remaining); return 0; + +nothing: + data->remaining = 0; + return 1; } /* @@ -164,7 +223,8 @@ static const struct monitor_opers fanotify_opers = { .op_get_fd = fanotify_get_fd, .op_close_fd = fanotify_close_fd, .op_free_data = fanotify_free_data, - .op_process_event = fanotify_process_event + .op_process_event = fanotify_process_event, + .op_next_fs = fanotify_next_fs }; /**