Práce v prostředí ramdisku

Z DCEwiki
Skočit na navigaci Skočit na vyhledávání
Verze k tisku již není podporovaná a může obsahovat chyby s vykreslováním. Aktualizujte si prosím záložky ve svém prohlížeči a použijte prosím zabudovanou funkci prohlížeče pro tisknutí.

Zavaděč

Zavaděč je standalone binární aplikace, která se stará o zavedení binárního jádra operačního systému do paměti počítače a jeho spuštění. Tato aplikace musí být schopna rozpoznat blokové zařízení a přečíst souborový systém na kterém má operační systém své jádro uložen.


O spuštění zavaděče se stará BIOS (resp. UEFI) počítače:

BIOS
BIOS sahá na první sektor blokového zařízení (tzv. MBR - Master Boot Record), kde se pokouší najít informaci o tom, odkud a kolik bajtů dat má natáhnout do paměti – pokud ji najde, načte data z této oblasti do paměti a předá další řízení načtenému kódu.
UEFI
Má svoje soubory uloženy na diskovém oddíle se souborovým systémem FAT a v podstatě se dá říct, že jde o předinstalovaný zavaděč, který má do sebe zadrátovaný ověřovací mechanismus – secure boot – který před zavedením kódu zkontroluje, zda-li byl podepsán "tím správným klíčem".

UEFI si vynutil Microsoft, protože jedině secureboot je schopen zajistit aby se uživateli nenatáhnul do paměti infikovaný kernel. Pochopitelně pro linuxové uživatele představovalo zavedení UEFI opruz – obzvláště tam, kde nebylo možné secureboot vypnout. Aby secureboot při zavádění akceptoval vlastní kernel tak by musel být podepsán certifikátem od Microsoftu.

  • Dnes většina strojů umožňuje UEFI boot vypnout a použít tzv. Legacy Boot, kter funguje podobně jako při zavádění přes BIOS. V takovém případě, pokud chcete používat diskless, musíte použít tzv. Legacy PXE Boot
  • U slušných UEFI lze secureboot vypnout. Pak, pokud vaše UEFI podporuje u síťové karty PXE můžete pro zavádění disklessu využít UEFI PXE Boot
  • Pro ta ostatní UEFI dnes existuje několik způsobů jak ho obejít, většinou jsou založeny na tom, že secureboot natáhne podepsaný zavaděč.

Nejrozšířenější linuxový zavaděč pro zavádění z lokálních blokových zařízení je v současné době GRUB2, který má oproti staršímu zavaděči LILO výhodu především v tom, že jeho zaváděcí proces je velmi podobný tomu, jak funguje zavádění linuxového systému.

Upozornění Součástí načteného a spuštěného binárního kódu musí být vždy ovladače, které umožní další pokračování zaváděcího procesu. Bez ohledu na to, jde-li o zavaděč, nebo jádro operačního systému. Pokud některý z nich chybí, zavádění selže.
Kód natahovaný do paměti BIOSem, musí být vždy uložen na začátku disku, v prostoru mezi tabulkou rozdělení disku a začátkem prvního diskového oddílu. To v případě MS-DOS tabulky představovalo původně 62 datových bloků (cca 32 kB). Do tohoto prostoru se musel vejít veškerý kód zavaděče.

Více místa bylo mezi začátkem diskového oddílu a začátkem souborového systému (cca 66 kB). Toho využívala první verze zavaděče GRUB, která si na začátek disku uložila pouze malou část kódu, která si pak místo BIOSu natáhla do paměti vlastní kód zavaděče, uložený na začátku některého z diskových oddílů.

Tento koncept však přestal být s rostoucím množstvím existujícího hardware neudržitelný, protože nebylo možné do tak malého prostoru vtěsnat všechny potřebné ovladače. GRUB2, který nahradil původní verzi, používá podobný modulární koncept, jako linuxový kernel.

Na začátku disku je uloženo jádro s ovladači pro zpřístupnění adresáře s moduly a pak už lze natahovat moduly podle potřeby buďto manuálně z prostředí integrovaného shellu, nebo prostřednictvím konfiguračního souboru grub.cfg (GRUB legacy používal menu.lst).

