Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libmount: working on listmount test setup #3

Open
wants to merge 32 commits into
base: PR/libmount-statmount
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e0d829c
autotools: check for statmount and listmount syscalls
karelzak Aug 14, 2024
b0c6fea
meson: check for statmount and listmount syscalls
karelzak Aug 14, 2024
f8d2db4
include/mount-api-utils: add statmount and listmount
karelzak Aug 14, 2024
ef31895
libmount: add mount-api-utils.h to mountP.h
karelzak Jul 22, 2024
9b41d86
libmount: add statmount to features list
karelzak Jul 18, 2024
502df82
libmount: remember parsed propagation
karelzak Jun 13, 2024
d636774
libmount: Add API to get/set unique IDs
karelzak Jun 11, 2024
a4032e6
libmount: add API to read ID by statx()
karelzak Aug 14, 2024
bc5417f
libmount: use unique ID in utab
karelzak Jun 12, 2024
b7dbb62
include/c: add BIT()
karelzak Aug 14, 2024
84c5235
libmount: add support for statmount()
karelzak Aug 14, 2024
346c782
libmount: fix __table_insert_fs()
karelzak Aug 15, 2024
5f500d2
include/timeutils: add time_diff()
karelzak Aug 6, 2024
a32ed90
libmount: add support for listmount()
karelzak Aug 15, 2024
fe9dfb0
libmount: add listmount() sample
karelzak Aug 15, 2024
b376d60
libmount: (docs) add missing api indexes
karelzak Aug 15, 2024
653c636
libmount: fix typo in symbols list
karelzak Aug 15, 2024
b0b00e0
libmount: ifdef listmount and statmount stuff
karelzak Aug 19, 2024
786fe7f
libmount: ifdef STATX_MNT_ID_UNIQUE
karelzak Aug 20, 2024
ab76e6e
libmount: ifdef STATMOUNT_* in sample
karelzak Aug 20, 2024
9564c36
include/mount-api-utils: fix typo
karelzak Aug 21, 2024
87b708d
libmount: update tests
karelzak Aug 21, 2024
e6a93c7
libmount: use __unused__ for dummy get_mnt_id()
karelzak Aug 21, 2024
d5bd99b
libmount: Add integer type headers to private header file
karelzak Aug 21, 2024
4e70d37
test_sysinfo; fix fsopen() ifdef
karelzak Aug 21, 2024
fbd3dc4
libmount: remove unnecessary include
karelzak Aug 21, 2024
79f57cd
meson: fix after rebase
karelzak Sep 16, 2024
9defc7c
findmnt: add optional argument to --kernel
karelzak Sep 16, 2024
96c6ac5
findmnt: add --kernel=listmount
karelzak Sep 16, 2024
ee3040f
libmount: improve how library generates fs->optstr
karelzak Sep 23, 2024
c2becab
libmount: improve fs->stmnt_done mask use
karelzak Sep 23, 2024
0d4f517
libmount: working on listmount test setup
usiegl00 Sep 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -706,7 +706,20 @@ AS_IF([test "x$ul_cv_syscall_fsconfig" = xno ||
have_mountfd_api="no"
],[
have_mountfd_api="yes"
AC_DEFINE([HAVE_MOUNTFD_API], [1], [Define to 1 if you want mount API based on FDs.])
AC_DEFINE([HAVE_MOUNTFD_API], [1], [Define to 1 if you want to use mount API based on FDs.])
])


UL_CHECK_SYSCALL([statmount])
UL_CHECK_SYSCALL([listmount])

AS_IF([test "x$ul_cv_syscall_statmount" = xno ||
test "x$ul_cv_syscall_listmount" = xno],
[
have_statmount_api="no"
],[
have_statmount_api="yes"
AC_DEFINE([HAVE_STATMOUNT_API], [1], [Define to 1 if you want to use statmount API.])
])


Expand Down
2 changes: 2 additions & 0 deletions include/c.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
# define NAME_MAX PATH_MAX
#endif

#define BIT(n) (1 << (n))

