libmount: make dlopen() dependency

This commit is contained in:
Lennart Poettering
2025-09-26 08:29:37 +09:00
committed by Yu Watanabe
parent b97b8fd4e3
commit b3243f4bee
25 changed files with 270 additions and 113 deletions
+7 -7
View File
@@ -56,13 +56,13 @@ int fstab_has_fstype(const char *fstype) {
for (;;) {
struct libmnt_fs *fs;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return r;
if (r > 0) /* EOF */
return false;
if (streq_ptr(mnt_fs_get_fstype(fs), fstype))
if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype))
return true;
}
}
@@ -134,13 +134,13 @@ int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
struct libmnt_fs *fs;
const char *path;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return r;
if (r > 0) /* EOF */
return false;
path = mnt_fs_get_target(fs);
path = sym_mnt_fs_get_target(fs);
if (!path)
continue;
@@ -168,19 +168,19 @@ int fstab_is_mount_point_full(const char *where, const char *path) {
for (;;) {
struct libmnt_fs *fs;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r < 0)
return r;
if (r > 0) /* EOF */
return false;
if (where && !path_equal(mnt_fs_get_target(fs), where))
if (where && !path_equal(sym_mnt_fs_get_target(fs), where))
continue;
if (!path)
return true;
r = fstab_is_same_node(mnt_fs_get_source(fs), path);
r = fstab_is_same_node(sym_mnt_fs_get_source(fs), path);
if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r)))
return r;
}
+90 -7
View File
@@ -6,6 +6,83 @@
#include "libmount-util.h"
#include "log.h"
static void *libmount_dl = NULL;
DLSYM_PROTOTYPE(mnt_free_iter) = NULL;
DLSYM_PROTOTYPE(mnt_free_table) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_fs_options) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_fstype) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_id) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_option) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_options) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_passno) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_propagation) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_source) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_target) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_vfs_options) = NULL;
DLSYM_PROTOTYPE(mnt_get_builtin_optmap) = NULL;
DLSYM_PROTOTYPE(mnt_init_debug) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_enable_kernel) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_enable_userspace) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_get_fd) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_next_change) = NULL;
DLSYM_PROTOTYPE(mnt_new_iter) = NULL;
DLSYM_PROTOTYPE(mnt_new_monitor) = NULL;
DLSYM_PROTOTYPE(mnt_new_table) = NULL;
DLSYM_PROTOTYPE(mnt_optstr_get_flags) = NULL;
DLSYM_PROTOTYPE(mnt_table_find_devno) = NULL;
DLSYM_PROTOTYPE(mnt_table_find_target) = NULL;
DLSYM_PROTOTYPE(mnt_table_next_child_fs) = NULL;
DLSYM_PROTOTYPE(mnt_table_next_fs) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_file) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_mtab) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_stream) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_swaps) = NULL;
DLSYM_PROTOTYPE(mnt_unref_monitor) = NULL;
int dlopen_libmount(void) {
ELF_NOTE_DLOPEN("mount",
"Support for mount enumeration",
ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
"libmount.so.1");
return dlopen_many_sym_or_warn(
&libmount_dl,
"libmount.so.1",
LOG_DEBUG,
DLSYM_ARG(mnt_free_iter),
DLSYM_ARG(mnt_free_table),
DLSYM_ARG(mnt_fs_get_fs_options),
DLSYM_ARG(mnt_fs_get_fstype),
DLSYM_ARG(mnt_fs_get_id),
DLSYM_ARG(mnt_fs_get_option),
DLSYM_ARG(mnt_fs_get_options),
DLSYM_ARG(mnt_fs_get_passno),
DLSYM_ARG(mnt_fs_get_propagation),
DLSYM_ARG(mnt_fs_get_source),
DLSYM_ARG(mnt_fs_get_target),
DLSYM_ARG(mnt_fs_get_vfs_options),
DLSYM_ARG(mnt_get_builtin_optmap),
DLSYM_ARG(mnt_init_debug),
DLSYM_ARG(mnt_monitor_enable_kernel),
DLSYM_ARG(mnt_monitor_enable_userspace),
DLSYM_ARG(mnt_monitor_get_fd),
DLSYM_ARG(mnt_monitor_next_change),
DLSYM_ARG(mnt_new_iter),
DLSYM_ARG(mnt_new_monitor),
DLSYM_ARG(mnt_new_table),
DLSYM_ARG(mnt_optstr_get_flags),
DLSYM_ARG(mnt_table_find_devno),
DLSYM_ARG(mnt_table_find_target),
DLSYM_ARG(mnt_table_next_child_fs),
DLSYM_ARG(mnt_table_next_fs),
DLSYM_ARG(mnt_table_parse_file),
DLSYM_ARG(mnt_table_parse_mtab),
DLSYM_ARG(mnt_table_parse_stream),
DLSYM_ARG(mnt_table_parse_swaps),
DLSYM_ARG(mnt_unref_monitor));
}
int libmount_parse_full(
const char *path,
FILE *source,
@@ -19,8 +96,12 @@ int libmount_parse_full(
/* Older libmount seems to require this. */
assert(!source || path);
table = mnt_new_table();
iter = mnt_new_iter(MNT_ITER_FORWARD);
r = dlopen_libmount();
if (r < 0)
return r;
table = sym_mnt_new_table();
iter = sym_mnt_new_iter(MNT_ITER_FORWARD);
if (!table || !iter)
return -ENOMEM;
@@ -28,11 +109,11 @@ int libmount_parse_full(
* Only if both are empty, we use mnt_table_parse_mtab(). */
if (source)
r = mnt_table_parse_stream(table, source, path);
r = sym_mnt_table_parse_stream(table, source, path);
else if (path)
r = mnt_table_parse_file(table, path);
r = sym_mnt_table_parse_file(table, path);
else
r = mnt_table_parse_mtab(table, NULL);
r = sym_mnt_table_parse_mtab(table, NULL);
if (r < 0)
return r;
@@ -53,14 +134,16 @@ int libmount_is_leaf(
struct libmnt_fs *fs) {
int r;
assert(table);
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter_children = NULL;
iter_children = mnt_new_iter(MNT_ITER_FORWARD);
iter_children = sym_mnt_new_iter(MNT_ITER_FORWARD);
if (!iter_children)
return log_oom();
/* We care only whether it exists, it is unused */
_unused_ struct libmnt_fs *child;
r = mnt_table_next_child_fs(table, iter_children, fs, &child);
r = sym_mnt_table_next_child_fs(table, iter_children, fs, &child);
if (r < 0)
return r;
+37 -2
View File
@@ -4,10 +4,45 @@
/* This needs to be after sys/mount.h */
#include <libmount.h> /* IWYU pragma: export */
#include "dlfcn-util.h"
#include "forward.h"
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_table*, mnt_free_table, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_iter*, mnt_free_iter, NULL);
extern DLSYM_PROTOTYPE(mnt_free_iter);
extern DLSYM_PROTOTYPE(mnt_free_table);
extern DLSYM_PROTOTYPE(mnt_fs_get_fs_options);
extern DLSYM_PROTOTYPE(mnt_fs_get_fstype);
extern DLSYM_PROTOTYPE(mnt_fs_get_id);
extern DLSYM_PROTOTYPE(mnt_fs_get_option);
extern DLSYM_PROTOTYPE(mnt_fs_get_options);
extern DLSYM_PROTOTYPE(mnt_fs_get_passno);
extern DLSYM_PROTOTYPE(mnt_fs_get_propagation);
extern DLSYM_PROTOTYPE(mnt_fs_get_source);
extern DLSYM_PROTOTYPE(mnt_fs_get_target);
extern DLSYM_PROTOTYPE(mnt_fs_get_vfs_options);
extern DLSYM_PROTOTYPE(mnt_get_builtin_optmap);
extern DLSYM_PROTOTYPE(mnt_init_debug);
extern DLSYM_PROTOTYPE(mnt_monitor_enable_kernel);
extern DLSYM_PROTOTYPE(mnt_monitor_enable_userspace);
extern DLSYM_PROTOTYPE(mnt_monitor_get_fd);
extern DLSYM_PROTOTYPE(mnt_monitor_next_change);
extern DLSYM_PROTOTYPE(mnt_new_iter);
extern DLSYM_PROTOTYPE(mnt_new_monitor);
extern DLSYM_PROTOTYPE(mnt_new_table);
extern DLSYM_PROTOTYPE(mnt_optstr_get_flags);
extern DLSYM_PROTOTYPE(mnt_table_find_devno);
extern DLSYM_PROTOTYPE(mnt_table_find_target);
extern DLSYM_PROTOTYPE(mnt_table_next_child_fs);
extern DLSYM_PROTOTYPE(mnt_table_next_fs);
extern DLSYM_PROTOTYPE(mnt_table_parse_file);
extern DLSYM_PROTOTYPE(mnt_table_parse_mtab);
extern DLSYM_PROTOTYPE(mnt_table_parse_stream);
extern DLSYM_PROTOTYPE(mnt_table_parse_swaps);
extern DLSYM_PROTOTYPE(mnt_unref_monitor);
int dlopen_libmount(void);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_table*, sym_mnt_free_table, mnt_free_tablep, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter, mnt_free_iterp, NULL);
int libmount_parse_full(
const char *path,
+1 -1
View File
@@ -322,7 +322,7 @@ libshared_deps = [threads,
libgcrypt_cflags,
libkmod_cflags,
liblz4_cflags,
libmount,
libmount_cflags,
libopenssl,
libp11kit_cflags,
libpam_cflags,
+32 -24
View File
@@ -60,13 +60,13 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) {
struct libmnt_fs *fs;
const char *path;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r == 1)
break;
if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = mnt_fs_get_target(fs);
path = sym_mnt_fs_get_target(fs);
if (!path)
continue;
@@ -247,20 +247,20 @@ int bind_remount_recursive_with_mountinfo(
unsigned long flags = 0;
struct libmnt_fs *fs;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r == 1) /* EOF */
break;
if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = mnt_fs_get_target(fs);
path = sym_mnt_fs_get_target(fs);
if (!path)
continue;
if (!path_startswith(path, prefix))
continue;
type = mnt_fs_get_fstype(fs);
type = sym_mnt_fs_get_fstype(fs);
if (!type)
continue;
@@ -298,9 +298,9 @@ int bind_remount_recursive_with_mountinfo(
continue;
}
opts = mnt_fs_get_vfs_options(fs);
opts = sym_mnt_fs_get_vfs_options(fs);
if (opts) {
r = mnt_optstr_get_flags(opts, &flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
r = sym_mnt_optstr_get_flags(opts, &flags, sym_mnt_get_builtin_optmap(MNT_LINUX_MAP));
if (r < 0)
log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
}
@@ -438,15 +438,19 @@ int bind_remount_one_with_mountinfo(
rewind(proc_self_mountinfo);
table = mnt_new_table();
if (!table)
return -ENOMEM;
r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
r = dlopen_libmount();
if (r < 0)
return r;
fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD);
table = sym_mnt_new_table();
if (!table)
return -ENOMEM;
r = sym_mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
if (r < 0)
return r;
fs = sym_mnt_table_find_target(table, path, MNT_ITER_FORWARD);
if (!fs) {
r = access_nofollow(path, F_OK); /* Hmm, it's not in the mount table, but does it exist at all? */
if (r < 0)
@@ -455,9 +459,9 @@ int bind_remount_one_with_mountinfo(
return -EINVAL; /* Not a mount point we recognize */
}
opts = mnt_fs_get_vfs_options(fs);
opts = sym_mnt_fs_get_vfs_options(fs);
if (opts) {
r = mnt_optstr_get_flags(opts, &flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
r = sym_mnt_optstr_get_flags(opts, &flags, sym_mnt_get_builtin_optmap(MNT_LINUX_MAP));
if (r < 0)
log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
}
@@ -873,7 +877,11 @@ int mount_option_mangle(
assert(ret_mount_flags);
assert(ret_remaining_options);
map = mnt_get_builtin_optmap(MNT_LINUX_MAP);
r = dlopen_libmount();
if (r < 0)
return r;
map = sym_mnt_get_builtin_optmap(MNT_LINUX_MAP);
if (!map)
return -EINVAL;
@@ -1637,20 +1645,20 @@ int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_moun
const char *path;
int id1, id2;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r == 1)
break; /* EOF */
if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = mnt_fs_get_target(fs);
path = sym_mnt_fs_get_target(fs);
if (!path)
continue;
if (isempty(path_startswith(path, prefix)))
continue;
id1 = mnt_fs_get_id(fs);
id1 = sym_mnt_fs_get_id(fs);
r = path_get_mnt_id(path, &id2);
if (r < 0) {
log_debug_errno(r, "Failed to get mount ID of '%s', ignoring: %m", path);
@@ -1982,31 +1990,31 @@ int path_get_mount_info_at(
for (;;) {
struct libmnt_fs *fs;
r = mnt_table_next_fs(table, iter, &fs);
r = sym_mnt_table_next_fs(table, iter, &fs);
if (r == 1)
break; /* EOF */
if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
if (mnt_fs_get_id(fs) != mnt_id)
if (sym_mnt_fs_get_id(fs) != mnt_id)
continue;
_cleanup_free_ char *fstype = NULL, *options = NULL, *source = NULL;
if (ret_fstype) {
fstype = strdup(strempty(mnt_fs_get_fstype(fs)));
fstype = strdup(strempty(sym_mnt_fs_get_fstype(fs)));
if (!fstype)
return log_oom_debug();
}
if (ret_options) {
options = strdup(strempty(mnt_fs_get_options(fs)));
options = strdup(strempty(sym_mnt_fs_get_options(fs)));
if (!options)
return log_oom_debug();
}
if (ret_source) {
source = strdup(strempty(mnt_fs_get_source(fs)));
source = strdup(strempty(sym_mnt_fs_get_source(fs)));
if (!source)
return log_oom_debug();
}