From: Mike Yuan Date: Tue, 25 Nov 2025 01:34:08 +0000 (+0100) Subject: core/mount: comprehensively disable mount unit support if no libmount X-Git-Tag: v259-rc2~6^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1bee93e6e291b689c307ccf1496a44a73021fc84;p=thirdparty%2Fsystemd.git core/mount: comprehensively disable mount unit support if no libmount Follow-up for b3243f4beead231e27a4f017f53288a303177cb2 and 5df44d0f6a1ba23b52b0c46a5e720f334f152ae5 Since we now consider this a supported senario, let's hook up libmount loading with the high-level unit_type_supported() machinery and gracefully skip the whole unit accordingly. --- diff --git a/src/core/automount.c b/src/core/automount.c index b53d91dda1a..ddb524d01a4 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -1033,6 +1033,9 @@ static void automount_reset_failed(Unit *u) { static bool automount_supported(void) { static int supported = -1; + if (!unit_type_supported(UNIT_MOUNT)) + return false; + if (supported < 0) supported = access("/dev/autofs", F_OK) >= 0; diff --git a/src/core/mount.c b/src/core/mount.c index 3bd22bfb9ca..c2bc2106169 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -240,34 +240,6 @@ static void mount_done(Unit *u) { m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source); } -static int update_parameters_proc_self_mountinfo( - Mount *m, - const char *what, - const char *options, - const char *fstype) { - - MountParameters *p; - int r, q, w; - - assert(m); - - p = &m->parameters_proc_self_mountinfo; - - r = free_and_strdup(&p->what, what); - if (r < 0) - return r; - - q = free_and_strdup(&p->options, options); - if (q < 0) - return q; - - w = free_and_strdup(&p->fstype, fstype); - if (w < 0) - return w; - - return r > 0 || q > 0 || w > 0; -} - static int mount_add_mount_dependencies(Mount *m) { MountParameters *pm; int r; @@ -1747,6 +1719,34 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user } #if HAVE_LIBMOUNT +static int update_parameters_proc_self_mountinfo( + Mount *m, + const char *what, + const char *options, + const char *fstype) { + + MountParameters *p; + int r, q, w; + + assert(m); + + p = &m->parameters_proc_self_mountinfo; + + r = free_and_strdup(&p->what, what); + if (r < 0) + return r; + + q = free_and_strdup(&p->options, options); + if (q < 0) + return q; + + w = free_and_strdup(&p->fstype, fstype); + if (w < 0) + return w; + + return r > 0 || q > 0 || w > 0; +} + static int mount_setup_new_unit( Manager *m, const char *name, @@ -1927,10 +1927,8 @@ static int mount_setup_unit( return 0; } -#endif static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { -#if HAVE_LIBMOUNT _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; _cleanup_set_free_ Set *devices = NULL; @@ -1970,10 +1968,8 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { } return 0; -#else - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in"); -#endif } +#endif static void mount_shutdown(Manager *m) { assert(m); @@ -2025,6 +2021,7 @@ static void mount_enumerate_perpetual(Manager *m) { int r; assert(m); + assert(unit_type_supported(UNIT_MOUNT)); /* Whatever happens, we know for sure that the root directory is around, and cannot go away. Let's * unconditionally synthesize it here and mark it as perpetual. */ @@ -2044,13 +2041,13 @@ static void mount_enumerate_perpetual(Manager *m) { unit_add_to_dbus_queue(u); } +#if HAVE_LIBMOUNT static bool mount_is_mounted(Mount *m) { assert(m); return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED); } -#if HAVE_LIBMOUNT static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { Manager *m = ASSERT_PTR(userdata); Job *j; @@ -2072,16 +2069,11 @@ static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) { #endif static void mount_enumerate(Manager *m) { -#if HAVE_LIBMOUNT - int r; - assert(m); + assert(unit_type_supported(UNIT_MOUNT)); - r = dlopen_libmount(); - if (r < 0) { - log_error_errno(r, "Cannot enumerate mounts, as libmount is not available: %m"); - goto fail; - } +#if HAVE_LIBMOUNT + int r; sym_mnt_init_debug(0); @@ -2164,23 +2156,20 @@ static void mount_enumerate(Manager *m) { return; fail: - mount_shutdown(m); -#else - log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Cannot enumerate mounts, as libmount support is not compiled in"); - mount_shutdown(m); #endif + mount_shutdown(m); } static int drain_libmount(Manager *m) { -#if HAVE_LIBMOUNT - bool rescan = false; - int r; - assert(m); if (!m->mount_monitor) return false; +#if HAVE_LIBMOUNT + bool rescan = false; + int r; + /* 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 @@ -2196,14 +2185,13 @@ static int drain_libmount(Manager *m) { } while (r == 0); return rescan; + #else - return 0; + assert_not_reached(); #endif } static int mount_process_proc_self_mountinfo(Manager *m) { - _cleanup_set_free_ Set *around = NULL, *gone = NULL; - const char *what; int r; assert(m); @@ -2212,6 +2200,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) { if (r <= 0) return r; +#if HAVE_LIBMOUNT r = mount_load_proc_self_mountinfo(m, true); if (r < 0) { /* Reset flags, just in case, for later calls */ @@ -2223,6 +2212,8 @@ static int mount_process_proc_self_mountinfo(Manager *m) { manager_dispatch_load_queue(m); + _cleanup_set_free_ Set *around = NULL, *gone = NULL; + LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) { Mount *mount = MOUNT(u); @@ -2302,6 +2293,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) { mount->proc_flags = 0; } + const char *what; SET_FOREACH(what, gone) { if (set_contains(around, what)) continue; @@ -2311,6 +2303,9 @@ static int mount_process_proc_self_mountinfo(Manager *m) { } return 0; +#else + assert_not_reached(); +#endif } #if HAVE_LIBMOUNT @@ -2410,6 +2405,10 @@ static int mount_test_startable(Unit *u) { return true; } +static bool mount_supported(void) { + return dlopen_libmount() >= 0; +} + static int mount_subsystem_ratelimited(Manager *m) { assert(m); @@ -2554,6 +2553,7 @@ const UnitVTable mount_vtable = { .enumerate_perpetual = mount_enumerate_perpetual, .enumerate = mount_enumerate, .shutdown = mount_shutdown, + .supported = mount_supported, .subsystem_ratelimited = mount_subsystem_ratelimited, .status_message_formats = { diff --git a/src/core/unit.c b/src/core/unit.c index b840370e244..50c744f5c86 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -5023,6 +5023,11 @@ int unit_add_mounts_for(Unit *u, const char *path, UnitDependencyMask mask, Unit if (hashmap_contains(*unit_map, path)) /* Exit quickly if the path is already covered. */ return 0; + if (!unit_type_supported(UNIT_MOUNT)) { + log_once(LOG_NOTICE, "Mount unit not supported, skipping *MountsFor= dependencies."); + return 0; + } + /* Use the canonical form of the path as the stored key. We call path_is_normalized() * only after simplification, since path_is_normalized() rejects paths with '.'. * path_is_normalized() also verifies that the path fits in PATH_MAX. */