OS 再起動後、/var/run 直下に作ったディレクトリが消えてしまう

アプリケーションのコンフィグファイルを設定する際に、プロセスの pid のパスを決めないと行けないときがあります。

特に指定がなければ、pid ファイルは基本的に /var/run ディレクトリに直下に作成されます。

ただ、CentOS 7 で /var/run 直下に pid 専用のディレクトリを掘った場合には少し注意が必要です。

例えば、pid ファイルの保存先を /var/run/my-dir/hogehoge.pid にした場合、OS を再起動すると /var/run/my-dir ディレクトリが削除されたままになってしまいます。

ちなみに、CentOS 6 では何もしなくても /var/run 直下に作成したディレクトリは OS を再起動しても自動的に作成されます。

CentOS 6 : /var/run 直下にディレクトリ作成後、OS 再起動Raw Code(S)Raw Code(T)
# mkdir /var/run/test_dir

# echo "test document" > /var/run/test_dir/test.txt

# ls -l /var/run/test_dir/
合計 4
-rw-r--r--  1 root root  14  7月  1 16:43 test.txt

# ls -l /var/run/ | grep "test_dir"
drwxr-xr-x  2 root  root   4096 12月  4 15:04 2016 test_dir    #### 作成時間 : 15時 04分

# shutdown -r now

# ls -l /var/run/test_dir/    #### 再起動してもディレクトリは存在する (再作成される)
合計 0

# ls -l /var/run/ | grep "test_dir"
drwxr-xr-x  2 root  root   4096 12月  4 15:06 2016 test_dir    #### 作成時間 : 15時 06分

そもそも /var/run ディレクトリが tmpfs なので、中にあるディレクトリと *.pid ファイル等が削除されてしまうのは当たり前ですが、CentOS 7 だと OS 再起動後にディレクトリを再作成してくれないからそれが問題です。

主に、以下の作業を実施します。

  • /var/run 直下のディレクトリが削除されるかテストして見る
  • /var/run 直下に作成したディレクトリが削除されないようにする
  • 参考 : /usr/lib/tmpfiles.d と /etc/tmpfiles.d
  • オマケ : /tmp 直下のファイル・ディレクトリが消えないようにする

/var/run 直下のディレクトリが削除されるかテストして見る

/var/run 内に作成した任意のディレクトリが本当に削除されるか確認するために、以下のテストを実施します。

  • /var/run 直下に test_dir を作成
  • OS 再起動
  • /var/run 直下に test_dir が存在するか確認
CentOS 7 : /var/run 直下のディレクトリが削除されるかテストRaw Code(S)Raw Code(T)
# mkdir /var/run/test_dir

# echo "test document" > /var/run/test_dir/test.txt

# ls -l /var/run/test_dir/
合計 4
-rw-r--r--  1 root root  14  7月  1 16:39 test.txt

# shutdown -r now

# ls -la /var/run/test_dir
ls: /var/run/test_dir にアクセスできません: そのようなファイルやディレクトリはありません

OS を再起動したら /var/run/test_dir は、もう存在しない。 キレイに削除されてしまいました。

/var/run 直下に作成したディレクトリが削除されないようにする

表現としては、削除されないようにする よりは、システム起動時にディレクトリが自動的に作成されるようにする の方が合ってるかもしれません。

上記の事象は、systemd の systemd-tmpfiles と関係があります。

systemd-tmpfiles を使うと 例えば、ファイル・ディレクトリに有効期限を設けたり、ファイル作成時に UID と GID を与えたり、事前に定義された規則に従って、ファイルやディレクトリを管理することができます。

systemd-tmpfiles の設定ファイルは、/usr/lib/tmpfiles.d ディレクトリに保存されていて、既に多くの設定ファイルが保存されています。

tmpfiles.d のパラメータ詳細は、以下を参照してください。

/usr/lib/tmpfiles.d 内の設定ファイル リストRaw Code(S)Raw Code(T)
# ls -l /usr/lib/tmpfiles.d/
合計 116
-rw-r--r--  1 root root   91 12月  1  2015 abrt.conf
-rw-r--r--  1 root root  187 11月 21  2015 certmonger.conf
-rw-r--r--  1 root root  264 11月 21  2015 cups-lp.conf
-rw-r--r--  1 root root  125 11月 21  2015 cups.conf
-rw-r--r--  1 root root  464  6月 24 04:08 etc.conf
・・・

Step 1. /usr/lib/tmpfiles.d 直下にコンフィグファイル作成

以下の例では、OS 起動時に /var/run/test_dir というディレクトリを 権限 0755所有権 root:root有効期限なし で新規作成するようにします。

