]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/mount: comprehensively disable mount unit support if no libmount
authorMike Yuan <me@yhndnzj.com>
Tue, 25 Nov 2025 01:34:08 +0000 (02:34 +0100)
committerMike Yuan <me@yhndnzj.com>
Wed, 26 Nov 2025 01:40:27 +0000 (02:40 +0100)
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.

src/core/automount.c
src/core/mount.c
src/core/unit.c

index b53d91dda1af7c85aac103ca2da14b35c65121c6..ddb524d01a473ef1ab153a108a6f49b7b0ecd755 100644 (file)
@@ -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;
 
index 3bd22bfb9ca21e44b8fbad1edb81c243b8519704..c2bc2106169bb5fc96ba4a2ce62bbe9f6762d5ef 100644 (file)
@@ -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 = {
index b840370e24449bb3d38928fe5c4da685c06b90b7..50c744f5c86088fb07864a6690b5f244de140ab8 100644 (file)
@@ -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. */