Linux
redhat
systemd
centos7
tmpwatch

tmpwatch(CentOS6まで)とsystemd-tmpfiles(CentOS7)の挙動の違い

/tmp や /var/tmp のファイルやディレクトリを定期的にクリーンする機能として
CentOS6まではtmpwatchという機能がありました。

しかし、CentOS7からはtmpwatchは廃止されています。
この機能はsystemdに統合され、systemd-tmpfilesというものに代替されています。

これらの違いをまとめてみます。

ざっくりサマリー

結論を先にまとめておきます。

  • tmpwatch(CentOS6まで)

  実行トリガー:crond(cron.dairy)から実行される
  削除対象のチェック方法:「atime」のみをチェックする
  削除対象の設定:/tmp(240時間=10日以上経過しているもの)
          /var/tmp(720時間=30日以上経過しているもの)

  • systemd-tmpfiles(CentOS7)

  実行トリガー:systemd(systemd-tmpfiles-clean.timer)から実行される
  削除対象のチェック方法:「atime/mtime/ctime」の全てをチェックする
  削除対象の設定:/tmp(10日以上経過しているもの)
          /var/tmp(30日以上経過しているもの)

地味にハマるポイントを、太字にしました。
「今まで自動で消えてたファイルがCentOS7にしたら消えなくなった・・・」
そんな状況に遭遇したら、削除対象のチェック方法の違いに注意して見てみてください。

以下、個別に解説します。

tmpwatch(CentOS6まで)

※筆者はCentOS5の環境で確認しています。

tmpwatchはcron.daily/tmpwatchから実行される

ファイルの内容を見ると、具体的には下記のコマンドが実行されています。

/etc/cron.daily/tmpwatch
 /usr/sbin/tmpwatch 240 /tmp
 /usr/sbin/tmpwatch 720 /var/tmp

これらの意味するところは下記です。
・/tmp配下の240時間(=10日)以上(atimeが)古いファイル/ディレクトリを削除する
・/var/tmp配下の720時間(=30日)以上(atimeが)古いファイル/ディレクトリを削除する

tmpwatch は atime を見てファイル/ディレクトリを削除する

man tmpwatchを抜粋します。

-u, --atime

Make the decision about deleting a file based on the file's atime (access time). This is the default.
Note that the periodic updatedb file system scans keep the atime of directories recent.

デフォルト(オプション無し)の時、
tmpwatchは削除対象か否かを対象の atime を見て判断します。

余談:tmpwatchはnoatimeマウントオプションと相性が悪い

Linuxサーバーのパフォーマンスチューニングをしている場合、
マウント時にnoatimeオプションを設定しているかもしれません。
この設定していると、ファイルのリードを実行してもatimeが更新されなくなります。
「定期的にファイルをリードしていたはずなのにtmpwatchによってファイルが消された!」
というような時はnoatimeを設定していないかを疑ってみましょう・・・(筆者の実体験)。

systemd-tmpfiles(CentOS7)

systemd-tmpfiles は systemd-tmpfiles-clean.timer から実行される

systemd-tmpfilesは、以下のような順序関係で実行されます。

 systemd-tmpfiles-clean.timer
  ↓
 systemd-tmpfiles-clean.service
  ↓
 systemd-tmpfiles --clean

順を追って説明します。

systemd-tmpfiles-clean.timer とはなんぞや?

serviceファイルをcron的に実行したい場合はtimerファイルを設定します。
systemd-tmpfiles-clean.timerには以下のような設定が書かれていると思います。

systemd-tmpfiles-clean.timer
 [Timer]
 OnBootSec=15min
 OnUnitActiveSec=1d

ここでは「起動後15分、以降は1日1回」を意味します。

systemd-tmpfiles-clean.service は何をしてる?

前述の通り、timerによって定期的にserviceファイルが実行されます。

systemd-tmpfiles-clean.serviceには下記のような記述があります。

systemd-tmpfiles-clean.service
 [Service]
 Type=oneshot
 ExecStart=/usr/bin/systemd-tmpfiles --clean

実際に削除を行うコマンドは /usr/bin/systemd-tmpfiles --clean

systemd-tmpfiles コマンド は以下の設定ファイルに基づいて処理を実行します。

 /usr/lib/tmpfiles.d/tmp.conf

設定ファイルには以下の設定がされていると思います。

/usr/lib/tmpfiles.d/tmp.conf
 # Clear tmp directories separately, to make them easier to override
 v /tmp 1777 root root 10d
 v /var/tmp 1777 root root 30d

末尾の10dや30dがクリーンアップ設定を表しています。
/tmpの場合は10日経過以上、/var/tmpの場合は30日以上経過しているものが削除されます。
経過日数の設定値としては、tmpwatchと同じですね。

systemd-tmpfiles --clean は atime/mtime/ctimeの全てを見てファイル/ディレクトリを削除する

ここで、注意点です。
tmpwatchと違い、systemd-tmpfilesでは、
削除対象を判定する時、atime/mtime/ctime の全てがチェックされます

例えば、atimeが10日以上古くても、mtimeやctimeが新しければ、削除されません。

systemd-tmpfiles の挙動を確認したい

手動で下記のコマンドを実行すると「/tmp/hogeはmtimeがまだ新しいから削除しなかったよ!」等の
デバッグログがコンソールに出力されます。デバッグ時に役立ちますね。

# SYSTEMD_LOG_TARGET=console SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-tmpfiles --clean

除外設定をしたい(ファイルを消されたくない)場合は?

設定ファイルの置き場所は以下の3箇所があります。

/etc/tmpfiles.d/*.conf
/run/tmpfiles.d/*.conf
/usr/lib/tmpfiles.d/*.conf

個別に設定を追加する場合は、/etc/tmpfiles.d/配下に置くのが良いと思います。
例えば /tmp/hoge ファイルを削除除外する場合は、以下のような設定を追加します。

 例)
 x /tmp/hoge

詳細はman tmpfiles.d を参照してください。

本稿は、以下のURLを参考にさせていただきました。
https://www.thegeekdiary.com/centos-rhel-7-how-tmpfiles-clean-up-tmp-or-var-tmp-replacement-of-tmpwatch/

以上、どなたかの参考になれば幸いです。