Integrovaný shell, který umožňuje v průběhu zaváděcího procesu opravit případnou chybu v konfiguračním souboru je jednou z největších výhod zavaděče GRUB.


Upozornění Pokud se používá pro zavádění BIOS je třeba hlídat aby:
  1. sahal při zavádění na správné zařízení
  2. použité disky ve stroji neměly v MBR nějaké zbytkové záznamy, které by mohly zmást BIOS
  3. byla po aktualizaci zavaděče aktualizována také část, která je uložena na blokovém zařízení, odkud ji načítá BIOS

Chybí-li ovladač v jádře zavaděče, potřebný pro zpřístupnění souborového systému se zbývajícímu moduly, pak nelze problém vyřešit jinak, než pomocí zavedení prostřednictvím jiného zavaděče a nebo opravou záznamu na blokovém zařízení přes chroot z prostředí linuxového live CD.

Zavádění po síti

Zavádění po síti má oproti lokálnímu zavádění především tu výhodu, že můžeme operativně měnit zaváděné soubory, aniž by bylo nutné cokoliv instalovat na lokální stanici či server. Využívá se při tom tzv. Preboot Execution Environment – PXE, což je funkcionalita firmware síťové karty. Podmínkou je ale funkční a spolehlivá síť.

Funguje to tak že PXE pošle do sítě dotaz, na který mu odpoví DHCP server a spolu s konfigurací sítě mu zároveň cestku k binárnímu souboru zavaděče, který pak BIOS (UEFI) natáhne do paměti.

Pochopitelně musí jít o zavaděč, který má rovněž podporu PXE. Bez toho by bylo možné zavést systém pouze z lokálního disku. Použitelné jsou v současné době tyto tři:

PXELINUX
Má podporu pro zavádění jak z Legacy PXE (pxelinux.0), tak UEFI PXE (syslinux.efi). Výhodné při tom je, že oba typy zavaděče pracují se stejnými konfiguračními soubory. Problém je ale při zavádění přes UEFI, protože nemá (psáno v září 2019) podporu pro skriptování a neumí vypnínat stroje přes ACPI.
GRUB2
Soubor grubnetx64.efi zavedený přes UEFI PXE umí vypínat stroje přes ACPI. Protože má GRUB2 podporu skriptování, lze používat jeden konfigurační soubor a při tom mít zároveň všechny výhody, které má jeho lokální instalace. Bohužel má i svoje nectnosti – výstup z konzole je při zavádění přesměrován kamsi a pokud během zavádění jádra skončíte v ramdisku máte smůlu, protože se na konzoli – přes kterou by bylo možné problém opravit – nedostanete.
iPXE
Kombinuje výhody PXELINUXU a GRUBU. A v případě disklessových laboratoří lze brát jako výhodu i fakt, že u něj nelze proces zavádění přerušit a jádru předhodit jiné (nežádoucí) paramery.

Zavedení jádra

Zavaděč si lze představit jako jednoúčelový operační systém, který má za úkol:

  1. rozbalit jádro operačního systému do paměti počítače..
  2. spustit ho..
  3. ..a přitom mu předat případné parametry.

Jádro je spustitelný binární soubor, který poběží - na rozdíl od zavaděče - po celý čas běhu operačního systému.

Zavaděč jádro z úložiště přebírá ve formě samorozbalovacího archívu, jehož jméno podle obvyklého úzu začíná řetězcem vmlinuz. Toto pojmenování je závazné pouze do té míry, aby ho pod ním zavaděč v úložišti našel.

Jádro se rozbalí do paměti a od zavaděče převezme případné konfigurační volby. Pak se pokusí identifikovat a připojit zařízení, na kterém má být uložen operační systém a z něj spustit spouštěč dalších procesů - init. Aby to bylo možné, musí mít k dispozici všechny potřebné ovladače. Aby se jádro obešlo bez ramdisku, musí mít v sobě tyto ovladače zakompilované na tvrdo.

U distribucí, které si kompilují jádro na míru podle aktuální konfigurace stroje, s tím obvykle není problém. Ovšem u distribucí, které mají mít univerzální použití, by optimální konfigurace takového jádra mohla představovat neřešitelný problém. Proto se u nich využívá při zavádění tzv. RAM disk.

