core: improve log messages when we cannot process a mount point

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
This commit is contained in:
Lennart Poettering 2020-05-25 00:37:26 +02:00
parent 5aec5c751a
commit 2c905207db
3 changed files with 60 additions and 3 deletions

View 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.

View 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))

View 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