SYSTEMD

De TwisterWiki
La version imprimable n’est plus prise en charge et peut comporter des erreurs de génération. Veuillez mettre à jour les signets de votre navigateur et utiliser à la place la fonction d’impression par défaut de celui-ci.

systemd c'est quoi ?

  • systemd est le remplaçant de systemVinit
  • Les scripts dans /etc/init.d deviennent obsolètes et le fichier inittab est remplacé par /etc/systemd/system/default.target

Quels sont les avantages ?

  • Démarrage plus rapide car les services démarrent en parallèles
  • les projets systemd et udev sont fusionnés mais pour le moment installés avec des paquets différents ---------- system V init
  • Meilleur traçabilité sur les erreurs de démarrage des services

Quelques commandes utiles

  • systemctl : commande permettant de contrôler systemd
  • systemctl {start|stop|reload|restart|status} service
  • systemctl --system daemon-reload  : recharge tous les scripts de démarrage et recrée l'arbre de dépendances
  • systemctl reboot
  • systemctl poweroff
  • systemctl list-units : liste les services qui sont activés et affiche leur état
    • Exemple
UNIT                                               LOAD   ACTIVE SUB       JOB DESCRIPTION
proc-sys-fs-binfmt_misc.automount                  loaded active waiting       Arbitrary Executable File Formats File System Autom
sys-devices-pci0...t2:0:0-2:0:0:0-block-sr0.device loaded active plugged       VBOX_CD-ROM
sys-devices-pci0...00-0000:00:03.0-net-p2p1.device loaded active plugged       82540EM Gigabit Ethernet Controller
sys-devices-pci0...0000:00:05.0-sound-card0.device loaded active plugged       82801AA AC'97 Audio Controller
sys-devices-pci0...0-0:0:0:0-block-sda-sda1.device loaded active plugged       VBOX_HARDDISK
sys-devices-pci0...0-0:0:0:0-block-sda-sda2.device loaded active plugged       VBOX_HARDDISK
sys-devices-pci0...t0:0:0-0:0:0:0-block-sda.device loaded active plugged       VBOX_HARDDISK
sys-devices-platform-serial8250-tty-ttyS0.device   loaded active plugged       /sys/devices/platform/serial8250/tty/ttyS0
sys-devices-platform-serial8250-tty-ttyS1.device   loaded active plugged       /sys/devices/platform/serial8250/tty/ttyS1
sys-devices-platform-serial8250-tty-ttyS2.device   loaded active plugged       /sys/devices/platform/serial8250/tty/ttyS2
sys-devices-platform-serial8250-tty-ttyS3.device   loaded active plugged       /sys/devices/platform/serial8250/tty/ttyS3
sys-devices-virtual-block-dm\x2d0.device           loaded active plugged       /sys/devices/virtual/block/dm-0
sys-devices-virtual-block-dm\x2d1.device           loaded active plugged       /sys/devices/virtual/block/dm-1
sys-module-configfs.device                         loaded active plugged       /sys/module/configfs
sys-module-fuse.device                             loaded active plugged       /sys/module/fuse
sys-subsystem-net-devices-p2p1.device              loaded active plugged       82540EM Gigabit Ethernet Controller
-.mount                                            loaded active mounted       /
boot.mount                                         loaded active mounted       /boot
dev-hugepages.mount                                loaded active mounted       Huge Pages File System
dev-mqueue.mount                                   loaded active mounted       POSIX Message Queue File System
run-user-1000-gvfs.mount                           loaded active mounted       /run/user/1000/gvfs
sys-fs-fuse-connections.mount                      loaded active mounted       FUSE Control File System
sys-kernel-config.mount                            loaded active mounted       Configuration File System
sys-kernel-debug.mount                             loaded active mounted       Debug File System
rngd.service                                       loaded failed failed        Hardware RNG Entropy Gatherer Daemon
  • systemctl status rngd : permet de consulté les erreurs de démarrage d'un service
rngd.service - Hardware RNG Entropy Gatherer Daemon
         Loaded: loaded (/usr/lib/systemd/system/rngd.service; enabled)
         Active: failed (Result: exit-code) since Thu, 2013-07-11 14:38:33 CEST; 1h 52min ago
       Main PID: 588 (code=exited, status=1/FAILURE)
         CGroup: name=systemd:/system/rngd.service

Jul 11 14:38:33 chmartin2.ecritel.net systemd[1]: Starting Hardware RNG Entropy Gatherer Daemon...
Jul 11 14:38:33 chmartin2.ecritel.net systemd[1]: Started Hardware RNG Entropy Gatherer Daemon.
Jul 11 14:38:33 chmartin2.ecritel.net rngd[588]: Unable to open file: /dev/tpm0
Jul 11 14:38:33 chmartin2.ecritel.net rngd[588]: can't open any entropy source
Jul 11 14:38:33 chmartin2.ecritel.net rngd[588]: Maybe RNG device modules are not loaded
Jul 11 14:38:33 chmartin2.ecritel.net systemd[1]: rngd.service: main process exited, code=exited, status=1/FAILURE
Jul 11 14:38:33 chmartin2.ecritel.net systemd[1]: Unit rngd.service entered failed state


  • systemctl list-unit-files : liste les services qui sont activés
    • Exemple
UNIT FILE                                   STATE
proc-sys-fs-binfmt_misc.automount           static
dev-hugepages.mount                         static
dev-mqueue.mount                            static
proc-fs-nfsd.mount                          static
proc-sys-fs-binfmt_misc.mount               static
sys-fs-fuse-connections.mount               static
sys-kernel-config.mount                     static
sys-kernel-debug.mount                      static
tmp.mount                                   static
var-lib-nfs-rpc_pipefs.mount                static
cups.path                                   enabled
systemd-ask-password-console.path           static
systemd-ask-password-plymouth.path          static
systemd-ask-password-wall.path              static
abrt-ccpp.service                           enabled
abrt-oops.service                           enabled
abrt-vmcore.service                         enabled
initrd-switch-root.service                  static
instperf.service                            static
ip6tables.service                           disabled
iptables.service                            disabled

Emplacement des scripts de démarrage des services

  • Les scripts de démarrage sont situés dans le dossier /usr/lib/systemd/system/

Les différents types de fichiers

  • Les fichiers avec extension .mount
    • Ces fichiers permettent de monter les "device" et point de montage
  • Les fichiers .service
    • Ces fichiers permettent de démarrer les services
  • Les fichiers .umount
  • Les fichiers .target
  • Les fichiers .socket

Comment définir le "runlevel" ?

ln -s /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
ln -s /lib/systemd/system/graphical.target /etc/systemd/system/default.target

Contenu des scripts de démarrage

  • Exemple de contenu de script systemd avec ssh
[Unit]
Description=OpenSSH server daemon
After=syslog.target network.target auditd.service

[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStartPre=/usr/sbin/sshd-keygen
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process

[Install]
WantedBy=multi-user.target
  • Autre exemple avec le script de démarrage de MySQL
[Unit]
Description=MySQL database server
After=syslog.target
After=network.target

[Service]
Type=simple
User=mysql
Group=mysql

ExecStartPre=/usr/libexec/mysqld-prepare-db-dir %n
# Note: we set --basedir to prevent probes that might trigger SELinux alarms,
# per bug #547485
ExecStart=/usr/bin/mysqld_safe --basedir=/usr
ExecStartPost=/usr/libexec/mysqld-wait-ready $MAINPID

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

# Place temp files in a secure directory, not /tmp
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Howto sur systemd

Activer un service au boot

  • systemctl enable mon_service
    • Résultat de la commande sur une fedora :
ln -s '/usr/lib/systemd/system/mon_service.service' '/etc/systemd/system/multi-user.target.wants/mon_service.service'

Comment écrire un script de démarrage

  • Exemple pour le lancement de tomcat
[Unit]
Description=Tomcat server
After=syslog.target
After=network.target

[Service]
Type=simple
User=tomcat
Group=tomcat

ExecStart=/usr/local/tomcat/bin/startup.sh
ExecStop=/usr/local/tomcat/bin/shutdown.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

Options disponible pour les scripts de démarrage

  • Type = {simple, forking, oneshot, dbus, notify, idle}
    • simple : (c'est la valeur par défaut si BusName= n'est pas spécifié). le processus lancé par 'ExecStart=' est le processus principal du service
    • forking : le processus lancé par 'ExecStart=' fait appel à fork() lors du démarrage. il est recommander d'utiliser l'option 'PIDFile=' afin que systemd puisse identifier le processus principal du daemon.
    • oneshot : Le comportement est similaire à simple. 'RemainAfterExit=' est utile pour ce type de service.
    • dbus : Le comportement est similaire à simple. however it is expected that the daemon acquires a name on the D-Bus bus, as configured by BusName=. systemd will proceed starting follow-up units after the D-Bus bus name has been acquired. Service units with this option configured implicitly gain dependencies on the dbus.socket unit. This type is the default if BusName= is specified.
    • notify : Le comportement est simailaire à simple. il s’attend à ce que le demon envoie une notification via 'sd_notify(3)' ou équivalent à la fin du démarrage du service.
    • idle : Le comportement est similaire à simple, toutefois l'exécution réelle du binaire est retardée jusqu'a ce que tous les jobs soient terminées
  • RemainAfterExit = {yes|no}
    • Par défaut à no, le service peut-être considéré actif même quand le process à exit.
  • GuessMainPID=
    • Takes a boolean value that specifies whether systemd should try to guess the main PID of a service if it cannot be determined reliably. This option is ignored unless Type=forking is set and PIDFile= is unset because for the other types or with an explicitly configured PID file the main PID is always known. The guessing algorithm might come to incorrect conclusions if a daemon consists of more than one process. If the main PID cannot be determined failure detection and automatic restarting of a service will not work reliably. Defaults to yes.
  • PIDFile=
    • Takes an absolute file name pointing to the PID file of this daemon. Use of this option is recommended for services where Type= is set to forking. systemd will read the PID of the main process of the daemon after start-up of the service. systemd will not write to the file configured here.
  • BusName=
    • Takes a D-Bus bus name, that this service is reachable as. This option is mandatory for services where Type= is set to dbus, but its use is otherwise recommended as well if the process takes a name on the D-Bus bus.
  • ExecStart=
    • Commande avec ses arguments qui sera exécuter lors du démarrage du service. le premier argument doit être le chemin absolu
    • Si Type =/= onse shot, une seule commande peut-être fournie.
    • Si Type=oneshot on peut utiliser plusieurs commandes avec un "semicolon". Les commandes seront exécutées séquentiellement et dans l'ordre de la ligne de commande. Si une commande échoue, les autres commandes sont ignorées et considérées en échec à moins d'utiliser le prefix "-".
    • Si on souhaite utilisé une commande du shell, il faut préciser le shell comme dans l'exemple suivant :
ExecStart=/bin/sh -c 'dmesg | tac'
  • ExecStartPre=, ExecStartPost=
    • Additional commands that are executed before or after the command in ExecStart=, respectively. Syntax is the same as for ExecStart=, except that multiple command lines are allowed and the commands are executed one after the other, serially. If any of those commands (not prefixed with "-") fail, the rest are not executed and the unit is considered failed.
  • ExecReload=
    • Commande à exécuter pour effectuer un reload du serivice. Tout comme 'ExecStart=', il peut y avoir plusieurs commandes. Si $MAINPID est connu, on peut utiliser une commande comme celle-ci :
   /bin/kill -HUP $MAINPID
  • ExecStop=
    • Commandes à exécuter pour arrêter le service qui a été démarrer par 'ExecStart='. All processes remaining for a service after the commands configured in this option are run are terminated according to the KillMode= setting (see systemd.kill(5)). If this option is not specified the process is terminated right-away when service stop is requested. Specifier and environment variable substitution is supported (including $MAINPID, see above).
  • ExecStopPost=
    • Éventuelles commandes à exécuter après l'arrêt du service. This includes cases where the commands configured in ExecStop= were used, where the service doesn't have any ExecStop= defined, or where the service exited unexpectedly. This argument takes multiple command lines, following the same scheme as described for ExecStart. Use of these settings is optional. Specifier and environment variable substitution is supported.
  • RestartSec=
    • Configures the time to sleep before restarting a service (as configured with Restart=). Takes a unit-less value in seconds, or a time span value such as "5min 20s". Defaults to 100ms.
  • TimeoutStartSec=
    • Configures the time to wait for start-up. If a daemon service does not signal start-up completion within the configured time, the service will be considered failed and be shut down again. Takes a unit-less value in seconds, or a time span value such as "5min 20s". Pass 0 to disable the timeout logic. Defaults to 90s, except when Type=oneshot is used in which case the timeout is disabled by default.
  • TimeoutStopSec=
    • Configures the time to wait for stop. If a service is asked to stop but does not terminate in the specified time, it will be terminated forcibly via SIGTERM, and after another delay of this time with SIGKILL (See KillMode= in systemd.kill(5)). Takes a unit-less value in seconds, or a time span value such as "5min 20s". Pass 0 to disable the timeout logic. Defaults to 90s.
  • TimeoutSec=
    • A shorthand for configuring both TimeoutStartSec= and TimeoutStopSec= to the specified value.
  • WatchdogSec=
    • Configures the watchdog timeout for a service. The watchdog is activated when the start-up is completed. The service must call sd_notify(3) regularly with "WATCHDOG=1" (i.e. the "keep-alive ping"). If the time between two such calls is larger than the configured time then the service is placed in a failure state. By setting Restart= to on-failure or always the service will be automatically restarted. The time configured here will be passed to the executed service process in the WATCHDOG_USEC= environment variable. This allows daemons to automatically enable the keep-alive pinging logic if watchdog support is enabled for the service. If this option is used NotifyAccess= (see below) should be set to open access to the notification socket provided by systemd. If NotifyAccess= is not set, it will be implicitly set to main. Defaults to 0, which disables this feature.
  • Restart=
    • Peut avoir comme valeur : {no, on-success, on-failure, on-abort, always}
      • Configures whether the service shall be restarted when the service process exits, is killed, or a timeout is reached. The service process may be the main service process, but also one of the processes specified with ExecStartPre=, ExecStartPost=, ExecStopPre=, ExecStopPost=, or ExecReload=. When the death of the process is a result of systemd operation (e.g. service stop or restart), the service will not be restarted. Timeouts include missing the watchdog "keep-alive ping" deadline and a service start, reload, and stop operation timeouts.

Takes one of no, on-success, on-failure, on-abort, or always. If set to no (the default) the service will not be restarted. If set to on-success it will be restarted only when the service process exits cleanly. In this context, a clean exit means an exit code of 0, or one of the signals SIGHUP, SIGINT, SIGTERM, or SIGPIPE, and additionally, exit statuses and signals specified in SuccessExitStatus=. If set to on-failure the service will be restarted when the process exits with an nonzero exit code, is terminated by a signal (including on core dump), when an operation (such as service reload) times out, and when the configured watchdog timeout is triggered. If set to on-abort the service will be restarted only if the service process exits due to an uncaught signal not specified as a clean exit status. If set to always the service will be restarted regardless whether it exited cleanly or not, got terminated abnormally by a signal or hit a timeout. In addition to the above settings, the service will not be restarted if the exit code or signal is specified in RestartPreventExitStatus= (see below).

  • SuccessExitStatus=
    • Takes a list of exit status definitions that when returned by the main service process will be considered successful termination, in addition to the normal successful exit code 0 and the signals SIGHUP, SIGINT, SIGTERM and SIGPIPE. Exit status definitions can either be numeric exit codes or termination signal names, separated by spaces. Example: "SuccessExitStatus=1 2 8 SIGKILL", ensures that exit codes 1, 2, 8 and the termination signal SIGKILL are considered clean service terminations. This option may appear more than once in which case the list of successful exit statuses is merged. If the empty string is assigned to this option the list is reset, all prior assignments of this option will have no effect.
  • RestartPreventExitStatus=
    • Takes a list of exit status definitions that when returned by the main service process will prevent automatic service restarts regardless of the restart setting configured with Restart=. Exit status definitions can either be numeric exit codes or termination signal names, and are separated by spaces. Defaults to the empty list, so that by default no exit status is excluded from the configured restart logic. Example: "RestartPreventExitStatus=1 6 SIGABRT", ensures that exit codes 1 and 6 and the termination signal SIGABRT will not result in automatic service restarting. This option may appear more than once in which case the list of restart preventing statuses is merged. If the empty string is assigned to this option the list is reset, all prior assignments of this option will have no effect.
  • PermissionsStartOnly=
    • Takes a boolean argument. If true, the permission related execution options as configured with User= and similar options (see systemd.exec(5) for more information) are only applied to the process started with ExecStart=, and not to the various other ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, ExecStopPost= commands. If false, the setting is applied to all configured commands the same way. Defaults to false.
  • RootDirectoryStartOnly=
    • Takes a boolean argument. If true, the root directory as configured with the RootDirectory= option (see systemd.exec(5) for more information) is only applied to the process started with ExecStart=, and not to the various other ExecStartPre=, ExecStartPost=, ExecReload=, ExecStop=, ExecStopPost= commands. If false, the setting is applied to all configured commands the same way. Defaults to false.
  • NonBlocking=
    • Set O_NONBLOCK flag for all file descriptors passed via socket-based activation. If true, all file descriptors >= 3 (i.e. all except STDIN/STDOUT/STDERR) will have the O_NONBLOCK flag set and hence are in non-blocking mode. This option is only useful in conjunction with a socket unit, as described in systemd.socket(5). Defaults to false.
  • NotifyAccess=
    • Controls access to the service status notification socket, as accessible via the sd_notify(3) call. Takes one of none (the default), main or all. If none no daemon status updates are accepted from the service processes, all status update messages are ignored. If main only service updates sent from the main process of the service are accepted. If all all services updates from all members of the service's control group are accepted. This option should be set to open access to the notification socket when using Type=notify or WatchdogSec= (see above). If those options are used but NotifyAccess= not configured it will be implicitly set to main.
  • Sockets=
    • Specifies the name of the socket units this service shall inherit the sockets from when the service is started. Normally it should not be necessary to use this setting as all sockets whose unit shares the same name as the service (ignoring the different suffix of course) are passed to the spawned process.

Note that the same socket may be passed to multiple processes at the same time. Also note that a different service may be activated on incoming traffic than inherits the sockets. Or in other words: the Service= setting of .socket units doesn't have to match the inverse of the Sockets= setting of the .service it refers to. This option may appear more than once, in which case the list of socket units is merged. If the empty string is assigned to this option the list of sockets is reset, all prior uses of this setting will have no effect.

  • StartLimitInterval=, StartLimitBurst=
    • Configure service start rate limiting. By default services which are started more often than 5 times within 10s are not permitted to start any more times until the 10s interval ends. With these two options this rate limiting may be modified. Use StartLimitInterval= to configure the checking interval (defaults to 10s, set to 0 to disable any kind of rate limiting). Use StartLimitBurst= to configure how many starts per interval are allowed (defaults to 5). These configuration options are particularly useful in conjunction with Restart=, however apply to all kinds of starts (including manual), not just those triggered by the Restart= logic. Note that units which are configured for Restart= and which reach the start limit are not attempted to be restarted anymore, however they may still be restarted manually at a later point from which point on the restart logic is again activated. Note that systemctl reset-failed will cause the restart rate counter for a service to be flushed, which is useful if the administrator wants to manually start a service and the start limit interferes with that.
  • StartLimitAction=
    • Configure the action to take if the rate limit configured with StartLimitInterval= and StartLimitBurst= is hit. Takes one of none, reboot, reboot-force or reboot-immediate. If none is set, hitting the rate limit will trigger no action besides that the start will not be permitted. reboot causes a reboot following the normal shutdown procedure (i.e. equivalent to systemctl reboot), reboot-force causes an forced reboot which will terminate all processes forcibly but should cause no dirty file systems on reboot (i.e. equivalent to systemctl reboot -f) and reboot-immediate causes immediate execution of the reboot(2) system call, which might result in data loss. Defaults to none.