Cosa fa esattamente init?


43

Sto creando una distribuzione Linux e ora ho bisogno di un programma init. Riesco a scrivere il codice in c molto bene e conosco un po 'di Linux (non molto, ma sto usando Arch Linux per lo sviluppo da 4 anni), quindi ho pensato di provare a scrivere il mio script init di base in C. chiedo solo, quali attività fa init per configurare il sistema per una semplice shell? (Quando chiedo "cosa fa init?", So cos'è init e a cosa serve. Semplicemente non so quali compiti svolge.)

Non ho bisogno di codice e che forse non hanno nemmeno bisogno comandi di base, ma io non bisogno nell'ordine in cui vengono eseguiti in.


1
Puoi usare qualsiasi interprete che ti piace per gli script di init in stile SysV, inclusi Perl, awk, bash, (t) csh, binari nativi, ... Bash è normalmente usato perché è praticamente garantito per essere disponibile sul sistema in cui tali script sono distribuito nel punto rilevante del processo di avvio, non perché esiste un accoppiamento tra SysVinit e bash. SysVinit definisce il contratto e ogni script è libero di implementare quel contratto nel modo che lo sviluppatore ritiene opportuno.
un CVn

Risposte:


53

System 5 initti 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 inite System 5 rcrisalgono 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 gettyprocessi, montato 3 filesystem cablati da una tabella integrata ed eseguito direttamente un programma dalla directory home di un nome utente mel. La gettytabella 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+ rce 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/ rcnon è 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 initiniziano.
  • 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 gettygenerazione 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.initcui 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 svscancome 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 srcmstrprogramma IBM AIX , System Resource Controller
  • Gerrit Pape è runsvdirdi Runit
  • Daniel J. Bernstein è svscanda daemontools, di Adam Sampson svscandal freedt , di Bruce Guenter svscanda daemontools-bis, e Laurent Bercot di s6-svscanda s6
  • Wayne Marshall è perpddel perp
  • il Service Management Facility in Solaris 10
  • il service-managerda nosh

Allo stesso modo, come spiegato su https://superuser.com/a/888936/38062 , l'intera /dev/initctlidea 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, SIGWINCHe 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 SIGUSR1hanno 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 initprima 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/shnon 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-managerprogramma 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-managerprogramma, 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.


3
Risposta eccezionale e molto istruttiva. Ma mi chiedo dove sia in questa grande immagine OSX launchd. A volte le persone dimenticano completamente che OSX è un (fantastico) membro della grande famiglia * nix.
DavAlPi,

4

System V init su Debian (ci sono altre varianti e varianti) fa quanto segue:

  • Quando si inserisce un runlevel, chiama gli script in /etc/rcX.d/S*ordine alfanumerico, dove si Xtrova il runlevel. Questi script dovrebbero impostare il runlevel. L'installazione tipica è l'avvio dei demoni ed esegue attività di installazione per quel livello di esecuzione. Questa è una cosa da fare una volta quando entri nel runlevel.
  • Mentre si trova a un livello di esecuzione, avvia demoni elencati in /etc/inittabcome devono essere attivi durante quel livello di esecuzione. Se quei demoni smettono di funzionare, li riavvia. Sebbene tu possa avere qualsiasi demone che vuoi gestire init, almeno ne vuoi alcuni in gettymodo da poter effettuare l'accesso. gettyEsce una volta completato l'accesso, quindi lo initriavvia, fornendo un nuovo prompt di accesso.
    • Se il daemon si riavvia troppe volte in un tempo troppo breve, smette di provare a riavviarlo per un po '.
    • Solo perché qualcosa è stato avviato dagli script di kickoff quando si entra nel livello di esecuzione non si inittenta automaticamente di mantenerlo in esecuzione. Devi specificarlo separatamente in /etc/inittab.
  • Quando si esce da un runlevel, chiama gli script in /etc/rcX.d/K*ordine alfanumerico, dove si Xtrova il runlevel. Un modo per implementare l'arresto o il riavvio è definire un runlevel per quegli eventi e rendere l'ultimo task eseguito il comando halto reboot.
  • Chiamerà eseguibili in risposta a determinati eventi, come eventi di potenza o Ctrl-Alt-Canc.
  • Ascolta su un socket, se riceve determinati messaggi cambierà il runlevel.

