Blob Blame History Raw
From 2f79547e8bbb5434a84c0b07c30fff63b351590c Mon Sep 17 00:00:00 2001
From: Luca Boccassi <bluca@debian.org>
Date: Thu, 10 Nov 2022 15:47:19 +0000
Subject: [PATCH] tmpfiles: log at info level when some allowed failures occur

In provision.conf we ship:

d- /root :0700 root :root -
d- /root/.ssh :0700 root :root -

These are allowed to fail, for example on a read-only filesystem. But they still
log at error level, which is annoying and gets flagged. Tune those specific errors
down to info.

There are likely more that could be tuned down, but the important thing is to cover
the tmpfiles.d that we ship right now.

Before:

$ echo -e "d- /root :0700 root :root - \nd- /root/.ssh :0700 root :root -" | SYSTEMD_LOG_LEVEL=err build/systemd-tmpfiles --root=/tmp/img --create -
Failed to create directory or subvolume "/tmp/img/root": Read-only file system
Failed to open path '/tmp/img/root': No such file or directory
$

After:

$ echo -e "d- /root :0700 root :root - \nd- /root/.ssh :0700 root :root -" | SYSTEMD_LOG_LEVEL=err build/systemd-tmpfiles --root=/tmp/img --create -
$

(cherry picked from commit 244c2a8344c01e94cd9bdf835de998b89bc53179)

Related: #2138081
---
 src/tmpfiles/tmpfiles.c | 49 +++++++++++++++++++++++++++--------------
 1 file changed, 33 insertions(+), 16 deletions(-)

diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index 784b895577..18bb75715b 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -961,22 +961,34 @@ shortcut:
         return label_fix_full(fd, /* inode_path= */ NULL, /* label_path= */ path, 0);
 }
 
