SystemD est une alternative très intéressant à Init. Pourquoi ? Init est la base de toute architecture Linux/UNIX me direz vous, il est le coeur reliant tout le système au noyau.
Le soucis d’Init c’est qu’il est ancien et monotâche dirons nous. En effet, il traite de façon séquentielle les ordres. Une fois Init chargé, il va lancer les différents services et ainsi permettre le démarrage complet du système et des services associés. Pour se faire, il se base sur un arbre de dépendances défini sous Debian dans le dossier /etc/rc.d/, et ensuite lance séquentiellement les services.
Mais pourquoi on les lance un à un, après tout on pourrait lancer le service openLDAP en même temps que la base de données MySQL ou encore le serveur Apache en même temps que le service SSH, par exemple. SystemD permet déjà d’améliorer ceci en se basant sur son propre arbre et ses dépendances afin de lancer simultanément plusieurs services, en se basant non plus sur un ordre séquentiel mais sur des niveaux d’arborescences. Ainsi si syslog est nécessité par l’ensemble des services, il sera lancé en premier puis suivront dbus et avahi par exemple et ensuite openLDAP, MySQL et SSH.
Je vous copie ci-dessous un article très intéressant écrit par la communauté de Linux-FR.org explicant en détail le système.
Sur un système UNIX, le tout premier processus (PID 1) a un rôle particulier :
L’évolution de l’informatique fait que le système évolue au fil du temps (ajout ou suppression de périphériques, lancement ou arrêt de services). Nous avons aussi des plantages de services ou des mises à jour.
Sous GNU/Linux, c’est généralement SysVinit, le système d’initialisation hérité d’UNIX Système V qui assure ce rôle, remplacé par Upstart dans plusieurs distributions.
Hélas, SysVinit reste très basique, peu performant et sujet à de nombreux problèmes. Il n’est pas très adapté à toutes les évolutions modernes que connaît Linux.
Pour l’instant, ces modifications du système sont réalisées par des scripts lancés dynamiquement, généralement par root
ou par un autre service (udev
) ; mais si un système moderne était chargé de maintenir le système opérationnel, il devrait aussi s’occuper de ces modifications.
Le fichier « /etc/inittab »
permet historiquement d’assurer une forme basique de suivi des services et de définir plusieurs modes de fonctionnement ; mais dans les distributions actuelles, il est terriblement en perte de vitesse, toute la charge fonctionnelle étant déplacée dans les scripts SysVinit.
Lennart Poettering constate que le système d’initialisation SysV est vieux et lent. Pour améliorer les choses, il faudrait :
Pour démarrer moins de choses, une solution éprouvée est de retarder le démarrage de certains services jusqu’au moment où ils sont effectivement nécessaires (démarrage à la demande). Par exemple, bluetoothd
est inutile tant qu’aucun périphérique Bluetooth n’est présent et qu’aucune application ne s’adresse à lui via D-Bus. Pareillement, CUPS ne sert que pour configurer une imprimante ou pour imprimer, actions qui surviennent rarement dans les premières minutes de démarrage d’un système. Même SSH pourrait n’être démarré qu’au moment où arrive la première connexion entrante.
Pour démarrer les services en parallèle, il est nécessaire de tout lancer en même temps, et non de démarrer les services un à un comme le fait SysVinit.
Quasiment tous les systèmes qui tentent de paralléliser le démarrage de plusieurs services se servent d’un arbre de dépendances permettant d’imposer le lancement des services indispensables au démarrage d’un service donné. Avahi nécessite D-Bus, donc le système démarre D-Bus et attend qu’il soit prêt avant de lancer Avahi.
A ← B (B est dépendant de A)
Cette approche des dépendances est coûteuse en temps, et contournable. Lorsqu’une dépendance existe, le second service (B) n’a pas réellement besoin que l’initialisation du premier service (A) soit terminée pour commencer à démarrer (charger son code en mémoire vive, lire son fichier de configuration…).
En poussant le raisonnement plus loin, la seule chose nécessaire pour ne pas provoquer d’erreurs lors du lancement du second service (B) est que l’interface du premier (A) soit en place et capable de temporiser les requêtes reçues. Le second service (B) pourra alors s’y connecter sans recevoir d’erreur. Le premier service (A) traitera les requêtes lorsqu’il sera prêt.
Dans le cas de services répondant sur des sockets UNIX (AF_UNIX, présents comme des fichiers de type « s » sur le disque), la simple existence du socket est suffisante. Le noyau s’assure que les données reçues sont mises en attente ou que l’émetteur est bloqué tant qu’elles ne sont pas lues. Les services utilisateurs du démon de journalisation d’événements syslog ont besoin de se connecter à un socket appelé « /dev/log »
, ceux de CUPS utilisent « /var/run/cups/cups.sock »
, etc. Si les sockets correspondants existent, alors il est possible de lancer toutes les dépendances, et la synchronisation se fera toute seule au fur et à mesure que les services seront prêts et répondront aux requêtes reçues.
Sur un système UNIX où les entrées‐sorties sont assimilées à des fichiers, il est très facile de créer ces sockets avant même de lancer le service associé.
Si la création des sockets est indépendante du lancement des services, le problème de dépendances disparaît. Dans une première phase, nous pourrions créer tous les sockets nécessaires au système, et dans un second temps, lancer tous les services en parallèle.
Prenons l’exemple de Syslog. Dès l’instant où « /dev/log »
est créé, il est possible de lancer des services qui vont envoyer leurs événements dans « /dev/log »
. Ces messages seront mis en attente tant que Syslog ne sera pas prêt. Dès qu’il aura démarré, Syslog lira tous les messages reçus et assurera leur traitement.
Ce principe permet également de faire du démarrage à la demande. Si personne ne s’adresse à un service, il est inutile de le lancer. À l’instar d’inetd (et de son remplaçant xinetd) ; nous pouvons attendre qu’un service ait reçu une demande de connexion pour le lancer. Pour les postes de travail qui impriment trois pages par semaine, CUPS est un bon candidat. Tant qu’aucune impression n’est lancée, aucune donnée n’arrive et le service CUPS n’a pas de raison d’être démarré.
Nous trouvons un nouvel avantage à ce système de démarrage : une certaine forme de résistance aux crashs d’un service. Si votre service syslog
se plante lamentablement, les données qui arrivent dans « /dev/log »
sont mises en attente par le noyau. Lorsque syslog
est relancé, aucun message n’est perdu (si ce n’est ceux qu’il a déjà lus et perdus lors de son crash), même si le temps de démarrage est important.
De la même façon, en cas de redémarrage d’un service, par exemple suite à une mise à jour, aucun message n’est perdu.
Sur un système moderne, les services ne se limitent pas à un socket, ils reçoivent des connexions via le réseau IP ou via D-Bus. Est‐ce que ce mécanisme est aussi adaptable à ce type d’interface ? La réponse est oui.
D-Bus permet un mode « bus-activation » où un service est démarré par la réception d’un message lui étant destiné.
Concernant le réseau IP, c’est exactement ce que propose inetd
et ses successeurs depuis des années (en mode « wait »
). Le socket réseau est créé par inetd
. À la réception de données, le service est lancé déjà connecté au socket. La contrainte est que le service doit être capable de fonctionner sur un socket réseau déjà créé.
Résumé et Interlude
Par ce mécanisme, il est possible de démarrer tous les services en parallèle, sans aucun mécanisme de synchronisation. Il permet également de démarrer les services à la demande et non plus systématiquement. Ce système n’est pas nouveau, nous avons vu qu’
inetd
présentait déjà des aspects similaires. Apple a développé tous les points ci‐dessus dans son système Mac OS X, sous le nom de launchd. C’est cela qui permet à Mac OS X de démarrer très rapidement.
Le démarrage du système ne se limite pas au démarrage des services. La préparation des systèmes de fichiers est également une opération qui peut prendre beaucoup de temps. Il faut attendre que tous les périphériques listés dans « /etc/fstab »
soient créés, que chaque système de fichiers soit vérifié avec fsck, que le système soit monté et éventuellement que les quotas soient contrôlés.
Pour accélérer cela, Harald Hoyer a eu l’idée d’utiliser le système autofs
en mode direct. De la même façon que pour les sockets, autofs
permet de monter un pseudo système de fichiers à la place du système réel, et de ne basculer sur le vrai système qu’au moment où un accès est fait. Comme pour la création de sockets, le montage du pseudo système de fichiers est quasiment instantané.
Si un accès est fait alors que le système de fichiers n’est pas prêt (fsck
en cours, par exemple), alors le noyau bloque la requête (et celui qui l’a faite) jusqu’à ce que le système de fichiers soit disponible.
Pour la racine (« / »
), cela ne présente pas d’intérêt ; mais pour les grosses volumétries qui peuvent être montées sur « /home »
, ou pour des partitions de données qui ne sont pas nécessaires au démarrage du système, cela présente un gain important.
L’intégration de autofs
dans un système de démarrage peut faire peur à plus d’une personne. L’expérience montre que les processus bloqués par des fichiers qui ne sont pas disponibles peuvent être tués proprement, et qu’en cas d’erreur lors de la vérification du système de fichiers, il est possible de retourner une erreur au processus réclamant le fichier, de la même façon que cela se produit lorsqu’une partition tombe en erreur.
Les scripts sont rapides à coder, mais lents à exécuter. Tout le système de démarrage SysVinit est basé sur des scripts qui lancent des commandes externes. D’après Lennart cette approche est condamnée à être lente. Sur son système, les scripts dans « /etc/init.d/ »
appellent grep
au moins 77 fois, awk
l’est 92 fois, cut
, 23 fois, et sed
, 74 fois. À chaque appel, un processus doit être démarré, les bibliothèques résolues, la localisation initialisée, etc.. Après une manipulation de quelques octets, les données doivent être retournées à l’appelant via un descripteur de fichier et le processus est détruit. En outre, les scripts sont très sensibles à l’environnement et peu adaptés à la gestion des erreurs et des exceptions.
Tous ces scripts, ne faisant pour beaucoup que des tâches triviales, et contenant beaucoup de code dupliqué, auraient plutôt leur place dans le processus d’initialisation ou dans l’un de ses sous‐programmes. Tout ré‐écrire en C n’est pas pertinent ; mais le système devrait être capable de gérer bien plus de choses par lui‐même, sans faire appel à des scripts.
Une métrique intéressante est le PID du premier processus utilisable une fois le système démarré. Avec les noyaux actuels, cela donne une bonne idée du nombre de processus lancés. Amorcer le système, lancer un terminal, faire « echo $$ »
: sous Linux, le PID est 1823, sous Mac OS X c’est 154.
Une grosse part du mécanisme qui démarre les services devrait être la supervision : surveiller les services, pouvoir les identifier, redémarrer ceux qui plantent, collecter les traces.
Il devrait être capable de couper complètement un service. Cela semble facile mais est en réalité très difficile. Sous UNIX, un processus qui fait un double fork (le programme se relance lui‐même en tâche de fond) sort complètement de la supervision du processus qui l’a lancé. Prenons par exemple un script CGI lancé par un serveur Web. Lorsqu’il fait un double 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.
Pour résoudre ce problème, le noyau Linux implémente un mécanisme appelé cgroups
(control groups) qui, comme son nom l’indique, 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. Les cgroups
présentent un autre avantage (c’était leur objectif initial) : il est possible de placer certaines restrictions (processeur, mémoire, entrées‐sorties) afin de limiter la consommation d’un service dans sa globalité.
Un bon superviseur devrait également être capable de placer le service dans un environnement adapté et sécurisé. Jetez un coup d’œil aux scripts dans « /etc/init.d/ »
, tout le code dupliqué concerne le traitement des options, le changement d’utilisateur et de groupe, le réglage des paramètres de sécurité, la création d’un environnement avec une racine isolée (à l’aide de chroot
), la création d’un fichier contenant le PID, retrouver le processus pour lui envoyer un signal. Le même code, légèrement différent, se répète de script en script. Tout cela gagnerait à être normalisé et mutualisé.
Le système devrait permettre de régler les limites de ressources, la priorité, l’utilisateur et le groupe. Cela ne s’arrête pas là, le noyau Linux permet aussi de définir les capacités, les règles d’ordonnancement et d’entrées‐sorties, l’affinité avec les processeurs, supprimer l’accès en écriture à certaines partitions, et aussi tous les paramètres liés aux cgroups
.
Enfin, sous UNIX, tout processus a une sortie standard et une sortie d’erreur, qui sont la première source d’information en cas d’anomalie. Aujourd’hui, sur la majorité des distributions, ces données sont difficiles à récupérer, le système de démarrage devrait au contraire les conserver précieusement ; au moins en les redirigeant vers le service de journalisation des événements.
Second interlude : Upstart et les autres systèmes
Upstart est une grosse avancée par rapport à SysVinit. Il s’occupe du démarrage et de l’arrêt des services en fonction d’événements. Il gère tout un arbre de dépendances pour déterminer quoi démarrer et dans quel ordre, afin d’arriver à une situation cible. Malheureusement, cette gestion de dépendances demande de coder manuellement toutes les contraintes d’un service. Cela a plusieurs effets pervers :
- en cas d’anomalie, bien malin est celui qui retrouvera ce qui s’est produit et dans quel ordre ;
- le travail du système de démarrage a considérablement augmenté, puisqu’avant de démarrer quelque chose, il doit avoir constitué au moins une partie du graphe de dépendances ;
- il ne permet pas de réduire le démarrage aux services strictement nécessaires. Si un service (A) peut être utilisé par un autre (B), alors il doit être marqué comme dépendant et démarré avant le second (A ← B).
Lennart admet que certains de ces points sont en cours de correction, mais il s’agit de contournements du principe de fonctionnement d’Upstart. En dehors de SysVinit, Upstart et launchd (Mac OS X), un autre système mérite notre intérêt, c’est Solaris SMF. Il gère les dépendances entre les services, mais est très lié à Solaris et très complexe dans son fonctionnement (par exemple par son utilisation excessive de XML).
Ce qui a été décrit ci‐dessus est implémenté dans un système appelé systemd
qui est en cours d’adoption par plusieurs distributions GNU/Linux.
Le fonctionnement de systemd
est basé sur des unités (units) qui ont un nom et un type. Le nom correspond au nom du fichier décrivant l’unité.
Les types sont :
/etc/init.d/
;/etc/fstab
qui est utilisé directement ;multi-user.target
ou bluetooth.target
;udev
;cron
, en fonction de la date ;Toutes ces unités peuvent avoir des dépendances (Requires) et des conflits (Conflicts) déclarés de façon explicite.
cgroups
…stdout
et stderr
peuvent être redirigés vers le service de journalisation, vers « /dev/kmsg »
, vers un terminal ou vers un fichier.cgroup
.cgroup
, ce qui permet de fermer complètement une session et d’isoler un peu mieux les utilisateurs (processeur, mémoire).chkconfig
(de Red Hat) ainsi que celles de Debian et d’OpenSUSE sont utilisées lorsqu’elles sont disponibles. Sinon, l’ordre de démarrage dans « /etc/rc.d/ »
est utilisé. systemd est également capable de lire le fichier PID pour retrouver un service. Ces données permettent d’émuler une configuration classique SysVinit, facilitant la transition.« /etc/fstab »
est également lu comme s’il s’agissait d’un fichier de configuration de systemd
.systemd
masquent ces émulations, permettant de faire des paquets compatibles avec les deux systèmes, le nouveau masquant l’ancien si nécessaire.getty
des terminaux virtuels habituellement lancés).systemd
fourni une couche de compatibilité avec « /dev/initctl »
permettant d’utiliser les vieux binaires, tels que shutdown
ou reboot
. Les ordres sont transmis à systemd
via D-Bus. Il prend en charge également kexec
qui permet de relancer le noyau Linux.utmp
et wtmp
, les journaux système enregistrant les connexions.systemd
est capable de se ré‐exécuter lui‐même, afin de faire une mise à jour, ou de passer d’un processus provenant d’un « RAM‐disque » d’amorçage (initrd
) au système final. Tout l’état courant est migré d’un processus à l’autre.systemd
(/proc
, /sys
, /dev
), binfmt_misc
et HugeTBLfs
sont gérés via autofs
, ce qui évite d’avoir à les configurer en root
ou à charger le module correspondant.« systemd.confirm_spawn=1 »
.systemd
gère le readahead
qui permet d’optimiser les lectures disque au démarrage en pré‐chargeant les blocs qui vont être nécessaires par la suite (en se basant sur un enregistrement d’un démarrage précédent).L’administration se fait par l’intermédiaire de quelques commandes dédiées et quelques fichiers de configuration qui sont documentés via une vingtaine de pages de manuel. Un certain nombre de pages liées à l’utilisation de systemd
sont également modifiées.
Lorsque l’on regarde les scripts d’initialisation d’un service contenu dans le dossier « /etc/init.d »
, on constate que la plupart des scripts se ressemblent. L’information utile (programme à lancer, description du service, dépendances, niveaux de lancement) est complètement perdue dans le bruit généré par le code de gestion (création d’un fichier PID, s’assurer que le programme ne tourne pas déjà, gestion des cas d’utilisation…).
Systemd intègre toutes ces notions redondantes et permet à l’administrateur de définir un service de façon simple.
[Unit] Description=ABRT Automated Bug Reporting Tool After=syslog.target [Service] Type=dbus BusName=com.redhat.abrt ExecStart=/usr/sbin/abrtd -d -s [Install] WantedBy=multi-user.target
Ici, est défini le service ABRT. Comme on le voit, la définition est assez simple :
« /usr/sbin/abrtd -d -s »
;Regardons un autre exemple ressemblant un peu plus à ce que l’on a l’habitude de voir avec les scripts SysVinit :
[Unit] Description=Command Scheduler After=syslog.target [Service] EnvironmentFile=/etc/sysconfig/crond ExecStart=/usr/sbin/crond -n $CRONDARGS [Install] WantedBy=multi-user.target
Il est toujours possible de définir un fichier contenant les paramètres à passer au service :
$ cat /etc/sysconfig/crond ## Settings for the CRON daemon. ## CRONDARGS= : any extra command-line startup arguments for crond CRONDARGS=
Les fichiers de définition peuvent être trouvés dans les dossiers « /etc/systemd/ »
et « /lib/systemd/ »
. Le premier correspond à la configuration faite par l’administrateur, et le second aux fichiers livrés par la distribution.
Avec systemd
, la gestion des services se fait maintenant par l’utilitaire systemctl
.
Grâce à ce dernier, il est possible de lister toutes les unités présentes sur le système. Les commandes suivantes sont exécutées sur une distribution Fedora 15 :
$ systemctl list-units NIT LOAD ACTIVE SUB JOB DESCRIPTION
dev-hugepages.automount loaded active waiting Huge Pages File System Automount Point
dev-mqueue.automount loaded active waiting POSIX Message Queue File System Automount Point
proc-sys...misc.automount loaded active running Arbitrary Executable File Formats File System Automount Point
sys-kern...ebug.automount loaded active waiting Debug File System Automount Point
sys-kern...rity.automount loaded active waiting Security File System Automount Point
sys-devi...d-card0.device loaded active plugged N10/ICH 7 Family High Definition Audio Controller
sys-devi...et-eth0.device loaded active plugged BCM4313 802.11b/g LP-PHY
sys-devi...net-em2.device loaded active plugged RTL8101E/RTL8102E PCI Express Fast Ethernet controller
sys-devi...da-sda1.device loaded active plugged Hitachi_HTS725025A9A364
-.mount loaded active mounted /
boot.mount loaded active mounted /boot
home-spack-.gvfs.mount loaded active mounted /home/spack/.gvfs
home.mount loaded active mounted /home
media.mount loaded active mounted Media Directory
mcelog.service loaded active running Machine Check Exception Logging Daemon
mdmonitor.service loaded active running LSB: Start and stop the MD software RAID monitor
netfs.service loaded active exited LSB: Mount and unmount network filesystems.
NetworkManager.service loaded active running Network Manager
nfslock.service loaded active running LSB: Start up the NFS file locking sevice
ntpd.service loaded active running Network Time Service ntpdate.service loaded failed failed Set time via NTP
udev.service loaded active running udev Kernel Device Manager
dbus.socket loaded active running D-Bus System Message Bus Socket syslog.socket loaded active running Syslog Socket systemd-initctl.socket loaded active listening /dev/initctl Compatibility Named Pipe
systemd-logger.socket loaded active running Stdio Syslog Bridge Socket
systemd-shutdownd.socket loaded active listening Delayed Shutdown Socket
udev.socket loaded active running udev Kernel Device Manager Socket
sockets.target loaded active active Sockets sound.target loaded active active Sound Card
swap.target loaded active active Swap sysinit.target loaded active active System Initialization
syslog.target loaded active active Syslog
time-sync.target loaded active active System Time Synchronized
systemd-...ead-done.timer loaded active elapsed Stop Read-Ahead Data Collection 10s After Completed Startup
systemd-...es-clean.timer loaded active waiting Daily Cleanup of Temporary Directories
L’affichage a été réduit mais présente les différents éléments pris en compte par systemd
. On retrouve donc les différentes unités précédemment listées.
Vous constaterez que le service « ntpdate.service »
a échoué. Pour en savoir plus, nous pouvons utiliser la commande systemctl
suivie de l’argument « status »
et du nom de notre service :
$ systemctl status ntpdate.service ntpdate.service - Set time via NTP Loaded: loaded (/lib/systemd/system/ntpdate.service) Active: failed since Mon, 01 Aug 2011 16:01:49 +0200; 1h 58min ago Process: 741 ExecStart=/etc/init.d/ntpdate start (code=exited, status=1/FAILURE) CGroup: name=systemd:/system/ntpdate.service
On voit alors la commande exécutée et le code de retour renvoyé par le service : 1. Un coup d’œil au fichier « /var/log/messages »
nous en dira plus :
# grep ntpdate /var/log/messages Aug 1 16:01:49 spiro ntpdate[1654]: Can't find host 0.fedora.pool.ntp.org: Name or service not known (-2) Aug 1 16:01:49 spiro ntpdate[1654]: Can't find host 1.fedora.pool.ntp.org: Name or service not known (-2) Aug 1 16:01:49 spiro ntpdate[1654]: Can't find host 2.fedora.pool.ntp.org: Name or service not known (-2) Aug 1 16:01:49 spiro ntpdate[1654]: Can't find host 3.fedora.pool.ntp.org: Name or service not known (-2) Aug 1 16:01:49 spiro ntpdate[1654]: no servers can be used, exiting Aug 1 16:01:49 spiro systemd[1]: ntpdate.service: main process exited, code=exited, status=1 Aug 1 16:01:49 spiro systemd[1]: Unit ntpdate.service entered failed state.
À l’aide de systemctl
, il est bien sûr possible de démarrer, stopper et redémarrer les services. Voici, par exemple, comment l’on redémarre le service de prise en charge du Bluetooth :
# systemctl restart bluetooth.service
Nous avons vu que systemd
place chaque service dans un groupe distinct. Il serait donc intéressant d’identifier les différents groupes et les processus qu’ils contiennent. Pour cela, deux possibilités. Utiliser l’utilitaire ps
ou l’outil maison de systemd
: « systemd-cgls »
.
$ ps waxf -eo 'user,pid,cgroup,command' USER PID CGROUP COMMAND root 1 name=systemd:/system /sbin/init root 367 cpu:/system/systemd-logger. /lib/systemd/systemd-logger root 390 cpu:/system/udev.service;na /sbin/udevd root 544 cpu:/system/udev.service;na _ /sbin/udevd root 1450 cpu:/system/udev.service;na _ /sbin/udevd root 685 cpu:/system/abrtd.service;n /usr/sbin/abrtd -d -s root 694 cpu:/system/crond.service;n /usr/sbin/crond -n root 717 cpu:/system/rsyslog.service /sbin/rsyslogd -n -c 5 root 1086 cpu:/system/autofs.service; automount --pid-file /var/run/autofs.pid root 1127 cpu:/system/prefdm.service; /usr/sbin/gdm-binary -nodaemon root 1135 cpu:/system/prefdm.service; _ /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 root 1139 cpu:/system/prefdm.service; _ /usr/bin/Xorg :0 -background none -verbose -auth /var/run/gdm/auth-for-gdm-GWn7Er/database -n root 1352 name=systemd:/user/spack/1 _ pam: gdm-password spack 1374 name=systemd:/user/spack/1 _ gnome-session spack 1526 name=systemd:/user/spack/1 _ /usr/libexec/gnome-settings-daemon spack 1562 name=systemd:/user/spack/1 _ /usr/bin/gnome-shell spack 1786 name=systemd:/user/spack/1 | _ gnome-terminal spack 1791 name=systemd:/user/spack/1 | _ gnome-pty-helper spack 1792 name=systemd:/user/spack/1 | _ bash spack 1810 name=systemd:/user/spack/1 | _ bash spack 1823 name=systemd:/user/spack/1 | _ ps waxf -eo user,pid,cgroup,command spack 1569 name=systemd:/user/spack/1 _ gnome-power-manager spack 1574 name=systemd:/user/spack/1 _ nm-applet spack 1575 name=systemd:/user/spack/1 _ abrt-applet spack 1578 name=systemd:/user/spack/1 _ gnome-screensaver root 1151 cpu:/system/getty@.service/ /sbin/agetty tty2 38400 root 1152 cpu:/system/getty@.service/ /sbin/agetty tty6 38400 root 1155 cpu:/system/getty@.service/ /sbin/agetty tty4 38400 root 1159 cpu:/system/getty@.service/ /sbin/agetty tty3 38400 root 1160 cpu:/system/getty@.service/ /sbin/agetty tty5 38400
$ systemd-cgls ├ user │ └ spack │ └ 1 │ ├ 1352 pam: gdm-password │ ├ 1374 gnome-session │ ├ 1383 dbus-launch --sh-syntax --exit-with-session │ ├ 1384 /bin/dbus-daemon --fork --print-pid 5 --print-address 7 --session │ ├ 1445 /usr/libexec/gvfsd │ ├ 1521 /usr/libexec/gconfd-2 │ ├ 1526 /usr/libexec/gnome-settings-daemon │ ├ 1529 /usr/bin/pulseaudio --start │ ├ 1562 /usr/bin/gnome-shell │ ├ 1569 gnome-power-manager │ ├ 1574 nm-applet │ ├ 1575 abrt-applet │ ├ 1578 gnome-screensaver │ ├ 1583 /usr/libexec/dconf-service │ ├ 1786 gnome-terminal │ ├ 1791 gnome-pty-helper │ ├ 1792 bash │ └ 1809 systemd-cgls └ system ├ 1 /sbin/init ├ getty@.service │ ├ tty5 │ │ └ 1160 /sbin/agetty tty5 38400 │ ├ tty3 │ │ └ 1159 /sbin/agetty tty3 38400 │ ├ tty4 │ │ └ 1155 /sbin/agetty tty4 38400 │ ├ tty6 │ │ └ 1152 /sbin/agetty tty6 38400 │ └ tty2 │ └ 1151 /sbin/agetty tty2 38400 ├ prefdm.service │ ├ 1127 /usr/sbin/gdm-binary -nodaemon │ ├ 1135 /usr/libexec/gdm-simple-slave --display-id /org/gnome/DisplayManager/Display1 │ ├ 1139 /usr/bin/Xorg :0 -background none -verbose -auth /var/run/gdm/auth-for-gdm-GWn7Er/database -nolisten tcp vt1 │ └ 1363 /usr/bin/gnome-keyring-daemon --daemonize --login ├ autofs.service │ └ 1086 automount --pid-file /var/run/autofs.pid ├ dbus.service │ ├ 707 /bin/dbus-daemon --system --address=systemd: --nofork --systemd-activation │ ├ 720 /usr/libexec/polkit-1/polkitd │ ├ 750 /usr/sbin/modem-manager │ ├ 816 /usr/sbin/wpa_supplicant -c /etc/wpa_supplicant/wpa_supplicant.conf -B -u -f /var/log/wpa_supplicant.log -P /var/run/wpa_supplic... │ ├ 1037 /usr/libexec/colord │ ├ 1282 /usr/libexec/udisks-daemon │ ├ 1283 udisks-daemon: not polling any devices │ ├ 1288 /usr/libexec/upowerd │ └ 1559 /usr/libexec/packagekitd ├ crond.service │ └ 694 /usr/sbin/crond -n ├ rsyslog.service │ └ 717 /sbin/rsyslogd -n -c 5 ├ abrtd.service │ └ 685 /usr/sbin/abrtd -d -s ├ home.mount ├ boot.mount ├ fsck@.service ├ udev.service │ ├ 390 /sbin/udevd │ ├ 544 /sbin/udevd │ └ 1450 /sbin/udevd ├ systemd-logger.service │ └ 367 /lib/systemd/systemd-logger └ media.mount
Vous l’aurez constaté, systemd
gère non seulement les ressources du système, mais aussi celles des utilisateurs.
L’utilisation de systemd
simplifie un certain nombre de choses dans l’écriture d’un service :
chroot
; tout cela étant pris en charge par systemd
;cgroups
, il n’est plus nécessaire d’écrire un fichier PID permettant de retrouver le service via son identifiant de processus ;Ces recommandations sont très semblables à celles d’Apple pour utiliser launchd
. Pour les services écrits de façon classique, systemd
dispose de mécanismes de compatibilité afin de pouvoir les démarrer selon l’ancienne mode. Enfin, il est tout à fait possible — et recommandé — d’écrire des services qui fonctionnent dans tous les modes (autonomes ou systemd
), évitant de produire une version spéciale ou de créer une branche.
systemd
vient avec un kit d’intégration en C, qui facilite l’intégration dans un service. Lennart a publié deux notes de documentation et une page de manuel très complète :
Au travers de cet article vous a été présenté un sous‐ensemble des fonctionnalités offertes par systemd
. Il repense totalement la gestion des processus des systèmes basés sur le noyau Linux, et utilise pleinement les technologies offertes par ce dernier.
Plusieurs distributions intègrent ou vont intégrer systemd
. D’après l’article concernant systemd sur Wikipédia, il est utilisé depuis Fedora 15, et est optionnel dans Fedora 14. openSUSE prévoyait de l’intégrer dans la version 11.4, mais cela semble être repoussé à la 12.1. Mandriva 2011 est prévue avec. Arch Linux a un paquet expérimental. Debian a un paquet dans « unstable » et devrait permettre de choisir un système ou l’autre dans une prochaine version. Gentoo rend systemd
accessible dans « testing ». Le grand absent est Ubuntu, qui a beaucoup investi dans Upstart et n’a pas manifesté, pour l’instant, de volonté de passer à systemd
(bien qu’un début d’intégration existe).
Cet outil à tout faire, semble faire un pied de nez à la philosophie d’UNIX en combinant plusieurs fonctions en un seul programme. D’un autre côté, le système de démarrage actuel montre ses limites.
La gestion de l’initialisation est très importante pour le système. On peut donc se demander s’il est judicieux d’inclure tant de fonctionnalités dans un programme critique ? Cependant, avec les contraintes de performances et la complexité des systèmes actuels, n’est‐ce pas un mal nécessaire pour gérer efficacement les processus exécutés sur nos systèmes ?
L’installation de SystemD se fait en deux temps. Tout d’abord installez le paquet
apt-get install systemd
Les options suivantes du noyau doivent être positionnées comme ci-dessous
Ensuite on va changer le démarrage afin de remplacer init par systemd, ouvrez le fichier /etc/default/grub et éditez la ligne suivante:
GRUB_CMDLINE_LINUX_DEFAULT="quiet init=/bin/systemd"
Tapez ensuite la commande de mise à jour de grub:
update-grub
Redémarrez maintenant le système.
On va maintenant remplacer sysvinit par celui de systemD. Faites d’abord une copie de init puis installez le paquet systemd-sysv à la place. Lors de la désinstallation il vous sera demandé d’inscrire que vous êtes conscient que vous faites une erreur, normal vu que vous allez remplacer le système de chargement du système.
cp -av /sbin/init /sbin/init.sysvinit
apt-get remove sysvinit
apt-get install systemd-sysv
Redémarrez de nouveau.
Voilà vous êtes désormais passé de init à systemD
Nous allons maintenant changer quelques options intéressantes. Ouvrez le fichier /etc/systemd/system.conf et ajustez les valeurs suivantes:
CPUAffinity 1 2 3 4
MountAuto=yes
SwapAuto=yes
Il est intéressant de mettre le montage automatique des partitions et du swap, ainsi chacun ne sera monté qu’à la demande. En ce qui concerne l’option CPU affinity, elle indique à systemd sur quels processeurs (cores de processeurs) se greffer. Ici nous l’avons mis sur les 4 coeurs de processeur. Par défaut il n’en utilise au maximum que 2.