|
1.
Runlevely
Boot systému
Během bootování systému si pravděpodobně všimnete toho, jak po monitoru ubíhá
poměrně hodně textu. Budete-li pozorní, zjistíte, že při každém rebootu jde o
ty samé informace. Pořadí těchto akcí se nazývá bootovací sekvence a je
(do značné míry) pevně daná.
Nejprve bootloader načte do paměti obraz jádra (určený v konfiguračním
souboru) a předá jej CPU k provedení. Kernel si poté zinicializuje potřebné
datové struktury a pochody a spustí proces init.
Tento proces postupně namountuje všechny potřebné souborové systémy (určeno
v /etc/fstab) a spustí různé soubory z adresáře
/etc/init.d, které se starají o spuštění služeb, které potřebujete
k bezproblémovému provozu počítače.
Nakonec, když jsou všechny skripty provedeny, aktivuje init terminály
(ve většině případů pouze virtuální konzole ukryté za Alt-F1,
Alt-F2 atd.) pomocí procesu agetty. Ten se postará o to, abyste se
byli schopni přihlásit - spustí login.
Init skripty
init samozřejmě neprovádí skripty z adresáře
/etc/init.d náhodně. Nejen, že dodržuje jejich správné pořadí,
ale provádí jenom ty, které má. Všechny potřebné informace má k dispozici
v adresáři /etc/runlevels.
Nejprve spouští init ty skripty z /etc/init.d, na
které vede odkaz z /etc/runlevels/boot. Většinou je pořadí
spouštění určeno abecedně, ale některé skripty obsahují informace o
závislostech, podle kterých systém zjistí, že je potřeba nejdříve spustit jiný
skript.
Po zpracování /etc/runlevels/boot pokračuje init skripty,
na které vede symbolický odkaz z in /etc/runlevels/default.
Znovu platí, že pořadí jejich spuštění je určeno abecedně, a případné
závislosti jsou dodrženy.
Jak init pracuje
Samozřejmě se init o tom všem nerozhoduje sám; potřebuje konfigurační
soubor, který mu říká, co má dělat. Tento soubor se jmenuje
/etc/inittab.
Pamatujete-li si na bootovací sekvenci, jistě si vzpomenete i na to, že jako
první byly připojeny potřebné souborové systémy. Tuto akci obstará následující
řádek v /etc/inittab:
Výpis kódu 1.1: Řádek inicializace systému v /etc/inittab |
si::sysinit:/sbin/rc sysinit
|
Tento řádek říká initu, že pro inicializaci systému musí spustit
/sbin/rc sysinit. Skript /sbin/rc se o ni postará; můžeme
tedy říci, že init toho moc nedělá - úkol pouze převede na jiný proces.
Jako druhý krok init provede všechny skripty, na které vedou symbolické
odkazy z /etc/runlevels/boot, viz tento řádek:
Výpis kódu 1.1: Pokračování inicializace systému |
rc::bootwait:/sbin/rc boot
|
O samotné provedení úkolu se opět stará skript rc. Povšimněte si, že
parametr předaný skriptu (boot) je zároveň i jméno použitého adresáře
uvnitř /etc/runlevels.
Nyní se init podívá do svého konfiguračního souboru, aby zjistil,
v jakém runlevelu má systém běžet. Řádka
z /etc/inittab:
Výpis kódu 1.1: Řádek initdefault |
id:3:initdefault:
|
V tomto případě (který bude používat většina uživatelů Gentoo) je číslo
runlevelu 3. init tedy zjistí, že musí spustit
runlevel 3:
Výpis kódu 1.1: Definice runlevelů |
l0:0:wait:/sbin/rc shutdown
l1:S1:wait:/sbin/rc single
l2:2:wait:/sbin/rc nonetwork
l3:3:wait:/sbin/rc default
l4:4:wait:/sbin/rc default
l5:5:wait:/sbin/rc default
l6:6:wait:/sbin/rc reboot
|
Opět vidíme, že řádka definující runlevel 3 používá ke spuštění
služeb skript rc, nyní s parametrem default. Parametr
předaný skriptu rc se znovu shoduje se jménem adresáře
z /etc/runlevels.
Až rc skončí svoji práci, init se rozhodne, jaké virtuální
konzole má aktivovat a jaké programy na nich spustit:
Výpis kódu 1.1: Definice virtualních konzolí |
c1:12345:respawn:/sbin/agetty 38400 tty1 linux
c2:12345:respawn:/sbin/agetty 38400 tty2 linux
c3:12345:respawn:/sbin/agetty 38400 tty3 linux
c4:12345:respawn:/sbin/agetty 38400 tty4 linux
c5:12345:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
|
Co je to runlevel?
Ukázali jsme, že se init při rozhodování o tom, do jakého
runlevelu vstoupit, drží číselného schématu. Runlevel je stav, ve
kterém Váš systém běží; váží se k němu skripty (skripty runlevelu nebo
init skripty), které musí být spuštěny, když systém do runlevelu vstupuje
a nebo jej ukončuje.
V Gentoo je definováno sedm runlevelů: tři pro vnitřní potřebu a čtyři
uživatelsky definované. Runlevely pro vnitřní potřebu jsou sysinit,
shutdown a reboot a dělají to, co jejich jména napovídají -
starají se o inicializaci systému, jeho vypnutí a restart.
Uživatelsky definované runlevely jsou ty, které používají podadresář
/etc/runlevels - boot, default,
nonetwork a single. Runlevel boot
spouští všechny nezbytné služby, které dále používají další runlevely.
Zbývající tři runlevely se odlišují počtem a druhy služeb, které spouští:
runlevel default slouží pro běžný chod systému,
nonetwork pro dobu, kdy není potřeba síť, a single
tehdy, je-li potřeba opravit systém.
Práce s init skripty
Skripty, které spouští proces rc, se nazývají init skripty. Každý
ze skriptů uložených v /etc/init.d může být spuštěn
s parametry start, stop, restart, pause,
zap, status, ineed, iuse, needsme,
usesme nebo broken.
Pro spuštění, zastavení a nebo restart služby (a zároveň všech služeb, které na
ní závisí), slouží parametry start, stop a restart:
Výpis kódu 1.1: Spuštění Postfixu |
# /etc/init.d/postfix start
|
Poznámka:
Pouze služby, které ji potřebují, jsou zastaveny nebo restartovány.
Další na ní závislé služby (ty, které ji používají, ale nepotřebují),
nejsou dotčeny.
|
Chcete-li zastavit službu, ale ne další služby, které na ní závisí, můžete
použít parametr pause:
Výpis kódu 1.1: Pozastavení Postfixu a ponechání dalších služeb naživu |
# /etc/init.d/postfix pause
|
Chcete-li vědět, v jakém stavu se daná služba právě nachází (zda běží, je
ukončená a nebo pozastavená), můžete použít argument status:
Výpis kódu 1.1: Informace o stavu Postfixu |
# /etc/init.d/postfix status
|
Říká-li informace o stavu, že služba běží, avšak Vy víte, že ne, můžete tuto
informaci změnit pomocí argumentu zap:
Výpis kódu 1.1: Změna informace o stavu služby postfix |
# /etc/init.d/postfix zap
|
Pro zjištění závislostí služby můžete použít iuse či ineed.
Parametr ineed vypíše seznam služeb, které služba aktuální ke svému
chodu opravdu potřebuje; iuse naproti tomu ukáže ty služby, které daná
služba používat může, ale ke správné funkci je nutně nevyžaduje.
Výpis kódu 1.1: Výpis všech služeb, na kterých Postfix závisí |
# /etc/init.d/postfix ineed
|
Podobně se můžete dotázat na služby, které danou službu potřebují
(needsme) nebo mohou používat (usesme):
Výpis kódu 1.1: Výpis všech služeb, které potřebují Postfix |
# /etc/init.d/postfix needsme
|
Konečně, je možné požádat i o výpis závislostí, které služba vyžaduje, ale
které chybí:
Výpis kódu 1.1: Výpis chybějících závislostí Postfixu |
# /etc/init.d/postfix broken
|
1.
Práce s rc-update
Co je rc-update?
Init systém Gentoo používá pro rozhodování o pořadí spouštění služeb strom
závislostí. Protože jeho udržování je poměrně zdlouhavé a únavné, vytvořili jsme
nástroje, které správu runlevelů a init skriptů usnadňují.
Nástrojem rc-update můžete do runlevelu přidávat a odebírat skripty, a
on se sám postará o zavolání skriptu depscan.sh pro znovuvytvoření
stromu závislostí
Přidání a odebírání služeb
Během instalace Gentoo jste již init skripty přidávali do runlevelu "default".
Tehdy jste možná ještě neměli páru, k čemu onen "default" slouží, ale teď
už byste to vědět měli. Skript rc-update vyžaduje i druhý argument
definující akci k provedení: add, del nebo show.
Pro přidání či odebrání init skriptu jednoduše spusťte rc-update
s argumentem add (přidání) nebo del (odebrání) následovaným
jménem init skriptu a runlevelem. Například takto:
Výpis kódu 1.1: Odstranění Postfixu z výchozího runlevelu |
# rc-update del postfix default
|
Příkaz rc-update show zobrazí dostupné init skripty a patřičné runlevely,
ve kterých jsou skripty aktivní:
Výpis kódu 1.1: Informace o init skriptech |
# rc-update show
|
1.
Konfigurace služeb
K čemu další konfigurace?
Init skripty mohou být poměrně komplexní, a proto není vhodné, aby je měnili
uživatelé sami, kvůli riziku zanesení chyb. Služby je však potřeba
konfigurovat, například někdy můžete potřebovat předat samotné službě další
parametry.
Druhým důvodem k tomu, abychom udržovali informace o konfiguraci mimo init
skript jsou aktualizace, resp. zamezení obavám o to, že o svoji konfiguraci
během aktualizace přijdete.
Adresář /etc/conf.d
Konfigurace služeb je v Gentoo snadná - každý konfigurovatelný init skript
má svůj soubor v adresáři /etc/conf.d. Kupříkladu
konfigurace init skriptu apache2 (/etc/init.d/apache2) se provádí
v souboru /etc/conf.d/apache2; tento obsahuje parametry
předávané serveru Apache 2 při jeho spuštění:
Výpis kódu 1.1: Proměnná definovaná v /etc/conf.d/apache2 |
APACHE2_OPTS="-D PHP4"
|
V těchto konfiguračních souborech nenajdete nic než proměnné, ovlivňující
chování daného init skriptu, a samozřejmě komentáře. Formát je podobný jako
v /etc/make.conf.
1.
Psaní init skriptu
Musím?
Ne, psaní init skriptů většinou není nutné, protože Gentoo poskytuje skripty
připravené k použití. Avšak je možné, že jste si nainstalovali nějakou
službu, která není v Portage, a v takovém případě si budete muset
init skript pravděpodobně vytvořit.
Nepoužívejte init skript, který není napsaný přímo pro Gentoo -- formát jiných
distribucí není s naším kompatibilní!
Schéma
Základní uspořádání init skriptu je ukázáno níže:
Výpis kódu 1.1: Základní uspořádání init skriptu |
#!/sbin/runscript
depend() {
}
start() {
}
stop() {
}
restart() {
}
|
Každý init skript musí obsahovat funkci start(), všechny další
sekce jsou volitelné.
Závislosti
Můžete definovat dva druhy závislostí: use a need. Jak již bylo
zmíněno výše, need je striktnější než use. Obě dvě akceptují buď
jméno služby, kterou potřebujete či používáte a nebo virtuální závislost.
Virtuální závislost může být poskytovaná více službami. Váš init skript
může například záviset na systémovém loggeru, avšak protože jich je více
možných (metalogd, syslog-ng, sysklogd,...), a služba nemůže přes need
záviset na všech (žádný rozumný systém nemá všechny nainstalované a spuštěné),
použijete virtuální závislost, poskytovanou pomocí provide.
Podívejme se na na informace o závislostech pro službu postfix:
Výpis kódu 1.1: Informace o závislostech Postfixu |
depend() {
need net
use logger dns
provide mta
}
|
Jak můžete vidět, služba postfix:
-
vyžaduje (virtuální) závislost net (kterou poskytuje například
/etc/init.d/net.eth0)
-
používá (virtuální) závislost logger (kterou poskytuje například
/etc/init.d/syslog-ng)
-
používá (virtuální) závislost dns (kterou poskytuje například
/etc/init.d/named)
-
poskytuje (virtuální) závislost mta (která je společná pro všechny
mailservery)
Kontrola pořadí
V některých případech nebudete nějakou službu potřebovat, ale přejete si,
aby byla ta Vaše spuštěna před (before) nebo až po (after) nějaké
jiné, pokud je tato v systému přítomná (povšimněte si podmínky - již nejde
o závislost) a zároveň je ve stejném runlevelu (opět podmínka -
v úvahu jsou brány pouze služby ve stejném runlevelu). Takového
chování můžete dosáhnout pomocí nastavení before nebo after.
Jako příklad se podíváme na nastavení služby portmap:
Výpis kódu 1.1: Funkce depend() služby portmap |
depend() {
need net
before inetd
before xinetd
}
|
Také můžete použít metaznak "*", který znamená "všechny služby
v runlevelu", avšak není to doporučeno.
Výpis kódu 1.1: Spuštění init skriptu jako první v runlevelu |
depend() {
before *
}
|
Standardní funkce
Dále je potřeba definovat funkci start(), která musí obsahovat všechny
příkazy potřebné ke spuštění služby. Je dobré použít funkce ebegin
a eend, aby uživatel viděl, co se děje:
Výpis kódu 1.1: Ukázková funkce start() |
start() {
ebegin "Starting my_service"
start-stop-daemon --start --quiet --exec /path/to/my_service
eend $?
}
|
Potřebujete-li více příkladů funkce start(), přečtěte si, prosím,
zdrojové kódy dostupných init skriptů v adresáři /etc/init.d.
Příkaz start-stop-daemon má výbornou manuálovou stránku, potřebujete-li
další informace:
Výpis kódu 1.1: Zobrazení manuálové stránky start-stop-daemon |
# man start-stop-daemon
|
Další funkce, které můžete definovat, jsou stop a restart, není
to však povinné! Náš init systém je natolik inteligentní, že pokud používáte
start-stop-daemon, doplní si tyto funkce sám.
Syntaxe init skriptů používaných v Gentoo je kompatibilní s Bourne
Again Shellem (bash), čili v nich můžete používat rozšíření bashe.
Přidání vlastních možností
Chcete-li, aby Vaše init skripty podporovaly více voleb než ty, na které jsme
zatím narazili, měli byste je přidat do proměnné opts a definovat funkci
se jménem shodným, jako má daná možnost. Například pro volbu
restartdelay:
Výpis kódu 1.1: Podpora volby restartdelay |
opts="${opts} restartdelay"
restartdelay() {
stop
sleep 3
start
}
|
Proměnné pro konfiguraci služeb
Abyste mohli využívat konfiguraci v /etc/conf.d, nemusíte
dělat vůbec nic - když je váš skript spuštěn, provede se "source" všech těchto
souborů (tj. proměnné z nich budou k dispozici):
- /etc/conf.d/<Váš init skript>
- /etc/conf.d/basic
- /etc/rc.conf
Zároveň pokud Váš init skript poskytuje virtuální závislost (například
net), bude soubor s ní asociovaný rovněž zpracován (například
/etc/conf.d/net).
1.
Změna výchozího chování
Kdo by to mohl použít?
Mnoho uživatelů notebooků tuto situaci zná - doma chcete spouštět
net.eth0, ale na cestách ne, protože během nich síť k dispozici
nemáte. S Gentoo můžete změnit chování runlevelů k obrazu svému.
Můžete si například přidat druhý "výchozí" runlevel, do kterého můžete
nabootovat, s přiřazenými patřičnými skripty. Při spuštění počítače si
budete moci vybrat, který runlevel se má zavést.
Používáme softlevel
Nejprve vytvořte adresář pro svůj "druhý" výchozí runlevel. Jako příklad
vytvoříme runlevel offline:
Výpis kódu 1.1: Vytvoření adresáře runlevelu |
# mkdir /etc/runlevels/offline
|
Přidejte nezbytné init skripty do nově vytvořeného adresáře. Například pokud
chcete mít přesnou kopii současného runlevelu default, avšak bez
net.eth0:
Výpis kódu 1.1: Přidání nezbytných init skriptů |
# cd /etc/runlevels/default
# for service in *; do rc-update add $service offline; done
# rc-update del net.eth0 offline
# rc-update show offline
acpid | offline
domainname | offline
local | offline
net.eth0 |
|
Nyní změňte konfiguraci svého bootloaderu a přidejte novou položku pro runlevel
default. Například pro /boot/grub/grub.conf:
Výpis kódu 1.1: Přidání položky pro runlevel offline |
title Gentoo Linux Offline Usage
root (hd0,0)
kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offline
|
Voilà, to je všechno. Když nyní při bootování Vašeho systému vyberete nově
přidanou položku, runlevel offline bude použit místo výchozího
default.
Používáme bootlevel
Použití bootlevelu je úplně stejné jako pro softlevel, jediný
rozdíl je, že místo druhého runlevelu "default" definujete druhý runlevel
"boot".
|