From 43687c22ab5a07906482271cf47c581087924638 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Nov 2025 13:07:39 +0100 Subject: [PATCH 1/4] tests: Assume we're running in a chroot if check fails running_in_chroot() will fail when a test is executed as a non-root user without CAP_DAC_READ_SEARCH as it won't be able to access /proc/1/root. Let's make things more robust by skipping tests if we can't detect if we're in a chroot or not, since if we can't even detect if we're in a chroot or not, chances are we're missing the required privileges to execute the test anyway. --- src/test/test-execute.c | 2 +- src/test/test-loop-block.c | 2 +- src/test/test-mount-util.c | 2 +- src/test/test-mountpoint-util.c | 2 +- src/test/test-reread-partition-table.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/test-execute.c b/src/test/test-execute.c index d043521034..65908bc8fc 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -1612,7 +1612,7 @@ static int intro(void) { if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) return log_tests_skipped("not privileged"); - if (running_in_chroot() > 0) + if (running_in_chroot() != 0) return log_tests_skipped("running in chroot"); if (enter_cgroup_subroot(NULL) == -ENOMEDIUM) diff --git a/src/test/test-loop-block.c b/src/test/test-loop-block.c index 144f898f3c..76046f98ad 100644 --- a/src/test/test-loop-block.c +++ b/src/test/test-loop-block.c @@ -240,7 +240,7 @@ static int run(int argc, char *argv[]) { if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) return log_tests_skipped("not running privileged"); - if (detect_container() > 0 || running_in_chroot() > 0) + if (detect_container() != 0 || running_in_chroot() != 0) return log_tests_skipped("Test not supported in a container/chroot, requires udev/uevent notifications"); assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, 0, LO_FLAGS_PARTSCAN, LOCK_EX, &loop) >= 0); diff --git a/src/test/test-mount-util.c b/src/test/test-mount-util.c index 5d352a7df0..7e40ca79ea 100644 --- a/src/test/test-mount-util.c +++ b/src/test/test-mount-util.c @@ -38,7 +38,7 @@ #define CHECK_PRIV \ if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) \ return (void) log_tests_skipped("Not privileged"); \ - if (running_in_chroot() > 0) \ + if (running_in_chroot() != 0) \ return (void) log_tests_skipped("running in chroot"); TEST(mount_option_mangle) { diff --git a/src/test/test-mountpoint-util.c b/src/test/test-mountpoint-util.c index 04426365f8..d4c830b476 100644 --- a/src/test/test-mountpoint-util.c +++ b/src/test/test-mountpoint-util.c @@ -457,7 +457,7 @@ static int intro(void) { /* let's move into our own mount namespace with all propagation from the host turned off, so * that /proc/self/mountinfo is static and constant for the whole time our test runs. */ - if (running_in_chroot() > 0) { + if (running_in_chroot() != 0) { /* We cannot remount file system with MS_PRIVATE when running in chroot. */ log_notice("Running in chroot, proceeding in originating mount namespace."); return EXIT_SUCCESS; diff --git a/src/test/test-reread-partition-table.c b/src/test/test-reread-partition-table.c index c56e44d8ef..33ab36c5f2 100644 --- a/src/test/test-reread-partition-table.c +++ b/src/test/test-reread-partition-table.c @@ -49,7 +49,7 @@ TEST(rereadpt) { return (void) log_tests_skipped("test not available in container"); if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) return (void) log_tests_skipped("test requires privileges"); - if (running_in_chroot() > 0) + if (running_in_chroot() != 0) return (void) log_tests_skipped("test not available in chroot()"); _cleanup_free_ char *sfdisk_path = NULL; From dee7dfea1db4291f2418a73487a90e7513c3cb8a Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Nov 2025 12:51:14 +0100 Subject: [PATCH 2/4] test-reread-partition-table: Only check for CAP_SYS_ADMIN We might have CAP_SYS_ADMIN even without being root. --- src/test/test-reread-partition-table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/test-reread-partition-table.c b/src/test/test-reread-partition-table.c index 33ab36c5f2..f6234f0f8a 100644 --- a/src/test/test-reread-partition-table.c +++ b/src/test/test-reread-partition-table.c @@ -47,7 +47,7 @@ TEST(rereadpt) { if (detect_container() > 0) return (void) log_tests_skipped("test not available in container"); - if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0) + if (have_effective_cap(CAP_SYS_ADMIN) <= 0) return (void) log_tests_skipped("test requires privileges"); if (running_in_chroot() != 0) return (void) log_tests_skipped("test not available in chroot()"); From e910f9bc63356ccaca6d87bd62fd79d36b1cccd4 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Nov 2025 11:53:12 +0100 Subject: [PATCH 3/4] test-reread-partition-table: Don't keep open fds around Avoids EBUSY from BLKRRPART when built without libblkid support. --- src/test/test-reread-partition-table.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/test/test-reread-partition-table.c b/src/test/test-reread-partition-table.c index f6234f0f8a..f171d1737a 100644 --- a/src/test/test-reread-partition-table.c +++ b/src/test/test-reread-partition-table.c @@ -97,11 +97,12 @@ TEST(rereadpt) { ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); - _cleanup_close_ int pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); - ASSERT_OK_ERRNO(pfd); + _cleanup_close_ int pfd = -EBADF; + ASSERT_OK_ERRNO(pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY)); uint64_t size; ASSERT_OK(blockdev_get_device_size(pfd, &size)); ASSERT_EQ(size, 20U*1024U*1024U); + pfd = safe_close(pfd); /* No change */ ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); @@ -122,11 +123,14 @@ TEST(rereadpt) { ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); + ASSERT_OK_ERRNO(pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY)); ASSERT_OK(blockdev_get_device_size(pfd, &size)); ASSERT_EQ(size, 30U*1024U*1024U); + pfd = safe_close(pfd); /* No change */ ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); + ASSERT_OK_ERRNO(pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY)); /* Move */ log_notice("MOVING BY 50M"); @@ -137,19 +141,19 @@ TEST(rereadpt) { ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_ERROR(reread_partition_table_fd(loop->fd, /* flags= */ 0), EBUSY); + pfd = safe_close(pfd); + ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); - - safe_close(pfd); - ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); - pfd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); - ASSERT_OK_ERRNO(pfd); + pfd = ASSERT_OK_ERRNO(open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY)); ASSERT_OK(blockdev_get_device_size(pfd, &size)); ASSERT_EQ(size, 15U*1024U*1024U); + pfd = safe_close(pfd); /* No change */ ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); + pfd = ASSERT_OK_ERRNO(open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY)); /* Remove */ log_notice("REMOVING"); @@ -159,9 +163,9 @@ TEST(rereadpt) { ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); ASSERT_ERROR(reread_partition_table_fd(loop->fd, /* flags= */ 0), EBUSY); + pfd = safe_close(pfd); ASSERT_OK_ZERO_ERRNO(access(p, F_OK)); - pfd = safe_close(pfd); ASSERT_OK(reread_partition_table_fd(loop->fd, /* flags= */ 0)); ASSERT_ERROR_ERRNO(access(p, F_OK), ENOENT); } From 7336f2c748fd37a60a3f5353ad198c1534d6cb5f Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 24 Nov 2025 10:57:58 +0100 Subject: [PATCH 4/4] meson: Still build libshared even if libmount is disabled Currently, if the libmount feature is disabled, we don't build libshared and as a result skip building every other executable as well. Among other things, this makes our nodeps CI builds kind of pointless since hardly any code will be compiled. Let's improve on the situation by making libmount properly optional in libshared. Then, we only skip building the executables that actually need libmount. --- meson.build | 3 +- src/core/meson.build | 47 ++++++++++++++++--------- src/creds/meson.build | 4 +++ src/cryptsetup/meson.build | 2 +- src/fstab-generator/meson.build | 4 +++ src/mount/meson.build | 4 +++ src/remount-fs/meson.build | 4 +++ src/shared/fstab-util.c | 14 ++++++++ src/shared/libmount-util.c | 11 +++++- src/shared/libmount-util.h | 12 ++++--- src/shared/mount-util.c | 61 +++++++++++++++++++++++++-------- src/shutdown/meson.build | 4 +++ src/test/meson.build | 2 ++ src/test/test-dlopen-so.c | 2 +- test/meson.build | 4 +-- tools/update-dbus-docs.py | 4 +-- 16 files changed, 138 insertions(+), 44 deletions(-) diff --git a/meson.build b/meson.build index 8b08bb3178..6f4017d5e2 100644 --- a/meson.build +++ b/meson.build @@ -1163,8 +1163,9 @@ endif libmount = dependency('mount', version : fuzzer_build ? '>= 0' : '>= 2.30', - disabler : true, required : get_option('libmount')) +have = libmount.found() +conf.set10('HAVE_LIBMOUNT', have) libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true) libfdisk = dependency('fdisk', diff --git a/src/core/meson.build b/src/core/meson.build index fbadd0f6a6..887fb52b85 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -1,5 +1,36 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +load_fragment_gperf_gperf = custom_target( + input : 'load-fragment-gperf.gperf.in', + output: 'load-fragment-gperf.gperf', + command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@']) + +libcore_build_dir = meson.current_build_dir() +core_includes = [includes, include_directories('.')] + +systemd_pc = custom_target( + input : 'systemd.pc.in', + output : 'systemd.pc', + command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'], + install : pkgconfigdatadir != 'no', + install_tag : 'devel', + install_dir : pkgconfigdatadir) + +if conf.get('HAVE_LIBMOUNT') != 1 + libcore = disabler() + + core_test_template = test_template + { + 'link_with' : [ + libcore, + libshared, + ], + 'include_directories' : core_includes, + 'suite' : 'core', + } + + subdir_done() +endif + libcore_sources = files( 'audit-fd.c', 'automount.c', @@ -84,11 +115,6 @@ endif sources += libcore_sources -load_fragment_gperf_gperf = custom_target( - input : 'load-fragment-gperf.gperf.in', - output: 'load-fragment-gperf.gperf', - command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@']) - load_fragment_gperf_c = custom_target( input : load_fragment_gperf_gperf, output : 'load-fragment-gperf.c', @@ -123,7 +149,6 @@ man_page_depends += bpf_delegate_xml generated_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c, bpf_delegate_configs_inc] libcore_sources += [load_fragment_gperf_c, load_fragment_gperf_nulstr_c, bpf_delegate_configs_inc] -libcore_build_dir = meson.current_build_dir() libcore_name = 'systemd-core-@0@'.format(shared_lib_tag) libcore_static = static_library( @@ -155,8 +180,6 @@ libcore = shared_library( install : true, install_dir : pkglibdir) -core_includes = [includes, include_directories('.')] - systemd_sources = files( 'main.c', 'crash-handler.c', @@ -257,14 +280,6 @@ foreach item : in_files install_dir : dir) endforeach -systemd_pc = custom_target( - input : 'systemd.pc.in', - output : 'systemd.pc', - command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'], - install : pkgconfigdatadir != 'no', - install_tag : 'devel', - install_dir : pkgconfigdatadir) - install_data('org.freedesktop.systemd1.conf', install_dir : dbuspolicydir) install_data('org.freedesktop.systemd1.service', diff --git a/src/creds/meson.build b/src/creds/meson.build index 1cd6f8c42f..a6e66495b6 100644 --- a/src/creds/meson.build +++ b/src/creds/meson.build @@ -1,5 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +if conf.get('HAVE_LIBMOUNT') != 1 + subdir_done() +endif + executables += [ executable_template + { 'name' : 'systemd-creds', diff --git a/src/cryptsetup/meson.build b/src/cryptsetup/meson.build index a029a016bc..d9778259c2 100644 --- a/src/cryptsetup/meson.build +++ b/src/cryptsetup/meson.build @@ -1,6 +1,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -if conf.get('HAVE_LIBCRYPTSETUP') != 1 +if conf.get('HAVE_LIBCRYPTSETUP') != 1 or conf.get('HAVE_LIBMOUNT') != 1 subdir_done() endif diff --git a/src/fstab-generator/meson.build b/src/fstab-generator/meson.build index 93e074e244..66e44c9770 100644 --- a/src/fstab-generator/meson.build +++ b/src/fstab-generator/meson.build @@ -1,5 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +if conf.get('HAVE_LIBMOUNT') != 1 + subdir_done() +endif + executables += [ generator_template + { 'name' : 'systemd-fstab-generator', diff --git a/src/mount/meson.build b/src/mount/meson.build index feb00d8c2a..019b2f1eba 100644 --- a/src/mount/meson.build +++ b/src/mount/meson.build @@ -1,5 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +if conf.get('HAVE_LIBMOUNT') != 1 + subdir_done() +endif + executables += [ executable_template + { 'name' : 'systemd-mount', diff --git a/src/remount-fs/meson.build b/src/remount-fs/meson.build index 6f619c16e1..d312d1936a 100644 --- a/src/remount-fs/meson.build +++ b/src/remount-fs/meson.build @@ -1,5 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +if conf.get('HAVE_LIBMOUNT') != 1 + subdir_done() +endif + executables += [ libexec_template + { 'name' : 'systemd-remount-fs', diff --git a/src/shared/fstab-util.c b/src/shared/fstab-util.c index e8b1d7e42f..da9c691de6 100644 --- a/src/shared/fstab-util.c +++ b/src/shared/fstab-util.c @@ -38,6 +38,7 @@ bool fstab_enabled_full(int enabled) { } int fstab_has_fstype(const char *fstype) { +#if HAVE_LIBMOUNT _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; int r; @@ -65,6 +66,9 @@ int fstab_has_fstype(const char *fstype) { if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype)) return true; } +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } bool fstab_is_extrinsic(const char *mount, const char *opts) { @@ -92,6 +96,7 @@ bool fstab_is_extrinsic(const char *mount, const char *opts) { return false; } +#if HAVE_LIBMOUNT static int fstab_is_same_node(const char *what_fstab, const char *path) { _cleanup_free_ char *node = NULL; @@ -110,8 +115,10 @@ static int fstab_is_same_node(const char *what_fstab, const char *path) { return false; } +#endif int fstab_has_mount_point_prefix_strv(char * const *prefixes) { +#if HAVE_LIBMOUNT _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; int r; @@ -147,9 +154,13 @@ int fstab_has_mount_point_prefix_strv(char * const *prefixes) { if (path_startswith_strv(path, prefixes)) return true; } +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } int fstab_is_mount_point_full(const char *where, const char *path) { +#if HAVE_LIBMOUNT _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; int r; @@ -184,6 +195,9 @@ int fstab_is_mount_point_full(const char *where, const char *path) { if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r))) return r; } +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } int fstab_filter_options( diff --git a/src/shared/libmount-util.c b/src/shared/libmount-util.c index c6c6074c25..8de8baeff8 100644 --- a/src/shared/libmount-util.c +++ b/src/shared/libmount-util.c @@ -1,9 +1,11 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "libmount-util.h" + +#if HAVE_LIBMOUNT #include #include "fstab-util.h" -#include "libmount-util.h" #include "log.h" static void *libmount_dl = NULL; @@ -39,8 +41,10 @@ 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; +#endif int dlopen_libmount(void) { +#if HAVE_LIBMOUNT ELF_NOTE_DLOPEN("mount", "Support for mount enumeration", ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, @@ -81,8 +85,12 @@ int dlopen_libmount(void) { DLSYM_ARG(mnt_table_parse_stream), DLSYM_ARG(mnt_table_parse_swaps), DLSYM_ARG(mnt_unref_monitor)); +#else + return -EOPNOTSUPP; +#endif } +#if HAVE_LIBMOUNT int libmount_parse_full( const char *path, FILE *source, @@ -151,3 +159,4 @@ int libmount_is_leaf( return r == 1; } +#endif diff --git a/src/shared/libmount-util.h b/src/shared/libmount-util.h index 15921a2f42..1438efbfd1 100644 --- a/src/shared/libmount-util.h +++ b/src/shared/libmount-util.h @@ -1,11 +1,14 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include "shared-forward.h" + +#if HAVE_LIBMOUNT + /* This needs to be after sys/mount.h */ #include /* IWYU pragma: export */ #include "dlfcn-util.h" -#include "shared-forward.h" extern DLSYM_PROTOTYPE(mnt_free_iter); extern DLSYM_PROTOTYPE(mnt_free_table); @@ -39,8 +42,6 @@ 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); @@ -55,14 +56,12 @@ static inline int libmount_parse_mountinfo( FILE *source, struct libmnt_table **ret_table, struct libmnt_iter **ret_iter) { - return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter); } static inline int libmount_parse_with_utab( struct libmnt_table **ret_table, struct libmnt_iter **ret_iter) { - return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter); } @@ -71,3 +70,6 @@ int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **r int libmount_is_leaf( struct libmnt_table *table, struct libmnt_fs *fs); +#endif + +int dlopen_libmount(void); diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index fb3f5b5206..0cfcfd9cc5 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -38,6 +38,7 @@ #include "user-util.h" int umount_recursive_full(const char *prefix, int flags, char **keep) { +#if HAVE_LIBMOUNT _cleanup_fclose_ FILE *f = NULL; int n = 0, r; @@ -110,6 +111,9 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) { } return n; +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } #define MS_CONVERTIBLE_FLAGS (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_NOSYMFOLLOW|MS_RELATIME|MS_NOATIME|MS_STRICTATIME|MS_NODIRATIME) @@ -175,11 +179,6 @@ int bind_remount_recursive_with_mountinfo( char **deny_list, FILE *proc_self_mountinfo) { - _cleanup_fclose_ FILE *proc_self_mountinfo_opened = NULL; - _cleanup_set_free_ Set *done = NULL; - unsigned n_tries = 0; - int r; - assert(prefix); if ((flags_mask & ~MS_CONVERTIBLE_FLAGS) == 0 && strv_isempty(deny_list) && !skip_mount_set_attr) { @@ -206,6 +205,12 @@ int bind_remount_recursive_with_mountinfo( return 0; /* Nice, this worked! */ } +#if HAVE_LIBMOUNT + _cleanup_fclose_ FILE *proc_self_mountinfo_opened = NULL; + _cleanup_set_free_ Set *done = NULL; + unsigned n_tries = 0; + int r; + if (!proc_self_mountinfo) { r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo_opened); if (r < 0) @@ -404,6 +409,9 @@ int bind_remount_recursive_with_mountinfo( log_trace("Remounted %s.", x); } } +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } int bind_remount_one_with_mountinfo( @@ -412,12 +420,6 @@ int bind_remount_one_with_mountinfo( unsigned long flags_mask, FILE *proc_self_mountinfo) { - _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; - unsigned long flags = 0; - struct libmnt_fs *fs; - const char *opts; - int r; - assert(path); assert(proc_self_mountinfo); @@ -438,6 +440,13 @@ int bind_remount_one_with_mountinfo( return 0; /* Nice, this worked! */ } +#if HAVE_LIBMOUNT + _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; + unsigned long flags = 0; + struct libmnt_fs *fs; + const char *opts; + int r; + rewind(proc_self_mountinfo); r = dlopen_libmount(); @@ -481,6 +490,9 @@ int bind_remount_one_with_mountinfo( } return 0; +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } int bind_remount_one(const char *path, unsigned long new_flags, unsigned long flags_mask) { @@ -859,6 +871,16 @@ int mount_option_mangle( unsigned long *ret_mount_flags, char **ret_remaining_options) { + assert(ret_mount_flags); + assert(ret_remaining_options); + + if (!options) { + *ret_mount_flags = mount_flags; + *ret_remaining_options = NULL; + return 0; + } + +#if HAVE_LIBMOUNT const struct libmnt_optmap *map; _cleanup_free_ char *ret = NULL; int r; @@ -876,9 +898,6 @@ int mount_option_mangle( * The validity of options stored in '*ret_remaining_options' is not checked. * If 'options' is NULL, this just copies 'mount_flags' to *ret_mount_flags. */ - assert(ret_mount_flags); - assert(ret_remaining_options); - r = dlopen_libmount(); if (r < 0) return r; @@ -922,6 +941,9 @@ int mount_option_mangle( *ret_remaining_options = TAKE_PTR(ret); return 0; +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } static int mount_in_namespace_legacy( @@ -1640,6 +1662,7 @@ void sub_mount_array_free(SubMount *s, size_t n) { free(s); } +#if HAVE_LIBMOUNT static int sub_mount_compare(const SubMount *a, const SubMount *b) { assert(a); assert(b); @@ -1659,9 +1682,10 @@ static void sub_mount_drop(SubMount *s, size_t n) { m = i; } } +#endif int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_mounts) { - +#if HAVE_LIBMOUNT _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; SubMount *mounts = NULL; @@ -1738,6 +1762,9 @@ int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_moun *ret_mounts = TAKE_PTR(mounts); *ret_n_mounts = n; return 0; +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } int bind_mount_submounts( @@ -2015,6 +2042,7 @@ int path_get_mount_info_at( char **ret_options, char **ret_source) { +#if HAVE_LIBMOUNT _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; int r, mnt_id; @@ -2077,6 +2105,9 @@ int path_get_mount_info_at( } return log_debug_errno(SYNTHETIC_ERRNO(ESTALE), "Cannot find mount ID %i from /proc/self/mountinfo.", mnt_id); +#else + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); +#endif } int path_is_network_fs_harder_at(int dir_fd, const char *path) { diff --git a/src/shutdown/meson.build b/src/shutdown/meson.build index 00d3d52c0a..60b66a87d5 100644 --- a/src/shutdown/meson.build +++ b/src/shutdown/meson.build @@ -1,5 +1,9 @@ # SPDX-License-Identifier: LGPL-2.1-or-later +if conf.get('HAVE_LIBMOUNT') != 1 + subdir_done() +endif + systemd_shutdown_sources = files( 'detach-dm.c', 'detach-loopback.c', diff --git a/src/test/meson.build b/src/test/meson.build index a32ff9f99e..6a66c51aea 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -349,6 +349,7 @@ executables += [ }, test_template + { 'sources' : files('test-libmount.c'), + 'conditions' : ['HAVE_LIBMOUNT'], 'dependencies' : [ libmount_cflags, threads, @@ -368,6 +369,7 @@ executables += [ }, test_template + { 'sources' : files('test-mount-util.c'), + 'conditions' : ['HAVE_LIBMOUNT'], 'dependencies' : libmount_cflags, }, test_template + { diff --git a/src/test/test-dlopen-so.c b/src/test/test-dlopen-so.c index 508e4cd004..47b8470ffb 100644 --- a/src/test/test-dlopen-so.c +++ b/src/test/test-dlopen-so.c @@ -54,7 +54,7 @@ static int run(int argc, char **argv) { ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID); ASSERT_DLOPEN(dlopen_libfido2, HAVE_LIBFIDO2); ASSERT_DLOPEN(dlopen_libkmod, HAVE_KMOD); - ASSERT_DLOPEN(dlopen_libmount, true); + ASSERT_DLOPEN(dlopen_libmount, HAVE_LIBMOUNT); ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM); ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP); ASSERT_DLOPEN(dlopen_libselinux, HAVE_SELINUX); diff --git a/test/meson.build b/test/meson.build index 1f1ec0a0e1..7e8c3296ab 100644 --- a/test/meson.build +++ b/test/meson.build @@ -108,7 +108,7 @@ endif ############################################################ test_compare_versions_sh = files('test-compare-versions.sh') -if want_tests != 'false' +if want_tests != 'false' and executables_by_name.has_key('systemd-analyze') exe = executables_by_name.get('systemd-analyze') test('test-compare-versions', test_compare_versions_sh, @@ -151,7 +151,7 @@ endif ############################################################ test_fstab_generator_sh = files('test-fstab-generator.sh') -if want_tests != 'false' +if want_tests != 'false' and executables_by_name.has_key('systemd-fstab-generator') exe = executables_by_name.get('systemd-fstab-generator') test('test-fstab-generator', test_fstab_generator_sh, diff --git a/tools/update-dbus-docs.py b/tools/update-dbus-docs.py index 17006f3d86..8e4ab62569 100755 --- a/tools/update-dbus-docs.py +++ b/tools/update-dbus-docs.py @@ -331,8 +331,8 @@ def main(): print(item, file=sys.stderr) sys.exit(77 if arguments.test else 1) - if not os.path.exists(f'{arguments.build_dir}/systemd'): - sys.exit(f"{arguments.build_dir}/systemd doesn't exist. Use --build-dir=.") + if not os.path.exists(f'{arguments.build_dir}'): + sys.exit(f"{arguments.build_dir} doesn't exist.") missing_version = [] stats = {page.split('/')[-1] : process(page, missing_version) for page in arguments.pages}