Monolitické jádro
Nepotřebuje ramdisk protože je kompilované na míru a obsahuje pouze potřebné ovladače. Má výhodu v tom, že může být lépe optimalizované a tím pádem i o něco výkonnější.
Modulární jádro
Nemusí využívat ramdisk, pokud má potřebné ovladače k dispozici. Výhoda ramdisku je však v tom, že mu stačí pouze základní ovladače potřebné pro rozbalení a připojení ramdisku. Ostatní ovladače jsou uloženy ve formě jaderných modulů v ramdisku a do jádra se zavádějí pouze v případě že jsou zatřebí. Takové jádro je tedy mnohem více flexibilní z hlediska diverzity hardware.


Prostředí RAM disku

Je čistě technicky vzato další kus operační paměti (odtud RAM disk), kam si jádro vybalí z komprimovaného cpio archívu minimalistické linuxové prostředí. Jádro s ním pak pracuje jako by šlo o normální systémový disk. Tzn. že si jej připojí, a pak z něj spustí busybox, kterému předhodí init skript.

V tomto případě u nejde o binární spouštěč procesů (tím je busybox), ale shellový skript, který postupně spouští další skripty. Z hlediska zavádění systému je podstatné, že skript init obsahuje podmínky, které umožňují proces zavádění cíleně přerušit.

K takovému přerušení zaváděcího procesu obvykle dojde, když některý ze spouštěcích skriptů vrátí chybu.

Prostředí a nástroje v ramdisku, umožňují zjistit příčinu chyby a případně provést její opravu. Někdy ale může být v okamžiku selhání příliš pozdě na to zjišťovat kde je problém, proto je dobré vědět:

  1. Jak cíleně přerušit zaváděcí proces v určité fázi zavádění
  2. Jak konfigurovat síťová rozhraní v prostředí ramdisku
  3. Jak rozbalit nebo vypsat obsah ramdisku
  4. Jak zabalit upravený obsah ramdisku
  5. Jak korektně do ramdisku přidat chybějící jaderné moduly a další užitečné nástroje
  6. Jak přidat do ramdisku vlastní skripty a tím ovlivnit proces zavedení systému
  7. Jak restartovat stroj z prostředí ramdisku
  8. Jakým způsobem v ramdisku řešit problémy se zaváděním systému

Přerušení zaváděcího procesu

Zaváděcí proces postupně prochází následující fáze:

top
Parametr top vyvolá přerušení zaváděcího procesu před spuštěním prvního skriptu. Jediná operace, která se realizuje dřív, je načtení obsahu paměti z disku - pokud byl systém při předchozím spuštění uspán na disk.
modules
Parametrem modules se přeruší zavádění předtím, než init zavolá funkci load_modules, která zavádí do jádra další moduly, které nemusí být bezprostředně vázané na konkrétní hardware, ale mohou být kupř. nezbytné pro další zavádění systému.
premount
K přerušení dojde v okamžiku, než se spustí proces přípravy na to, aby ho bylo možné připojit zařízení na kterém je uložen systém.
mount
K přerušení dojde před připojením zařízení na kterém je uložen systém.
bottom
Zaváděcí proces je přerušen po připojení zařízení. Kdy jsou už aplikovány skripty pro tuto fázi
init
Poslední přerušení těsně před tím než dojde k přepnutí do finálního systému, ze kterého se pak spustí /sbin/init

Přerušit ho lze tím, že jádru předá při zavádění volba break:

vmlinuz... break ...

Že jsme se ocitli v prostředí ramdisku se pozná tak, že se místo obvyklého přihlášení rovnou objeví příkazový řádek:

(initramfs)

Jaké proměnné byly předány při spuštění jádra si lze vypsat (pokud je součástí ramdisku busybox) příkazem env. Pokud byl předán pouze parametr break bez bližšího upřesnění fáze, nastaví init jako výchozí hodnotu premount. Má to tedy stejný efekt, jako kdybychom jádru předali toto:

vmlinuz... break=premount ...

Zaváděcí proces bude přerušen ve fázi premount. Odesláním příkazu exit opustíte příkazový řádek ramdisku a zaváděcí proces bude dále pokračovat.