/usr/lib/tmpfiles.d/var-run.confRaw Code(S)Raw Code(T)
#Type  Path               Mode  UID   GID   Age  Argument
d      /var/run/test_dir  0755  root  root  -

var-run.conf について

この例では、/usr/lib/tmpfiles.d/var-run.conf というファイルを新規作成していますが、特に規則はないので、分かりやすい名前で作成してください。

Step 2. 動作確認

先と同じやり方で、今度は /var/run 内に作成した任意のディレクトリが OS 再起動後に、新規作成されることを確認します。

  • /var/run 直下に test_dir を作成
  • OS 再起動
  • /var/run 直下に test_dir が存在するか確認
/var/run 直下にディレクトリが作成されることを確認Raw Code(S)Raw Code(T)
# mkdir /var/run/test_dir

# echo "test document" > /var/run/test_dir/test.txt

# ls -l /var/run/test_dir/
合計 4
-rw-r--r--  1 root root  14  7月  1 16:43 test.txt

# shutdown -r now

# ls -l /var/run/test_dir/
合計 0
drwxr-xr-x  2 root root  40  7月  1 16:43 .
drwxr-xr-x 33 root root 980  7月  1 16:44 ..

OS を再起動すると /var/run/test_dir は、まるごと削除されるため、中にあるファイルも当然削除されます。

ここでは、テストのため test.txt を作成しましたが、大事なのは、pid ファイルが作成されるディレクトリが存在するか・しないかなので、OS 再起動後に /var/run/ 配下に test_dir が作成されたことに意味があります。

参考 : /usr/lib/tmpfiles.d と /etc/tmpfiles.d

tmpfiles.d において、設定ファイルの置き場所は、以下の通りです。

設定ファイルの置き場所 備考
/usr/lib/tmpfiles.d デフォルト本体
/etc/tmpfiles.d 上書き用 (優先される)

設定ファイルの置き場所が分かれていて、個人的にはちょっと紛らわしいなと思いました。

特に、/etc/tmpfiles.d 直下の設定が優先されることだけは覚えておくと良いです。

なので、tmpfiles.d の設定をいじる時には、自分なりにルールを決めといた方が良いかもしれません。

例えば、以下のようにすると管理しやすいかなと。

  • 新規コンフィグ作成、既存コンフィグ修正 両方 /usr/lib/tmpfiles.d の下で作業
  • 新規コンフィグ作成、既存コンフィグ修正 両方 /etc/tmpfiles.d の下で作業。 ただ、既存コンフィグ修正時には、シンボリックリンクを作成する

オマケ : /tmp 直下のファイル・ディレクトリが消えないようにする

CentOS 7 では systemd の systemd-tmpfiles-clean.timer (旧 tmpwatch) によってテンポラリファイルが管理されます。

systemd-tmpfiles-clean.timerRaw Code(S)Raw Code(T)
# systemctl list-unit-files | fgrep 'systemd-tmpfiles-clean.timer'
systemd-tmpfiles-clean.timer        static

そのため、/tmp 下のファイルは、有効期限が切れると自動的に削除されてしまう恐れがあります。

名前通りに /tmp の中身は基本的に消えるという認識でいた方が良いですが、削除されないようにしたい時には、別途、設定が必要になります。

設定方法は、先と同じです。

また、/usr/lib/tmpfiles.d/tmp.conf には有効期限が付いていたり、特定のディレクトリ・ファイルは削除対象から除外するような設定が入っているので、消されたくないファイルがあれば、既存の設定を真似して設定を追加してください。

以下の例では、/tmp/proxy_cache* が削除されないようにします。

/tmp/proxy_cache* が削除されないようにするRaw Code(S)Raw Code(T)
# ls -l /usr/lib/tmpfiles.d/
合計 116
・・・
-rw-r--r--  1 root root  675  7月  4 09:18 tmp.conf

# cat /etc/tmpfiles.d/tmp.conf | grep -v "^#" | grep -v "^$"
v /tmp 1777 root root 10d
v /var/tmp 1777 root root 30d
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp

# ln -s /usr/lib/tmpfiles.d/tmp.conf /etc/tmpfiles.d/tmp.conf

# ls -l /etc/tmpfiles.d/
合計 4
lrwxrwxrwx 1 root root 28  7月  4 09:30 tmp.conf -> /usr/lib/tmpfiles.d/tmp.conf

# vi /etc/tmpfiles.d/tmp.conf
・・・
x /tmp/proxy_cache*

以上、CentOS 7 : /var/run 直下に作ったディレクトリが消えないようにする でした。