Mécanismes OS lors du redémarrage

LicenceInformatique et Intelligence ArtificielleRedemarrer un ordinateurMécanismes OS lors du redémarrage~11 min de lecture

Suivre un redémarrage pas à pas : de systemctl reboot au retour de default.target

Un redémarrage Linux est une chaîne d'étapes ordonnées : arrêter les services dans l'ordre inverse de leurs dépendances, écrire sur le disque ce qui reste en mémoire, démonter, redémarrer le matériel, puis remonter du firmware au noyau et jusqu'à systemd ; chaque étape protège la cohérence des données.

Objectifs

  • Décrire, dans l'ordre, les étapes de l'arrêt d'un système Linux géré par systemd.
  • Expliquer le rôle du cache de pages, de la synchronisation disque (sync, fsync) et de la journalisation du système de fichiers.
  • Décrire la chaîne de démarrage : firmware BIOS ou UEFI, chargeur d'amorçage, noyau et initramfs, PID 1.
  • Observer chaque étape avec les outils standard : systemctl, journalctl, systemd-analyze, efibootmgr.

Vue d'ensemble

On suit une seule machine : le serveur de la bibliothèque numérique d'un lycée de Kumasi, sous Debian, sur lequel Ama tape systemctl reboot. On avance étape par étape ; chaque étape ne commence que lorsque la précédente est terminée.

flowchart LR
  A[systemctl reboot] --> B[Arret des services]
  B --> C[Ecriture du cache]
  C --> D[Demontage des disques]
  D --> E[Appel reboot au noyau]
  E --> F[Firmware UEFI ou BIOS]
  F --> G[Chargeur GRUB]
  G --> H[Noyau et initramfs]
  H --> I[systemd PID 1]
  I --> J[default target]

Partie 1 — La séquence d'arrêt

Étape 1 : systemd reçoit la demande et vise reboot.target

systemctl reboot demande à systemd (le processus de PID 1) d'activer l'unité cible reboot.target. Les unités de service ont par défaut une dépendance Conflicts=shutdown.target : activer la cible d'arrêt implique donc d'arrêter ces services. On peut voir ce que la cible entraîne avec systemctl list-dependencies reboot.target.

Étape 2 : arrêt des services dans l'ordre inverse du démarrage

Si le service web est déclaré After=postgresql.service (il démarre après la base), alors à l'arrêt systemd l'arrête avant la base : l'ordre d'arrêt est l'inverse de l'ordre de démarrage. Ainsi, la base ne disparaît pas sous les pieds de l'application qui lui écrit encore.

Pour chaque service, systemd :

  1. exécute la commande ExecStop= si elle existe ;
  2. envoie le signal SIGTERM (réglable par KillSignal=) : le programme doit terminer ses transactions et fermer ses fichiers ;
  3. attend au plus TimeoutStopSec= (par défaut 90 secondes, valeur réglée par DefaultTimeoutStopSec= dans /etc/systemd/system.conf) ;
  4. envoie SIGKILL aux processus restants : ils meurent sans pouvoir rien enregistrer.

Étape 3 : écriture des données en attente (synchronisation)

Les pages modifiées mais pas encore écrites s'appellent des pages sales (dirty pages). Le noyau les écrit périodiquement ; deux réglages en donnent le rythme :

  • vm.dirty_writeback_centisecs (par défaut 500, soit 5 s) : intervalle de réveil des fils d'écriture ;
  • vm.dirty_expire_centisecs (par défaut 3000, soit 30 s) : âge à partir duquel une page sale doit être écrite.

Un programme qui veut une garantie appelle fsync() sur son fichier : l'appel ne rend la main qu'une fois les données sur le disque. C'est ce que font les bases de données à chaque validation de transaction. À l'arrêt, systemd et le noyau forcent l'écriture de tout le cache (l'équivalent de la commande sync).

Ordre de grandeur : un programme qui écrit sans fsync() à \(r = 20\) Mo/s peut avoir jusqu'à environ

\[ Q \approx r \times t_{\text{expire}} = 20 \text{ Mo/s} \times 30 \text{ s} = 600 \text{ Mo} \]

