]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: fix detection of unitialized-/etc
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 26 Sep 2022 12:22:49 +0000 (14:22 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 27 Sep 2022 14:48:46 +0000 (16:48 +0200)
In 6ec4c852c910b1aca649e87ba3143841334f01fa I changed specifier_machine_id() to
return EUNATCH, but the code catching in tmpfiles wasn't adjusted.

Instead of translating errors at various levels, let the "original" errno value
(whatever was returned by the low-level reading function) propagate all the way
to the logging function, and only check which errnos to suppress there. This
makes it easier to follow the flow of data through all the layers. Also, we
don't need to provide wrapper functions for each place where we want to do the
supression.

The common set of errnos that have similar meaning are are caught using
ERRNO_IS_NOINFO(). It is more managable to use a wider net than to figure out
which errors could be returned in specific cases.

src/tmpfiles/tmpfiles.c

index 705721ffbd38b8ac0ef6387a81f8b8940f728f40..6cd19d929b4d1861bdde14b9b438c8abe4162d94 100644 (file)
@@ -225,17 +225,12 @@ static const char *const creation_mode_verb_table[_CREATION_MODE_MAX] = {
 
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(creation_mode_verb, CreationMode);
 
-static int specifier_machine_id_safe(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
-        int r;
-
-        /* If /etc/machine_id is missing or empty (e.g. in a chroot environment) return a recognizable error
-         * so that the caller can skip the rule gracefully. */
-
-        r = specifier_machine_id(specifier, data, root, userdata, ret);
-        if (IN_SET(r, -ENOENT, -ENOMEDIUM))
-                return -ENXIO;
-
-        return r;
+/* Different kinds of errors that mean that information is not available in the environment. */
+static inline bool ERRNO_IS_NOINFO(int r) {
+        return IN_SET(abs(r),
+                      EUNATCH,    /* os-release or machine-id missing */
+                      ENOMEDIUM,  /* machine-id or another file empty */
+                      ENXIO);     /* env var is unset */
 }
 
 static int specifier_directory(char specifier, const void *data, const char *root, const void *userdata, char **ret) {
@@ -320,15 +315,15 @@ static int user_config_paths(char*** ret) {
                 return r;
 
         r = xdg_user_config_dir(&persistent_config, "/user-tmpfiles.d");
-        if (r < 0 && r != -ENXIO)
+        if (r < 0 && !ERRNO_IS_NOINFO(r))
                 return r;
 
         r = xdg_user_runtime_dir(&runtime_config, "/user-tmpfiles.d");
-        if (r < 0 && r != -ENXIO)
+        if (r < 0 && !ERRNO_IS_NOINFO(r))
                 return r;
 
         r = xdg_user_data_dir(&data_home, "/user-tmpfiles.d");
-        if (r < 0 && r != -ENXIO)
+        if (r < 0 && !ERRNO_IS_NOINFO(r))
                 return r;
 
         r = strv_extend_strv_concat(&res, config_dirs, "/user-tmpfiles.d");
@@ -3151,7 +3146,7 @@ static int parse_line(
                 { 'B', specifier_os_build_id,     NULL },
                 { 'H', specifier_hostname,        NULL },
                 { 'l', specifier_short_hostname,  NULL },
-                { 'm', specifier_machine_id_safe, NULL },
+                { 'm', specifier_machine_id,      NULL },
                 { 'o', specifier_os_id,           NULL },
                 { 'v', specifier_kernel_release,  NULL },
                 { 'w', specifier_os_version_id,   NULL },
@@ -3231,7 +3226,7 @@ static int parse_line(
         i.try_replace = try_replace;
 
         r = specifier_printf(path, PATH_MAX-1, specifier_table, arg_root, NULL, &i.path);
-        if (r == -ENXIO)
+        if (ERRNO_IS_NOINFO(r))
                 return log_unresolvable_specifier(fname, line);
         if (r < 0) {
                 if (IN_SET(r, -EINVAL, -EBADSLT))
@@ -3419,7 +3414,7 @@ static int parse_line(
         if (!unbase64) {
                 /* Do specifier expansion except if base64 mode is enabled */
                 r = specifier_expansion_from_arg(specifier_table, &i);
-                if (r == -ENXIO)
+                if (ERRNO_IS_NOINFO(r))
                         return log_unresolvable_specifier(fname, line);
                 if (r < 0) {
                         if (IN_SET(r, -EINVAL, -EBADSLT))
@@ -3437,7 +3432,8 @@ static int parse_line(
                 r = read_credential(i.argument, &i.binary_argument, &i.binary_argument_size);
                 if (IN_SET(r, -ENXIO, -ENOENT)) {
                         /* Silently skip over lines that have no credentials passed */
-                        log_syntax(NULL, LOG_INFO, fname, line, 0, "Credential '%s' not specified, skipping line.", i.argument);
+                        log_syntax(NULL, LOG_INFO, fname, line, 0,
+                                   "Credential '%s' not specified, skipping line.", i.argument);
                         return 0;
                 }
                 if (r < 0)