summaryrefslogtreecommitdiff
path: root/src/tmpfiles
diff options
context:
space:
mode:
authorDaan De Meyer <daan.j.demeyer@gmail.com>2023-03-28 11:05:46 +0200
committerDaan De Meyer <daan.j.demeyer@gmail.com>2023-03-30 11:45:05 +0200
commit65e179a1e7021ab655c07dc392d5dd6fba2d2acb (patch)
tree7b460ed7fd3c049be03c9d7e996a2737b346c33f /src/tmpfiles
parent5ccf06074abfd53e7f580764137eb17542830928 (diff)
downloadsystemd-65e179a1e7021ab655c07dc392d5dd6fba2d2acb.tar.gz
tmpfiles: Try to take a BSD lock on files as well
Similar to what we do for directories, just before we remove a file, let's try to take a BSD lock on it. If that fails, skip removing the file.
Diffstat (limited to 'src/tmpfiles')
-rw-r--r--src/tmpfiles/tmpfiles.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
index c3741088c3..6cd76e8df8 100644
--- a/src/tmpfiles/tmpfiles.c
+++ b/src/tmpfiles/tmpfiles.c
@@ -754,6 +754,8 @@ static int dir_cleanup(
r = log_warning_errno(errno, "Failed to remove directory \"%s\", ignoring: %m", sub_path);
} else {
+ _cleanup_close_ int fd = -EBADF;
+
/* Skip files for which the sticky bit is set. These are semantics we define, and are
* unknown elsewhere. See XDG_RUNTIME_DIR specification for details. */
if (sx.stx_mode & S_ISVTX) {
@@ -794,6 +796,14 @@ static int dir_cleanup(
cutoff_nsec, sub_path, age_by_file, false))
continue;
+ fd = xopenat(dirfd(d), de->d_name, O_RDONLY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME, 0);
+ if (fd < 0 && fd != -ENOENT)
+ log_warning_errno(fd, "Opening file \"%s\" failed, ignoring: %m", sub_path);
+ if (fd >= 0 && flock(fd, LOCK_EX|LOCK_NB) < 0 && errno == EAGAIN) {
+ log_debug_errno(errno, "Couldn't acquire shared BSD lock on file \"%s\", skipping: %m", p);
+ continue;
+ }
+
log_debug("Removing \"%s\".", sub_path);
if (unlinkat(dirfd(d), de->d_name, 0) < 0)
if (errno != ENOENT)