]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
tmpfiles: restore timestamps after removing directories
authordongshengyuan <545258830@qq.com>
Wed, 15 Jul 2026 05:28:57 +0000 (13:28 +0800)
committerdongshengyuan <545258830@qq.com>
Thu, 23 Jul 2026 08:56:06 +0000 (16:56 +0800)
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 3b63d2d31d0850bd7a81ab9b468218d2c4c461e8.

src/tmpfiles/tmpfiles.c
test/units/TEST-22-TMPFILES.12.sh

index 9de612c1d6be6529421c08318b8e39d6a3b27372..5c520ac0682a7f2ed647c14e797701d9e1cf0667 100644 (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
index 44bb9498254a9d6aa51dec1f3956f097a6de82f1..1aa4faa0d380511fef242c378263b658a2ce4e98 100755 (executable)
@@ -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