]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libmount: make dlopen() dependency
authorLennart Poettering <lennart@poettering.net>
Wed, 24 Sep 2025 20:36:30 +0000 (22:36 +0200)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 25 Sep 2025 23:29:37 +0000 (08:29 +0900)
25 files changed:
meson.build
src/core/meson.build
src/core/mount.c
src/creds/creds.c
src/creds/meson.build
src/cryptsetup/cryptsetup.c
src/cryptsetup/meson.build
src/fstab-generator/fstab-generator.c
src/fstab-generator/meson.build
src/mount/meson.build
src/mount/mount-tool.c
src/remount-fs/meson.build
src/remount-fs/remount-fs.c
src/shared/fstab-util.c
src/shared/libmount-util.c
src/shared/libmount-util.h
src/shared/meson.build
src/shared/mount-util.c
src/shutdown/detach-swap.c
src/shutdown/meson.build
src/shutdown/umount.c
src/test/meson.build
src/test/test-dlopen-so.c
src/test/test-libmount.c
src/test/test-mount-util.c

index ffeef36f6e498a26c68fdf46f4c996b849ffbc13..8ec025c8d6ee49dbc8fe8d478b0b0ef57c7a8b6f 100644 (file)
@@ -1122,6 +1122,7 @@ libmount = dependency('mount',
                       version : fuzzer_build ? '>= 0' : '>= 2.30',
                       disabler : true,
                       required : get_option('libmount'))
+libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true)
 
 libfdisk = dependency('fdisk',
                       version : '>= 2.32',
index 1d897a0ddc3551bed2887503e5aad3d43d69c954..fc549ce20f4dca0d0e2895df36b3ede255be16d2 100644 (file)
@@ -134,7 +134,7 @@ libcore_static = static_library(
         dependencies : [libaudit_cflags,
                         libdl,
                         libm,
-                        libmount,
+                        libmount_cflags,
                         librt,
                         libseccomp_cflags,
                         libselinux,
@@ -222,7 +222,7 @@ executables += [
                         libcore,
                         libshared
                 ],
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
         fuzz_template + {
                 'sources' : files('fuzz-manager-serialize.c'),
index 36a877ab148372ab0dbb946e1c3ab9a111c8a7e2..801d2195b3237d1f97560dcaf9bd41bec23192a8 100644 (file)
@@ -1952,16 +1952,16 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
                 struct libmnt_fs *fs;
                 const char *device, *path, *options, *fstype;
 
-                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_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
 
-                device = mnt_fs_get_source(fs);
-                path = mnt_fs_get_target(fs);
-                options = mnt_fs_get_options(fs);
-                fstype = mnt_fs_get_fstype(fs);
+                device = sym_mnt_fs_get_source(fs);
+                path = sym_mnt_fs_get_target(fs);
+                options = sym_mnt_fs_get_options(fs);
+                fstype = sym_mnt_fs_get_fstype(fs);
 
                 if (!device || !path)
                         continue;
@@ -1983,8 +1983,10 @@ static void mount_shutdown(Manager *m) {
 
         m->mount_event_source = sd_event_source_disable_unref(m->mount_event_source);
 
-        mnt_unref_monitor(m->mount_monitor);
-        m->mount_monitor = NULL;
+        if (m->mount_monitor) {
+                sym_mnt_unref_monitor(m->mount_monitor);
+                m->mount_monitor = NULL;
+        }
 }
 
 static void mount_handoff_timestamp(
@@ -2075,33 +2077,39 @@ static void mount_enumerate(Manager *m) {
 
         assert(m);
 
-        mnt_init_debug(0);
+        r = dlopen_libmount();
+        if (r < 0) {
+                log_error_errno(r, "Cannot enumerate mounts, as libmount is not available: %m");
+                goto fail;
+        }
+
+        sym_mnt_init_debug(0);
 
         if (!m->mount_monitor) {
                 usec_t mount_rate_limit_interval = 1 * USEC_PER_SEC;
                 unsigned mount_rate_limit_burst = 5;
                 int fd;
 
-                m->mount_monitor = mnt_new_monitor();
+                m->mount_monitor = sym_mnt_new_monitor();
                 if (!m->mount_monitor) {
                         log_oom();
                         goto fail;
                 }
 
-                r = mnt_monitor_enable_kernel(m->mount_monitor, 1);
+                r = sym_mnt_monitor_enable_kernel(m->mount_monitor, 1);
                 if (r < 0) {
                         log_error_errno(r, "Failed to enable watching of kernel mount events: %m");
                         goto fail;
                 }
 
-                r = mnt_monitor_enable_userspace(m->mount_monitor, 1, NULL);
+                r = sym_mnt_monitor_enable_userspace(m->mount_monitor, 1, NULL);
                 if (r < 0) {
                         log_error_errno(r, "Failed to enable watching of userspace mount events: %m");
                         goto fail;
                 }
 
                 /* mnt_unref_monitor() will close the fd */
-                fd = r = mnt_monitor_get_fd(m->mount_monitor);
+                fd = r = sym_mnt_monitor_get_fd(m->mount_monitor);
                 if (r < 0) {
                         log_error_errno(r, "Failed to acquire watch file descriptor: %m");
                         goto fail;
@@ -2165,6 +2173,9 @@ static int drain_libmount(Manager *m) {
 
         assert(m);
 
+        if (!m->mount_monitor)
+                return false;
+
         /* Drain all events and verify that the event is valid.
          *
          * Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir
@@ -2172,7 +2183,7 @@ static int drain_libmount(Manager *m) {
          *
          * error: r < 0; valid: r == 0, false positive: r == 1 */
         do {
-                r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
+                r = sym_mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
                 if (r < 0)
                         return log_error_errno(r, "Failed to drain libmount events: %m");
                 if (r == 0)
index 198574075424ce5621bdf811d9b8c7dfa9831869..e2aaccfe79017094d851db7b94e7785702e1f7bc 100644 (file)
@@ -191,19 +191,23 @@ static int is_tmpfs_with_noswap(dev_t devno) {
         _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
         int r;
 
-        table = mnt_new_table();
+        r = dlopen_libmount();
+        if (r < 0)
+                return r;
+
+        table = sym_mnt_new_table();
         if (!table)
                 return -ENOMEM;
 
-        r = mnt_table_parse_mtab(table, /* filename= */ NULL);
+        r = sym_mnt_table_parse_mtab(table, /* filename= */ NULL);
         if (r < 0)
                 return r;
 
-        struct libmnt_fs *fs = mnt_table_find_devno(table, devno, MNT_ITER_FORWARD);
+        struct libmnt_fs *fs = sym_mnt_table_find_devno(table, devno, MNT_ITER_FORWARD);
         if (!fs)
                 return -ENODEV;
 
-        r = mnt_fs_get_option(fs, "noswap", /* value= */ NULL, /* valuesz= */ NULL);
+        r = sym_mnt_fs_get_option(fs, "noswap", /* value= */ NULL, /* valuesz= */ NULL);
         if (r < 0)
                 return r;
 
index 37d122ac416b8e84715d28376828e1e30e1b0839..1cd6f8c42f675f49f5ec85d65865e1dfb95e5e75 100644 (file)
@@ -6,7 +6,7 @@ executables += [
                 'public' : true,
                 'sources' : files('creds.c'),
                 'dependencies' : [
-                        libmount,
+                        libmount_cflags,
                         libopenssl,
                         threads,
                 ],
index c7897a2f208bdd54585f5923ec283ea241b2fc10..7351e5dc2a4a7597e79f25f3902fc59e52606505 100644 (file)
@@ -753,12 +753,12 @@ static char* disk_mount_point(const char *label) {
         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 NULL;
 
-                if (path_equal(mnt_fs_get_source(fs), device)) {
-                        const char *target = mnt_fs_get_target(fs);
+                if (path_equal(sym_mnt_fs_get_source(fs), device)) {
+                        const char *target = sym_mnt_fs_get_target(fs);
                         if (target)
                                 return strdup(target);
                 }
index cb47fd94172866d02abb85bedbbe9c811a4034d1..a029a016bcb2593346006dcfe7a61b125f6c6892 100644 (file)
@@ -19,7 +19,7 @@ executables += [
                 'sources' : systemd_cryptsetup_sources,
                 'dependencies' : [
                         libcryptsetup,
-                        libmount,
+                        libmount_cflags,
                         libopenssl,
                         libp11kit_cflags,
                 ],
index 1b68689bf9daa81759ea04e295d5f0113a3e48d0..4165cf4680f6d0bb714ee739d737a63658d385e6 100644 (file)
@@ -1048,18 +1048,22 @@ static int parse_fstab(bool prefix_sysroot) {
         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 log_error_errno(r, "Failed to get next entry from '%s': %m", fstab);
                 if (r > 0) /* EOF */
                         return ret;
 
-                r = parse_fstab_one(fstab,
-                                    mnt_fs_get_source(fs), mnt_fs_get_target(fs),
-                                    mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
-                                    prefix_sysroot,
-                                    /* accept_root = */ false,
-                                    /* use_swap_enabled = */ true);
+                r = parse_fstab_one(
+                                fstab,
+                                sym_mnt_fs_get_source(fs),
+                                sym_mnt_fs_get_target(fs),
+                                sym_mnt_fs_get_fstype(fs),
+                                sym_mnt_fs_get_options(fs),
+                                sym_mnt_fs_get_passno(fs),
+                                prefix_sysroot,
+                                /* accept_root = */ false,
+                                /* use_swap_enabled = */ true);
                 if (arg_sysroot_check && r > 0)
                         return true;  /* We found a mount or swap that would be started… */
                 RET_GATHER(ret, r);
@@ -1445,18 +1449,22 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
         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 log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred);
                 if (r > 0) /* EOF */
                         return ret;
 
-                RET_GATHER(ret, parse_fstab_one("/run/credentials",
-                                                mnt_fs_get_source(fs), mnt_fs_get_target(fs),
-                                                mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
-                                                prefix_sysroot,
-                                                /* accept_root = */ true,
-                                                /* use_swap_enabled = */ true));
+                RET_GATHER(ret, parse_fstab_one(
+                                           "/run/credentials",
+                                           sym_mnt_fs_get_source(fs),
+                                           sym_mnt_fs_get_target(fs),
+                                           sym_mnt_fs_get_fstype(fs),
+                                           sym_mnt_fs_get_options(fs),
+                                           sym_mnt_fs_get_passno(fs),
+                                           prefix_sysroot,
+                                           /* accept_root = */ true,
+                                           /* use_swap_enabled = */ true));
         }
 }
 
index fb5dccdd41b391a000c2d9f1a99108403475c2af..93e074e244b4e13032fd7260635ff670b9298a50 100644 (file)
@@ -4,7 +4,7 @@ executables += [
         generator_template + {
                 'name' : 'systemd-fstab-generator',
                 'sources' : files('fstab-generator.c'),
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
 ]
 
index dd996cfba4cb7c407c45415099401e5550709cde..feb00d8c2a277444b4ebb1e6f50987557b5cd198 100644 (file)
@@ -5,7 +5,7 @@ executables += [
                 'name' : 'systemd-mount',
                 'public' : true,
                 'sources' : files('mount-tool.c'),
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
 ]
 
index c8bb9a192bd613596d8eede49304754577ed501f..10a2ad7ad46af184dc27ca1e24595bbaf3381e40 100644 (file)
@@ -860,14 +860,14 @@ static int find_mount_points_by_source(const char *what, char ***ret) {
                 struct libmnt_fs *fs;
                 const char *source, *target;
 
-                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_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
 
-                source = mnt_fs_get_source(fs);
-                target = mnt_fs_get_target(fs);
+                source = sym_mnt_fs_get_source(fs);
+                target = sym_mnt_fs_get_target(fs);
                 if (!source || !target)
                         continue;
 
index 9ff7c9b8e48e4da5faa5b083243930be814ffa24..6f619c16e1d19c6fb907730bbcb1c2b865f67d78 100644 (file)
@@ -4,6 +4,6 @@ executables += [
         libexec_template + {
                 'name' : 'systemd-remount-fs',
                 'sources' : files('remount-fs.c'),
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
 ]
index ceaa2676ca6e43ae7fb3c55a254ee2bff572f626..4f8f725864e9956bc26c764ea25cb2dd16366dba 100644 (file)
@@ -90,13 +90,13 @@ static int remount_by_fstab(Hashmap **ret_pids) {
         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 log_error_errno(r, "Failed to get next entry from fstab: %m");
                 if (r > 0) /* EOF */
                         break;
 
-                const char *target = mnt_fs_get_target(fs);
+                const char *target = sym_mnt_fs_get_target(fs);
                 if (!target)
                         continue;
 
index 57ab68deb67cdc9d1438bc433b6efb4082c6cb15..e8b1d7e42f72ba0fbaa68589caee0bf19237424e 100644 (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;
         }
index aada5a7eb538472e1acdc5e7b6dcfd1a6b725ce6..126ed948af551757b51ccdf0bd1ea27585a8e1e5 100644 (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;
 
index b6bd7f1d592cb005b7225e78e74abf6c8a697cc3..17f8ebf0ad5234b96151f24fd198893df5571d2a 100644 (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,
index 2dbf8c961c8afb80ff99c79e6b125d1c03dba00f..9acb83a47e7859269f231ab779c9de3fbd7ae46f 100644 (file)
@@ -322,7 +322,7 @@ libshared_deps = [threads,
                   libgcrypt_cflags,
                   libkmod_cflags,
                   liblz4_cflags,
-                  libmount,
+                  libmount_cflags,
                   libopenssl,
                   libp11kit_cflags,
                   libpam_cflags,
index f38628a98e1b4f4ede93ed5e005709ae619c6974..52f45b74e4dcc0df74ef836dbd7409c1ab930c5e 100644 (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();
+        r = dlopen_libmount();
+        if (r < 0)
+                return r;
+
+        table = sym_mnt_new_table();
         if (!table)
                 return -ENOMEM;
 
-        r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
+        r = sym_mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
         if (r < 0)
                 return r;
 
-        fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD);
+        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();
                 }
index 208134cb157a56952f7dfcaab91d52da2a6dc496..f064473ef77a25a8fc02598ab08112f38f89c527 100644 (file)
@@ -36,12 +36,16 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
 
         assert(head);
 
-        t = mnt_new_table();
-        i = mnt_new_iter(MNT_ITER_FORWARD);
+        r = dlopen_libmount();
+        if (r < 0)
+                return log_error_errno(r, "Cannot enumerate swap partitions, no libmount support.");
+
+        t = sym_mnt_new_table();
+        i = sym_mnt_new_iter(MNT_ITER_FORWARD);
         if (!t || !i)
                 return log_oom();
 
-        r = mnt_table_parse_swaps(t, swaps);
+        r = sym_mnt_table_parse_swaps(t, swaps);
         if (r == -ENOENT) /* no /proc/swaps is fine */
                 return 0;
         if (r < 0)
@@ -52,13 +56,13 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
                 _cleanup_free_ SwapDevice *swap = NULL;
                 const char *source;
 
-                r = mnt_table_next_fs(t, i, &fs);
+                r = sym_mnt_table_next_fs(t, i, &fs);
                 if (r == 1) /* EOF */
                         break;
                 if (r < 0)
                         return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps");
 
-                source = mnt_fs_get_source(fs);
+                source = sym_mnt_fs_get_source(fs);
                 if (!source)
                         continue;
 
index 4893ea62e3681063b04598811b6e6d1f77176b19..c239ec35726e620ec2d58da8678dc9a14e0c9cf5 100644 (file)
@@ -16,7 +16,7 @@ executables += [
                 'name' : 'systemd-shutdown',
                 'sources' : systemd_shutdown_sources + systemd_shutdown_extract_sources,
                 'extract' : systemd_shutdown_extract_sources,
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
         libexec_template + {
                 'name' : 'systemd-shutdown.standalone',
@@ -28,11 +28,11 @@ executables += [
                         libshared_static,
                         libsystemd_static,
                 ],
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
         test_template + {
                 'sources' : files('test-umount.c'),
                 'objects' : ['systemd-shutdown'],
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
 ]
index 45c6db9245e233c3ae012d4ec3c95b0f39b9810b..46f208824aafe4f34f885606bbfcff54b0d814ca 100644 (file)
@@ -69,17 +69,17 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
                 bool try_remount_ro, is_api_vfs, is_network;
                 _cleanup_free_ MountPoint *m = NULL;
 
-                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_error_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;
 
-                fstype = mnt_fs_get_fstype(fs);
+                fstype = sym_mnt_fs_get_fstype(fs);
 
                 /* Combine the generic VFS options with the FS-specific options. Duplicates are not a problem
                  * here, because the only options that should come up twice are typically ro/rw, which are
@@ -87,9 +87,9 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
                  *
                  * Even if there are duplicates later in mount_option_mangle() they shouldn't hurt anyways as
                  * they override each other. */
-                if (!strextend_with_separator(&options, ",", mnt_fs_get_vfs_options(fs)))
+                if (!strextend_with_separator(&options, ",", sym_mnt_fs_get_vfs_options(fs)))
                         return log_oom();
-                if (!strextend_with_separator(&options, ",", mnt_fs_get_fs_options(fs)))
+                if (!strextend_with_separator(&options, ",", sym_mnt_fs_get_fs_options(fs)))
                         return log_oom();
 
                 /* Ignore mount points we can't unmount because they are API or because we are keeping them
@@ -122,7 +122,7 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
                          * were when the filesystem was mounted, except for the desired changes. So we
                          * reconstruct both here and adjust them for the later remount call too. */
 
-                        r = mnt_fs_get_propagation(fs, &remount_flags);
+                        r = sym_mnt_fs_get_propagation(fs, &remount_flags);
                         if (r < 0) {
                                 log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path);
                                 continue;
index ea031701e9a4672f6ca5ff0a6fd6a9b182332495..d95323fc75b88a791f42a826a95ca394575395d5 100644 (file)
@@ -215,7 +215,7 @@ simple_tests += files(
 ############################################################
 
 common_test_dependencies = [
-        libmount,
+        libmount_cflags,
         librt,
         libseccomp_cflags,
         libselinux,
@@ -289,6 +289,7 @@ executables += [
                 'dependencies' : [
                         libblkid_cflags,
                         libkmod_cflags,
+                        libmount_cflags,
                         libp11kit_cflags,
                         libseccomp_cflags,
                 ],
@@ -341,7 +342,7 @@ executables += [
         test_template + {
                 'sources' : files('test-libmount.c'),
                 'dependencies' : [
-                        libmount,
+                        libmount_cflags,
                         threads,
                 ],
         },
@@ -359,7 +360,7 @@ executables += [
         },
         test_template + {
                 'sources' : files('test-mount-util.c'),
-                'dependencies' : libmount,
+                'dependencies' : libmount_cflags,
         },
         test_template + {
                 'sources' : files('test-netlink-manual.c'),
index 68975d473ccc6363eb294b1f6525994fdf3666e9..b677e2b2b33ef53e27b727431d4e1d23c6093ced 100644 (file)
@@ -12,6 +12,7 @@
 #include "libarchive-util.h"
 #include "libaudit-util.h"
 #include "libfido2-util.h"
+#include "libmount-util.h"
 #include "main-func.h"
 #include "module-util.h"
 #include "pam-util.h"
@@ -58,6 +59,7 @@ static int run(int argc, char **argv) {
         ASSERT_DLOPEN(dlopen_libacl, HAVE_ACL);
         ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
         ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
+        ASSERT_DLOPEN(dlopen_libmount, true);
 
         return 0;
 }
index b53de31c482ca8897e7e09d63a5f9f0bfd41c59f..8fe9da79db24316413ba6770b983e544cc686870 100644 (file)
@@ -32,7 +32,7 @@ static void test_libmount_unescaping_one(
 
         /* We allow this call and the checks below to fail in some cases. See the case definitions below. */
 
-        r = mnt_table_next_fs(table, iter, &fs);
+        r = sym_mnt_table_next_fs(table, iter, &fs);
         if (r != 0 && may_fail) {
                 log_error_errno(r, "mnt_table_next_fs failed: %m");
                 return;
@@ -41,8 +41,8 @@ static void test_libmount_unescaping_one(
 
         assert_se(x = cescape(string));
 
-        assert_se(source = mnt_fs_get_source(fs));
-        assert_se(target = mnt_fs_get_target(fs));
+        assert_se(source = sym_mnt_fs_get_source(fs));
+        assert_se(target = sym_mnt_fs_get_target(fs));
 
         assert_se(cs = cescape(source));
         assert_se(ct = cescape(target));
@@ -63,7 +63,7 @@ static void test_libmount_unescaping_one(
         assert_se(may_fail || streq(source, expected_source));
         assert_se(may_fail || streq(target, expected_target));
 
-        assert_se(mnt_table_next_fs(table, iter, &fs) == 1);
+        assert_se(sym_mnt_table_next_fs(table, iter, &fs) == 1);
 }
 
 TEST(libmount_unescaping) {
index 804d4f4e5e305cb7eb637999de68bc2436b9f532..40ebf7e7446765c4be166ef298e263de21d5a660 100644 (file)
@@ -361,7 +361,7 @@ TEST(umount_recursive) {
                         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;
                                 if (r < 0) {
@@ -369,7 +369,7 @@ TEST(umount_recursive) {
                                         _exit(EXIT_FAILURE);
                                 }
 
-                                log_debug("left after complete umount: %s", mnt_fs_get_target(fs));
+                                log_debug("left after complete umount: %s", sym_mnt_fs_get_target(fs));
                         }
 
                         _exit(EXIT_SUCCESS);