/*
* __GNUC_PREREQ is deprecated in favour of __has_attribute() and
* __has_feature(). The __has macros are supported by clang and gcc>=5.
Expand Down
217 changes: 212 additions & 5 deletions include/mount-api-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,16 @@
#ifndef UTIL_LINUX_MOUNT_API_UTILS
#define UTIL_LINUX_MOUNT_API_UTILS

#if defined(HAVE_MOUNTFD_API) && defined(HAVE_LINUX_MOUNT_H)

#include <sys/syscall.h>
#ifdef HAVE_LINUX_MOUNT_H
#include <sys/mount.h>
#include <linux/mount.h>
#include <sys/syscall.h>
#include <inttypes.h>

/*
* File descritors based mount API
*/
#ifdef HAVE_MOUNTFD_API

/* Accepted by both open_tree() and mount_setattr(). */
#ifndef AT_RECURSIVE
Expand Down Expand Up @@ -203,6 +209,207 @@ static inline int fspick(int dfd, const char *pathname, unsigned int flags)
}
#endif

#endif /* HAVE_MOUNTFD_API && HAVE_LINUX_MOUNT_H */
#endif /* UTIL_LINUX_MOUNT_API_UTILS */
#endif /* HAVE_MOUNTFD_API */

/*
* statmount() and listmount()
*/
#ifdef HAVE_STATMOUNT_API

#ifndef MNT_ID_REQ_SIZE_VER0
# define MNT_ID_REQ_SIZE_VER0 24 /* sizeof first published struct */
#endif
#ifndef MNT_ID_REQ_SIZE_VER1
# define MNT_ID_REQ_SIZE_VER1 32 /* sizeof second published struct */
#endif

/*
* The structs mnt_id_req and statmount may differ between kernel versions, so
* we must ensure that the structs contain everything we need. For now (during
* development), it seems best to define local copies of the structs to avoid
* relying on installed kernel headers and to avoid a storm of #ifdefs.
*/

/*
* listmount() and statmount() request
*/
struct ul_mnt_id_req {
uint32_t size;
uint32_t spare;
uint64_t mnt_id;
uint64_t param;
uint64_t mnt_ns_id;
};

/*
* Please note that due to the variable length of the statmount buffer, the
* struct cannot be versioned by size (like struct mnt_id_req).
*/
struct ul_statmount {
uint32_t size; /* Total size, including strings */
uint32_t mnt_opts; /* [str] Mount options of the mount */
uint64_t mask; /* What results were written */
uint32_t sb_dev_major; /* Device ID */
uint32_t sb_dev_minor;
uint64_t sb_magic; /* ..._SUPER_MAGIC */
uint32_t sb_flags; /* SB_{RDONLY,SYNCHRONOUS,DIRSYNC,LAZYTIME} */
uint32_t fs_type; /* [str] Filesystem type */
uint64_t mnt_id; /* Unique ID of mount */
uint64_t mnt_parent_id; /* Unique ID of parent (for root == mnt_id) */
uint32_t mnt_id_old; /* Reused IDs used in proc/.../mountinfo */
uint32_t mnt_parent_id_old;
uint64_t mnt_attr; /* MOUNT_ATTR_... */
uint64_t mnt_propagation; /* MS_{SHARED,SLAVE,PRIVATE,UNBINDABLE} */
uint64_t mnt_peer_group; /* ID of shared peer group */
uint64_t mnt_master; /* Mount receives propagation from this ID */
uint64_t propagate_from; /* Propagation from in current namespace */
uint32_t mnt_root; /* [str] Root of mount relative to root of fs */
uint32_t mnt_point; /* [str] Mountpoint relative to current root */
uint64_t mnt_ns_id; /* ID of the mount namespace */
uint64_t __spare2[49];
char str[]; /* Variable size part containing strings */
};

