tmpfiles: restore timestamps after removing directories

dir_cleanup() restored parent timestamps after removing files, but not
after removing child directories. Mark directory removals as changes too.

Reproducer:
  rm -rf /tmp/tf-mtime-dir
  mkdir -p /tmp/tf-mtime-dir/old-child
  touch -d '2020-01-01 00:00:00' \
        /tmp/tf-mtime-dir/old-child /tmp/tf-mtime-dir
  before=$(stat -c %Y /tmp/tf-mtime-dir)
  systemd-tmpfiles --clean - <<'EOT'
  d /tmp/tf-mtime-dir - - - M:1s
  EOT

Before:
  equal=no
  gone=yes

Follow-up for 3b63d2d31d.
This commit is contained in:
dongshengyuan
2026-07-23 16:56:06 +08:00
parent ac18c0569e
commit f936c9b366
2 changed files with 23 additions and 3 deletions
+8 -3
View File
@@ -808,9 +808,14 @@ static int dir_cleanup(
log_action("Would remove", "Removing", "%s directory \"%s\"", sub_path);
if (!arg_dry_run &&
unlinkat(dirfd(d), de->d_name, AT_REMOVEDIR) < 0 &&
!IN_SET(errno, ENOENT, ENOTEMPTY))
r = log_warning_errno(errno, "Failed to remove directory \"%s\", ignoring: %m", sub_path);
unlinkat(dirfd(d), de->d_name, AT_REMOVEDIR) < 0) {
if (errno == ENOTEMPTY)
continue;
if (errno != ENOENT)
r = log_warning_errno(errno, "Failed to remove directory \"%s\", ignoring: %m", sub_path);
}
deleted = true;
} else {
_cleanup_close_ int fd = -EBADF; /* This file descriptor is defined here so that the
+15
View File
@@ -204,3 +204,18 @@ test ! -d /tmp/ageby/d3
# Cleanup the test directory (fail if not empty).
rmdir /tmp/ageby
# Removing an old child directory should restore the parent directory mtime.
rm -rf /tmp/ageby-mtime
mkdir -p /tmp/ageby-mtime/old-child
touch --date "2020-01-01 00:00:00" /tmp/ageby-mtime/old-child /tmp/ageby-mtime
before="$(stat -c %Y /tmp/ageby-mtime)"
systemd-tmpfiles --clean - <<-EOF
d /tmp/ageby-mtime - - - M:1s
EOF
after="$(stat -c %Y /tmp/ageby-mtime)"
test "$before" = "$after"
test ! -e /tmp/ageby-mtime/old-child
rmdir /tmp/ageby-mtime