Путеводитель по Руководству Linux

  User  |  Syst  |  Libr  |  Device  |  Files  |  Other  |  Admin  |  Head  |



   systemd.unit    ( 5 )

конфигурация агрегата (Unit configuration)

Примеры (Examples)

Example 1. Allowing units to be enabled

The following snippet (highlighted) allows a unit (e.g. foo.service) to be enabled via systemctl enable:

[Unit] Description=Foo

[Service] ExecStart=/usr/sbin/foo-daemon

[Install] WantedBy=multi-user.target

After running systemctl enable, a symlink /etc/systemd/system/multi-user.target.wants/foo.service linking to the actual unit will be created. It tells systemd to pull in the unit when starting multi-user.target. The inverse systemctl disable will remove that symlink again.

Example 2. Overriding vendor settings

There are two methods of overriding vendor settings in unit files: copying the unit file from /usr/lib/systemd/system to /etc/systemd/system and modifying the chosen settings. Alternatively, one can create a directory named unit.d/ within /etc/systemd/system and place a drop-in file name.conf there that only changes the specific settings one is interested in. Note that multiple such drop-in files are read if present, processed in lexicographic order of their filename.

The advantage of the first method is that one easily overrides the complete unit, the vendor unit is not parsed at all anymore. It has the disadvantage that improvements to the unit file by the vendor are not automatically incorporated on updates.

The advantage of the second method is that one only overrides the settings one specifically wants, where updates to the unit by the vendor automatically apply. This has the disadvantage that some future updates by the vendor might be incompatible with the local changes.

This also applies for user instances of systemd, but with different locations for the unit files. See the section on unit load paths for further details.

Suppose there is a vendor-supplied unit /usr/lib/systemd/system/httpd.service with the following contents:

[Unit] Description=Some HTTP server After=remote-fs.target sqldb.service Requires=sqldb.service AssertPathExists=/srv/webserver

[Service] Type=notify ExecStart=/usr/sbin/some-fancy-httpd-server Nice=5

[Install] WantedBy=multi-user.target

Now one wants to change some settings as an administrator: firstly, in the local setup, /srv/webserver might not exist, because the HTTP server is configured to use /srv/www instead. Secondly, the local configuration makes the HTTP server also depend on a memory cache service, memcached.service, that should be pulled in (Requires=) and also be ordered appropriately (After=). Thirdly, in order to harden the service a bit more, the administrator would like to set the PrivateTmp= setting (see systemd.exec(5) for details). And lastly, the administrator would like to reset the niceness of the service to its default value of 0.

The first possibility is to copy the unit file to /etc/systemd/system/httpd.service and change the chosen settings:

[Unit] Description=Some HTTP server After=remote-fs.target sqldb.service memcached.service Requires=sqldb.service memcached.service AssertPathExists=/srv/www

[Service] Type=notify ExecStart=/usr/sbin/some-fancy-httpd-server Nice=0 PrivateTmp=yes

[Install] WantedBy=multi-user.target

Alternatively, the administrator could create a drop-in file /etc/systemd/system/httpd.service.d/local.conf with the following contents:

[Unit] After=memcached.service Requires=memcached.service # Reset all assertions and then re-add the condition we want AssertPathExists= AssertPathExists=/srv/www

[Service] Nice=0 PrivateTmp=yes

Note that for drop-in files, if one wants to remove entries from a setting that is parsed as a list (and is not a dependency), such as AssertPathExists= (or e.g. ExecStart= in service units), one needs to first clear the list before re-adding all entries except the one that is to be removed. Dependencies (After=, etc.) cannot be reset to an empty list, so dependencies can only be added in drop-ins. If you want to remove dependencies, you have to override the entire unit.

Example 3. Top level drop-ins with template units

Top level per-type drop-ins can be used to change some aspect of all units of a particular type. For example by creating the /etc/systemd/system/service.d/ directory with a drop-in file, the contents of the drop-in file can be applied to all service units. We can take this further by having the top-level drop-in instantiate a secondary helper unit. Consider for example the following set of units and drop-in files where we install an OnFailure= dependency for all service units.

/etc/systemd/system/failure-handler@.service:

[Unit] Description=My failure handler for %i

[Service] Type=oneshot # Perform some special action for when %i exits unexpectedly. ExecStart=/usr/sbin/myfailurehandler %i

We can then add an instance of failure-handler@.service as an OnFailure= dependency for all service units.

/etc/systemd/system/service.d/10-all.conf:

[Unit] OnFailure=failure-handler@%N.service

Now, after running systemctl daemon-reload all services will have acquired an OnFailure= dependency on failure-handler@%N.service. The template instance units will also have gained the dependency which results in the creation of a recursive dependency chain. We can break the chain by disabling the drop-in for the template instance units via a symlink to /dev/null:

mkdir /etc/systemd/system/failure-handler@.service.d/ ln -s /dev/null /etc/systemd/system/failure-handler@.service.d/10-all.conf systemctl daemon-reload

This ensures that if a failure-handler@.service instance fails it will not trigger an instance named failure-handler@failure-handler.service.