Systém 5 init
vám řekne jen malou část příběhu.
Existuje určitý druh krátkozrakosti, který ovlivňuje svět Linuxu. Lidé si myslí, že používají věc zvanou „System 5 init
“, a to je jak tradiční, tak i nejlepší místo, kde začít. Ve skutečnosti tomu tak není ani jedno.
Tradice ve skutečnosti není to, co tito lidé říkají, že je, pro začátek. Systém 5 init
a System 5 rc
od AT&T UNIX System 5, což bylo téměř tak daleko po prvním UNIXu, jako jsme nyní (řekněme) po první verzi Linux-Mandrake.
1. vydání UNIX měl pouze init
. Neměl rc
. Jazyk sestavení 1. vydání init
(jehož kód byl obnoven a zpřístupněn Warrenem Toomey et al.) přímo spawnoval a respawnoval 12 getty
procesy, připojil 3 pevně připojené souborové systémy z vestavěné tabulky a přímo spustil program z domovského adresáře uživatele jménem mel
. getty
tabulka byla také přímo v obrazu programu.
Bylo to další desetiletí po UNIX System 5, kdy přišel takzvaný „tradiční“ iniciační systém Linux. V roce 1992 Miquel van Smoorenburg (re-)napsal Linux init
+rc
a jejich přidružené nástroje, které nyní lidé označují jako "System 5 init
", i když to ve skutečnosti není software z UNIX System 5 (a není to jen init
).
Systém 5 init
/rc
není to nejlepší místo, kde začít, a i když se přidá znalost systemd, nepokrývá polovinu toho, co je potřeba vědět. Jen v posledních dvou desetiletích bylo v oblasti návrhu init systému (pro Linux a BSD) vykonáno mnoho práce. Byly prodiskutovány, provedeny, navrženy, implementovány a praktikovány nejrůznější inženýrská rozhodnutí. Hodně toho udělal i komerční Unices.
Stávající systémy ke studiu a učení se
Zde je neúplný seznam některých hlavních init systémů jiných než ty dva a jeden nebo dva z jejich (několika) hlavních bodů:
- Finit Joachima Nilssona se vydal cestou použití konfiguračního souboru lépe čitelného pro člověka.
- Minit Felixe von Leitnera se zaměřil na konfigurační systém filesystem-is-the-database, malé nároky na paměť a závislosti start/stop mezi věcmi, které
init
začíná. - Runit Gerrita Papea sloužil k tomu, co jsem dříve popsal jako právě vytvořené čtyři skripty shell přístup.
- Cílem InitNG bylo mít závislosti, pojmenované cíle, více konfiguračních souborů a flexibilnější konfigurační syntaxi s celou řadou dalších nastavení pro podřízené procesy.
- Počátečníci šli do úplného přepracování a modelovali systém nikoli jako služby a vzájemné závislosti, ale jako události a úlohy jimi spouštěné.
- Návrh nosh zahrnuje vytlačení veškeré správy služeb (včetně
getty
spawnování a sklízení zombie) do samostatného správce služeb a jen zpracování zařízení/symlinků/adresářů a systémových událostí specifických pro operační systém. - sinit je velmi jednoduchý init. Provede
/bin/rc.init
jehož úkolem je spouštět programy, připojovat souborový systém atd. K tomu můžete použít něco jako minirc.
Navíc asi před 10 lety proběhla diskuze mezi uživateli daemontools a ostatními o použití svscan
jako proces č. 1, který vedl k projektům jako svscan Paula Jarca jako studie procesu 1, nápady Gerrita Papea a svscan Laurenta Bercota jako proces 1.
Což nás přivádí k tomu, co programy č. 1 dělají.
Jaký proces dělají programy č. 1
Představy o tom, co proces #1 „má“ dělat, jsou ze své podstaty subjektivní. Smysluplný cíl kritériem návrhu je to, co proces č. 1 minimálně musí dělat. Jádro na něj klade několik požadavků. A vždy existují určité věci různého druhu specifické pro operační systém, které musí dělat. Když přijde na to, jaký proces #1 má tradičně hotovo, pak nejsme na tomto minimu a nikdy ve skutečnosti nebyli.
Existuje několik věcí, které různá jádra operačního systému a další programy vyžadují od procesu č. 1, kterým prostě nelze uniknout.
Lidé vám řeknou, že fork()
vkládání věcí a vystupování jako rodič osiřelých procesů je hlavní funkcí procesu č. 1. Je ironií, že to není pravda. Zacházení s osiřelými procesy je (s nedávnými linuxovými jádry, jak je vysvětleno na https://unix.stackexchange.com/a/177361/5132) součástí systému, kterou lze do značné míry vyřadit z procesu č. 1 do jiných procesů, jako je např. specializovaný správce služeb . Všichni tito jsou správci služeb, kterým běží proces #1:
- IBM AIX
srcmstr
program, řadič systémových prostředků - Gerrit Pape
runsvdir
z runit svscan
Daniela J. Bernsteina z daemontools,svscan
Adama Sampsona od freedta,svscan
Bruce Guentera z daemontools-encore as6-svscan
Laurenta Bercota od s6- Wayne Marshall
perpd
od pachatele - nástroj pro správu služeb v systému Solaris 10
service-manager
od nosh
Podobně, jak je vysvětleno na https://superuser.com/a/888936/38062, celý /dev/initctl
myšlenka nemusí být nikde blízko procesu #1. Je ironií, že je to vysoce centralizovaný systém, který demonstruje, že jej lze přesunout z procesu #1.
Naopak povinné věci pro init
, na které lidé obvykle zapomínají ve svých prvotřídních návrzích, jsou věci jako zpracování SIGINT
, SIGPWR
, SIGWINCH
, a tak dále odesílané z jádra a uzákonění různých požadavků na změnu stavu systému odesílaných z programů, které "vědí", že určité signály pro zpracování #1 znamenají určité věci. (Například:Jak je vysvětleno na https://unix.stackexchange.com/a/196471/5132, sady nástrojů BSD „vědí“, že SIGUSR1
má specifický význam.)
Existují také jednorázové inicializační a dokončovací úlohy, kterým nelze uniknout, nebo jejich neprovedením bude velmi trpět, jako je připojení "API" souborových systémů nebo vyprázdnění mezipaměti souborového systému.
Základy práce se souborovými systémy "API" se trochu liší od fungování init
rom 1st Edition UNIX:Jeden má seznam informací pevně připojený k programu a druhý jednoduše mount()
s všechny položky v seznamu. Tento mechanismus najdete v tak rozmanitých systémech, jako je BSD (sic!) init
, prostřednictvím nosh system-manager
, na systemd.
"nastavit systém pro jednoduchý shell"
Jak jste si všimli, init=/bin/sh
nepřipojuje souborové systémy "API", havaruje nemotorným způsobem bez vyprázdnění mezipaměti, když zadáte exit
(https://unix.stackexchange.com/a/195978/5132) a obecně ponechává na (super)uživateli ruční provádění akcí, díky nimž je systém minimálně použitelný.
Chcete-li vidět, co vlastně člověk nemá jinou možnost, než dělat v procesních programech č. 1, a nasměrovat vás tak na dobrý kurz k vašemu stanovenému cíli designu, nejlepší možností je podívat se na přesahy v provozu runitu Gerrita Papea, Felix von Leitnerův minit a system-manager
program z nosh balíčku. První dva ukazují dva pokusy být minimalistický, ale přesto zvládnout věci, kterým se nelze vyhnout.
Poslední jmenovaný je užitečný, navrhuji, pro jeho rozsáhlé ruční zadávání system-manager
program, který přesně popisuje, jaké "API" souborové systémy jsou připojeny, jaké inicializační úlohy jsou spouštěny a jaké signály jsou zpracovávány; v systému, který je navržený má systémový manažer právě zplodit tři další věci (správce služeb, doprovodný logger a program pro spuštění změn stavu) a v procesu č. 1 dělá pouze to nevyhnutelné.
System V init na Debianu (existují další varianty a variace) dělá následující:
- Při zadávání úrovně běhu volá skripty v
/etc/rcX.d/S*
v alfanumerickém pořadí, kdeX
je runlevel. Tyto skripty by měly nastavit úroveň běhu. Typickým nastavením je spouštění démonů a provádění úloh nastavení pro danou úroveň běhu. Toto je jednorázová věc, kterou provedete při vstupu do úrovně běhu. - Na úrovni běhu spouští démony, kteří jsou uvedeni v
/etc/inittab
jako potřeba být aktivní během této úrovně běhu. Pokud tito démoni přestanou běžet, restartuje je. I když můžete mít libovolného démona, kterého chcete spravovat pomocíinit
, budete chtít minimálně párgetty
's, abyste se mohli přihlásit.getty
po dokončení přihlášení se ukončí a potéinit
restartuje jej a poskytne novou výzvu k přihlášení.
- Pokud se démon restartuje příliš mnohokrát během příliš krátké doby, přestane se ho na chvíli pokoušet restartovat.
- Jen proto, že něco bylo spuštěno startovacími skripty při vstupu do úrovně běhu, neznamená to
init
automaticky se snaží udržet v chodu. Musíte to specifikovat samostatně v/etc/inittab
.
- Při ukončení úrovně běhu volá skripty v
/etc/rcX.d/K*
v alfanumerickém pořadí, kdeX
je runlevel. Způsob, jak implementovat vypnutí nebo restartování, je definovat úroveň běhu pro tyto události a nastavit poslední spuštěnou úlohu jakohalt
neboreboot
příkaz. - V reakci na určité události, jako jsou události napájení nebo Ctrl-Alt-Del, bude volat spustitelné soubory.
- Naslouchá na soketu, pokud obdrží určité zprávy, změní úroveň běhu.
Můžete tedy použít init
jako základní správce služeb, chcete-li, ale hlavním úkolem dnešní doby je udržet getty
's k dispozici, takže se uživatel může přihlásit a spustit přechody runlevel.
Jen mě zajímalo, jaké úkoly dělá init, aby nastavil systém na jednoduchý shell?
Cokoliv chceš. V Debianu v každém /etc/rcX.d
adresář je symbolický odkaz na skript v /etc/init.d
a tyto skripty můžete plně přizpůsobit nebo odebrat. Pořadí je stanoveno tak, že každý skript předchází 00
, 01
, atd.
Můžete také zadat -b
možnost init
(tj. přes příkazový řádek jádra), pokud chcete pouze init
zplodit skořápku. Když opustíte shell, init
zemře a když init
zemře, jádro zpanikaří.
Absolutní minimum, které musí init udělat, je spustit alespoň jeden další program a nikdy neukončit. Pokud se init ukončí, systém se zhroutí. Předpokládám, že ani spuštění jednoho dalšího programu není nezbytně nutné, ale pokud to neuděláte, init by musel být odpovědný za provedení všech věcí, které se od systému očekává, nebo by to nebylo příliš užitečné.