From 57ab4dc3781765a182cbb63dd04b5f25a2d88724 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 11 Jun 2024 11:55:39 +0200 Subject: [PATCH] libmount: Add API to get/set unique IDs Since the Linux kernel version 6.8, there are two types of IDs available: the "old" ID used in /proc/self/mountinfo, and a new 64-bit unique ID that is never recycled. This new ID is provided by the statx(STATX_MNT_ID_UNIQUE) and statmount() syscalls. Note that this patch only adds the API for retrieving these unique IDs, but the backing code has not been implemented yet. Signed-off-by: Karel Zak --- libmount/docs/libmount-sections.txt | 3 ++ libmount/src/fs.c | 58 ++++++++++++++++++++++++++++- libmount/src/libmount.h.in | 7 ++++ libmount/src/libmount.sym | 6 +++ libmount/src/mountP.h | 2 + 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/libmount/docs/libmount-sections.txt b/libmount/docs/libmount-sections.txt index 0b4adb595..a8a503144 100644 --- a/libmount/docs/libmount-sections.txt +++ b/libmount/docs/libmount-sections.txt @@ -229,10 +229,12 @@ mnt_fs_get_freq mnt_fs_get_fs_options mnt_fs_get_fstype mnt_fs_get_id +mnt_fs_get_uniq_id mnt_fs_get_option mnt_fs_get_optional_fields mnt_fs_get_options mnt_fs_get_parent_id +mnt_fs_get_parent_uniq_id mnt_fs_get_passno mnt_fs_get_priority mnt_fs_get_propagation @@ -273,6 +275,7 @@ mnt_fs_set_priority mnt_fs_set_root mnt_fs_set_source mnt_fs_set_target +mnt_fs_set_uniq_id mnt_fs_set_userdata mnt_fs_strdup_options mnt_fs_streq_srcpath diff --git a/libmount/src/fs.c b/libmount/src/fs.c index 5b3a5511f..d8886dc38 100644 --- a/libmount/src/fs.c +++ b/libmount/src/fs.c @@ -1361,13 +1361,52 @@ int mnt_fs_set_bindsrc(struct libmnt_fs *fs, const char *src) * mnt_fs_get_id: * @fs: /proc/self/mountinfo entry * - * Returns: mount ID (unique identifier of the mount) or negative number in case of error. + * This ID is "old" and used in mountinfo only. Since Linux v6.8 there is also unique + * 64-bit ID, see mnt_fs_get_uniq_id(). + * + * Returns: mount ID or negative number in case of error. */ int mnt_fs_get_id(struct libmnt_fs *fs) { return fs ? fs->id : -EINVAL; } +/** + * mnt_fs_get_uniq_id: + * @fs: filesystem instance + * + * This ID is provided by statmount() or statx(STATX_MNT_ID_UNIQUE) since Linux + * kernel since v6.8. + * + * Returns: unique mount ID + * + * Since: 2.41 + */ +uint64_t mnt_fs_get_uniq_id(struct libmnt_fs *fs) +{ + return fs ? fs->uniq_id : 0; +} + +/** + * mnt_fs_set_uniq_id: + * @fs: filesystem instance + * @id: mount node ID + * + * This ID is provided by statmount() or statx(STATX_MNT_ID_UNIQUE) since Linux + * kernel since v6.8. + * + * Returns: 0 or negative number in case of error. + * + * Since: 2.41 + */ +int mnt_fs_set_uniq_id(struct libmnt_fs *fs, uint64_t id) +{ + if (!fs) + return -EINVAL; + fs->uniq_id = id; + return 0; +} + /** * mnt_fs_get_parent_id: * @fs: /proc/self/mountinfo entry @@ -1379,6 +1418,19 @@ int mnt_fs_get_parent_id(struct libmnt_fs *fs) return fs ? fs->parent : -EINVAL; } +/** + * mnt_fs_get_parent_uniq_id: + * @fs: filesystem instance + * + * This ID is provided by statmount() since Linux kernel since v6.8. + * + * Returns: parent mount ID or 0 if not avalable + */ +uint64_t mnt_fs_get_parent_uniq_id(struct libmnt_fs *fs) +{ + return fs ? fs->uniq_parent : 0; +} + /** * mnt_fs_get_devno: * @fs: /proc/self/mountinfo entry @@ -1714,6 +1766,10 @@ int mnt_fs_print_debug(struct libmnt_fs *fs, FILE *file) fprintf(file, "id: %d\n", mnt_fs_get_id(fs)); if (mnt_fs_get_parent_id(fs)) fprintf(file, "parent: %d\n", mnt_fs_get_parent_id(fs)); + if (mnt_fs_get_uniq_id(fs)) + fprintf(file, "uniq-id: %" PRIu64 "\n", mnt_fs_get_uniq_id(fs)); + if (mnt_fs_get_parent_uniq_id(fs)) + fprintf(file, "uniq-parent: %" PRIu64 "\n", mnt_fs_get_parent_uniq_id(fs)); if (mnt_fs_get_devno(fs)) fprintf(file, "devno: %d:%d\n", major(mnt_fs_get_devno(fs)), minor(mnt_fs_get_devno(fs))); diff --git a/libmount/src/libmount.h.in b/libmount/src/libmount.h.in index 0a2d82199..90f6a66c0 100644 --- a/libmount/src/libmount.h.in +++ b/libmount/src/libmount.h.in @@ -31,6 +31,7 @@ extern "C" { #include #include #include +#include /* Make sure libc MS_* definitions are used by default. Note that MS_* flags * may be already defined by linux/fs.h or another file -- in this case we @@ -530,8 +531,14 @@ extern const char *mnt_fs_get_root(struct libmnt_fs *fs); extern int mnt_fs_set_root(struct libmnt_fs *fs, const char *path); extern const char *mnt_fs_get_bindsrc(struct libmnt_fs *fs); extern int mnt_fs_set_bindsrc(struct libmnt_fs *fs, const char *src); + extern int mnt_fs_get_id(struct libmnt_fs *fs); +extern uint64_t mnt_fs_get_uniq_id(struct libmnt_fs *fs); +extern int mnt_fs_set_uniq_id(struct libmnt_fs *fs, uint64_t id); + extern int mnt_fs_get_parent_id(struct libmnt_fs *fs); +extern uint64_t mnt_fs_get_parent_uniq_id(struct libmnt_fs *fs); + extern dev_t mnt_fs_get_devno(struct libmnt_fs *fs); extern pid_t mnt_fs_get_tid(struct libmnt_fs *fs); diff --git a/libmount/src/libmount.sym b/libmount/src/libmount.sym index 2b6b12d5c..cdd76ba32 100644 --- a/libmount/src/libmount.sym +++ b/libmount/src/libmount.sym @@ -381,3 +381,9 @@ MOUNT_2_40 { mnt_unref_lock; mnt_monitor_veil_kernel; } MOUNT_2_39; + +MOUNT_2_41 { + mnt_fs_get_uniq_id; + mnt_fs_get_parent_uniq_id; + mnt_fs_set_uniq_id; +} MOUNT_2_40; diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h index bfdf8f451..370bcd9e7 100644 --- a/libmount/src/mountP.h +++ b/libmount/src/mountP.h @@ -201,7 +201,9 @@ struct libmnt_fs { struct libmnt_optlist *optlist; int id; /* mountinfo[1]: ID */ + uint64_t uniq_id; /* unique node ID; statx(STATX_MNT_ID_UNIQUE); statmount->mnt_id */ int parent; /* mountinfo[2]: parent */ + uint64_t uniq_parent; /* unique parent ID; statmount->mnt_parent_id */ dev_t devno; /* mountinfo[3]: st_dev */ char *bindsrc; /* utab, full path from fstab[1] for bind mounts */ -- 2.47.2