Fedoraでtmpディレクトリの中身が再起動すると削除される

投稿者: | 2017年12月27日

先日、”ThinkPad R61e”に導入した”Fedora 27″を使っていて不思議な現象に遭遇しました。

/tmpの中身が再起動ごとに削除される

アーカイブの解凍データをtmpディレクトリに置いて再起動すると綺麗に消えている...。
再度、解凍すればよい話なので重大な問題ではないものの気になったので調べてみました。

調査開始

tmpwatchを疑う

$ whereis tmpwatch
tmpwatch:

そもそも入っていませんでした...。

cronを疑う

# ls /etc/cron
cron.d/       cron.daily/   cron.deny     cron.hourly/  cron.monthly/ cron.weekly/  crontab
# cat /etc/cron.d/0hourly | grep tmp
# cat /etc/cron.daily/logrotate | grep tmp
# cat /etc/cron.hourly/0anacron | grep tmp
# ls /etc/cron.monthly/
# ls /etc/cron.weekly/
# crontab -l
no crontab for root

cronも特に設定されていないようです。

systemctlを疑う

# systemctl list-timers
NEXT                         LEFT       LAST                         PASSED       UNIT                         ACTIVATES
Sun 2017-12-24 15:33:43 JST  35min left Sun 2017-12-24 14:33:40 JST  24min ago    dnf-makecache.timer          dnf-makecache.service
Mon 2017-12-25 00:00:00 JST  9h left    Sun 2017-12-24 09:19:20 JST  5h 38min ago mlocate-updatedb.timer       mlocate-updatedb.service
Mon 2017-12-25 14:38:40 JST  23h left   Sun 2017-12-24 14:38:40 JST  19min ago    systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service

3 timers listed.
Pass --all to see loaded but inactive timers, too.

systemd-tmpfiles-clean.service, systemd-tmpfiles-clean.timerが定義されています。

# systemctl status systemd-tmpfiles-clean.service
● systemd-tmpfiles-clean.service - Cleanup of Temporary Directories
   Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.service; static; vendor preset: disabled)
   Active: inactive (dead) since Sun 2017-12-24 14:38:40 JST; 21min ago
     Docs: man:tmpfiles.d(5)
           man:systemd-tmpfiles(8)
  Process: 1303 ExecStart=/usr/bin/systemd-tmpfiles --clean (code=exited, status=0/SUCCESS)
 Main PID: 1303 (code=exited, status=0/SUCCESS)

12月 24 14:38:40 arc.localdomain systemd[1]: Starting Cleanup of Temporary Directories...
12月 24 14:38:40 arc.localdomain systemd[1]: Started Cleanup of Temporary Directories.

# systemctl status systemd-tmpfiles-clean.timer
● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
   Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: disabled)
   Active: active (waiting) since Sun 2017-12-24 14:23:58 JST; 37min ago
  Trigger: Mon 2017-12-25 14:38:40 JST; 23h left
     Docs: man:tmpfiles.d(5)
           man:systemd-tmpfiles(8)

12月 24 14:23:58 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.

statusを確認すると、どちらのスクリプトも”/usr/lib/systemd/system/”下にあるようです。
また、以下に説明があるというので見てみます。

  • man:tmpfiles.d(5)
  • man:systemd-tmpfiles(8)
以下(man : tmpfiles.d)抜粋
# man 5 tmpfiles.d
NAME
       tmpfiles.d - Configuration for creation, deletion and cleaning of volatile and temporary files

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

DESCRIPTION
       systemd-tmpfiles uses the configuration files from the above directories to describe the creation, cleaning and removal of
       volatile and temporary files and directories which usually reside in directories such as /run or /tmp.

       Volatile and temporary files and directories are those located in /run (and its alias /var/run), /tmp, /var/tmp, the API file
       systems such as /sys or /proc, as well as some other directories below /var.

       System daemons frequently require private runtime directories below /run to place communication sockets and similar in. For these,
       consider declaring them in their unit files using RuntimeDirectory= (see systemd.exec(5) for details), if this is feasible.

CONFIGURATION FORMAT

           #Type Path        Mode UID  GID  Age Argument
           d     /run/user   0755 root root 10d -
           L     /tmp/foobar -    -    -    -   /dev/null

       Fields may be enclosed within quotes and contain C-style escapes.

   Age
       The date field, when set, is used to decide what files to delete when cleaning. If a file or directory is older than the current
       time minus the age field, it is deleted. The field format is a series of integers each followed by one of the following suffixes
       for the respective time units: s, m or min, h, d, w, ms, and us, meaning seconds, minutes, hours, days, weeks, milliseconds, and
       microseconds, respectively. Full names of the time units can be used too.

tmpやrunディレクトリを対象に削除するスクリプトのようです。

以下(man : systemd-tmpfiles)抜粋
# man 8 systemd-tmpfiles
SYSTEMD-TMPFILES(8)                                          systemd-tmpfiles                                         SYSTEMD-TMPFILES(8)

NAME
       systemd-tmpfiles, systemd-tmpfiles-setup.service, systemd-tmpfiles-setup-dev.service, systemd-tmpfiles-clean.service, systemd-
       tmpfiles-clean.timer - Creates, deletes and cleans up volatile and temporary files and directories

SYNOPSIS
       systemd-tmpfiles [OPTIONS...] [CONFIGFILE...]
       systemd-tmpfiles-setup.service
       systemd-tmpfiles-setup-dev.service
       systemd-tmpfiles-clean.service
       systemd-tmpfiles-clean.timer