-static int path_open_parent_safe(const char *path) {
+static int path_open_parent_safe(const char *path, bool allow_failure) {
         _cleanup_free_ char *dn = NULL;
         int r, fd;
 
         if (!path_is_normalized(path))
-                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to open parent of '%s': path not normalized.", path);
+                return log_full_errno(allow_failure ? LOG_INFO : LOG_ERR,
+                                      SYNTHETIC_ERRNO(EINVAL),
+                                      "Failed to open parent of '%s': path not normalized%s.",
+                                      path,
+                                      allow_failure ? ", ignoring" : "");
 
         r = path_extract_directory(path, &dn);
         if (r < 0)
-                return log_error_errno(r, "Unable to determine parent directory of '%s': %m", path);
+                return log_full_errno(allow_failure ? LOG_INFO : LOG_ERR,
+                                      r,
+                                      "Unable to determine parent directory of '%s'%s: %m",
+                                      path,
+                                      allow_failure ? ", ignoring" : "");
 
-        r = chase_symlinks(dn, arg_root, CHASE_SAFE|CHASE_WARN, NULL, &fd);
+        r = chase_symlinks(dn, arg_root, allow_failure ? CHASE_SAFE : CHASE_SAFE|CHASE_WARN, NULL, &fd);
         if (r == -ENOLINK) /* Unsafe symlink: already covered by CHASE_WARN */
                 return r;
         if (r < 0)
-                return log_error_errno(r, "Failed to open path '%s': %m", dn);
+                return log_full_errno(allow_failure ? LOG_INFO : LOG_ERR,
+                                      r,
+                                      "Failed to open path '%s'%s: %m",
+                                      dn,
+                                      allow_failure ? ", ignoring" : "");
 
         return fd;
 }
@@ -1431,7 +1443,7 @@ static int write_one_file(Item *i, const char *path, CreationMode creation) {
 
         /* Validate the path and keep the fd on the directory for opening the file so we're sure that it
          * can't be changed behind our back. */
-        dir_fd = path_open_parent_safe(path);
+        dir_fd = path_open_parent_safe(path, i->allow_failure);
         if (dir_fd < 0)
                 return dir_fd;
 
@@ -1481,7 +1493,7 @@ static int create_file(Item *i, const char *path) {
 
         /* Validate the path and keep the fd on the directory for opening the file so we're sure that it
          * can't be changed behind our back. */
-        dir_fd = path_open_parent_safe(path);
+        dir_fd = path_open_parent_safe(path, i->allow_failure);
         if (dir_fd < 0)
                 return dir_fd;
 
@@ -1549,7 +1561,7 @@ static int truncate_file(Item *i, const char *path) {
 
         /* Validate the path and keep the fd on the directory for opening the file so we're sure that it
          * can't be changed behind our back. */
-        dir_fd = path_open_parent_safe(path);
+        dir_fd = path_open_parent_safe(path, i->allow_failure);
         if (dir_fd < 0)
                 return dir_fd;
 
@@ -1628,7 +1640,7 @@ static int copy_files(Item *i) {
 
         /* Validate the path and use the returned directory fd for copying the target so we're sure that the
          * path can't be changed behind our back. */
-        dfd = path_open_parent_safe(i->path);
+        dfd = path_open_parent_safe(i->path, i->allow_failure);
         if (dfd < 0)
                 return dfd;
 
@@ -1664,6 +1676,7 @@ static int create_directory_or_subvolume(
                 const char *path,
                 mode_t mode,
                 bool subvol,
+                bool allow_failure,
                 struct stat *ret_st,
                 CreationMode *ret_creation) {
 
@@ -1679,7 +1692,7 @@ static int create_directory_or_subvolume(
         if (r < 0)
                 return log_error_errno(r, "Failed to extract filename from path '%s': %m", path);
 
-        pfd = path_open_parent_safe(path);
+        pfd = path_open_parent_safe(path, allow_failure);
         if (pfd < 0)
                 return pfd;
 
@@ -1720,7 +1733,11 @@ static int create_directory_or_subvolume(
 
                 /* Then look at the original error */
                 if (r < 0)
-                        return log_error_errno(r, "Failed to create directory or subvolume \"%s\": %m", path);
+                        return log_full_errno(allow_failure ? LOG_INFO : LOG_ERR,
+                                              r,
+                                              "Failed to create directory or subvolume \"%s\"%s: %m",
+                                              path,
+                                              allow_failure ? ", ignoring" : "");
 
                 return log_error_errno(errno, "Failed to open directory/subvolume we just created '%s': %m", path);
         }
@@ -1748,7 +1765,7 @@ static int create_directory(Item *i, const char *path) {
         assert(i);
         assert(IN_SET(i->type, CREATE_DIRECTORY, TRUNCATE_DIRECTORY));
 
-        fd = create_directory_or_subvolume(path, i->mode, /* subvol= */ false, &st, &creation);
+        fd = create_directory_or_subvolume(path, i->mode, /* subvol= */ false, i->allow_failure, &st, &creation);
         if (fd == -EEXIST)
                 return 0;
         if (fd < 0)
@@ -1766,7 +1783,7 @@ static int create_subvolume(Item *i, const char *path) {
         assert(i);
         assert(IN_SET(i->type, CREATE_SUBVOLUME, CREATE_SUBVOLUME_NEW_QUOTA, CREATE_SUBVOLUME_INHERIT_QUOTA));
 
-        fd = create_directory_or_subvolume(path, i->mode, /* subvol = */ true, &st, &creation);
+        fd = create_directory_or_subvolume(path, i->mode, /* subvol = */ true, i->allow_failure, &st, &creation);
         if (fd == -EEXIST)
                 return 0;
         if (fd < 0)
@@ -1845,7 +1862,7 @@ static int create_device(Item *i, mode_t file_type) {
 
         /* Validate the path and use the returned directory fd for copying the target so we're sure that the
          * path can't be changed behind our back. */
-        dfd = path_open_parent_safe(i->path);
+        dfd = path_open_parent_safe(i->path, i->allow_failure);
         if (dfd < 0)
                 return dfd;
 
@@ -1947,7 +1964,7 @@ static int create_fifo(Item *i) {
         if (r == O_DIRECTORY)
                 return log_error_errno(SYNTHETIC_ERRNO(EISDIR), "Cannot open path '%s' for creating FIFO, is a directory.", i->path);
 
-        pfd = path_open_parent_safe(i->path);
+        pfd = path_open_parent_safe(i->path, i->allow_failure);
         if (pfd < 0)
                 return pfd;
 
@@ -2032,7 +2049,7 @@ static int create_symlink(Item *i) {
         if (r == O_DIRECTORY)
                 return log_error_errno(SYNTHETIC_ERRNO(EISDIR), "Cannot open path '%s' for creating FIFO, is a directory.", i->path);
 
-        pfd = path_open_parent_safe(i->path);
+        pfd = path_open_parent_safe(i->path, i->allow_failure);
         if (pfd < 0)
                 return pfd;