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/

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