Upozornění Po spuštění init skriptu již nelze měnit obsah proměnných předaných na příkazové řádce jádru. Tudíž není možné postupovat od fáze k fázi tím, že by se postupně měnila hodnota proměnné break.

Jak debugovat skripty v ramdisku

Pokud máte spouštění v některé fázi přerušeno, můžete skripty debugovat s využitím funkcí ramdisku. Na začátek testovaného spriptu přidejte následující kód:

. /scripts/functions

Tím do vašeho skriptu načtete standardní funkce ramdisku. Pokud chcete v některém míste jeho běh přerušit, přidejte na příslušné místo:

panic "Info text"

Při vykonávání skriptu dojde k přerušení a otevření nové instance konzole. Že jste na nově otevřeném shellu můžete poznat podle chybové hlášky:

sh: cant't access tty: job control turned off

Vyskočíte z ní příkazem exit, stejným způsobem jako když pokračujete ve zpracování výchozího init skriptu.

Chcete-li zpracování skriptu přerušit v konkrétním místě a dodatečně zjistit kde, umístěte ve skriptu za příkaz exit číselným kód. Co se vrátilo vypíšete přes:

echo $?

Více viz manuál pro dash.

busybox

Je binární aplikace, která má v sobě zakompilovanou sadu potřebných nástrojů pro práci v ramdisku, pro které ve spuštěném systému existují plnotučné verze.

Pokud si vylistujete obsah adresáře /bin v ramdisku, zjistíte že obsahuje řadu souborů – ve skutečnosti je většina z nich pouhým hardlinkem na busybox, což zjistíte při pozornějším pohledu na výpis:

Tyto hardlinky vygeneruje nástroj initramfs-tools jen pokud do ramdisku nepřidáte jejich plnotučnou verzi. Ta pochopitelně dostane přednost.

Důležité je mít na paměti, že nástroje z busyboxu jsou očesané na funkční minimum, takže některé věci přes ně není možné realizovat. Na druhou stranu busybox můžete použít v situaci, kdy vám specializovaný nástroj chybí. Např. pokud potřebujete stáhnout soubor přes TFTP a nemáte nainstalovaného tftp klienta.

~# busybox tftp -g -r turtle.conf 192.168.210.5
Poznámka Příkaz tftp z busyboxu můžete využívat také k odeslání upravených spouštěcích skriptů z ramdisku na DHCP server:
tftp -p -l soubor_k_odeslani -r cilovy_soubor <adresa TFTP serveru>

Pamatuje ale na to, že přes TFTP půjde odeslat soubor pouze do adresáře kam lze zapisovat, případně do souboru, který na TFTP severu již existuje a je do něj možné zapisovat.

Co všechno vaše verze busyboxu podporuje se dozvíte pokud mu předáte parametr --help:

~# busybox --help

Mimo jiné obsahuje také interpreter ash, který zpracovává skript init. Ten má podobné funkcionality jako bash, ale v některých detailech se může lišit. Více se dozvíte na stránce https://busybox.net/downloads/BusyBox.html

Konfigurace sítě

K nastavení sítě v prostředí ramdisku lze použít nástroj ipconfig (součást balíku klibc-utils), který používají skripty z initramfs-tools nebo utilitu ip z balíku iproute2.

ipconfig

Upozornění Pozor ipconfig je binární nástroj, který umožňuje staticky nebo s využitím DHCP[1] nastavit pouze IPv4 adresu!

Tento nástroj volají shellové funkce, které používá u bezdiskového systému skript /scripts/nfs během fáze mount. Nastavuje jím síťová rozhraní podle parametrů předaných jádru těsně předtím, než se pokusí o namountování systémového disku publikovaného přes NFS server.

Konfigurace pro rozhraní, přes které má být NFS připojeno, se předává jádru prefixem "ip=" nebo "nfsaddrs=". Z hlediska použití mezi nimi není rozdíl, neboť v případě "nfsaddrs=" jde pouze o relikt. Výsledek je v obou případech stejný.

Jaký je aktuální obsah proměnných ramdisku si lze ověřit příkazem env. Nastavení sítě pak můžeme provést předáním proměnné utilitě ipconfig.

(initramfs) ipconfig ${ip}

Pokud chceme použít jiné nastavení, než je obsahem této proměnné, můžeme ho vypsat manuálně. Syntaxe je stejná, jako když se předává parametrem "ip=" jádru při zavádění.