/* sb_flags (defined in kernel include/linux/fs.h) */
#ifndef SB_RDONLY
# define SB_RDONLY BIT(0) /* Mount read-only */
# define SB_NOSUID BIT(1) /* Ignore suid and sgid bits */
# define SB_NODEV BIT(2) /* Disallow access to device special files */
# define SB_NOEXEC BIT(3) /* Disallow program execution */
# define SB_SYNCHRONOUS BIT(4) /* Writes are synced at once */
# define SB_MANDLOCK BIT(6) /* Allow mandatory locks on an FS */
# define SB_DIRSYNC BIT(7) /* Directory modifications are synchronous */
# define SB_NOATIME BIT(10) /* Do not update access times. */
# define SB_NODIRATIME BIT(11) /* Do not update directory access times */
# define SB_SILENT BIT(15)
# define SB_POSIXACL BIT(16) /* Supports POSIX ACLs */
# define SB_INLINECRYPT BIT(17) /* Use blk-crypto for encrypted files */
# define SB_KERNMOUNT BIT(22) /* this is a kern_mount call */
# define SB_I_VERSION BIT(23) /* Update inode I_version field */
# define SB_LAZYTIME BIT(25) /* Update the on-disk [acm]times lazily */
#endif

/*
* @mask bits for statmount(2)
*/
#ifndef STATMOUNT_SB_BASIC
# define STATMOUNT_SB_BASIC 0x00000001U /* Want/got sb_... */
#endif
#ifndef STATMOUNT_MNT_BASIC
# define STATMOUNT_MNT_BASIC 0x00000002U /* Want/got mnt_... */
#endif
#ifndef STATMOUNT_PROPAGATE_FROM
# define STATMOUNT_PROPAGATE_FROM 0x00000004U /* Want/got propagate_from */
#endif
#ifndef STATMOUNT_MNT_ROOT
# define STATMOUNT_MNT_ROOT 0x00000008U /* Want/got mnt_root */
#endif
#ifndef STATMOUNT_MNT_POINT
# define STATMOUNT_MNT_POINT 0x00000010U /* Want/got mnt_point */
#endif
#ifndef STATMOUNT_FS_TYPE
# define STATMOUNT_FS_TYPE 0x00000020U /* Want/got fs_type */
#endif
#ifndef STATMOUNT_MNT_NS_ID
# define STATMOUNT_MNT_NS_ID 0x00000040U /* Want/got mnt_ns_id */
#endif
#ifndef STATMOUNT_MNT_OPTS
# define STATMOUNT_MNT_OPTS 0x00000080U /* Want/got mnt_opts */
#endif

/*
* Special @mnt_id values that can be passed to listmount
*/
#ifdef LSMT_ROOT
# define LSMT_ROOT 0xffffffffffffffff /* root mount */
#endif

#ifndef LISTMOUNT_REVERSE
# define LISTMOUNT_REVERSE BIT(0) /* List later mounts first */
#endif

#if defined(SYS_statmount)
static inline int ul_statmount(uint64_t mnt_id,
uint64_t ns_id,
uint64_t mask,
struct ul_statmount *buf,
size_t bufsize, unsigned int flags)
{
struct ul_mnt_id_req req = {
.size = MNT_ID_REQ_SIZE_VER1,
.mnt_id = mnt_id,
.param = mask,
.mnt_ns_id = ns_id
};

return syscall(SYS_statmount, &req, buf, bufsize, flags);
}
#endif

#if defined(SYS_listmount)
static inline ssize_t ul_listmount(uint64_t mnt_id,
uint64_t ns_id,
uint64_t last_mnt_id,
uint64_t list[], size_t num,
unsigned int flags)
{
struct ul_mnt_id_req req = {
.size = MNT_ID_REQ_SIZE_VER1,
.mnt_id = mnt_id,
.param = last_mnt_id,
.mnt_ns_id = ns_id
};

return syscall(SYS_listmount, &req, list, num, flags);
}
#endif

/* This is a version of statmount() that reallocates @buf to be large enough to
* store data for the requested @id. This function never deallocates; it is the
* caller's responsibility.
*/
static inline int sys_statmount(uint64_t id,
uint64_t ns_id,
uint64_t mask,
struct ul_statmount **buf,
size_t *bufsiz,
unsigned int flags)
{
size_t sz;
int rc = 0;

if (!buf || !bufsiz)
return -EINVAL;

sz = *bufsiz;
if (!sz)
sz = 32 * 1024;

do {
if (sz > *bufsiz) {
struct ul_statmount *tmp = realloc(*buf, sz);
if (!tmp)
return -ENOMEM;
*buf = tmp;
*bufsiz = sz;
}

errno = 0;
rc = ul_statmount(id, ns_id, mask, *buf, *bufsiz, flags);
if (!rc)
break;
if (errno != EOVERFLOW)
break;
if (sz >= SIZE_MAX / 2)
break;
sz <<= 1;
} while (rc);

return rc;
}

