Hlavní navigace

Inicializace aneb od Initu k Runitu

30. 6. 2004
Doba čtení: 5 minut

Sdílet

Ve zkratce: Na počátku byl init. Pak přišel Daniel J. Bernstein.

O čem seriál bude? Náplní prvního dílu je vysvětlení standardního spouštěcího mechanismu Linuxu (pro pokročilé uživatele nic nového). Nikoli vyčerpávajícím způsobem, od toho jsou manuálové stránky, ale především v souvislosti s dalšími díly. Druhý díl se bude zabývat nedostatky tohoto systému a řešením pomocí daemontools od D.J. Bernsteina. Ve třetím dílu půjdeme ještě dál – zcela nahradíme init runitem Gerrita Papeho.

Init

Loading Linux.................. 

Po nastartování jádra spustí jádro první proces, init. Tento proces je rodičem všech ostatních procesů. V Linuxu náležejí procesy do jediného stromu, jehož je init kořenem; zda je tomu tak i teď, můžete zkontrolovat příkazem pstree:

# pstree -ap

Init je současně prvním i posledním běžícím procesem, což znamená, že je zodpovědný za start i ukončení systému. Protože má toto privilegium, nezabije ho ani signál SIGKILL. Init sám je program, nalezneme ho v adresáři /sbin. Na jeho konfigurační soubor /etc/inittab se nyní podíváme blíže. Je vcelku nudný, sestává z několika řádků, každý ve formátu

id:runlevels:ac­tion:process

id je unikátní 1–4znakový identifikátor řádku, runlevels jsou čísla úrovní, pro které řádek platí,action je akce (…) a process je příkaz, který se má vykonat.

Co init umí?

Spoustu věcí. V dalších dílech zjistíme, že možná zbytečně mnoho. Jeho hlavním úkolem je totiž zajistit spuštění všech ostatních programů.

  • vykoná příkaz při inicializaci systému

    si::bootwait:/et­c/init.d/boot

    zde je příkazem skript /etc/init.d/boot. Bude vykonán jako úplně první. Úkolem skriptu je připojit disky, načíst moduly do jádra, provést různé kontroly atp.

  • definuje základní úroveň běhu (runlevel)

    id:5:initdefault:

    zde se dá ovlivnit, zda počítač nastartuje do grafického režimu, či nikoli (v našem případě ano). Runlevelů je standardně 6, přičemž 0, 1 a 6 jsou vyhrazené.

    0 způsobí vypnutí počítače (halt), 1 znamená jednouživatelský režim, 2 víceuživatelský režim bez NFS, 3 víceuživatelský režim bez grafického rozhraní, 4 není použito, 5 víceuživatelský režim s grafickým rozhraním a 6 reboot

    Po proběhnutí inicializace se můžeme přepnout do jiného runlevelu příkazem telinit (případně jen init):

    # telinit 3
    # telinit 5
  • vykoná příkaz podle úrovně běhu (runlevelu)

    l1:1:wait:/et­c/init.d/rc 1 l2:2:wait:/et­c/init.d/rc 2 l3:3:wait:/et­c/init.d/rc 3 … l6:6:wait:/et­c/init.d/rc 6

    Je vidět, že příkaz, tedy skript /etc/init.d/rc, převezme kontrolu nad inicializací všech úrovní. Akce wait zaručí spuštění příkazu pro daný runlevel pouze jednou a init počká, až příkaz doběhne.

  • spouští getty

    Getty je program, který zobrazí login na konzoli.

    1:2345:respaw­n:/sbin/minget­ty tty1 2:2345:respaw­n:/sbin/minget­ty tty2 3:2345:respaw­n:/sbin/minget­ty tty3 4:2345:respaw­n:/sbin/minget­ty tty4

    proces mingetty bude spouštěn v úrovních 2 až 5, na konzoli 1 až 4. „Spouštěn“ píšu kvůli akci respawn – jakmile dojde k jeho ukončení (odhlášením z konzole), init spustí mingetty znovu, tj. opět se zobrazí login.

  • reaguje na některé klávesové kombinace

    ca::ctrlaltdel:/sbin/s­hutdown -h now

  • reaguje na výpadek proudu

    pf:12345:power­fail:/sbin/shut­down -h now

init.d skripty

Řekněme, že init proběhl. V našem případě spustil nejdříve skript /etc/init.d/boot a následně přešel do runlevelu 5. Proto nyní spouští /etc/init.d/rc 5, který se postará o zbytek inicializace…

INIT: Entering runlevel: 5 

V tomto bodě se inicializační proces liší u jednotlivých distribucí. Většina vychází buď z modelu System V, nebo BSD. Principiálně se však odehrává totéž – v určitém pořadí jsou spouštěny skripty z /etc/init.d. Zjednodušeně: co skript, to služba. Službou je myšleno apache, mysql, ale pozor! na rozdíl od Windows i grafické rozhraní (služba xdm).

Jde o shellové skripty, každý s funkcemi start, stop, restart, reload a status. Používat je lze i ručně

# /etc/init.d/apache start
# /etc/init.d/xdm restart
# /etc/init.d/mysql stop

Úrovně běhu (runlevely)

Bylo by dost mepraktické, kdybychom museli po zapnutí počítače startovat služby ručně. Od toho jsou runlevely. Jde vlastně o seznam služeb, které mají být spuštěny, případně ukončeny. Jak již bylo napsáno výše, seznamů je standardně šest, přičemž při inicializaci se použije základní, viz initdefault v /etc/inittab.

Mandrake, RedHatu nebo SuSE

řeší runlevely pomocí adresářů. Adresáře mají v názvu číslo runlevelu a obsahují symlinky na skripty v /etc/init.d. Tj. každý adresář jako by obsahoval jen vybrané skripty z /etc/init.d.

Ukážeme si příklad runlevelu 5, tedy adresáře /etc/init.d/rc5.d. Vidíme v něm symlinky:

K05×dm → /etc/init.d/xdm
K06cron → /etc/init.d/cron

S08sshd → /etc/init.d/sshd
S09portmap → /etc/init.d/portmap
S15mysql → /etc/init.d/mysql
 

Po přechodu do runlevelu 5 budou všechny skripty postupně spouštěny v abecedním pořadí (stará se o to skript /etc/init.d/rc, viz inittab).

  1. Nejprve přijdou na řadu symlinky s K na začátku. K jako kill – ukončí služby, které případně běžely v předchozím runlevelu, ale v runlevelu 5 běžet nemají.
  2. Následně budou vykonány symlinky S, startovací.
  3. Dvojčíslí má význam pro zajištění pořadí spouštění (abecední).

Službu můžeme do runlevelu přidat ručně, ale znamená to jednak určit závislosti na ostatních (pořadí spouštění) a druhak vytvořit oba symlinky s S i K. Různé distribuce mají různé nástroje, které toto provedou za nás. Přidávací nástroj SuSE kupříkladu zjišťuje závislosti ze speciálních hlaviček v init.d skriptech.

Gentoo

používá dokonalejší systém. Také spouští skripty z /etc/init.d, ale k určení pořadí neslouží jejich názvy. Místo toho je po startu spuštěn /sbin/depscan.sh, který načte závislosti ze skriptů a tyto závislosti uloží kamsi mimo. Vše se pak na jejich základě řeší automaticky, a to v případě potřeby. Má to výhody – ručním nastartováním služby se zároveň nastartují všechny služby závislé. Navíc si inicializační systém pamatuje, která služba byla nastartována a která ne, z čehož vyplývá další vlastnost – při restartu služby se nejprve ukončí všechny na ní závislé, služba se restartuje, načež se ukončené služby opět nastartují. Příkladem je restart sítě, který ukončí apache, mysql,…

# /etc/init.d/net.eth0 restart

Gentoo však neřeší situaci, kdy služba spadne – nadále totiž předpokládá, že běží, a odmítá ji spustit. Je nutné mu přímo přikázat, aby ji považoval za vypnutou

# /etc/init.d/apache zap

Závěr

Každý inicializační systém má svá pro a proti. V Gentoo je vyspělý, ale zase mnohem složitější a citlivější (užil jsem si s ním své). Ani jeden neumožňuje současné spouštění služeb, které vede k rychlejšímu startu systému.

Na alternativní řešení se podíváme příště. Existují již dlouho, jsou spolehlivější a jednodušší. Bohužel, velké distribuce setrvávají u zažitých. To ovšem neznamená, že je nemůžete používat.

UX DAy - tip 2

Odkazy:

Source Mage GNU/Linux – VII aneb Není init jako init – I
System V init
Gentoo init system
Daemontools
Runit

Autor je lektorem OKsystem.

Byl pro vás článek přínosný?