(initramfs) ipconfig -t 2 147.32.87.200:147.32.87.255:147.32.87.129:255.255.255.128:diskless:eth0:none
IP-Config: eth0 hardware address be:be:be:01:71:12 mtu 1500
IP-Config: eth0 guessed broadcast address 147.32,87,255
IP-Config: eth0 complete (from 147.32.87.255):
address: 147.32.87.200     broadcast: 147.32.87.255    netmask: 255.255.255.128
gateway: 147.32.87.200     dns0     :   0.0.0.0        dns1
host   : diskless
rootserver: 147.32.87.255 rootpath:
filename  :

Zda-li došlo k nastavení síťového rozhraní můžeme zjistit příkazy ifconfig nebo ip

147.32.87.200 - IPv4 adresa stroje
147.32.87.255 - IPv4 adresa NFS serveru (broadcast)
147.32.87.129 - gateway
255.255.255.128 - maska
diskless - hostname stroje
eth0 - síťové rozhraní
none - použitá metoda
Poznámka Chybí-li nastavení pro lo zařízení, lze provést konfiguraci takto:
(initramfs) ipconfig 127.0.0.1:::::lo:none

Nastavení IPv4 adresy síťového rozhraní s využitím DHCP

(initramfs) ipconfig -t 2 -c dhcp eth0

Nastavení IPv4 adres na více síťových rozhraní současně

(initramfs) ipconfig -c any eth0 eth1 192.168.1.1:::::eth2:none
 

ip

Protože ipconfig umí pracovat pouze s IPv4 je nutné pro nastavení IPv6 adresy použít utilitu ip (součást balíku iproute2)

(initramfs) ip route add 2001:718:2:1612::/64 dev eth0
(initramfs) ip route add fe80::/64 dev eth0
(initramfs) ip route add default via fe80::7272:cfff:fe1b:d243 dev eth0
(initramfs) ip -6 route

Tuto utilitu by pochopitelně bylo možné použít také u diskless strojů. Vyžadovalo by to však manuální úpravu skriptů v ramdisku. Nicméně pro úplnost uvádím také použití této utility pro nastavení IPv4 adresy

(initramfs) ip address add 147.32.87.216/25 dev eth0
(initramfs) ip link set eth0 up
(initramfs) ip route add default via 147.32.87.129 dev eth0

Připojení může selhat také kvůli některé z následujících příčin:

  • v jádře i ramdisku může chybět ovladač síťového rozhraní - v takovém případě je ho třeba přidat do souboru /etc/initramfs-tools/modules a poté aktualizovat ramdisk
  • konfigurované síťové rozhraní také může být omylem připojeno do subnetu, který nemá přístup na vzdálené úložiště
  • také může být úříčina v konfiguraci vzdáleného úložiště, kdy pro IP adresu klientské stanice nemusí být povolen přístup
  • chyba se může také vyskytnout v konfiguraci pro síťové zařízení, nebo v nastavení pro připojení vzdáleného zařízení (NFS, iSCSI, NBD,...).

NFS

Pokud se používá systémový adresář sdílený z NFS serveru, stará se v ramdisku o jeho připojení skript /scripts/nfs, který je součástí instalačního balíčku initramfs-tools. V systému ho však nenajdete mezi skripty v adresáři /etc/initramfs-tools, nýbrž v /usr/share/initramfs-tools/scripts.

Poznámka U běžných blokových zařízení jádro před jejich připojením kontroluje integritu souborového systému. Většina z klasických souborových systémů vyžaduje aby během kontroly zařízení nebylo pokud možno připojené, nebo když už, tak na něj nebyl povolen zápis - proto se jádru předává také parametr ro který zajistí aby bylo v ramdisku zařízení připojeno jen pro čtení.

U připojení přes NFS se žádná kontrola neprovádí, takže je tento parametr většinou zbytečný.

Skript /scripts/nfs volá binární utilitu nfsmount, které obsah proměnné nfsroot, která se jádru předává ještě před začátkem zavádění jako parametr.

nfsroot=<IP adresa NFS serveru>:<publikovaný adresář>[,<další parametry NFS připojení>]