de données seulement en mémoire, dans la limite fixée par vm.dirty_ratio et vm.dirty_background_ratio (part de la mémoire au-delà de laquelle l'écriture est accélérée ou imposée). C'est ce volume qu'une coupure de courant peut faire perdre.

Étape 4 : démontage des systèmes de fichiers

Une fois les processus arrêtés, systemd démonte les systèmes de fichiers (unités .mount) et désactive le swap. Le système de fichiers racine, encore utilisé, est remonté en lecture seule. Un ext4 démonté proprement est marqué « propre » : au prochain démarrage, aucune vérification longue n'est nécessaire.

Étape 5 : systemd-shutdown et l'appel système reboot()

En fin de parcours, PID 1 se remplace par le programme systemd-shutdown, qui tue les derniers processus, tente de démonter ou remonter en lecture seule ce qui reste, détache les volumes (boucles, RAID logiciel, chiffrement), puis appelle l'appel système reboot() avec la commande de redémarrage. Le noyau arrête les périphériques et demande au matériel de repartir.

Le service web.service est déclaré After=postgresql.service. Que fait systemd au redémarrage ?

  1. Il arrête PostgreSQL d'abord, puis le service web.
  2. Il arrête le service web d'abord, puis PostgreSQL.
  3. Il les tue tous les deux en même temps avec SIGKILL.
L'ordre d'arrêt est l'inverse de l'ordre de démarrage : ce qui démarre après s'arrête avant. La base reste disponible tant que l'application lui écrit.

Partie 2 — La séquence de démarrage

Étape 6 : le firmware (BIOS ou UEFI)

Le firmware effectue l'auto-test (POST) et initialise le matériel, puis cherche un programme d'amorçage :

  • BIOS (ancien mode) : il lit le premier secteur du disque, le MBR (512 octets, dont 446 de code d'amorçage), et lui passe la main.
  • UEFI : il consulte ses entrées de démarrage enregistrées en mémoire non volatile et lance un fichier .efi situé sur la partition système EFI (ESP, formatée en FAT). Sous Linux, efibootmgr -v liste ces entrées et leur ordre.

Étape 7 : le chargeur d'amorçage

GRUB (ou systemd-boot) affiche éventuellement un menu, charge en mémoire l'image du noyau (vmlinuz) et l'image initiale initramfs, et transmet au noyau sa ligne de commande (par exemple root=UUID=… pour désigner la partition racine). On la relit après démarrage dans /proc/cmdline.

Étape 8 : le noyau et l'initramfs

Le noyau s'initialise (mémoire, ordonnanceur, pilotes intégrés), puis exécute l'initramfs : un petit système de fichiers en mémoire qui contient les pilotes et outils nécessaires pour trouver la vraie racine (pilote de contrôleur disque, déchiffrement LUKS, LVM, RAID). Si le système de fichiers n'a pas été démonté proprement, c'est ici ou juste après que le journal est rejoué ou que fsck est lancé. Ensuite, la racine réelle est montée et l'on bascule dessus.

Étape 9 : systemd, PID 1, jusqu'à default.target

Le noyau lance /sbin/init, qui est systemd sur la plupart des distributions actuelles. systemd lit les unités, calcule les dépendances (Requires=, Wants=, After=), démarre en parallèle tout ce qui peut l'être et vise default.target (souvent multi-user.target sur un serveur, graphical.target sur un poste de travail ; systemctl get-default l'affiche).

Après un redémarrage, la machine s'arrête sur une invite de l'initramfs indiquant que la racine est introuvable. Quelle étape est en cause ?

  1. Le POST du firmware.
  2. L'arrêt des services par systemd.
  3. Le montage de la racine (pilote absent de l'initramfs ou paramètre root= erroné).
L'initramfs a pour rôle de trouver et monter la racine. S'il échoue, le noyau et le chargeur ont fonctionné : il faut regarder le paramètre root= et le contenu de l'initramfs.

Partie 3 — Exemples résolus

Exemple 1 — Pourquoi l'arrêt a-t-il pris 90 secondes ?

Au service informatique d'une mairie à Niamey, chaque redémarrage affiche « A stop job is running for collecteur.service (1min 30s) ». Analyse la situation.

Étape 1 — Lire le journal de l'arrêt précédent : journalctl -b -1 -u collecteur.service. On y voit « State 'stop-sigterm' timed out. Killing. » : le service n'a pas réagi au SIGTERM.
Étape 2 — Relier au délai : 1 min 30 s correspond exactement au TimeoutStopSec par défaut de 90 s. systemd a attendu tout le délai, puis envoyé SIGKILL.
Étape 3 — Évaluer le risque : tué par SIGKILL, le collecteur n'a pas pu vider ses tampons ; ses dernières données peuvent être perdues.
Étape 4 — Corriger la cause : faire gérer SIGTERM par le programme (fermer ses fichiers, appeler fsync puis quitter). Réduire le délai par un fichier de surcharge (systemctl edit collecteur.service, avec TimeoutStopSec=20s) ne fait que raccourcir l'attente, sans protéger les données.

Exemple 2 — Mesurer le démarrage

Après le redémarrage, Ama veut savoir combien de temps a pris chaque phase et quel service ralentit le démarrage. Quelles commandes, et comment lire le résultat ? Cherche d'abord.

Voir la solution

systemd-analyze affiche le temps passé dans le firmware, le chargeur, le noyau, l'initramfs et l'espace utilisateur, par exemple « Startup finished in 4.1s (firmware) + 2.0s (loader) + 1.8s (kernel) + 3.2s (initrd) + 12.5s (userspace) ». Le total est la somme :

\[ 4{,}1 + 2{,}0 + 1{,}8 + 3{,}2 + 12{,}5 = 23{,}6 \text{ s} \]

L'espace utilisateur pèse le plus lourd (\(12{,}5 / 23{,}6 \approx 53\,\%\)). systemd-analyze blame classe les services par durée de démarrage ; systemd-analyze critical-chain montre la chaîne de dépendances qui retarde réellement default.target (un service lent mais hors de cette chaîne ne retarde rien, car il démarre en parallèle).

Exemple 3 — Coupure de courant pendant une écriture

Pendant un délestage, le serveur s'éteint brutalement alors qu'un script copiait des fichiers sans fsync(), et que PostgreSQL validait des transactions. Que retrouve-t-on au redémarrage ?

Voir la solution

Aucune des étapes 2 à 5 n'a eu lieu. Au montage, ext4 rejoue son journal : la structure du système de fichiers est cohérente. Les fichiers copiés depuis moins d'environ 30 s peuvent être vides, tronqués ou absents, car leurs données étaient encore dans le cache. PostgreSQL, qui fait un fsync() de son journal d'écriture anticipée (WAL) à chaque validation, rejoue ce journal au démarrage : les transactions validées sont conservées, celles en cours sont annulées. Leçon : la cohérence vient de la combinaison « journal du système de fichiers + fsync de l'application ».

Erreurs fréquentes

  • Croire que « écrit » veut dire « sur le disque » : sans fsync() ni sync, les données peuvent rester en mémoire plusieurs secondes.
  • Croire que le journal ext4 protège le contenu des fichiers : en mode data=ordered, il protège la structure, pas les données non synchronisées.
  • Confondre ordre et dépendance : After= fixe l'ordre, Requires= ou Wants= fixent le besoin. Un service avec Requires= mais sans After= peut démarrer en même temps que ce dont il dépend.
  • Confondre BIOS et UEFI : le MBR et ses 446 octets de code concernent l'amorçage BIOS ; en UEFI, on lance un fichier .efi de la partition ESP.
  • Lire le mauvais journal : pour comprendre un arrêt, il faut le démarrage précédent, journalctl -b -1, et non journalctl -b.

Récapitulatif

  1. systemctl reboot active reboot.target.
  2. Les services s'arrêtent dans l'ordre inverse du démarrage : ExecStop, SIGTERM, attente (90 s par défaut), SIGKILL.
  3. Le cache de pages est écrit sur le disque ; les applications sérieuses ont déjà fait fsync().
  4. Les systèmes de fichiers sont démontés, la racine remontée en lecture seule.
  5. systemd-shutdown appelle reboot().
  6. Firmware (POST, BIOS/MBR ou UEFI/ESP) → GRUB → noyau + initramfs → montage de la racine → systemd (PID 1) → default.target.

Quelle commande montre la chaîne de dépendances qui a réellement retardé l'arrivée à default.target ?

  1. systemd-analyze critical-chain
  2. efibootmgr -v
  3. journalctl -b -1
critical-chain suit le chemin critique des dépendances ; efibootmgr concerne les entrées de démarrage UEFI et journalctl -b -1 le journal du démarrage précédent.
reboot.target
Cible systemd activée par systemctl reboot ; son activation provoque l'arrêt des services.
SIGTERM puis SIGKILL
Demande d'arrêt poli, puis mise à mort après TimeoutStopSec (90 s par défaut).
Page sale
Donnée modifiée en mémoire, pas encore écrite sur le disque ; perdue en cas de coupure.
fsync()
Appel qui ne rend la main qu'une fois les données d'un fichier écrites sur le disque.
initramfs
Petit système en mémoire chargé avec le noyau pour trouver et monter la vraie racine.
UEFI et ESP
Le firmware UEFI lance un fichier .efi de la partition système EFI, formatée en FAT.

Teste tes connaissances sur ce cours

Crée ton compte gratuitement pour accéder aux quiz associés et suivre ta progression.