Système 5 init
ne vous racontera qu'une petite partie de l'histoire.
Il y a une sorte de myopie qui affecte le monde Linux. Les gens pensent qu'ils utilisent une chose appelée "System 5 init
", et c'est à la fois ce qui est traditionnel et le meilleur endroit pour commencer. Ni l'un ni l'autre n'est en fait le cas.
La tradition n'est en fait pas ce que ces gens disent qu'elle est, pour commencer. Système 5 init
et Système 5 rc
date d'AT&T UNIX System 5, qui était presque aussi loin après le premier UNIX que nous le sommes maintenant (disons) après la première version de Linux-Mandrake.
La 1ère édition d'UNIX n'avait que init
. Il n'avait pas rc
. Le langage d'assemblage de la 1ère édition init
(dont le code a été restauré et mis à disposition par Warren Toomey et al.) directement engendré et réapparu 12 getty
processus, monté 3 systèmes de fichiers câblés à partir d'une table intégrée et exécuté directement un programme à partir du répertoire personnel d'un utilisateur nommé mel
. Le getty
table était également directement dans l'image du programme.
Ce n'est qu'une décennie après UNIX System 5 que le soi-disant système d'initialisation Linux "traditionnel" est apparu. En 1992, Miquel van Smoorenburg a (ré)écrit un Linux init
+rc
, et leurs outils associés, que les gens appellent désormais "System 5 init
", même s'il ne s'agit pas réellement du logiciel d'UNIX System 5 (et non seulement de init
).
Système 5 init
/rc
n'est pas le meilleur endroit pour commencer, et même si l'on ajoute des connaissances sur systemd, cela ne couvre pas la moitié de ce qu'il y a à savoir. Il y a eu beaucoup de travail dans le domaine de la conception du système init (pour Linux et les BSD) au cours des deux dernières décennies seulement. Toutes sortes de décisions d'ingénierie ont été discutées, prises, conçues, mises en œuvre et mises en pratique. Les Unix commerciaux ont fait beaucoup aussi.
Systèmes existants à étudier et à partir desquels apprendre
Voici une liste incomplète de certains des principaux systèmes d'initialisation autres que ces deux, et un ou deux de leurs (plusieurs) points saillants :
- Le fini de Joachim Nilsson a choisi d'utiliser un fichier de configuration plus lisible par l'homme.
- Le minit de Felix von Leitner a opté pour un système de configuration du système de fichiers est la base de données, de petites empreintes mémoire et des dépendances de démarrage/arrêt parmi des choses qui
init
démarre. - Le runit de Gerrit Pape a opté pour ce que j'ai décrit précédemment comme les quatre scripts shell juste générés approche.
- InitNG avait pour objectif d'avoir des dépendances, des cibles nommées, plusieurs fichiers de configuration et une syntaxe de configuration plus flexible avec beaucoup plus de paramètres pour les processus enfants.
- upstart a opté pour une refonte complète, modélisant le système non pas comme des services et des interdépendances, mais comme des événements et des tâches déclenchés par eux.
- La conception de nosh inclut la suppression de toute la gestion des services (y compris même le
getty
frai et récolte de zombies) dans un gestionnaire de services séparé, et juste gestion des périphériques/liens symboliques/répertoires et événements système "API" spécifiques au système d'exploitation. - sinit est un init très simple. Il exécute
/bin/rc.init
dont le travail consiste à démarrer des programmes, monter un système de fichiers, etc. Pour cela, vous pouvez utiliser quelque chose comme minirc.
De plus, il y a environ 10 ans, il y avait des discussions entre les utilisateurs de daemontools et d'autres sur l'utilisation de svscan
as process #1, qui a conduit à des projets comme l'étude svscan as process 1 de Paul Jarc, les idées de Gerrit Pape et l'étude svscan as process 1 de Laurent Bercot.
Ce qui nous amène au processus n°1 des programmes.
Ce que font les programmes du processus 1
Les notions de ce que le processus #1 est "censé" faire sont par nature subjectives. Un objectif significatif le critère de conception est ce que le processus #1 doit au minimum fais. Le noyau lui impose plusieurs exigences. Et il y a toujours des choses spécifiques au système d'exploitation de différentes sortes qu'il doit faire. En ce qui concerne le processus n° 1 traditionnellement fait, alors nous ne sommes pas à ce minimum et ne l'avons jamais vraiment été.
Il y a plusieurs choses que divers noyaux de système d'exploitation et d'autres programmes exigent du processus n°1 auxquelles on ne peut tout simplement pas échapper.
Les gens vous diront que fork()
ing choses et agir en tant que parent de processus orphelins est la fonction première du processus #1. Ironiquement, c'est faux. La gestion des processus orphelins est (avec les noyaux Linux récents, comme expliqué sur https://unix.stackexchange.com/a/177361/5132) une partie du système que l'on peut largement exclure du processus n ° 1 dans d'autres processus, tels que un responsable de service dédié . Ce sont tous des gestionnaires de service, qui s'exécutent en dehors du processus 1 :
- l'IBM AIX
srcmstr
programme, le contrôleur de ressources système - Le
runsvdir
de Gerrit Pape de runit - Le
svscan
de Daniel J. Bernstein de daemontools,svscan
d'Adam Sampson de freedt, lesvscan
de Bruce Guenter de daemontools-encore, et les6-svscan
de Laurent Bercot depuis s6 - Le
perpd
de Wayne Marshall du perp - la fonction de gestion des services dans Solaris 10
- le
service-manager
de nosh
De même, comme expliqué sur https://superuser.com/a/888936/38062, l'ensemble /dev/initctl
l'idée n'a pas besoin d'être proche du processus #1. Ironiquement, c'est le systemd hautement centralisé qui démontre qu'il peut être retiré du processus #1.
Inversement, les choses obligatoires pour init
, que les gens oublient généralement dans leurs conceptions improvisées, sont des choses telles que la gestion de SIGINT
, SIGPWR
, SIGWINCH
, et ainsi de suite envoyés depuis le noyau et exécutant les diverses demandes de changement d'état du système envoyées par des programmes qui "savent" que certains signaux au processus #1 signifient certaines choses. (Par exemple :comme expliqué sur https://unix.stackexchange.com/a/196471/5132, les outils BSD "savent" que SIGUSR1
a une signification spécifique.)
Il existe également des tâches d'initialisation et de finalisation ponctuelles auxquelles on ne peut pas échapper ou qui souffriront grandement de ne pas les faire, telles que le montage de systèmes de fichiers "API" ou le vidage du cache du système de fichiers.
Les bases de la gestion des systèmes de fichiers "API" sont peu différentes du fonctionnement de init
rom 1st Edition UNIX :l'un a une liste d'informations câblées dans le programme, et l'autre simplement mount()
s toutes les entrées de la liste. Vous trouverez ce mécanisme dans des systèmes aussi divers que BSD (sic !) init
, par le nez system-manager
, à systemd.
"configurer le système pour un simple shell"
Comme vous l'avez observé, init=/bin/sh
n'obtient pas les systèmes de fichiers "API" montés, se bloque de manière disgracieuse sans vidage du cache lorsque l'on tape exit
(https://unix.stackexchange.com/a/195978/5132), et laisse en général au (super)utilisateur le soin d'effectuer manuellement les actions qui rendent le système minimalement utilisable.
Pour voir ce que l'on n'a réellement d'autre choix que de faire dans les programmes de processus n ° 1, et ainsi vous mettre sur la bonne voie pour atteindre votre objectif de conception déclaré, votre meilleure option est d'examiner les chevauchements dans le fonctionnement du runit de Gerrit Pape, Felix von minit de Leitner et le system-manager
programme du paquet nosh. Les deux premiers montrent deux tentatives d'être minimalistes, tout en gérant les choses qu'il est impossible d'éviter.
Ce dernier est utile, je suggère, pour sa saisie manuelle étendue pour le system-manager
programme, qui détaille exactement quels systèmes de fichiers "API" sont montés, quelles tâches d'initialisation sont exécutées et quels signaux sont gérés ; dans un système qui par conception fait que le gestionnaire du système génère trois autres choses (le gestionnaire de service, un enregistreur d'accompagnement et le programme pour exécuter les changements d'état) et ne fait que l'inévitable dans le processus n° 1.
System V init sur Debian (il existe d'autres variantes et variantes) fait ce qui suit :
- Lors de la saisie d'un niveau d'exécution, il appelle des scripts en
/etc/rcX.d/S*
par ordre alphanumérique, oùX
est le niveau d'exécution. Ces scripts doivent configurer le niveau d'exécution. La configuration typique consiste à démarrer des démons et à effectuer des tâches de configuration pour ce niveau d'exécution. Il s'agit d'une action unique effectuée lors de l'entrée dans le niveau d'exécution. - Dans un niveau d'exécution, il démarre les démons qui sont répertoriés dans le
/etc/inittab
comme devant être actif pendant ce niveau d'exécution. Si ces démons cessent de fonctionner, il les redémarre. Alors que vous pouvez avoir n'importe quel démon que vous voulez géré parinit
, vous voulez au minimum quelquesgetty
's pour que vous puissiez vous connecter.getty
quitte une fois la connexion terminée, puisinit
le redémarre, en fournissant une nouvelle invite de connexion.
- Si le démon redémarre trop de fois en trop peu de temps, il arrête d'essayer de le redémarrer pendant un moment.
- Ce n'est pas parce que quelque chose a été démarré par les scripts de démarrage lors de l'entrée dans le niveau d'exécution que
init
essaie automatiquement de le faire fonctionner. Vous devez le spécifier séparément dans le/etc/inittab
.
- Lors de la sortie d'un niveau d'exécution, il appelle des scripts en
/etc/rcX.d/K*
dans l'ordre alphanumérique, oùX
est le niveau d'exécution. Une façon d'implémenter l'arrêt ou le redémarrage consiste à définir un niveau d'exécution pour ces événements et à faire de la dernière tâche exécutée lehalt
oureboot
commande. - Il appellera des exécutables en réponse à certains événements, tels que des événements d'alimentation ou Ctrl-Alt-Suppr.
- Il écoute sur un socket, s'il reçoit certains messages il changera de niveau d'exécution.
Vous pouvez donc utiliser init
en tant que gestionnaire de service rudimentaire si vous le souhaitez, mais sa tâche principale de nos jours est de conserver getty
est disponible pour qu'un utilisateur puisse se connecter et lancer des transitions de niveau d'exécution.
Je me demandais simplement quelles tâches effectue init pour configurer le système pour un simple shell ?
Tout ce que vous voulez. Sur Debian, dans chaque /etc/rcX.d
répertoire est un lien symbolique vers un script dans /etc/init.d
et vous pouvez entièrement personnaliser ou supprimer ces scripts. L'ordre est établi en faisant précéder chaque script d'un 00
, 01
, etc.
Vous pouvez également spécifier un -b
option à init
(c'est-à-dire via la ligne de commande du noyau) si vous voulez juste init
pour faire apparaître un coquillage. Lorsque vous quittez le shell, init
meurt et quand init
meurt, le noyau va paniquer.
Le strict minimum absolu que doit faire init est d'exécuter au moins un autre programme et de ne jamais quitter. Si init se termine, le système plante. Je suppose que même l'exécution d'un autre programme n'est pas strictement nécessaire, mais si vous ne le faites pas, init devrait être responsable de tout ce que le système est censé faire, sinon ce ne serait pas très utile.