Systemd

Reference

CONCEPTS

systemd is a system and service manager for Linux operating systems. When run as first process on boot (as PID 1), it acts as init system that brings up and maintains userspace services.

CONCEPTS
       systemd provides a dependency system between various entities called "units" of 11 different types. Units encapsulate various objects that are relevant for system boot-up and
       maintenance. The majority of units are configured in unit configuration files, whose syntax and basic set of options is described in systemd.unit(5), however some are created
       automatically from other configuration, dynamically from system state or programmatically at runtime. Units may be "active" (meaning started, bound, plugged in, ..., depending on the
       unit type, see below), or "inactive" (meaning stopped, unbound, unplugged, ...), as well as in the process of being activated or deactivated, i.e. between the two states (these states
       are called "activating", "deactivating"). A special "failed" state is available as well, which is very similar to "inactive" and is entered when the service failed in some way (process
       returned error code on exit, or crashed, an operation timed out, or after too many restarts). If this state is entered, the cause will be logged, for later reference. Note that the
       various unit types may have a number of additional substates, which are mapped to the five generalized unit states described here.

       The following unit types are available:

        1. Service units, which start and control daemons and the processes they consist of. For details, see systemd.service(5).

        2. Socket units, which encapsulate local IPC or network sockets in the system, useful for socket-based activation. For details about socket units, see systemd.socket(5), for details on
           socket-based activation and other forms of activation, see daemon(7).

        3. Target units are useful to group units, or provide well-known synchronization points during boot-up, see systemd.target(5).

        4. Device units expose kernel devices in systemd and may be used to implement device-based activation. For details, see systemd.device(5).

        5. Mount units control mount points in the file system, for details see systemd.mount(5).

        6. Automount units provide automount capabilities, for on-demand mounting of file systems as well as parallelized boot-up. See systemd.automount(5).

        7. Timer units are useful for triggering activation of other units based on timers. You may find details in systemd.timer(5).

        8. Swap units are very similar to mount units and encapsulate memory swap partitions or files of the operating system. They are described in systemd.swap(5).

        9. Path units may be used to activate other services when file system objects change or are modified. See systemd.path(5).

       10. Slice units may be used to group units which manage system processes (such as service and scope units) in a hierarchical tree for resource management purposes. See systemd.slice(5).

       11. Scope units are similar to service units, but manage foreign processes instead of starting them as well. See systemd.scope(5).

       Units are named as their configuration files. Some units have special semantics. A detailed list is available in systemd.special(7).

systemd 可以管理11种units,如上所示。

要创建一个unit,通过在/etc/systemd/system目录创建一个文件,文件名就是unit的名字,比如创建一个socekt类型的unit(并关联到一个service)

                        cat > /root/echo.py <<- EOF
                                #!/usr/bin/python
                                import sys
                                sys.stdout.write(sys.stdin.readline().strip().upper() + 'rn')
                                EOF
                        chmod +x /root/echo.py
                        cat > /etc/systemd/system/echo@.service <<- EOF
                                [Unit] 
                                Description=Echo server service 
                                
                                [Service] 
                                ExecStart=/root/echo.py
                                StandardInput=socket
                                EOF
                        cat > /etc/systemd/system/echo.socket <<- EOF
                                [Unit]
                                Description = Echo server
                                
                                [Socket]
                                ListenStream = $server_ip4_1:30010
                                Priority=4
                                Accept = yes 
                                
                                [Install]
                                WantedBy = sockets.target
                                EOF
                        systemctl start echo.socket

各个unit有自己特有的配置,放到对应的sectino下,比如[Socket],[Service]...
他们也有通用的配置,放到[Unit] section里面
另外还有一个[INSTALL] sectino.
[INSTALL] SECTION OPTIONS
       Unit files may include an "[Install]" section, which carries installation information for the unit. This section is not interpreted by systemd(1) during runtime; it is used by the enable
       and disable commands of the systemctl(1) tool during installation of a unit.

       Alias=
           A space-separated list of additional names this unit shall be installed under. The names listed here must have the same suffix (i.e. type) as the unit filename. This option may be
           specified more than once, in which case all listed names are used. At installation time, systemctl enable will create symlinks from these names to the unit filename. Note that not
           all unit types support such alias names, and this setting is not supported for them. Specifically, mount, slice, swap, and automount units do not support aliasing.

       WantedBy=, RequiredBy=
           This option may be used more than once, or a space-separated list of unit names may be given. A symbolic link is created in the .wants/ or .requires/ directory of each of the listed
           units when this unit is installed by systemctl enable. This has the effect that a dependency of type Wants= or Requires= is added from the listed unit to the current unit. The
           primary result is that the current unit will be started when the listed unit is started. See the description of Wants= and Requires= in the [Unit] section for details.

           WantedBy=foo.service in a service bar.service is mostly equivalent to Alias=foo.service.wants/bar.service in the same file. In case of template units, systemctl enable must be called
           with an instance name, and this instance will be added to the .wants/ or .requires/ list of the listed unit. E.g.  WantedBy=getty.target in a service getty@.service will result in
           systemctl enable getty@tty2.service creating a getty.target.wants/getty@tty2.service link to getty@.service.

       Also=
           Additional units to install/deinstall when this unit is installed/deinstalled. If the user requests installation/deinstallation of a unit with this option configured, systemctl
           enable and systemctl disable will automatically install/uninstall units listed in this option as well.

           This option may be used more than once, or a space-separated list of unit names may be given.

       DefaultInstance=
           In template unit files, this specifies for which instance the unit shall be enabled if the template is enabled without any explicitly set instance. This option has no effect in
           non-template unit files. The specified string must be usable as instance identifier.

       The following specifiers are interpreted in the Install section: %n, %N, %p, %i, %j, %U, %u, %m, %H, %b, %v. For their meaning see the next section.

