tmpwatch の動作を確認する

/tmp と /var/tmp の違い - しょぼんメモリ (´・ω・`)
の記事がはてブされたので、tmpwatch についてもメモ。

tmpwatch の動作

man によると、tmpwatch は次のように振る舞う。
tmpwatch(8) - Linux man page

It does not follow symbolic links in the directories it's cleaning (even
if a symbolic link is given as its argument), will not switch
filesystems, skips lost+found directories owned by the root user, and
only removes empty directories, regular files, and symbolic links.

シンボリックリンクはたどらない。
Owner が root の lost+found は処理しない。
空のディレクトリ、通常のファイル、シンボリックリンクを削除する。
(switch filesystems の条件が分からない・・・CIFSマウントしたディレクトリなどが対象外になるのかと思えば、対象となって削除される模様)

CentOS-6 の /etc/cron.daily/tmpwatch

$ cat /etc/cron.daily/tmpwatch
#! /bin/sh
flags=-umc
/usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \
        -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \
        -X '/tmp/hsperfdata_*' 10d /tmp
/usr/sbin/tmpwatch "$flags" 30d /var/tmp
for d in /var/{cache/man,catman}/{cat?,X11R6/cat?,local/cat?}; do
    if [ -d "$d" ]; then
        /usr/sbin/tmpwatch "$flags" -f 30d "$d"
    fi
done


上記で使われている各オプションの意味は以下の通り。
-u:最終アクセス時刻
-m:最終ファイル変更時刻
-c:最終i-node変更時刻
-x:指定したパスを対象外とする
-X:指定したパターンにマッチしたパスを対象外とする

「flags=-umc」と記載があり、tmpwatch に -umc オプションが付加される。
-u, -m, -c が同時に指定されると、最大値(最新時刻)が判定条件になる。


なお、CentOS-6を最小インストールした場合、tmpwatchがインストールされていない。
yum で追加インストールすれば良い。

tmpwatch の動作確認方法

コマンドは、/usr/sbin 以下にある。

書式は、以下の通り。

$ tmpwatch [option] [time] [dirs]

[time]には、削除対象となる閾値を指定する。
m/h/d を数値の後に付けると、それぞれ分/時/日で指定できる(省略するとデフォルトは h になる)

以下の2つは同じ。

$ tmpwatch 240 /tmp
$ tmpwatch 10d /tmp

tmpwatch コマンドでファイル/ディレクトリが削除されるか試す際、以下のオプションが有効。
-t:テストモード(実際に削除はしない)
-v:詳細表示

通常ファイルを削除(その1)

test と書かれた sample.txt を作成し、ファイルの更新日時/アクセス日時を2013/1/1に変更する。

# echo 'test' > /tmp/twtest/sample.txt
# touch -t 201301010000 /tmp/twtest/sample.txt
# ls -l /tmp/twtest/sample.txt
-rw-r--r-- 1 root root 5  11 00:00 2013 /tmp/twtest/sample.txt

-umc オプションでは削除対象にならない。
touch コマンドでは、-c に相当するi-node変更時刻を変更できないため。

# /usr/sbin/tmpwatch -umctv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest

-um だけ指定して実行すると、削除対象になる。

# /usr/sbin/tmpwatch -umtv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest
removing file /tmp/twtest/sample.txt

通常ファイルを削除(その2)

test と書かれた sample.txt を作成し、ファイルの更新日時/アクセス日時を2013/1/1に変更する。

# echo 'test' > /tmp/twtest/sample.txt
# touch -t 201301010000 /tmp/twtest/sample.txt
# ls -l /tmp/twtest/sample.txt
-rw-r--r-- 1 root root 5  11 00:00 2013 /tmp/twtest/sample.txt

cat でファイルを開いてアクセス日時を更新する。

# cat /tmp/twtest/sample.txt
test

cat でアクセス日時を更新しているため、-um オプションでは削除対象にならない。

# /usr/sbin/tmpwatch -umtv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest

-m だけ指定して実行すると、削除対象になる。

# /usr/sbin/tmpwatch -mtv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest
removing file /tmp/twtest/sample.txt


ls -l でファイルのタイムスタンプを確認し、tmpwatch で削除される事を期待していても削除されない場合は、「最終アクセス日時が更新されている」可能性がある。
「tmpwatch 消えない」という場合は、この辺を確認。

ls -l では、アクセス日時は表示されない。

# ls -l /tmp/twtest/sample.txt
-rw-r--r-- 1 root root 5  11 00:00 2013 /tmp/twtest/sample.txt

アクセス日時を表示するには、ls -lu とする。

# ls -lu /tmp/twtest/sample.txt
-rw-r--r-- 1 root root 5 1012 22:29 2014 /tmp/twtest/sample.txt

空のディレクトリを削除

空のディレクトリと、中にファイルがあるディレクトリを作成して、ディレクトリの更新日時とアクセス日時を2013/1/1にする。

# mkdir /tmp/twtest/dummy-dir1
# mkdir /tmp/twtest/dummy-dir2
# touch /tmp/twtest/dummy-dir2/hoge.txt
# touch -t 201301010000 /tmp/twtest/dummy-dir1
# touch -t 201301010000 /tmp/twtest/dummy-dir2
(ここでls -l するとディレクトリにアクセス日時が更新される)
# ls -l /tmp/twtest/
合計 8
drwxr-xr-x 2 root root 4096  11 00:00 2013 dummy-dir1/
drwxr-xr-x 2 root root 4096  11 00:00 2013 dummy-dir2/

最終更新日時だけ削除対象の条件として実行。

# /usr/sbin/tmpwatch -mtv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest
cleaning up directory /tmp/twtest/dummy-dir2
removing directory /tmp/twtest/dummy-dir2 if empty
cleaning up directory /tmp/twtest/dummy-dir1
removing directory /tmp/twtest/dummy-dir1 if empty

-t オプションを外して実行すると、中身が空である dummy-dir1 だけが削除される。

Owner が root の lost+found

Owner が root の lost+found を作成し、更新日時とアクセス日時を2013/1/1にする。

# mkdir /tmp/twtest/lost+found
# touch -t 201301010000 /tmp/twtest/lost+found/
# /usr/sbin/tmpwatch -mtv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest

Owner を apache(root 以外のユーザ)に変更して試す。

# chown apache.apache /tmp/twtest/lost+found/
# touch -t 201301010000 /tmp/twtest/lost+found/
# /usr/sbin/tmpwatch -mtv 10d /tmp/twtest/
grace period is 864000 seconds
cleaning up directory /tmp/twtest
cleaning up directory /tmp/twtest/lost+found
removing directory /tmp/twtest/lost+found if empty

Owner が root でない場合、lost+found は他のディレクトリと同様に扱われるて削除対象となる。

シンボリックリンク

sample.txt を作成し、このファイルへのシンボリックリンク slink を作成する。
更新日時とアクセス日時いずれも、2013/1/1に変更する。

# echo 'test' > /tmp/twtest/sample.txt
# mkdir /tmp/twtest/dummy
# ln -s /tmp/twtest/sample.txt /tmp/twtest/dummy/slink
# touch -t 201301010000 /tmp/twtest/sample.txt
# touch -t 201301010000 -h /tmp/twtest/dummy/slink

シンボリックリンクは辿らず、シンボリックリンクそのものが削除される。

# /usr/sbin/tmpwatch -mtv 10d /tmp/twtest/dummy/
grace period is 864000 seconds
cleaning up directory /tmp/twtest/dummy
removing file /tmp/twtest/dummy/slink