Pokud se vyskytne nějaký problém při mountování NFS adresáře, zůstane jádro "viset" na opakovaných pokusech o jeho připojení. Ve skriptu je nastaveno 180 pokusů o připojení se sekundovou prodlevou, takže zhruba po třech minutách, pokud se připojení nezdaří zkusí jádro připojit adresář /tftpboot/%s a pokud ani to neprojde, zůstanete v prostředí ramdisku.

Příčiny selhání mohou být různé:

  • chybná adresu NFS serveru
  • chyba v cestě ke vzdálenému adresáři
  • špatně nastavená přístupová práva na NFS serveru
Upozornění Utilita nfsmount umí komunikovat pouze jako NFSv3, protože v prostředí ramdisku neběží démoni potřební pro autorizaci a šifrovanou komunikaci!

Aby bylo možné zjistit co je špatně, lze jádru předat parametr - nfsrootdebug - který zajistí, že se během zavádění do logu umístěného v /tmp/initramfs zapíší informace, které umožní zjistit co se dělo a na jejich základě odhalit chybu.

Poznámka U Debianu který postupně přechází na systemd se můžete setkat s tím, že se během bezdiskového zavádění systém opakovaně pokouší namountovat systémový disk z NFS. Na straně NFS serveru je vidět že se klient opakovaně připojuje a odpojuje. Nakonec ale vše naběhne jak má. Může za to pravděpodobně démon /lib/systemd-udevd, že původní test kterým se ve skriptu /scripts/nfs kontrolovalo zda-li je vzdálený adresář připojen přestal fungovat.

V repozitáři intramfs-tools již je od 3.června 2014 oprava. Distribuční verze balíku initramfs-tools 0.116 už je opravena:

diff --git a/scripts/nfs b/scripts/nfs
index 6fa0c43..967e67f 100644
--- a/scripts/nfs
+++ b/scripts/nfs
@@ -66,7 +66,8 @@ mountroot()
 
 	# loop until nfsmount succeeds
 	do_nfsmount
-	while [ ${retry_nr} -lt ${delay} ] && [ ! -e ${rootmnt}${init} ]; do
+	while [ ${retry_nr} -lt ${delay} ] \
+		&& ! chroot "${rootmnt}" test -x "${init}" ; do
 		[ "$quiet" != "y" ] && log_begin_msg "Retrying nfs mount"
 		/bin/sleep 1
 		do_nfsmount

Řízení zaváděcího procesu v ramdisku

Skript init, který je v kořeni ramdisku, se generuje na základě konfigurace v souboru /etc/initramfs-tools/initramfs.conf při sestavení souboru initrd. Ostatní skripty, které má ramdisk v adresáři /scripts. Se při jeho sestavení, či aktualizaci kopírují z adresáře /etc/initramfs-tools/scripts.

top

Během této fáze jádro provádí inicializaci existujících fyzických zařízení. Ty se přitom ohlašují svým specifickým kódem, na jehož základě jádro provádí identifikaci a natažení příslušného ovladače.

Protože k zařízení může existovat více ovladačů, které pochopitelně nelze používat současně, je součástí ramdisku adresář /etc/modprobe.d, s konfiguračními soubory k jaderným modulům, ve kterých může být použití konfliktních modulů zakázáno.

Může se však vyskytnout situace, kdy některý z automaticky natahovaných modulů obsahuje chybu, která vede ke hroucení jádra. Pro takové případy akceptuje jádro seznam zakázaných modulů předaný zavaděčem prostřednictvím volby blacklist

vmlinuz... blacklist="xfs jfs ceph" ...

I když pak může být do určité míry systém omezen, můžeme jej dostat do stavu kdy se dá problém vyřešit.

Poznámka Tabulka, podle které jádro provádí tuto identifikaci se generuje před(!) sestavením, či aktualizací ramdisku příkazem depmod

modules

Seznam těchto modulů může být uložen rovnou v ramdisku - soubor /conf/modules, ale také předán jádru prostřednictvím zavaděče

vmlinuz... modules="aufs reisefs" ...

premount

Kromě jaderných modulů a skriptů, které řídí zaváděcí proces, obsahuje ramdisk také nástroje a utility, co umožňují zavést systém ze sdíleného NFS adresáře, sestavit RAID pole, nahodit LVM skupinu, používat kryptovaný souborový systém, opravit poškozený souborový systém aj.

