Understanding systemd-tmpfiles to manage temporary files and directories in CentOS/RHEL

Managing Temporary Files

A modern system requires a large number of temporary files and directories. Some applications (and users) use the /tmp directory to hold temporary data, while others use a more task-specific location such as daemon and user-specific volatile directories under /run. In this context, volatile means that the file system storing these files only exists in memory. When the system reboots or loses power, all the contents of volatile storage will be gone.

To keep a system running cleanly, it is necessary for these directories and files to be created when they do not exist, because daemons and scripts might rely on them being there, and for old files to be purged so that they do not fill up disk space or provide faulty information. CentOS/RHEL 7 and later include a new tool called systemd-tmpfiles, which provides a structured and configurable method to manage temporary directories and files.

When systemd starts a system, one of the first service units launched is systemd-tmpfilessetup. This service runs the command systemd-tmpfiles –create –remove. This command reads configuration files from /usr/lib/tmpfiles.d/*.conf, /run/tmpfiles.d/*.conf, and /etc/tmpfiles.d/*.conf. Any files and directories marked for deletion in those configuration files is removed, and any files and directories marked for creation (or permission fixes) will be created with the correct permissions if necessary.

Cleaning Temporary Files with a Systemd Timer

To ensure that long-running systems do not fill up their disks with stale data, a systemd timer unit called systemd-tmpfiles-clean.timer triggers systemd-tmpfiles-clean.service on a regular interval, which executes the systemd-tmpfiles –clean command. The systemd timer unit configuration files have a [Timer] section that indicates how often the service with the same name should be started.

Use the following systemctl command to view the contents of the systemd-tmpfilesclean.timer unit configuration file:


[user@host ~]$ systemctl cat systemd-tmpfiles-clean.timer
# /usr/lib/systemd/system/systemd-tmpfiles-clean.timer
#  SPDX-License-Identifier: LGPL-2.1+
#
#  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.

[Unit]
Description=Daily Cleanup of Temporary Directories
Documentation=man:tmpfiles.d(5) man:systemd-tmpfiles(8)

[Timer]
OnBootSec=15min

In the preceding configuration the parameter OnBootSec=15min indicates that the service unit called systemd-tmpfiles-clean.service gets triggered 15 minutes after the system has booted up. The parameter OnUnitActiveSec=1d indicates that any further trigger to the systemd-tmpfiles-clean.service service unit happens 24 hours after the service unit was activated last.

Based on your requirement, you can change the parameters in the **systemd-tmpfilesclean.timer **timer unit configuration file. For example, the value 30min for the parameter OnUnitActiveSec triggers the systemd-tmpfiles-clean.service service unit 30 minutes after the service unit was last activated. As a result, systemd-tmpfiles-clean.service gets triggered every 30 minutes after bringing the changes into effect.

After changing the timer unit configuration file, use the systemctl daemon-reload command to ensure that systemd is aware of the change. This command reloads the systemd manager configuration.

[root@host ~]# systemctl daemon-reload

After you reload the systemd manager configuration, use the following systemctl command to activate the systemd-tmpfiles-clean.timer unit.

[root@host ~]# systemctl enable --now systemd-tmpfiles-clean.timer

Cleaning Temporary Files Manually

The command systemd-tmpfiles –clean parses the same configuration files as the systemd-tmpfiles –create command, but instead of creating files and directories, it will purge all files which have not been accessed, changed, or modified more recently than the maximum age defined in the configuration file.

The format of the configuration files for systemd-tmpfiles is detailed in the tmpfiles.d manual page. The basic syntax consists of seven columns: Type, Path, Mode, UID, GID, Age, and Argument. Type refers to the action that systemd-tmpfiles should take; for example, d to create a directory if it does not yet exist, or Z to recursively restore SELinux contexts and file permissions and ownership.

The following are some examples with explanations.

d /run/systemd/seats 0755 root root

When creating files and directories, create the /run/systemd/seats directory if it does not yet exist, owned by the user root and the group root, with permissions set to rwxr-xr-x. This directory will not be automatically purged.

D /home/student 0700 student student 1d

Create the /home/student directory if it does not yet exist. If it does exist, empty it of all contents. When systemd-tmpfiles –clean is run, remove all files which have not been accessed, changed, or modified in more than one day.

L /run/fstablink - root root - /etc/fstab

Create the symbolic link /run/fstablink pointing to /etc/fstab. Never automatically purge this line.

Configuration File Precedence

Configuration files can exist in three places:

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

The files in /usr/lib/tmpfiles.d/ are provided by the relevant RPM packages, and you should not edit these files. The files under /run/tmpfiles.d/ are themselves volatile files, normally used by daemons to manage their own runtime temporary files. The files under /etc/tmpfiles.d/ are meant for administrators to configure custom temporary locations, and to override vendor-provided defaults.

If a file in /run/tmpfiles.d/ has the same file name as a file in /usr/lib/tmpfiles.d/, then the file in /run/tmpfiles.d/ is used. If a file in /etc/tmpfiles.d/ has the same file name as a file in either /run/tmpfiles.d/ or /usr/lib/tmpfiles.d/, then the file in /etc/tmpfiles.d/ is used.

Given these precedence rules, you can easily override vendor-provided settings by copying the relevant file to **/etc/tmpfiles.d/, **and then editing it. Working in this fashion ensures that administrator-provided settings can be easily managed from a central configuration management system, and not be overwritten by an update to a package.