Quindi init, se lo desideri, puoi utilizzare come rudimentale service manager, ma al giorno d'oggi il compito principale è di mantenerlo gettydisponibile in modo che un utente possa effettuare il login e dare il via alle transizioni di runlevel.

Mi stavo solo chiedendo, quali compiti fa init per configurare il sistema per una semplice shell?

Tutto quello che vuoi. Su Debian, in ogni /etc/rcX.ddirectory è presente un collegamento simbolico a uno script /etc/init.de puoi personalizzare o rimuovere completamente quegli script. L'ordine è stabilita dalla precedente ogni script con un 00, 01ecc

Puoi anche specificare -bun'opzione su init(cioè tramite la riga di comando del kernel) se vuoi solo initgenerare una shell. Quando esci dalla shell, initmuore e quando initmuore, il kernel sarà preso dal panico.


2

Il minimo indispensabile che deve fare init è eseguire almeno un altro programma e non uscire mai. Se init esce, il sistema si arresta in modo anomalo. Suppongo che anche eseguire un altro programma non sia strettamente necessario, ma se non lo fai, init dovrebbe essere responsabile di fare tutto ciò che il sistema dovrebbe fare, o non sarebbe molto utile.


1
Ho avuto sistemi Linux difettosi in cui il PID 1 si è arrestato in modo anomalo ma il sistema ha continuato a funzionare. La gravità dell'arresto anomalo del PID 1 può dipendere dalla versione del kernel.
Gilles 'SO- smetti di essere malvagio' il

1

init puoi fare quello che vuoi

init è un eseguibile arbitrario chiamato dal kernel Linux al termine del processo di avvio (e l'unico eseguibile di questo tipo).

Normalmente è implementato come eseguibile ELF, ma può anche essere uno script di shell con chmod +x: Init come script di shell

Le implementazioni tipiche come sysemd leggeranno i file di configurazione, /etc/initrcquindi, e quindi eseguiranno il fork di una serie di processi userland basati su tali configurazioni, per implementare vari aspetti del sistema.

Tuttavia, questo è completamente specifico per l'implementazione e pertanto non è possibile rispondere alla domanda senza specificare un'implementazione specifica. Ad esempio, ho giocato con un initprocesso che fa semplicemente una rebootscala di messaggi per scopi educativi.

Il kernel Linux cerca semplicemente l'eseguibile sul percorso /initper impostazione predefinita, ma questo può essere sovrascritto dal init=parametro della riga di comando del kernel Linux.

Un ottimo modo per giocare initè usare QEMU, dal momento che puoi passare i parametri della riga di comando del kernel a QEMU dalla riga di comando QEMU con l' -appendopzione e senza il timore di creare il tuo desktop.

Ecco la mia configurazione minima completamente automatizzata di Buildroot + QEMU che rende molto facile giocare con i tuoi dati per demistificare la questione.


0

Se sei impegnato nel principio modulare "fai una cosa e fallo bene", allora un initprogramma dovrebbe iniziare i processi.

Avvia i processi

Dovrebbe essere eseguito dopo che il kernel è stato decompresso con successo, occupandosi di tutte le attività elementari coinvolte nell'inizializzazione di tutti i processi iniziali che un sistema richiede di operare (come montare unità trovate in / etc / fstab, far apparire interfacce di rete e presto).

Poiché il processo di avvio e spegnimento sono essenzialmente inversi l'uno dall'altro, è comune che un programma init assicuri anche che i processi vengano arrestati con un comando di arresto.

Arresta i processi

Ciò significa che deve arrestare i processi in base alla pagina man di quel processo (in altre parole, non solo palesemente kill -9, dovrebbe abbattere il processo nel modo in cui vuole essere terminato), smontare le unità e infine emettere il comando di spegnimento finale .

Riferimenti

Un buon riferimento a come questo viene fatto dagli altri è quello di guardare gli script /etc/rc.d di Slackware e anche un semplice sistema init che esiste già, come ninit (un successore del minit). Ha la supervisione del processo (nel senso che se un processo muore, viene riavviato), che probabilmente non è il lavoro di init, ma è ancora abbastanza semplice e semplice da capire, specialmente attraverso gli script di esempio dell'autore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.