Linux systemd-tmpfiles-*服务
1 简介
在大多数现代Linux系统中,需要大量临时文件和目录才能进行最佳处理,如果不经常清理,它们可能会累积使用更多的存储空间,因此,有必要清除旧文件,以免它们占用磁盘空间。
另外,一些用户/应用程序将使用/tmp目录来保存临时数据,而其他用户/应用程序将使用特定的位置,例如守护进程和/run下的用户特定目录,文件仅存在于内存中,如果系统重新启动或断电,这些存储的所有内容都将消失。
高版本内核中,systemd提供了一个结构化的可配置方法来管理临时文件和目录,即systemd-tmpfiles,可以创建、删除和管理临时文件的服务。该工具提供了一种结构化且可配置的方法来管理临时目录和文件。
2 systemd-tmpfiles-*服务
Linux的systemd提供了tmpfiles相关的服务:
#systemctl -a|grep tmpfiles
systemd-tmpfiles-clean.service loaded inactive dead Cleanup of Temporary Directories
systemd-tmpfiles-setup-dev.service loaded active exited Create Static Device Nodes in /dev
systemd-tmpfiles-setup.service loaded active exited Create Volatile Files and Directories
systemd-tmpfiles-clean.timer loaded active waiting Daily Cleanup of Temporary Directories
tmpfiles服务一般分成两类:
- 开机启动时
systemd-tmpfiles-setup.service
systemd-tmpfiles-setup-dev.service
- Linux正常运行期间
systemd-tmpfiles-clean.timer
可以使用以下命令检查启动服务:
systemctl status systemd-tmpfiles-*
此处以Linux 5.4 内核,高通SDX12终端操作:
# systemctl status systemd-tmpfiles-*
● systemd-tmpfiles-setup-dev.service - Create Static Device Nodes in /dev
Loaded: loaded (/lib/systemd/system/systemd-tmpfiles-setup-dev.service; static; vendor preset: enabled)
Active: active (exited) since Thu 2023-03-09 02:26:54 UTC; 1 weeks 0 days ago
Docs: man:tmpfiles.d(5)
man:systemd-tmpfiles(8)
Process: 128 ExecStart=/bin/systemd-tmpfiles --prefix=/dev --create --boot (code=exited, status=0/SUCCESS)
Main PID: 128 (code=exited, status=0/SUCCESS)
● systemd-tmpfiles-setup.service - Create Volatile Files and Directories
Loaded: loaded (/lib/systemd/system/systemd-tmpfiles-setup.service; static; vendor preset: enabled)
Active: active (exited) since Thu 2023-03-09 02:27:01 UTC; 1 weeks 0 days ago
Docs: man:tmpfiles.d(5)
man:systemd-tmpfiles(8)
Process: 177 ExecStart=/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev (code=exited, status=73)
Main PID: 177 (code=exited, status=73)
● systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories
Loaded: loaded (/lib/systemd/system/systemd-tmpfiles-clean.timer; static; vendor preset: enabled)
Active: active (waiting) since Thu 2023-03-09 02:27:02 UTC; 1 weeks 0 days ago
Trigger: Fri 2023-03-17 07:49:06 UTC; 20h left
Docs: man:tmpfiles.d(5)
man:systemd-tmpfiles(8)
2.1 systemd-tmpfiles-setup.service
开机时,创建和清理临时目录
#systemctl cat systemd-tmpfiles-setup.service
[Unit]
Description=Create Volatile Files and Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs.target systemd-sysusers.service
Before=sysinit.target shutdown.target
RefuseManualStop=yes
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-tmpfiles --create --remove --boot --exclude-prefix=/dev
SuccessExitStatus=65 73
2.2 systemd-tmpfiles-setup-dev.service
开机时,在/dev/中创建静态设备节点
#systemctl cat systemd-tmpfiles-setup-dev.service
[Unit]
Description=Create Static Device Nodes in /dev
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=systemd-sysusers.service
Before=sysinit.target local-fs-pre.target systemd-udevd.service shutdown.target
ConditionCapability=CAP_SYS_MODULE
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/systemd-tmpfiles --prefix=/dev --create --boot
SuccessExitStatus=65 73
2.3 systemd-tmpfiles-clean.timer
从timer具体内容可以知道系统启动15分钟后和每天会运行一次服务。那么timer定时运行的是哪些服务呢? 默认是同名的带有.service后缀的单元,也可以在配置中指定。
# systemctl cat systemd-tmpfiles-clean.timer
[Unit]
Description=Daily Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
[Timer]
OnBootSec=15min
OnUnitActiveSec=1d
2.4 systemd-tmpfiles-clean.service
systemd-tmpfiles-clean.service就是systemd-tmpfiles-clean.timer定时执行的服务,用于清理目录。
#systemctl cat systemd-tmpfiles-clean.service
[Unit]
Description=Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)
DefaultDependencies=no
Conflicts=shutdown.target
After=local-fs.target time-sync.target
Before=shutdown.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemd-tmpfiles --clean
SuccessExitStatus=65
IOSchedulingClass=idle
3 配置
启动systemd-tmpfiles-setup服务单元时,它将运行systemd-tmpfiles –create –remove命令,该命令从以下位置检查配置文件:
/usr/lib/tmpfiles.d/.conf
/run/tmpfiles.d/.conf
/etc/tmpfiles.d/*.conf
对于不同目录下的同名配置文件,仅以优先级最高的目录中的那一个为准。具体说来就是: /etc/tmpfiles.d 的优先级最高、 /run/tmpfiles.d 的优先级居中、 /usr/lib/tmpfiles.d 的优先级最低。
软件包应该将自带的配置文件安装在 /usr/lib/tmpfiles.d 目录中, 而 /etc/tmpfiles.d 目录仅供系统管理员使用。
所有的配置文件,无论其位于哪个目录中,都统一按照文件名的字典顺序处理。 如果在多个配置文件中设置了同一个路径(文件或目录),那么仅以文件名最靠前(字典顺序)的那一个为准, 其他针对同一个路径的配置项将会作为警告信息记录到错误日志中。
如果有两行的路径互为前后缀,那么始终是先创建前缀行、再创建后缀行, 如果还需要删除,那么顺序正好相反,始终是先删除后缀行、再删除前缀行。
所有带有shell风格通配符的行,都在所有不带通配符的行之后处理。如果有多个操作符应用于同一个文件(例如 ACL, xattr, 文件属性调整),那么将始终按固定的顺序操作。
除上述清空之外,对于其他情况, 文件与目录总是按照它们在配置文件中出现的顺序处理。
如果上述配置文件中有标记为删除的文件和目录,则会将其删除,对于标记为创建的文件和目录,必要时使用正确的权限创建它们。
4 示例
此处以高通SDX12 内核5.4举例,我们使用上述工具来对我们需要操作的目录和文件修改权限,在x12平台中我们的配置文件是/etc/tmpfiles.d/data_systemd_tmpfiles.conf,在代码路径下:sdx12-le-1-0\apps_proc\poky\meta-qti-data-prop\recipes\data\files\data_systemd_tmpfiles.conf。按照规则我们做如下修改:
## SOCKET directory - /dev/socket
# Create directory in /dev/socket for location with required permissions
d /dev/socket/data 0755 radio radio - -
d /tmp/data 0755 radio radio - -
d /data/data_qcmap 0755 radio radio - -
d /run/data 0755 radio radio - -
# Create directories for tinyproxy
d /var/log/tinyproxy 0755 nobody inet - -
d /run/tinyproxy 0755 nobody inet - -
#create a directory for QCMAP Webclient
d /dev/socket/data/www 0775 www-data root - -
# Required for iptables command
f /run/xtables.lock 0644 root root - -
#lighttpd requirements
d /data/www 0775 www-data www-data - -
f /data/www/lighttpd.user 0770 www-data www-data - -
T /dev/socket/data/www - - - - security.selinux="system_u:object_r:webserver_socket_device_t:s0"
#port-bridge requirement
d /data 0777 radio radio - -
d /data/usb 0755 radio radio - -
f /data/usb/at_w_dun 0755 radio radio - -
d /data/upgrade 0777 radio radio - -
#f /data/usbmode.cfg 0777 radio radio - -
d /var/log/fibo 0755 radio radio - -
f /etc/thermal-engine.conf 0777 radio radio - -
d /data/misc 0755 radio radio - -
d /run 0755 radio radio - -
通过上面这些命令,我们就可以让对应的目录和文件以指定的用户组和权限创建。如:
创建/run目录,用户和用户组均为radio,目录权限为0755
d /run 0755 radio radio - -
在目录/etc下创建thermal-engine.conf文件,户和用户组均为radio,目录权限为0777
f /etc/thermal-engine.conf 0777 radio radio - -
修改前:
修改后: