EEIJ

Païou : Mandriva Linux depuis 2002. Aujourd'hui, c'est Mageia Linux


Sommaire


Conforme à XHTML 1.0 Strict Conforme à CSS!

On se lasse de tout, sauf de comprendre.
Attribué à Virgile.

Démarrage de Linux avec Systemd

Historique

01 octobre 2011 : Ébauche de cette page.
11 septembre 2012 : actualisation avec cauldron (mageia 3)
20 novembre 2013 : refonte et actualisation avec cauldron (mageia 4)

Difficulté

Pour : linuxien averti.

 Introduction

La page : Démarrage de l'ordinateur a présenté la partie commune à tous les systèmes d'exploitation.

Dans la présente page, vous trouverez la suite, c'est-à-dire le démarrage de Linux.
System V (cinq) a longtemps été le système de démarrage de Linux, donc de Mandriva et également de Mageia 1.
Mageia 2 utilise maintenant systemd pour démarrer le système linux.

 Le noyau linux

Vous avez vu, sur la page précédente, que la noyau linux a pris la relève du BIOS, grâce au chargeur de démarrage (GRUB par exemple).
Le noyau initialise différents composants matériels (processeur, périphériques, carte graphique ...)
Le noyau lance /sbin/init (en réalité /usr/sbin/init) mais, avec systemd, il s'agit d'un lien vers /usr/lib/systemd/systemd
Pour des raisons de compatibilité, il existe également un fichier /usr/bin/systemd et qui pointe également vers /usr/lib/systemd/systemd.

Haut

 Le processus /sbin/init (/usr/lib/systemd/systemd)

Le noyau exécute donc le processus numéro 1, /sbin/init qui pointe en réalité vers /usr/lib/systemd/systemd. Son fichier de configuration est : /etc/systemd/system.conf. Ce dernier permet de modifier le système de journalisation (logs) ainsi que quelques autres paramètres, surtout intéressants pour le débogage.

Le mode de démarrage de l'ordinateur (le runlevel) est donné par le fichier /etc/systemd/system/default.target.

C'est un lien symbolique vers l'un des fichiers correspondant aux anciens runlevel, situés dans le répertoire /usr/lib/systemd/system/ :

Avant de poursuivre dans le processus de démarrage, il faut comprendre le système des unités de systemd.

Haut

 Les unités

Systemd fait appel à la notion d'Unités. Celles-ci peuvent être définies par :

Ces fichiers et répertoires se trouvent dans le répertoire /etc/systemd/system, pour ceux qui sont paramétrables par l'administrateur système, et dans le répertoire /usr/lib/systemd/system pour les autres.

Haut

 Syntaxe des fichiers .service

La syntaxe est inspirée des fichiers .desktop, avec des groupes fonctionnels [Unit], [Service] et [Install]

  1. [Unit] contient la description du service et la gestion des interactions avec les autres services (requires, conflicts, after ...)
  2. [Service] décrit les commandes lancées par le service et, éventuellement, celles pour le relancer, le tuer ...
  3. [Install] décrit comment il sera installé (demandé par, alias ...)
Pour les curieux, survolez : le fichier lightdm.service

[Unit]
Description=Light Display Manager
Documentation=man:lightdm(1)
Conflicts=getty@tty1.service
After=systemd-user-sessions.service getty@tty1.service plymouth-quit.service

[Service]
ExecStart=/usr/sbin/lightdm
Restart=Always
IgnoreSIGPIPE=no
BusName=org.freedesktop.DisplayManager

[Install]
Alias=display-manager.service

Quelques précisions

Conflicts= l'unité ne doit pas être démarrée si une ou plusieurs autres sont encore en cours d'exécution.

Requires= le fonctionnement de cette unité dépend d'une ou de plusieurs autres unités qui doivent également démarrer. Requires ne détermine pas l'ordre dans lequel les unités doivent être démarrées ou arrêtées. Elles peuvent démarrer simultanément.
Si le démarrage d'une ou de plusieurs autres unités demandées échoue, cette unité sera désactivée.

Wants= comme Requires, mais ici le fonctionnement d'une autre unité est optionnel.

Before, After= configure l'ordre dans lequel les unités doivent être démarrées.
Si une unité foo.service contient un argument Before=bar.service et si les deux unités sont demandées, le démarrage de bar.service est retardé jusqu'à ce que foo.service est mis en marche.

ExecStart= commande à exécuter pour démarrer

ExecStop= commande à exécuter pour arrêter

Restart= précise comment un service peut être redémarré

BusName il s’agit d’un service D-Bus

Alias la présente unité peut également être installée en invoquant le nom de l'unité alias

Haut

 Syntaxe du fichier .socket

Il vient en complément d'un fichier .service et comprend les groupes fonctionnels [Unit], [Socket] et [Install]

  1. [Unit] contient la description du socket
  2. [Socket] décrit la ou les socket(s) qui peuvent être des sockets unix ou réseau (TCP, UDP)
  3. [Install] décrit comment il sera installé (demandé par, alias ...)
Pour les curieux, survolez : le fichier cups.socket

[Unit]
Description=CUPS Printing Service Socket

[Socket]
ListenStream=/var/run/cups/cups.sock

[Install]
WantedBy=socket.target

Haut

 Syntaxe du fichier .target

Une cible (target) est un groupe fonctionnel d'unités. Elle est définie par un fichier .target.

Les fichiers des unités .target ne renseignent pas directement sur les commandes à exécuter. C'est un répertoire
.target.wants qui donnent des liens vers des fichiers
.service ou vers d'autres fichiers .target.

Dans la pratique, il peut y avoir deux répertoires .target.wants, l'un dans /etc/systemd/system, l'autre dans /usr/lib/systemd/system.

Pour les curieux, survolez : le fichier default.target

[Unit]
Description=Multi-User System
Documentation=man:systemd.special(7)
Requires=basic.target
Conflicts=rescue.service rescue.target
After=basic.target rescue.service rescue.target
AllowIsolate=yes
[Install]
Alias=default.target

Quelques précisions

Requires= le fonctionnement de cette unité dépend d'une autre unité qui doit également être démarrée.
Conflicts= cette unité ne doit pas être démarrée si une ou plusieurs autres unités sont en cours d'exécution.
After= cette unité doit être démarrée après une ou plusieurs autres. À la différence de Requires=, After= n'implique pas que ces unités doivent encore tourner.
AllowIsolate= cette unité peut éventuellement être lancée manuellement avec une commande :
systemctl isolate multi-user.target

Haut

 Examen de quelques fichiers d'unités

Compte tenu du grand nombre d'unités, il serait fastidieux d'analyser tous les fichiers de définition. Voici quelques exemples.

La première unité que nous rencontrons est default.target

Afin de simplifier les écritures, les conventions suivantes s'appliquent :

L'unité default.target

Elle est définie par un fichier (etc)/default.target et un répertoire (etc)/default.target.wants

Le fichier (etc)/default.target

C'est un lien qui renvoie à → (usr)/runlevelx.target
x=3 si vous démarrez en mode texte, sinon x=5, ce qui est généralement le cas.

Le répertoire (etc)/default.target.wants

Il contient deux liens vers → (usr)/systemd-readahead-collect.service et → (usr)/systemd-readahead-replay.service

En résumé

L'unité default.target renvoie vers l'unité qui doit effectivement être démarrée, en l’occurrence runlevel5.target. Mais il faut également que les deux services spécifiés soient actifs.

L'unité runlevel3.target

Cette unité est définie par un fichier (usr)/runlevel3.target et un répertoire (usr)/runlevel3.target.wants.

Le fichier (usr)/runlevel3.target

C'est un lien qui renvoie à → (usr)/multi-user.target

Le répertoire (usr)/runlevel3.target.wants

Il contient un un lien vers → (usr)/systemd-update-utmp-runlevel.service

En résumé

Dans le mode console (runlevel3), le service systemd-update-utmp-runlevel doit être activé, puis runlevel3.target renvoie vers l'unité multi-user.target

L'unité runlevel5.target

Cette unité est définie par un fichier (usr)/runlevel5.target et un répertoire (usr)/runlevel5.target.wants.

Le fichier (usr)/runlevel5.target

C'est un lien qui renvoie à → (usr)/graphical.target

Le répertoire (usr)/runlevel5.target.wants

Il contient un lien vers → (usr)/systemd-update-utmp-runlevel.service

En résumé

Dans le mode graphique (runlevel5), le service systemd-update-utmp-runlevel doit être activé, puis runlevel5.target renvoie vers l'unité graphical.target

L'unité multi-user.target

Cette unité est définie par un fichier (usr)/multi-user.target, un répertoire (etc)/multi-user.target.wants et un autre répertoire (usr)/multi-user.target.wants.

Le fichier (usr)/multi-user.target

L'unité multi-user.target

Le répertoire (etc)/multi-user.target.wants

Ce répertoire contient plusieurs liens symboliques : acpid.service, avahi-daemon.service, cpupower.service, crond.service, gpm.service, remote-fs.target, shorewall.service, shorewall6.service, pointant tous vers des fichiers du même nom dans le répertoire → (usr)/

Le répertoire (usr)/multi-user.target.wants

Ce répertoire contient également plusieurs liens symboliques : dbus.service, getty.target, plymouth-quit-wait.service, plymouth-quit.service, rpcbind.target, system-ask-password-wall.path, systemd-logind.service, systemd-user-sessions.service, pointant tous vers des fichiers du même nom dans le répertoire → (usr)/

En résumé

Le fichier multi-user.target nous dit que l'unité basic.target est nécessaire et qu'elle doit déjà être en cours d'exécution. Les répertoires (etc)/multi-user.target.wants et (usr)/multi-user.target.wants nous disent que plusieurs autres unités sont nécessaires (souvent des services). Cela dépend des applications et surtout des serveurs qui sont installés.

Haut

L'unité graphical.target

Elle est définie par un fichier (usr)/graphical.target et un répertoire (etc)/graphical.target.wants.

Le fichier (usr)/graphical.target

L'unité graphical.target

Le répertoire (etc)/graphical.target.wants

Ce répertoire contient deux liens symboliques → (usr)udisksd.service et → (usr)upower.service

En résumé

Le fichier (usr)/graphical.target nous dit que l'unité (usr)/multi-user.target est nécessaire et qu'elle doit déjà être en cours d'exécution, que, si possible, le service (usr)/display-manager doit tourner, mais que (usr)/rescue.target ne doit pas être démarré. Le répertoire (etc)/graphical.target.wants nous dit que les services (usr)/udisksd.service et (usr)/upower.service doivent être actifs.

Haut

L'unité basic.target

Cette unité est définie par un fichier (usr)/basic.target et deux répertoires (etc)/basic.target.wants et (usr)/basic.target.wants.

Le fichier (usr)/basic.target

L'unité basic.target

Le répertoire (etc)/basic.target.wants

Ce répertoire contient deux liens symboliques vers : → (usr)/ip6tables.service, → (usr)/iptables.service

Le répertoire (usr)/basic.target.wants

Ce répertoire contient huit liens symboliques vers : alsa-restore.service, alsa-state.service, fedora-autorelabel-mark.service, fedora-autorelabel.service, fedora-configure.service, fedora-loadmodule.service, mandriva-everytime.service, mandriva-save-dmesg.service, pointant tous vers des fichiers du même nom dans le répertoire (usr)/

En résumé

Le fichier basic.target nous dit que l'unité sysinit.target est nécessaire, que les unités sockets.target, timers.target, paths.target et slices.target sont souhaitées et qu'elles doivent toutes déjà être activées.
Les deux répertoires basic.target.wants nous disent que plusieurs autres services sont nécessaires.

Haut

Les unités display-manager.service et prefdm.service

Les unités du type .service ne nécessitent qu'un seul fichier de configuration. Le fichier (usr)/display-manager.service pointe vers le fichier → (usr)/prefdm.service.

L'unité prefdm.service

Haut

 Les outils pour analyser

Afin de suivre le déroulement du processus de démarrage, quelques commandes sont utiles.

Pour des informations plus complètes, voyez la page : Archlinux

systemctl list-units

Elle permet de lister toutes les unités présentes sur le systèmes sans renseigner sur la chronologie.
Les commandes suivantes peuvent être exécutées :
systemctl list-units : liste les unités actives
systemctl list-units -a (ou --all) : liste toutes les unités pouvant être démarrées, actives ou non
systemctl list-units -t service (ou --type=service) : liste tous les services actifs

Pour les curieux, survolez : extrait de la sortie de systemctl list-units
UNIT                     LOAD   ACTIVE SUB     DESCRIPTION
home.mount               loaded active mounted /home
accounts-daemon.service  loaded active running Accounts Service
prefdm.service           loaded active running Display Manager
basic.target             loaded active active  Basic System
graphical.target         loaded active active  Graphical Interface

Avec la signification des 5 colonnes :

  • UNIT : Le nom d'une unité de systemd,
  • LOAD : information indiquant si l'unité a été chargée correctement,
  • ACTIVE : état général d'activation d'une unité,
  • SUB : état d'activation (dépend du type de l'unité : waiting, plugged, mounted, running, exited, listening, active ...),
  • DESCRIPTION : description brève.
systemctl show

systemctl show multi-user.target : pour voir toutes les caractéristiques d'une unité.
systemctl show -p "Wants" multi-user.target : pour voir quels services sont démarrés par une cible donnée (par ex. multi-user.target).
À la place de Wants, vous pouvez également demander "WantedBy", "Requires", "RequiredBy", "Conflicts", "ConflictedBy", "Before", "After".

systemd-cgls

Sous UNIX, un processus peut créer un fork (le programme relance une nouvelle instance, en tâche de fond). Il sort alors complètement de la supervision du processus qui l’a lancé. Prenons, par exemple, un script CGI lancé par un serveur Web. Lorsqu’il crée un fork, il devient orphelin et est rattaché au processus de PID 1. L’arrêt du serveur Web ne le concerne pas, et aucun script système n’est en mesure de le retrouver automatiquement pour le couper.

Le noyau Linux implémente un mécanisme appelé cgroups (control groups) qui permet de créer un groupe et d’y placer des processus. Tout processus créé au sein d’un cgroup y reste, résolvant ainsi notre problème de CGI fou.

La commande systemd-cgls permet d'afficher, de manière récursive, le contenu des groupes de contrôle (cgroup).

Pour les curieux, survolez : extrait de la sortie de systemd-cgls
system.slice
 ┣ 1   /sbin/init
 ┣ rtkit-daemon.service
 ┃  ┗1624  /usr/libexec/rtkit-daemon
 ┣ udisks2.service
 ┃  ┗1484  /usr/lib/udisks2/udisksd --no-debug
 ┣ accounts-daemon.service
 ┃  ┗ 761  /usr/libexec/accounts-daemon
 :
 ┣ prefdm.service
 ┃  ┣ 708  /usr/sbin/lightdm -nodaemon
 ┃  ┗ 794  /etc/X11/X :0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt1 -novtswitch
 :
ps waxf -eo 'user,pid,cgroup,command'

Cette commande liste les processus actifs et présente le résultat selon la syntaxe donnée par l'option -eo

Pour les curieux, survolez : extrait de la sortie de ps waxf -eo 'user,pid,cgroup,command'
USER PID CGROUP                                    COMMAND
root   2 -                                         [kthreadd]
root   3 -                                           \_ [ksoftirqd/0]
...
root   1 name=systemd:/system.slice                /sbin/init
...
root 708 name=systemd:/system.slice/prefdm.service /usr/sbin/lightdm -nodaemon
root 794 name=systemd:/system.slice/prefdm.service  \_ /etc/X11/X :0 -auth /var/run/lightdm/root/:0
                                                                     -nolisten tcp vt1 -novtswitch
...
systemd-analyze

Cet outil permet d'analyser le démarrage :

systemd --test

Cette commande donne le résultat d'une simulation de démarrage, avec une longue liste des unités mises en jeu , puis la succession des Jobs.

En travaux Travaux



Haut

 Le processus de démarrage

Les premières unités étant déjà été décrites plus haut, vous trouverez juste une énumération de celles qui sont concernées.

Afin de simplifier les écritures, les conventions suivantes s'appliquent :

Voici donc les fichiers et répertoires mis en jeu

Le démarrage en mode texte, dans un terminal virtuel

(etc)/@default.target → (usr)/runlevel3.target
   ┃  correspond à l'ancien niveau 3 : démarrage en mode texte et ouverture du terminal virtuel n°1.
(usr)/runlevel3.target.wants/ = répertoire contenant :
   ┃   ┗@systemd-update-utmp-runlevel.service → (usr)/systemd-update-utmp-runlevel.service
   ┃       ┗(usr)/systemd-update-utmp-runlevel.service
   ┃         effectue l'actualisation du niveau (runlevel) dans le fichier utmp
(usr)/@runlevel3.target → (usr)/multi-user.target (Linux est un système multi-utilisateurs.)
       ┃     Cette cible lance les principaux services communs aux différents niveaux (runlevel)
(etc)/multi-user.target.wants = répertoire contenant :
       ┃   ┣@acpid.service → (usr)/acpid.service
       ┃   ┃   ┗(usr)/acpid.service
       ┃   ┃     lance le service acpid (gestion de l'énergie)
       ┃   ┣@avahi-daemon.service → (usr)/avahi-daemon.service
       ┃   ┃   ┗(usr)/avahi-daemon.service
       ┃   ┃     lance le service avahi (implémente le protocole mDNS)
       ┃   ┣@cpupower.service → (usr)/cpupower.service
       ┃   ┃   ┗(usr)/cpupower.service
       ┃   ┃     lance le service cpupower (gestion de la puissance du processeur)
       ┃   ┣@crond.service → (usr)/crond.service
       ┃   ┃   ┗(usr)/crond.service
       ┃   ┃     lance le service crond (tâches planifiées)
       ┃   ┣@gpm.service → (usr)/gpm.service
       ┃   ┃   ┗(usr)/gpm.service
       ┃   ┃     lance le service gpm (gestion de la souris en mode terminal)
       ┃   ┣@shorewall.service → (usr)/shorewall.service
       ┃   ┃   ┗(usr)/shorewall.service
       ┃   ┃     lance le service shorewall (pare-feu)
       ┃   ┣@shorewall6.service → (usr)/shorewall6.service
       ┃   ┃   ┗(usr)/shorewall6.service
       ┃   ┃     lance le service shorewall6 (pare-feu en IPV6)

En travaux Travaux

       ┃   ┗@remote-fs.target → (usr)/remote-fs.target
       ┃       ┗(usr)/remote-fs.target(résumé Travaux)
(usr)/multi-user.target.wants = répertoire contenant :
       ┃   ┣@dbus.service → (usr)/dbus.service
       ┃   ┃   ┗(usr)/dbus.service
       ┃   ┃     lance le service D-Bus



(usr)/multi-user.target → voir répertoire(s) wants, demande : basic.target
       ┃   ┣@getty.target → (usr)/getty.target
       ┃   ┃   ┣(usr)/getty.target ne fait rien, directement
       ┃   ┃   ┗/etc/systemd/systemgetty.target.wants = répertoire contenant :
       ┃   ┃       ┗getty@tty1.service →(lib)/getty@.service
       ┃   ┃           ┗/lib/systemd/system/getty@.service
       ┃   ┃             ouverture d'un terminal avec getty, sur tty1
       ┃   ┣plymouth-quit-wait.service → /lib/systemd/system/plymouth-quit-wait.service
       ┃   ┃   ┗/lib/systemd/system/plymouth-quit-wait.service
       ┃   ┃     attend l'affichage de l'écran Plymouth et quitte
       ┃   ┣plymouth-quit.service → /lib/systemd/system/plymouth-quit.service
       ┃   ┃   ┗/lib/systemd/system/plymouth-quit.service
       ┃   ┃     termine l'affichage de l'écran Plymouth
       ┃   ┣rpcbind.target → /lib/systemd/system/rpcbind.target
       ┃   ┃   ┗/lib/systemd/systemrpcbind.target ne fait rien, directement
       ┃   ┃     pas de répertoires rpcbind.target.wants : donc non utilisé actuellement
       ┃   ┣systemd-ask-password-wall.path → /lib/systemd/system/systemd-ask-password-wall.path
       ┃   ┃   ┗/lib/systemd/system/systemd-ask-password-wall.path
       ┃   ┃     fait suivre la demande de mot de passe à wall (write all)
       ┃   ┣systemd-logind.service → /lib/systemd/system/systemd-logind.service
       ┃   ┃   ┗/lib/systemd/system/systemd-logind.service
       ┃   ┃     demande le mot de passe et exécute les services associés
       ┃   ┗systemd-user-sessions.service → /lib/systemd/system/systemd-user-sessions.service
       ┃       ┗/lib/systemd/system/systemd-user-sessions.service
       ┃         vérifie le mot de passe et ouvre la session



rsyslog.service → /lib/systemd/system/rsyslog.service
/lib/systemd/system/rsyslog.service
                 lance le service rsyslog (gestion de la journalisation)

Ceci n'est cependant qu'un premier niveau des unités qui sont mises en jeu dans le processus de démarrage. En effet, chacune de ces unités peut entraîner la mise en oeuvre d'autres unités.

Haut

 Le démarrage en mode graphique

/etc/systemd/system/default.target → (usr)/runlevel5.target
   ┃  correspond à l'ancien niveau 5 : démarrage en mode graphique.
(usr)/runlevel5.target.wants/ = répertoire contenant :
   ┃   ┗systemd-update-utmp-runlevel.service → (usr)/systemd-update-utmp-runlevel.service
   ┃       ┗(usr)/systemd-update-utmp-runlevel.service
   ┃         effectue l'actualisation du niveau dans le fichier utmp
(usr)/runlevel5.target → (usr)/graphical.target

Travaux Travaux







Haut