为什么`systemd-tmpfiles --clean` 不起作用?

mag*_*nus 6 systemd tmp

我有以下配置来清理临时文件(CentOS 7 的默认设置),它表示如果文件/tmp超过 10 天,则应删除它们。

[root]# tail -n +10 /usr/lib/tmpfiles.d/tmp.conf | head -n 3
# Clear tmp directories separately, to make them easier to override
d /tmp 1777 root root 10d
d /var/tmp 1777 root root 30d
Run Code Online (Sandbox Code Playgroud)

但是,即使在运行 之后systemd-tmpfiles --clean,当我查看 的内容时/tmp,里面也有超过 10 天的文件。

[root]# ls -dl /tmp/backup-inspection
drwxr-xr-x 8 root root 68 Aug 29  2014 /tmp/backup-inspection
Run Code Online (Sandbox Code Playgroud)

/tmp目录的内容很大:

[root]# du -h /tmp | tail -n 1
3.5G    /tmp
Run Code Online (Sandbox Code Playgroud)

谁能向我解释为什么backup-inspection不删除目录?快1岁了吧?

小智 12

我最近遇到了同样的问题并发现了这个问题,所以我分享我的经验。

实际上systemd-tmpfiles完全支持递归目录树处理,正如您所期望的(另一个答案让我很困惑,无法检查源代码)。文件未被删除的原因(在我的情况下)是atime. systemd-tmpfiles检查ctime(目录除外),mtime并且atime所有三个(或两个)必须足够旧才能删除文件(或目录)。

其实可能还有其他原因,因为systemd-tmpfiles跳过文件有很多内部规则。要找出某些文件未被删除的原因,请运行systemd-tmpfiles以下命令:

env SYSTEMD_LOG_LEVEL=debug systemd-tmpfiles --clean
Run Code Online (Sandbox Code Playgroud)

它可能会将大量输出转储到您的控制台中。请注意,如果您尝试重定向stdout到例如一个文件,输出将消失并发送到 systemd 日志(以便它可以通过 eg 获得journalctl)。在我的情况下,输出也在中间被切断(或者我只是不知道如何使用journalctl),所以我的解决方案是暂时增加终端模拟器中的历史缓冲区。


小智 9

我最近一直在竭尽全力解决我职权范围内的服务器上的类似问题。

简单的答案基本上就是:systemd-tmpfiles --clean是一团糟,你应该寻找替代方案

不太简单的答案有点长。

systemd-tmpfiles执行各种任务,但它的主要任务与--clean选项无关:确保在重新启动时适当地“重置”系统状态。也就是说,它确保创建因各种原因需要存在的目录和文件,删除不应该存在的目录和文件(以及一长串相对深奥的事情,例如创建文件系统子卷和配额、块设备等.、更改权限、SELinux 属性等。如果您对所有内容都感到好奇,请参阅联机帮助页)。这些任务由systemd-tmpfiles --create(对于大多数事情)和systemd-tmpfiles --remove(用于删除文件和目录)。这两个子命令粗略地考虑了每个配置行的开始:第一个字段是操作的类型,第二个字段是目标,第三个是模式,等等。通常,systemd-tmpfiles --create --remove在系统启动后不久运行类似的东西,在任何事情之前这可能取决于它采取的行动。需要注意的一件重要事情是,这些操作永远不会查看第五个参数,即 Age 参数。这就是--clean进来的地方。

systemd-tmpfiles --clean本质上是通过添加一个字段:年龄字段来捎带在这个基础设施之上。它只考虑其他子命令执行的一些特定类型的操作,但是:d, D, v, q, Q, C, 和xand X(它的存在只是为了从它的清理中排除特定的东西)。这些是相关的正常使用情况下,那些只是dD,但是,用于目录,创建-IF-doesn't并存,创造-IF-doesn't并存,或排空-IF-IT-做, 分别。标记年龄后,systemd-tmpfiles --clean当年龄比配置的年龄大时,将删除列出的路径。

这里有一个问题:它实际上表示列出的路径- 年龄标记不会递归应用于文件夹的内容。这意味着您问题中的配置行只会删除整个/tmpor /var/tmp,并且仅当它们分别在 10 或 30 天内没有发生任何事情时。更糟糕的是,除了xand之外,没有任何影响年龄的东西支持 globs X,它们用于从清理中排除东西。

手册tmpfiles.d页确实列出了一件有趣的事情,如果幸运的话,它可能适用于您的情况:“如果年龄字段以波浪号字符“~”开头,则清理仅适用于指定目录内一级的文件和目录,但不是直接在其中的文件和目录。” - 就我而言,清理需要在以下两个级别进行/tmp,因此无法使用此方法取得良好效果。

查看用于清理/tmp目录内容的其他解决方案,这些解决方案将其视为其主要目的,而不是像systemd-tmpfiles --clean现在这样被固定在最后。


小智 1

  • d用于创建目录
  • r用于删除文件

tempfiles.d(5)。您不需要其他东西,尝试:

d /tmp      1d

   d
       Create a directory if it does not exist yet.

   D
       Create or empty a directory.
r
       Remove a file or directory if it exists. This may not be used to
       remove non-empty directories, use R for that. Lines of this type
       accept shell-style globs in place of normal path names. Does not
       follow symlinks.

   R
       Recursively remove a path and all its subdirectories (if it is a
       directory). Lines of this type accept shell-style globs in place
       of normal path names. Does not follow symlinks.
Run Code Online (Sandbox Code Playgroud)