]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: improve log messages when we cannot process a mount point
authorLennart Poettering <lennart@poettering.net>
Sun, 24 May 2020 22:37:26 +0000 (00:37 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 26 May 2020 07:17:48 +0000 (09:17 +0200)
Whenever we pick up a new line in /proc/self/mountinfo and want to
synthesize a new mount unit from it, let's say which one it is.
Moreover, downgrade the log message when we encounter a mount point with
an overly long name to LOG_WARNING, since it's generally fine to ignore
such mount points.

Also, attach a catalog entry to explain the situation further.

Prompted-By: #15221
catalog/systemd.catalog.in
src/core/mount.c
src/systemd/sd-messages.h

index 3342d594223c869df58edc71189c86a609d85e65..b29ba6d65b84599bc1144bacf0cf18160cc2315b 100644 (file)
@@ -435,3 +435,34 @@ hyphen and otherwise fully numeric.
 For further details on strict and relaxed user/group name rules, see:
 
 https://systemd.io/USER_NAMES
+
+-- 1b3bb94037f04bbf81028e135a12d293
+Subject: Failed to generate valid unit name from path '@MOUNT_POINT@'.
+Defined-By: systemd
+Support: %SUPPORT_URL%
+
+The following mount point path could not be converted into a valid .mount
+unit name:
+
+    @MOUNT_POINT@
+
+Typically this means that the path to the mount point is longer than allowed
+for valid unit names.
+
+systemd dynamically synthesizes .mount units for all mount points appearing on
+the system. For that a simple escaping algorithm is applied: the absolute path
+name is used, with all "/" characters replaced by "-" (the leading one is
+removed). Moreover, any non-alphanumeric characters (as well as any of ":",
+"-", "_", ".", "\") are replaced by "\xNN" where "NN" is the hexadecimal code
+of the character. Finally, ".mount" is suffixed. The resulting string must be
+under 256 characters in length to be a valid unit name. This restriction is
+made in order for all unit names to also be suitable as file names. If a mount
+point appears that — after escaping — is longer than this limit it cannot be
+mapped to a unit. In this case systemd will refrain from synthesizing a unit
+and cannot be used to manage the mount point. It will not appear in the service
+manager's unit table and thus also not be torn down safely and automatically at
+system shutdown.
+
+It is generally recommended to avoid such overly long mount point paths, or —
+if used anyway – manage them independently of systemd, i.e. establish them as
+well as tear them down automatically at system shutdown by other software.
index 48500b49327580434fddbb94c9651fd2a3333a36..86a6098332aac9fb7266c82411ed0558c358939c 100644 (file)
@@ -1672,9 +1672,30 @@ static int mount_setup_unit(
         if (!is_path(where))
                 return 0;
 
+        /* Mount unit names have to be (like all other unit names) short enough to fit into file names. This
+         * means there's a good chance that overly long mount point paths after mangling them to look like a
+         * unit name would result in unit names we don't actually consider valid. This should be OK however
+         * as such long mount point paths should not happen on regular systems — and if they appear
+         * nonetheless they are generally synthesized by software, and thus managed by that other
+         * software. Having such long names just means you cannot use systemd to manage those specific mount
+         * points, which should be an OK restriction to make. After all we don't have to be able to manage
+         * all mount points in the world — as long as we don't choke on them when we encounter them. */
         r = unit_name_from_path(where, ".mount", &e);
-        if (r < 0)
-                return log_error_errno(r, "Failed to generate unit name from path '%s': %m", where);
+        if (r < 0) {
+                static RateLimit rate_limit = { /* Let's log about this at warning level at most once every
+                                                 * 5s. Given that we generate this whenever we read the file
+                                                 * otherwise we probably shouldn't flood the logs with
+                                                 * this */
+                        .interval = 5 * USEC_PER_SEC,
+                        .burst = 1,
+                };
+
+                return log_struct_errno(
+                                ratelimit_below(&rate_limit) ? LOG_WARNING : LOG_DEBUG, r,
+                                "MESSAGE_ID=" SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR,
+                                "MOUNT_POINT=%s", where,
+                                LOG_MESSAGE("Failed to generate valid unit name from path '%s', ignoring mount point: %m", where));
+        }
 
         u = manager_get_unit(m, e);
         if (u)
@@ -1684,7 +1705,7 @@ static int mount_setup_unit(
                  * by the sysadmin having called mount(8) directly. */
                 r = mount_setup_new_unit(m, e, what, where, options, fstype, &flags, &u);
         if (r < 0)
-                return log_warning_errno(r, "Failed to set up mount unit: %m");
+                return log_warning_errno(r, "Failed to set up mount unit for '%s': %m", where);
 
         /* If the mount changed properties or state, let's notify our clients */
         if (flags & (MOUNT_PROC_JUST_CHANGED|MOUNT_PROC_JUST_MOUNTED))
index 162b650e649b22eb87ed05fec33d34ae2dcbd4b5..f5dd0a04c76dea7a53a5bc097acc9291bc33c230 100644 (file)
@@ -161,6 +161,11 @@ _SD_BEGIN_DECLARATIONS;
 #define SD_MESSAGE_UNSAFE_USER_NAME       SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
 #define SD_MESSAGE_UNSAFE_USER_NAME_STR   SD_ID128_MAKE_STR(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f)
 
+#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE \
+                                          SD_ID128_MAKE(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93)
+#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR \
+                                          SD_ID128_MAKE_STR(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93)
+
 _SD_END_DECLARATIONS;
 
 #endif