System 5 init
ti dirà solo una piccola parte della storia.
C'è una sorta di miopia che colpisce il mondo Linux. Le persone pensano di usare una cosa chiamata "Sistema 5 init
", che è sia ciò che è tradizionale sia il posto migliore da cui iniziare. Né è in effetti il caso.
La tradizione non è in realtà ciò che dicono queste persone, tanto per cominciare. System 5 init
e System 5 rc
risalgono ad AT&T UNIX System 5, che era quasi dopo il primo UNIX come lo siamo ora (diciamo) dopo la prima versione di Linux-Mandrake.
1a edizione UNIX aveva solo init
. Non aveva rc
. Il linguaggio assembly della 1a Edizione init
(il cui codice è stato ripristinato e reso disponibile da Warren Toomey et al. ) Ha generato e rigenerato direttamente 12 getty
processi, montato 3 filesystem cablati da una tabella integrata ed eseguito direttamente un programma dalla directory home di un nome utente mel
. La getty
tabella era anche direttamente nell'immagine del programma.
Fu un altro decennio dopo UNIX System 5 che arrivò il cosiddetto sistema init Linux "tradizionale". Nel 1992, Miquel van Smoorenburg (ri) scrisse un Linux init
+ rc
e i loro strumenti associati, che la gente ora chiama "Sistema 5 init
", anche se in realtà non è il software di UNIX System 5 (e non è solo init
).
System 5 init
/ rc
non è il punto migliore da cui iniziare, e anche se si aggiunge la conoscenza di systemd che non copre la metà di ciò che c'è da sapere. C'è stato molto lavoro nell'area della progettazione di sistemi init (per Linux e BSD) che è avvenuto solo negli ultimi due decenni. Sono state discusse, prese, progettate, implementate e messe in pratica ogni sorta di decisione ingegneristica. Anche gli Unices commerciali hanno fatto molto.
Sistemi esistenti per studiare e da cui imparare
Ecco un elenco incompleto di alcuni dei principali sistemi init diversi da questi due e uno o due dei loro (diversi) punti salienti:
- La finzione di Joachim Nilsson ha seguito la strada dell'uso di un file di configurazione più leggibile dall'uomo.
- L' aspetto positivo di Felix von Leitner è andato per un sistema di configurazione filesystem-is-the-database, piccole impronte di memoria e dipendenze di avvio / arresto tra le cose che
init
iniziano.
- Il runit di Gerrit Pape è andato per quello che ho precedentemente descritto come l' approccio a quattro shell shell appena generato .
- InitNG mirava ad avere dipendenze, destinazioni nominate, più file di configurazione e una sintassi di configurazione più flessibile con un intero carico di più impostazioni per i processi figlio.
- upstart ha optato per una riprogettazione completa, modellando il sistema non come servizi e interdipendenze, ma come eventi e lavori innescati da essi.
- Il design di nosh include l' inserimento di tutta la gestione del servizio (compresi persino la
getty
generazione di zombi e la generazione) in un gestore di servizi separato, e la semplice gestione di dispositivi / link simbolici / directory "API" specifici del sistema operativo.
- sinit è un init molto semplice. Esegue il
/bin/rc.init
cui compito è avviare programmi, montare filesystem, ecc. Per questo puoi usare qualcosa come minirc .
Inoltre, circa 10 anni fa, ci sono state discussioni tra gli utenti di daemontools e altri sull'utilizzo svscan
come processo n. 1, che ha portato a progetti come lo svscan di Paul Jarc come studio del processo 1 , le idee di Gerrit Pape e lo svscan di Laurent Bercot come processo 1 .
Il che ci porta a ciò che fanno i programmi di processo n. 1.
Cosa fanno i programmi di processo n. 1
Le nozioni di ciò che il processo n. 1 è "supposto" da fare sono per natura soggettive. Un criterio progettuale oggettivo significativo è ciò che il processo n. 1 deve fare almeno . Il kernel impone diversi requisiti su di esso. E ci sono sempre alcune cose specifiche del sistema operativo di vario genere che deve fare. Quando si tratta di ciò che tradizionalmente ha fatto il processo n. 1 , allora non siamo al minimo e non lo siamo mai stati.
Ci sono molte cose che vari kernel del sistema operativo e altri programmi richiedono al processo n. 1 che semplicemente non si può sfuggire.
La gente ti dirà che fork()
l'ingegnerizzazione dei processi orfani è la funzione principale del processo n. 1. Ironia della sorte, questo non è vero. Gestire i processi orfani è (con i recenti kernel Linux, come spiegato in https://unix.stackexchange.com/a/177361/5132 ) una parte del sistema che si può in gran parte escludere dal processo n. 1 in altri processi, come un service manager dedicato . Tutti questi sono gestori di servizi, che si esauriscono con il processo n. 1:
- il
srcmstr
programma IBM AIX , System Resource Controller
- Gerrit Pape è
runsvdir
di Runit
- Daniel J. Bernstein è
svscan
da daemontools, di Adam Sampson svscan
dal freedt , di Bruce Guenter svscan
da daemontools-bis, e Laurent Bercot di s6-svscan
da s6
- Wayne Marshall è
perpd
del perp
- il Service Management Facility in Solaris 10
- il
service-manager
da nosh
Allo stesso modo, come spiegato su https://superuser.com/a/888936/38062 , l'intera /dev/initctl
idea non deve necessariamente avvicinarsi al processo n. 1. Ironia della sorte, è il sistema altamente centralizzato che dimostra che può essere spostato dal processo n. 1.
Al contrario, le cose obbligatorie per init
, che la gente di solito dimenticano nei loro progetti off-the-top-of-the-testa, sono cose come la manipolazione SIGINT
, SIGPWR
, SIGWINCH
e così via inviati dal kernel e promulgare le varie richieste di modifica dello stato del sistema inviati da programmi che "sanno" che certi segnali per elaborare il n. 1 significano certe cose. (Ad esempio: come spiegato in https://unix.stackexchange.com/a/196471/5132 , i set di strumenti BSD "sanno" che SIGUSR1
hanno un significato specifico.)
Esistono anche attività di inizializzazione e finalizzazione una tantum a cui non si può sfuggire, o che soffriranno molto per non farlo, come montare filesystem "API" o svuotare la cache del filesystem.
Le basi della gestione dei filesystem "API" sono leggermente diverse rispetto al funzionamento della init
prima edizione di UNIX: Uno ha un elenco di informazioni cablate nel programma e uno semplicemente mount()
tutte le voci nell'elenco. Troverai questo meccanismo in sistemi diversi come BSD (sic!) init
, Attraverso il nosh system-manager
, a systemd.
"imposta il sistema per una semplice shell"
Come hai osservato, init=/bin/sh
non ottiene i file system "API" montati, si arresta in modo sgraziato senza svuotare la cache quando si digita exit
( https://unix.stackexchange.com/a/195978/5132 ), e in generale lo lascia all'utente (super) di eseguire manualmente le azioni che rendono il sistema minimamente utilizzabile.
Per vedere ciò che in realtà non si ha altra scelta che fare nei processi n. 1, e quindi metterti sulla buona strada per il tuo obiettivo di design dichiarato, la tua migliore opzione è quella di guardare le sovrapposizioni nell'operazione della runit di Gerrit Pape, Felix von L'aspetto di Leitner e il system-manager
programma dal pacchetto nosh. I primi due mostrano due tentativi di essere minimalisti, eppure gestiscono ancora le cose che è impossibile evitare.
Quest'ultimo è utile, suggerisco, per la sua ampia immissione manuale per il system-manager
programma, che dettaglia esattamente quali file system "API" sono montati, quali attività di inizializzazione vengono eseguite e quali segnali vengono gestiti; in un sistema che per impostazione predefinita il gestore di sistema ha appena generato altre tre cose (il gestore del servizio, un logger di accompagnamento e il programma per eseguire i cambiamenti di stato) e fa solo l'inevitabile nel processo n. 1.