#endif /* HAVE_STATMOUNT_API */

#endif /* HAVE_LINUX_MOUNT_H */

#endif /* UTIL_LINUX_MOUNT_API_UTILS */
4 changes: 4 additions & 0 deletions include/timeutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,8 @@ static inline bool is_timespecset(const struct timespec *t)
return t->tv_sec || t->tv_nsec;
}

static inline double time_diff(const struct timeval *a, const struct timeval *b)
{
return (a->tv_sec - b->tv_sec) + (a->tv_usec - b->tv_usec) / (double) USEC_PER_SEC;
}
#endif /* UTIL_LINUX_TIME_UTIL_H */
20 changes: 20 additions & 0 deletions libmount/docs/libmount-docs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,24 @@ available from https://www.kernel.org/pub/linux/utils/util-linux/.
<title>Index of new symbols in 2.35</title>
<xi:include href="xml/api-index-2.35.xml"><xi:fallback /></xi:include>
</index>
<index role="2.37">
<title>Index of new symbols in 2.37</title>
<xi:include href="xml/api-index-2.37.xml"><xi:fallback /></xi:include>
</index>
<index role="2.38">
<title>Index of new symbols in 2.38</title>
<xi:include href="xml/api-index-2.38.xml"><xi:fallback /></xi:include>
</index>
<index role="2.39">
<title>Index of new symbols in 2.39</title>
<xi:include href="xml/api-index-2.39.xml"><xi:fallback /></xi:include>
</index>
<index role="2.40">
<title>Index of new symbols in 2.40</title>
<xi:include href="xml/api-index-2.40.xml"><xi:fallback /></xi:include>
</index>
<index role="2.41">
<title>Index of new symbols in 2.41</title>
<xi:include href="xml/api-index-2.41.xml"><xi:fallback /></xi:include>
</index>
</book>
26 changes: 26 additions & 0 deletions libmount/docs/libmount-sections.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -273,15 +275,33 @@ 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
mnt_fs_streq_target
mnt_fs_to_mntent
mnt_fs_fetch_statmount
mnt_fs_get_ns
mnt_fs_set_ns
mnt_new_fs
mnt_reset_fs
</SECTION>

<SECTION>
<FILE>statmount</FILE>
libmnt_statmnt
mnt_new_statmnt
mnt_ref_statmnt
mnt_unref_statmnt
mnt_statmnt_disable_fetching
mnt_statmnt_set_mask
mnt_fs_fetch_statmount
mnt_fs_get_statmnt
mnt_fs_refer_statmnt
mnt_table_refer_statmnt
</SECTION>

<SECTION>
<FILE>init</FILE>
mnt_init_debug
Expand Down Expand Up @@ -348,7 +368,9 @@ mnt_table_add_fs
mnt_table_append_intro_comment
mnt_table_append_trailing_comment
mnt_table_enable_comments
mnt_table_enable_listmount
mnt_table_enable_noautofs
mnt_table_fetch_listmount
mnt_table_find_devno
mnt_table_find_fs
mnt_table_find_mountpoint
Expand All @@ -371,6 +393,9 @@ mnt_table_is_empty
mnt_table_is_fs_mounted
mnt_table_is_noautofs
mnt_table_last_fs
mnt_table_listmount_set_id
mnt_table_listmount_set_ns
mnt_table_listmount_set_stepsiz
mnt_table_move_fs
mnt_table_next_child_fs
mnt_table_next_fs
Expand Down Expand Up @@ -427,6 +452,7 @@ mnt_get_mtab_path
mnt_get_swaps_path
mnt_guess_system_root
mnt_has_regular_mtab
mnt_id_from_path
mnt_mangle
mnt_match_fstype
mnt_tag_is_valid
Expand Down
2 changes: 2 additions & 0 deletions libmount/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ lib_mount_sources = '''

if LINUX
lib_mount_sources += '''
src/fs_statmount.c
src/tab_listmount.c
src/hooks.c
src/monitor.c
src/optlist.c
Expand Down
Loading