Poznámka Protože v tomto bodě vzniká při zavádění nečastěji problém, je parametr #premount výchozím pro volbu break, je-li uvedena bez parametru.

mount

Cestu k zařízení, na kterém má být uložen zaváděný systém, jádru předává zavaděč jako parametr volby root.

vmlinuz... root=/dev/sda1 ...

Skript init hodnotu /dev/sda1 uloží do proměnné ${ROOT}, která se před přepnutím do finálního systému zruší. V prostředí ramdisku si lze vypsat přes echo.

Během předchozí fáze mělo být zařízení připraveno a nyní se ho init pokusí připojit. Pokud se mu to nedaří, umožňuje přerušení ve fázi #mount zjistit proč.

Nejprve je třeba zkontrolovat obsah proměnné ${ROOT}. Jeví-li se v pořádku, je třeba zjistit, zda-li příslušné zařízení skutečně existuje.

Pokud ne, tak to může znamenat že..

  • jádru chybí potřebný ovladač (po kompilaci modulu nebyl aplikován depmod a zaktualizován příslušný ramdisk)
  • nebo došlo k přejmenování zařízení (kupř. po přidání dalšího blokového zařízení do počítače, či při změně pořadí diskových oddílů)
  • nebo z nějakého důvodu nedošlo k sestavení příslušného blokového zařízení (v případě RAID pole či LVM skupiny)
Poznámka Některé zavaděče, jako např. GRUB, umožňují parametr volby root změnit ještě před spuštěním zaváděcího procesu, ale jsou situace, kdy to udělat nelze a je třeba úpravu provést v ramdisku.
Upozornění Jednou z příčin, proč se nepodaří zařízení připojit, může být poškozený souborový systém. Proto musí být součástí ramdisku také nástroje, které ho umožňují opravit.

Pokud v něm chybí, pak to znamená, že je během sestavení ramdisku neměl systém k dispozici.

V takovém případě je třeba nejprve souborový systém opravit jiným způsobem. A pak přes chroot provést aktualizaci ramdisku

bottom

Většinu souborových systémů nelze opravit, pokud se s nimi pracuje. Systém uložený v ramdisku je tak ideálním prostředím pro takové operaci, protože

init

Na závěr přepne do finálního systému a spustí z něj /sbin/init

Pro úspěšné zavedení systému je tak nutné odstavit služby, které by se při startu pokoušely o rekonfiguraci síťového rozhraní přes které bude probíhat komunikace se vzdáleným úložištěm. V takovém případě by se totiž mohlo stát, že by stroj zůstal "viset" během zaváděcího procesu v ramdisku, bez možnosti přerušení zaváděcího procesu.


Úpravy ramdisku

Pro práci s ramdiskem jsou určeny nástroje z balíku initramfs-tools. Ale lze si poradit i bez nástrojů z tohoto balíku - pomocí běžně dostupných systémových utilit.

Bezdiskový systém

Upozornění Pokud chceme provozovat linuxový systém jako bezdiskový, tak musíme zajistit, aby měl stroj v okamžiku, kdy se pokusí o připojení zařízení kde má uložen systémem, funkční síťové připojení.

Výpis obsahu ramdisku

Pro výpis obsahu ramdisku lze použít nástroj lsinitramfs. Pokud ale není k dispozici, stačí vědět, že ramdisk je v podstatě pouze zkomprimovaný cpio archív

zcat /boot/initrd.img-3.2.0-2-686-pae | cpio -t

Rozbalení ramdisku

Pokud si chceme důkladněji prozkoumat obsah ramdisku, tak si ho můžeme vybalit do samostatného adresáře

zcat /boot/initrd.img-3.7.7 | cpio -i

Zabalení ramdisku

Po případných úpravách ho pak zase můžeme zabalit - pro jistotu do nového souboru

find . | cpio -o -H newc | gzip > /boot/initrd.img-3.7.7-upraveny

Korektní sestavení ramdisku u Debianu