DESCRIPTION
       systemd-tmpfiles creates, deletes, and cleans up volatile and temporary files and directories, based on the configuration file
       format and location specified in tmpfiles.d(5).

       If invoked with no arguments, it applies all directives from all configuration files. If one or more absolute filenames are passed
       on the command line, only the directives in these files are applied. If "-" is specified instead of a filename, directives are
       read from standard input. If only the basename of a configuration file is specified, all configuration directories as specified in
       tmpfiles.d(5) are searched for a matching file.

OPTIONS
       The following options are understood:

       --create
           If this option is passed, all files and directories marked with f, F, w, d, D, v, p, L, c, b, m in the configuration files are
           created or written to. Files and directories marked with z, Z, t, T, a, and A have their ownership, access mode and security
           labels set.

       --clean                                                                                                                               
           If this option is passed, all files and directories with an age parameter configured will be cleaned up.

       --remove
           If this option is passed, the contents of directories marked with D or R, and files or directories themselves marked with r or
           R are removed.

tmpfiles.d設定ファイルを確認する

“tmpfiles.d”のman(マニュアル)にあった一覧をチェックします。

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

/etc/tmpfiles.d/ はファイルなし

# ls /etc/tmpfiles.d/

/run/tmpfiles.d/ はカーネルモジュール関連(kmod)なのでスルー

# ls /run/tmpfiles.d/
kmod.conf

/usr/lib/tmpfiles.d/ にファイルあり!!!

# ls /usr/lib/tmpfiles.d/
abrt.conf     dnf.conf                  iscsi.conf          lvm2.conf     pam.conf      selinux-policy.conf   tmp.conf
colord.conf   etc.conf                  journal-nocow.conf  lxdm.conf     ppp.conf      spice-vdagentd.conf   var.conf
cups-lp.conf  gvfsd-fuse-tmpfiles.conf  legacy.conf         man-db.conf   rpcbind.conf  sudo.conf             x11.conf
cups.conf     home.conf                 libselinux.conf     mdadm.conf    rpm.conf      systemd-nologin.conf
dbus.conf     initscripts.conf          lockdev.conf        openssh.conf  samba.conf    systemd.conf

“/usr/lib/tmpfiles.d/tmp.conf”に設定ファイルがありました。

# cat /usr/lib/tmpfiles.d/tmp.conf 
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

# See tmpfiles.d(5) for details

# Clear tmp directories separately, to make them easier to override
q /tmp 1777 root root 10d
q /var/tmp 1777 root root 30d

# Exclude namespace mountpoints created with PrivateTmp=yes
x /tmp/systemd-private-%b-*
X /tmp/systemd-private-%b-*/tmp
x /var/tmp/systemd-private-%b-*
X /var/tmp/systemd-private-%b-*/tmp

# Remove top-level private temporary directories on each boot
R! /tmp/systemd-private-*
R! /var/tmp/systemd-private-*

確かに削除しているようですが、10d(10日経過後)となっています。
再起動直後に削除するスクリプトではないようです。

ログを見てみる

クリーンアップをしていることはわかりますが、詳細までは確認できません。

# journalctl -u systemd-tmpfiles-clean.timer
-- Logs begin at Fri 2017-12-22 10:21:34 JST, end at Sun 2017-12-24 15:17:27 JST. --
12月 22 19:20:11 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.
12月 22 10:40:52 arc.localdomain systemd[1]: Stopped Daily Cleanup of Temporary Directories.
-- Reboot --
12月 22 10:41:40 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.
12月 22 16:23:50 arc.localdomain systemd[1]: Stopped Daily Cleanup of Temporary Directories.
-- Reboot --
12月 22 16:25:09 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.
12月 22 16:31:10 arc.localdomain systemd[1]: Stopped Daily Cleanup of Temporary Directories.
-- Reboot --
12月 24 09:19:18 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.
12月 24 13:52:55 arc.localdomain systemd[1]: Stopped Daily Cleanup of Temporary Directories.
-- Reboot --
12月 24 14:23:58 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.
12月 24 15:15:18 arc.localdomain systemd[1]: Stopped Daily Cleanup of Temporary Directories.
-- Reboot --
12月 24 15:16:07 arc.localdomain systemd[1]: Started Daily Cleanup of Temporary Directories.

結果

tmpディレクトリがtmpfsにマウントされていました。
すごい遠回りした...。

base on https://ja.wikipedia.org/wiki/Tmpfs

tmpfsは揮発性メモリに保存されるようにできる。
リブートするときtmpfsに保存されているすべてのファイルは失われる。

# mount
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,seclabel)

# df -lh
ファイルシス            サイズ  使用  残り 使用% マウント位置
tmpfs                     991M  8.0K  991M    1% /tmp

なお、”systemd”下では、”/etc/fstab”にエントリを記述してなくても“/tmp”ディレクトリは自動的に”tmpfs”としてマウントされる模様。
インストールで”/(ルート)”とは別にtmpパーティションを作成しない(私みたいな)人は注意しないと危険です。

まとめ

ファイルの永続化は以下の3点が重要。

  • マウント
  • Systemctlの場合、以下に注意
    • systemd-tmpfiles-clean.service
    • systemd-tmpfiles-clean.timer
  • 従来の管理方法も合わせて注意
    • cron, crontab
    • tmpwatch