From dbd9c5143f2a75cde1d8eb5ccb66412fb89ac64e Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 10 Jun 2025 11:05:20 +0200 Subject: [PATCH] libmount: (monitor) add next-fs API Signed-off-by: Karel Zak --- libmount/docs/libmount-sections.txt | 1 + libmount/src/libmount.h.in | 3 ++ libmount/src/libmount.sym | 1 + libmount/src/monitor.c | 48 +++++++++++++++++++++++++++-- libmount/src/monitor.h | 2 ++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt index 60dffba7e..e791415d9 100644 --- a/libmount/docs/libmount-sections.txt +++ b/libmount/docs/libmount-sections.txt @@ -488,6 +488,7 @@ mnt_monitor_get_fd mnt_monitor_close_fd mnt_monitor_next_change mnt_monitor_event_cleanup +mnt_monitor_event_next_fs mnt_monitor_veil_kernel mnt_monitor_wait diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index f30f94cdc..50e865899 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -761,7 +761,10 @@ extern int mnt_monitor_wait(struct libmnt_monitor *mn, int timeout); extern int mnt_monitor_next_change(struct libmnt_monitor *mn, const char **filename, int *type); + extern int mnt_monitor_event_cleanup(struct libmnt_monitor *mn); +extern int mnt_monitor_event_next_fs(struct libmnt_monitor *mn, + struct libmnt_fs *fs); /* context.c */ diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index cbef26fb0..f8fdd0ef6 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -412,4 +412,5 @@ MOUNT_2_41 { MOUNT_2_42 { mnt_context_enable_exclusive; mnt_context_is_exclusive; + mnt_monitor_event_next_fs; } MOUNT_2_41; diff --git a/libmount/src/monitor.c b/libmount/src/monitor.c index 6272fbdd2..f625dafb6 100644 --- a/libmount/src/monitor.c +++ b/libmount/src/monitor.c @@ -413,8 +413,12 @@ static struct monitor_entry *get_active(struct libmnt_monitor *mn) * @filename: returns changed file (optional argument) * @type: returns MNT_MONITOR_TYPE_* (optional argument) * - * The function does not wait and it's designed to provide details about changes. - * It's always recommended to use this function to avoid false positives. + * The function does not wait and is designed to provide details about changes. + * It is always recommended to use this function to avoid false positives. + * + * This function iterates over a list of unprocessed events. When an event is returned + * by this function, it is marked as processed. If you need details about the last + * processed event, use the mnt_monitor_event_* functions. * * Returns: 0 on success, 1 no change, <0 on error */ @@ -428,6 +432,8 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn, if (!mn || mn->fd < 0) return -EINVAL; + mn->last = NULL; + me = get_active(mn); if (!me) { rc = read_epoll_events(mn, 0, &me); /* try without timeout */ @@ -436,6 +442,7 @@ int mnt_monitor_next_change(struct libmnt_monitor *mn, } me->active = 0; + mn->last = me; if (filename) *filename = me->path; @@ -466,6 +473,43 @@ int mnt_monitor_event_cleanup(struct libmnt_monitor *mn) return rc < 0 ? rc : 0; } +/** + * mnt_monitor_event_next_fs: + * @mn: monitor + * @fs: filesystem + * + * Fill in details about the next filesystem associated with the last event + * (as returned by mnt_monitor_next_change()). If the event does not provide + * details, it returns -ENOTSUP. + * + * + * + * while (mnt_monitor_next_change(mn, NULL, &type) == 0) { + * if (type == MNT_MONITOR_TYPE_FANOTIFY) { + * while (mnt_monitor_event_next_fs(mn, fs) == 0) { + * printf("ID=%ju\n", mnt_fs_get_uniq_id(fs)); + * } + * } + * } + * + * + * + * Returns: 0 on success, 1 no more data, <0 on error + * + * Since: 2.42 + */ +int mnt_monitor_event_next_fs(struct libmnt_monitor *mn, struct libmnt_fs *fs) +{ + if (!mn || !fs) + return -EINVAL; + if (!mn->last) + return 1; + if (!mn->last->opers->op_next_fs) + return -ENOTSUP; + + return mn->last->opers->op_next_fs(mn, mn->last, fs); +} + #ifdef TEST_PROGRAM static struct libmnt_monitor *create_test_monitor(int argc, char *argv[]) diff --git a/libmount/src/monitor.h b/libmount/src/monitor.h index 25c6c1f67..a7859c075 100644 --- a/libmount/src/monitor.h +++ b/libmount/src/monitor.h @@ -30,6 +30,7 @@ struct libmnt_monitor { int fd; /* public monitor file descriptor */ struct list_head ents; + struct monitor_entry *last; /* last active returned by mnt_monitor_next_change() */ bool kernel_veiled; }; @@ -39,6 +40,7 @@ struct monitor_opers { int (*op_close_fd)(struct libmnt_monitor *, struct monitor_entry *); int (*op_free_data)(struct monitor_entry *); int (*op_process_event)(struct libmnt_monitor *, struct monitor_entry *); + int (*op_next_fs)(struct libmnt_monitor *, struct monitor_entry *, struct libmnt_fs *); }; int monitor_modify_epoll(struct libmnt_monitor *mn, struct monitor_entry *me, int enable); -- 2.47.3