Výše uvedené postupy je dobré znát, ale pro korektní sestavení ramdisku je rozumnější používat nástroj update-initramfs z balíku initramfs-tools. Ten totiž zajistí - na základě konfigurace - aby sestavený ramdisk obsahoval vše potřebné i po každé aktualizaci, bez toho, že by bylo nutné pokaždé vytvářet či upravovat prostředí ramdisku ručně.

Ostatně stejný nástroj se volá i při instalaci nového jádra.

Konfigurační soubory a skripty spojené se sestavením ramdisku, se v systému vyskytují na třech místech:

  1. Adresáře v /etc/initramfs-tools jsou určeny pro uživatelskou konfiguraci
  2. Do adresáře /usr/share/initramfs-tools umísťují své skripty instalační balíčky
  3. A do adresáře /var/lib/initramfs-tools se ukládá kontrolní součet (realizovaný přes shasum ) ramdisku sestaveného pomocí initramfs-tools


kmod - se stará o načítání jaderných modulů v ramdisku

  1. načte shellový skript /hook-functions (používá funkce zde uvedené)
  2. zavolá funkci copy_exec, (která udělá co?)
  3. zkopíruje nástroje modprobe a rmmod
  4. se stará o include jaderných modulů.

udev -

Struktura konfiguračních adresářů pro sestavení ramdisku

/conf.d
/hooks 
/scripts
	/init-bottom
	/init-top
	… 	
initramfs.conf
modules
update-initramfs.conf
initramfs.conf
Je konfigurační soubor, který použije mkinitramfs při sestavení ramdisku a nakopíruje do adresáře /conf (ramdisku). V něm je určeno, zda-li se má použít komprese, kolik procent dostupné paměti se má vyčlenit pro tmpfs, do kterého se vybalí obsah ramdisku, atp.
update-initramfs.conf
Je konfigurační soubor pro nástroj update-initramfs, který se volá automaticky kupř. při aktualizaci linuxového jádra. V něm lze nastavit, jestli se má původní ramdisk odzálohovat, nebo se má rovnou přepsat.
modules
Obsahuje seznam modulů, které mají začleněny do ramdisku. By default se totiž do ramdisku zahrnou jen ty moduly, které jsou zavedeny v jádře během sestavení ramdisku. Na to je třeba dát velký pozor! Protože pokud sestavíte nový ramdisk bez ovladače pro souborový FS na kterém bude systém s ostatními moduly jádra, tak se vám spouštění systému nepodaří opravit, pokud nebudete mít ještě jiné jádro s ramdiskem, které ho mít bude.
/hooks
Adresář s uživatelskými skripty, které se spouští při sestavení ramdisku. S jejich pomocí lze do něj přidat další aplikace a moduly. A pomocné funkce se postarají o to, aby byly splněny případné závislosti. Potřebné moduly v takovém případě nutné přidávat do souboru modules.
/scripts
Obsahuje podadresáře, ve kterých jsou skripty, které spouští výchozí init skript v různých fázích zaváděcího procesu.
Poznámka Všechny skripty, ať již v adresáři /hooks, nebo v podadresářích adresáře /scripts musí být spustitelné. Pokud na to zapomenete, sestavení neprojde podle vašich představ a příslušné soubory či moduly budou v ramdisku chybět!
Upozornění Od jádra verze >= 3.5 je modul nfs rozdělen na více modulů

Reboot z prostředí ramdisku

echo b > /proc/sysrq-trigger

Vypnutí z prostředí ramdisku:

echo o > /proc/sysrq-trigger

Monitorování a řešení problémů během zaváděcího procesu

Zaváděcí parametry jádra

S jakými parametry bylo zavedeno jádro se lze dozvědět po spuštění systému z obsahu souboru /proc/cmdline

Debug ramdisku

vmlinuz... debug ...

Lokální přesměrování konzolového výstupu

vmlinuz... console=ttyS0 ...

Síťové přesměrování konzolového výstupu

Pokud má jádro zakompilovaný modul netconsole, lze výstup přesměrovat po síti.

vmlinuz... netconsole=6665@[IP stanice]/[síťové zařízení],6666@[IP vzdálené stanice]/[MAC síťového rozhraní vzdálené stanice]

Na vzdálené stanici ale musí na příslušném portu naslouchat aplikace. Použít lze kupř. utilitu nc

nc -u -l -p 6666