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

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



   daemon    ( 7 )

написание и упаковка системных демонов (Writing and packaging system daemons)

ACTIVATION

New-style init systems provide multiple additional mechanisms to activate services, as detailed below. It is common that services are configured to be activated via more than one mechanism at the same time. An example for systemd: bluetoothd.service might get activated either when Bluetooth hardware is plugged in, or when an application accesses its programming interfaces via D-Bus. Or, a print server daemon might get activated when traffic arrives at an IPP port, or when a printer is plugged in, or when a file is queued in the printer spool directory. Even for services that are intended to be started on system bootup unconditionally, it is a good idea to implement some of the various activation schemes outlined below, in order to maximize parallelization. If a daemon implements a D-Bus service or listening socket, implementing the full bus and socket activation scheme allows starting of the daemon with its clients in parallel (which speeds up boot-up), since all its communication channels are established already, and no request is lost because client requests will be queued by the bus system (in case of D-Bus) or the kernel (in case of sockets) until the activation is completed.

Activation on Boot Old-style daemons are usually activated exclusively on boot (and manually by the administrator) via SysV init scripts, as detailed in the LSB Linux Standard Base Core Specification[1]. This method of activation is supported ubiquitously on Linux init systems, both old-style and new-style systems. Among other issues, SysV init scripts have the disadvantage of involving shell scripts in the boot process. New-style init systems generally employ updated versions of activation, both during boot-up and during runtime and using more minimal service description files.

In systemd, if the developer or administrator wants to make sure that a service or other unit is activated automatically on boot, it is recommended to place a symlink to the unit file in the .wants/ directory of either multi-user.target or graphical.target, which are normally used as boot targets at system startup. See systemd.unit(5) for details about the .wants/ directories, and systemd.special(7) for details about the two boot targets.

Socket-Based Activation In order to maximize the possible parallelization and robustness and simplify configuration and development, it is recommended for all new-style daemons that communicate via listening sockets to employ socket-based activation. In a socket-based activation scheme, the creation and binding of the listening socket as primary communication channel of daemons to local (and sometimes remote) clients is moved out of the daemon code and into the init system. Based on per-daemon configuration, the init system installs the sockets and then hands them off to the spawned process as soon as the respective daemon is to be started. Optionally, activation of the service can be delayed until the first inbound traffic arrives at the socket to implement on-demand activation of daemons. However, the primary advantage of this scheme is that all providers and all consumers of the sockets can be started in parallel as soon as all sockets are established. In addition to that, daemons can be restarted with losing only a minimal number of client transactions, or even any client request at all (the latter is particularly true for state-less protocols, such as DNS or syslog), because the socket stays bound and accessible during the restart, and all requests are queued while the daemon cannot process them.

New-style daemons which support socket activation must be able to receive their sockets from the init system instead of creating and binding them themselves. For details about the programming interfaces for this scheme provided by systemd, see sd_listen_fds(3) and sd-daemon(3). For details about porting existing daemons to socket-based activation, see below. With minimal effort, it is possible to implement socket-based activation in addition to traditional internal socket creation in the same codebase in order to support both new-style and old-style init systems from the same daemon binary.

systemd implements socket-based activation via .socket units, which are described in systemd.socket(5). When configuring socket units for socket-based activation, it is essential that all listening sockets are pulled in by the special target unit sockets.target. It is recommended to place a WantedBy=sockets.target directive in the [Install] section to automatically add such a dependency on installation of a socket unit. Unless DefaultDependencies=no is set, the necessary ordering dependencies are implicitly created for all socket units. For more information about sockets.target, see systemd.special(7). It is not necessary or recommended to place any additional dependencies on socket units (for example from multi-user.target or suchlike) when one is installed in sockets.target.

Bus-Based Activation When the D-Bus IPC system is used for communication with clients, new-style daemons should employ bus activation so that they are automatically activated when a client application accesses their IPC interfaces. This is configured in D-Bus service files (not to be confused with systemd service unit files!). To ensure that D-Bus uses systemd to start-up and maintain the daemon, use the SystemdService= directive in these service files to configure the matching systemd service for a D-Bus service. e.g.: For a D-Bus service whose D-Bus activation file is named org.freedesktop.RealtimeKit.service, make sure to set SystemdService=rtkit-daemon.service in that file to bind it to the systemd service rtkit-daemon.service. This is needed to make sure that the daemon is started in a race-free fashion when activated via multiple mechanisms simultaneously.

Device-Based Activation Often, daemons that manage a particular type of hardware should be activated only when the hardware of the respective kind is plugged in or otherwise becomes available. In a new-style init system, it is possible to bind activation to hardware plug/unplug events. In systemd, kernel devices appearing in the sysfs/udev device tree can be exposed as units if they are tagged with the string "systemd". Like any other kind of unit, they may then pull in other units when activated (i.e. plugged in) and thus implement device-based activation. systemd dependencies may be encoded in the udev database via the SYSTEMD_WANTS= property. See systemd.device(5) for details. Often, it is nicer to pull in services from devices only indirectly via dedicated targets. Example: Instead of pulling in bluetoothd.service from all the various bluetooth dongles and other hardware available, pull in bluetooth.target from them and bluetoothd.service from that target. This provides for nicer abstraction and gives administrators the option to enable bluetoothd.service via controlling a bluetooth.target.wants/ symlink uniformly with a command like enable of systemctl(1) instead of manipulating the udev ruleset.

Path-Based Activation Often, runtime of daemons processing spool files or directories (such as a printing system) can be delayed until these file system objects change state, or become non-empty. New-style init systems provide a way to bind service activation to file system changes. systemd implements this scheme via path-based activation configured in .path units, as outlined in systemd.path(5).

Timer-Based Activation Some daemons that implement clean-up jobs that are intended to be executed in regular intervals benefit from timer-based activation. In systemd, this is implemented via .timer units, as described in systemd.timer(5).

Other Forms of Activation Other forms of activation have been suggested and implemented in some systems. However, there are often simpler or better alternatives, or they can be put together of combinations of the schemes above. Example: Sometimes, it appears useful to start daemons or .socket units when a specific IP address is configured on a network interface, because network sockets shall be bound to the address. However, an alternative to implement this is by utilizing the Linux IP_FREEBIND/IPV6_FREEBIND socket option, as accessible via FreeBind=yes in systemd socket files (see systemd.socket(5) for details). This option, when enabled, allows sockets to be bound to a non-local, not configured IP address, and hence allows bindings to a particular IP address before it actually becomes available, making such an explicit dependency to the configured address redundant. Another often suggested trigger for service activation is low system load. However, here too, a more convincing approach might be to make proper use of features of the operating system, in particular, the CPU or I/O scheduler of Linux. Instead of scheduling jobs from userspace based on monitoring the OS scheduler, it is advisable to leave the scheduling of processes to the OS scheduler itself. systemd provides fine-grained access to the CPU and I/O schedulers. If a process executed by the init system shall not negatively impact the amount of CPU or I/O bandwidth available to other processes, it should be configured with CPUSchedulingPolicy=idle and/or IOSchedulingClass=idle. Optionally, this may be combined with timer-based activation to schedule background jobs during runtime and with minimal impact on the system, and remove it from the boot phase itself.