tree: 78b479afbc8814da582322c916d122867458b7d7 [path history] [tgz]
  1. chromeos.conf
  2. dbus.conf
  3. OWNERS
  4. README.md
  5. syslog.conf
init/tmpfiles.d/README.md

tmpfiles.d Configuration Files

These .conf files define filesystem operations that are needed to set up paths. This is commonly creating specific files and directories with specific permissions and ownership before running a system daemon. For example an upstart job with:

pre-start script
  mkdir -p /run/dbus
  chown messagebus:messagebus /run/dbus
  mkdir -p /var/lib/dbus
end script

Can be replaced with a tmpfiles.d file with:

d= /run/dbus 0755 messagebus messagebus
d= /var/lib/dbus 0755 root root

See the upstream documentation for the configuration file format. On Chrome OS the = is used to remove a path if it has the wrong type (FIFO vs. directory vs. file vs. etc.) instead of failing with an error.

This configuration will take care of creating the listed paths with the correct type, ownership, permissions, and SELinux labels. If the path already exists with the wrong ownership or permissions they will be changed to match the configuration with some caveats (see the note below). Remember the root-fs is read-only and uses verity for integrity checking so you cannot create or change paths on it without building a new image. Also, tmpfiles.d checks to make sure symlinks in the parent directories paths do not cross from lower privilege to higher privilege.

Note: If the parent directory is not owned by root and a sub path is owned by a different user, it is treated as an unsafe transition. Currently, an unsafe transition in a configured path will cause tmpfiles.d to fail with an error and chromeos_startup will trigger a cleanup of the stateful partition.

The preferred location of these config files in the source tree is a subdirectory of the parent project named tmpfiles.d.

When not to use tmpfiles.d

Not all paths should be used with the tmpfiles.d mechanism.

For device-related paths under /dev and /sys, use udev rules instead to set ownership & permissions. These react well according to when the kernel finishes initialization and avoid race conditions with userland.

Configuration application timing

There are three primary ways to apply a tmpfiles.d configuration on Chrome OS.

  1. As part of the early system start-up.
  2. By using a tmpfiles stanza in an upstart job.
  3. By calling systemd-tmpfiles directly on a configuration.

Note that these are not mutually exclusive, so different combinations can be used if appropriate.

Early startup

Configurations intended to be applied from startup should have the .conf extension and be installed to /usr/lib/tmpfiles.d using dotmpfiles or newtmpfiles from tmpfiles.eclass. The --boot flag is supplied here so configuration entries with the ! action will be applied.

pre-startup.conf applies configurations for the following path prefixes:

  • /dev
  • /proc
  • /run

/sys can be added, but care needs to be taken because some subpaths are mounted at a later time like cgroups.

After pre-startup.conf finishes, chromeos_startup is executed, which covers the following path prefixes:

  • /home
  • /media
  • /mnt/stateful_partition
  • /var

Additional path prefixes can be added as needed, but care needs to be taking to make sure the parent paths are mounted before applying the configuration.

Upstart job pre-start

Adding a tmpfiles stanza to an upstart config applies the config before running the pre-start stanza. This does not prevent the config from also being applied at early boot.

Some reasons you might want a tmpfiles stanza are for paths created dynamically, or to reduce the risk of a compromise persisting between user-sessions (without a reboot).

Here is an excerpt from vm_concierge.conf with an example:

start on start-user-session
stop on stopping ui
respawn
expect daemon

tmpfiles /usr/lib/tmpfiles.d/arcvm.conf /usr/lib/tmpfiles.d/vm_tools.conf

The Chrome OS upstart patch that adds the tmpfiles stanza does not set the --boot flag so configuration entries with the ! action will not be applied.

On demand

Configurations that can not be applied in early boot should be installed to /usr/lib/tmpfiles.d/on-demand using doins or newins. These need either:

  • A tmpfiles stanza to the appropriate upstart config as shown in the previous section
  • A direct call to systemd-tmpfiles. Here is an example:
systemd-tmpfiles --create --remove --clean <absolute path to your-tmpfiles-d.conf>
Note: You may not need all the options --create, --remove, or --clean depending on the actions being applied. See the upstream documentation for more details.

One reason why this might be necessary is the cases a tmpfiles.d configuration has a path inside a mount that is created on demand.

Testing

Currently, an error in a tmpfiles.d config installed to /usr/lib/tmpfiles.d will result in a stateful repair boot-loop. To avoid this when testing, copy your config file to a different path and invoke it manually (or from an upstart job) with:

/bin/systemd-tmpfiles --boot --create --remove --clean <absolute path to your-tmpfiles-d.conf>

Generally, no errors are printed on success. If extra verbosity is desired, use:

export SYSTEMD_LOG_LEVEL=debug

Troubleshooting and Common Obstacles

For tmpfiles.d configurations applied at startup, errors cause a clobber of the stateful partition. Warnings and errors are logged to /run/tmpfiles.log because the system log is set up after chromeos_startup executes and writes to the stateful partition which may be clobbered. The clobber_state_collector crash collector preserves this log across stateful_partition clobbers and writes it to /var/spool/crash which can be checked when troubleshooting.

Warnings do not result in the stateful_partition being clobbered and the collect-early-logs upstart job applies the contents of /run/tmpfiles.log to the system log once it is available. These entries are prefixed with “tmpfiles.d”.

Here are some common errors with known resolutions.

Paths Missing SELinux File Context Entries

If you see errors that resemble something like:

Failed to determine SELinux security context for /run/rsyslogd: Resource temporarily unavailable
Failed to create directory or subvolume "/run/rsyslogd": Resource temporarily unavailable
Failed to determine SELinux security context for /var/log/bluetooth.log: Resource temporarily unavailable
Unable to fix SELinux security context of /var/log/bluetooth.log (/var/log/bluetooth.log): Resource temporarily unavailable

The problem is usually missing SELinux file context entries. This occurs because tmpfiles.d tries to restore the SELinux labels of the path. The restore operation depends on having a file context entry. In some cases the path may already have an existing label applied through a context transition policy rule, but without the file context entry tmpfiles.d will still fail.

Here are example entries to resolve the above errors from chromeos_file_contexts:

/run/rsyslogd             u:object_r:cros_run_rsyslogd:s0
/var/log/bluetooth.log    u:object_r:cros_var_log_bluetooth:s0
Note: the context label (e.g. cros_var_log_bluetooth) needs to be defined. Most are located in file.te.

More information about defining the SELinux policy can be found in the SELinux documentation.