具体的unit配置看手册:man systemd.unit

target类型的unit是用来进行同步用的,你可以在自己的unit里面"Wants,After,Requires"这些target。

系统会自动创建一些特殊unit,比如:
network.target 当网络栈可用后
network-online.target 当接口up并且有ip之后

[Unit]
After=network-online.target
Wants=network-online.target

Requires=
           Configures requirement dependencies on other units. If this unit gets activated, the units listed here will be activated as well. If one of the other units fails to activate, and an
           ordering dependency After= on the failing unit is set, this unit will not be started. Besides, with or without specifying After=, this unit will be stopped if one of the other units
           is explicitly stopped. This option may be specified more than once or multiple space-separated units may be specified in one option in which case requirement dependencies for all
           listed names will be created. Note that requirement dependencies do not influence the order in which services are started or stopped. This has to be configured independently with the
           After= or Before= options. If a unit foo.service requires a unit bar.service as configured with Requires= and no ordering is configured with After= or Before=, then both units will
           be started simultaneously and without any delay between them if foo.service is activated. Often, it is a better choice to use Wants= instead of Requires= in order to achieve a system
           that is more robust when dealing with failing services.

           Note that this dependency type does not imply that the other unit always has to be in active state when this unit is running. Specifically: failing condition checks (such as
           ConditionPathExists=, ConditionPathIsSymbolicLink=, ... — see below) do not cause the start job of a unit with a Requires= dependency on it to fail. Also, some unit types may
           deactivate on their own (for example, a service process may decide to exit cleanly, or a device may be unplugged by the user), which is not propagated to units having a Requires=
           dependency. Use the BindsTo= dependency type together with After= to ensure that a unit may never be in active state without a specific other unit also in active state (see below).

           Note that dependencies of this type may also be configured outside of the unit configuration file by adding a symlink to a .requires/ directory accompanying the unit file. For
           details, see above.

Wants=
           A weaker version of Requires=. Units listed in this option will be started if the configuring unit is. However, if the listed units fail to start or cannot be added to the
           transaction, this has no impact on the validity of the transaction as a whole. This is the recommended way to hook start-up of one unit to the start-up of another unit.

           Note that dependencies of this type may also be configured outside of the unit configuration file by adding symlinks to a .wants/ directory accompanying the unit file. For details,
           see above.

Before=, After=
           These two settings expect a space-separated list of unit names. They configure ordering dependencies between units. If a unit foo.service contains a setting Before=bar.service and
           both units are being started, bar.service's start-up is delayed until foo.service has finished starting up. Note that this setting is independent of and orthogonal to the requirement
           dependencies as configured by Requires=, Wants= or BindsTo=. It is a common pattern to include a unit name in both the After= and Requires= options, in which case the unit listed
           will be started before the unit that is configured with these options. This option may be specified more than once, in which case ordering dependencies for all listed names are
           created.  After= is the inverse of Before=, i.e. while After= ensures that the configured unit is started after the listed unit finished starting up, Before= ensures the opposite,
           that the configured unit is fully started up before the listed unit is started. Note that when two units with an ordering dependency between them are shut down, the inverse of the
           start-up order is applied. i.e. if a unit is configured with After= on another unit, the former is stopped before the latter if both are shut down. Given two units with any ordering
           dependency between them, if one unit is shut down and the other is started up, the shutdown is ordered before the start-up. It doesn't matter if the ordering dependency is After= or
           Before=, in this case. It also doesn't matter which of the two is shut down, as long as one is shut down and the other is started up. The shutdown is ordered before the start-up in
           all cases. If two units have no ordering dependencies between them, they are shut down or started up simultaneously, and no ordering takes place. It depends on the unit type when
           precisely a unit has finished starting up. Most importantly, for service units start-up is considered completed for the purpose of Before=/After= when all its configured start-up
           commands have been invoked and they either failed or reported start-up success.

这些系统创建的unit见手册: man systemd.special