]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libmount: (monitor) add next-fs API
authorKarel Zak <kzak@redhat.com>
Tue, 10 Jun 2025 09:05:20 +0000 (11:05 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 6 Aug 2025 12:52:56 +0000 (14:52 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libmount/docs/libmount-sections.txt
libmount/src/libmount.h.in
libmount/src/libmount.sym
libmount/src/monitor.c
libmount/src/monitor.h

index 60dffba7e184f851059bd496ad9981c87bb69bd8..e791415d9606c18032c0a796576018e570c73f58 100644 (file)
@@ -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
 </SECTION>
index f30f94cdc5c6fbc4b0abf6181f2bc513a155b5a6..50e8658994f20d7f291d86c2bcbb350b37d6b5b4 100644 (file)
@@ -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 */
index cbef26fb0b1e061362ca4b8b3e9a375127b88840..f8fdd0ef63845f5ba9fb7d1d1b0d75246ea75a91 100644 (file)
@@ -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;
index 6272fbdd286dce145891e439a26f28e99e4e2764..f625dafb6a31bf6e58d8724d2b3a526c3941e999 100644 (file)
@@ -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.
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   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));
+ *       }
+ *     }
+ *   }
+ *  </programlisting>
+ * </informalexample>
+ *
+ * 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[])
index 25c6c1f674304b364ceceb7f0a4caea9acff1d51..a7859c0750eff270689e447802e0114ac7a21987 100644 (file)
@@ -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);