Produkty Novinky Články Návody Kontakty

Konfigurační soubory - I

Konfigurace operačního systému Linux systému je řešena pomocí konfiguračních souborů a skriptů. My si ve třech čátech představíme jednotlivé skripty a soubory. Začneme představení konfiguračních souborů a skriptů, které mají na starost inicializaci a bezpečné ukončení běhu systému.

Soubor /etc/inittab

Na konci bootování jádra je spuštěn proces init (/sbin/init), první uživatelský proces, který má za úkol dokončit spouštění systému. Chování procesu init určuje obecně právě obsah souboru /etc/inittab.
Jelikož proces init je v našem případě vlastně jen symbolickým odkazem na spustitelný soubor Busyboxu, musíme obsah souboru /etc/inittab oproti klasickému procesu init přizpůsobit specifiku Busyboxu.
Ve výchozí konfiguraci Busybox existenci souboru /etc/inittab nevyžaduje. My jsme Busybox ovšem nakonfigurovali tak, aby jeho přítomnost v systému Busybox vyžadoval. Díky tomu můžeme ovlivňovat chování systému při jeho spouštění a vypínání.
Obsah souboru:
# /etc/inittab
​
# format <id>:<runlevels>:<action>:<proces>
​
# startup 
::sysinit:/etc/init.d/rcS
​
# when restarting init process 
::restart:/sbin/init
​
# restart or shutdown system 
::ctrlaltdel:/sbin/reboot 
::shutdown:/etc/init.d/rcK
​
# virtual terminals with login shell
tty1::respawn:-/bin/sh 
tty2::respawn:-/bin/sh
​
# serial port terminals with login shell
ttyS0::respawn:/sbin/getty -L ttyS0 38400 vt100
Něco málo k jeho formátu. Obsah souboru se skládá z několika řádků, které mají daný pevný formát:
  • Položka id určuje jednak číslo kontrolního terminálu (proto jí u většiny položek necháváme prázdnou) a pak také určuje na kterých konzolách se má spustit shell, případně login.
  • Položka runlevels je Busyboxem ignorována, protože úrovně běhu Busybox nepodporuje.
  • Položka action definuje, co má proces init dělat s programem určeným položkou process.
  • Položka proces definuje program, který je předmětem dané akce (action).
Vysvětlivky (k obsahu souboru):
  • při startu systému (akce sysinit) ještě předtím než proces init otevře systémovou konzoli a umožní přihlášení uživatele, se má provést skript /etc/init.d/rcS.
  • při vypínání systému (akce shutdown) se má jako úplně poslední uživatelský program provést úklidový skript spustí skript /etc/init.d/rcK.
  • při stisku Ctrl+Alt+Del (akce ctrlatldel) se provede příkaz reboot, který provede reset systému.
  • při restartu procesu init (akce restart) se má opět spustit proces init.
  • proces init má otevřít dva virtuální teminály, spustit na nich shell daný symbolickým odkazem /bin/sh a vyžadovat příhlášení uživatele. Povinnost se přihlásit je dána pomlčkou před cestou k shellu (bohužel nám to v žádné dostupné verzi Busyboxu dosud nefungovalo). Akce respawn říká, že v případě ukončení běhu shellu má být tento znovu spuštěn.
  • krom toho, má proces init také čekat na terminálové spojení na sériovém portu ttyS0 rychlostí 38400 Bd, vyžadovat příhlášení uživatele (volba -L) a očekávat terminálové zařízení typu VT100.

Skript /etc/init.d/rcS

Jak jsme si řekli před chvílí, shellový skript /etc/init.d/rcS má za úkol provést poslední kroky při startu systému ještě předtím, než jsou otevřena terminálová spojení a uživatel může začít se systémem pracovat. Typicky se v něm provádí nastavení síťového adaptéru (IP adresa, atd.), rozběhnutí služeb systému, připojení zbývajících souborových systémů (kromě kořenového - ten je už připojen při bootování jádra), atd.
Obsah souboru:
#!/bin/sh
​
# /etc/init.d/rcS: The first script started by init process
​
# user settings
IP=192.168.1.15
NETMASK=255.255.255.0
GATEWAY=192.168.1.254
​
# user functions
check_status()
{
        if [ $? = 0 ]
        then
                echo "[done]"
        else
                echo "[failed]"
        fi
}
​
mountit() 
{     
        if ! mountpoint -q $1
        then
                echo -en "Mounting $1...\t\t\t\t"
                mount $1 &> /dev/null
                check_status
        fi
}
​
# 1: print an intro
echo 
cat /etc/issue.rcs
echo
​
# 2: create /dev on RAM disk to be able to run out of RFS 
mountit /dev
​
# 3: create mount points on /dev dir created in RAM 
mkdir -p /dev/pts 
mkdir -p /dev/shm
​
# 4: mount file systems needed by kernel and processes
mountit /proc
mountit /sys
mountit /dev/pts
mountit /dev/shm
​
# 5: initialize and startup mdev (simple replacemnt of udev)
echo -en "Initializing mdev...\t\t\t\t"
echo /sbin/mdev > /proc/sys/kernel/hotplug
/sbin/mdev -s &> /dev/null 
check_status
​
# 6: mount /tmp as RAM disk
mountit /tmp
chmod 1777 /tmp
​
# 7: start system logger
echo -en "Starting system logger...\t\t\t" 
start-stop-daemon -S -q -x syslogd
check_status
​
# 8: start up network interface
echo -e "Enabling localhost interface...\t\t\t[done]"
ifconfig lo up 127.0.0.1 
route add 127.0.0.1 lo
​
echo -e "Enabling network interface...\t\t\t[done]"
ifconfig eth0 up $IP netmask $NETMASK
route add default gw $GATEWAY
​
# 9: start telnet daemon
echo -en "Starting telnetd...\t\t\t\t" 
start-stop-daemon -S -q -x telnetd 
check_status
​
# 10: mount all remaing file systems
echo -en "Mounting user file systems...\t\t\t"
mount -a &> /dev/null
check_status
​
# 11: print a logon screen
echo 
echo 
echo "EmlinDist: Embedded linux distribution by Elvoris s.r.o."
echo
Vysvětlivky (body odpovídají číslům v komentářích):
  1. Vytiskneme obsah souboru /etc/issue.rcs - úvodní obrazovku.
  2. Na místo původního adresáře /dev v RFS připojíme RAM disk. Tím jednak překryjeme původní obsah adresáře a hlavně bude možné vytvářet soubory zařízení za běhu systému bez ohledu na to, zda RFS je připojen v režimu jen pro čtení, či zda umožňuje i zápis. Tento krok vyžaduje správce souborů zařízení mdev (viz dále).
  3. V novém adresáři /dev v RAM disku vytvoříme adresáře /dev/pts a /dev/shm. První z nich je využíván pseudo terminály (telnetový klient, emulátor terminálu v X windows - xterm. atd.). Druhý pak pro meziprocesovou komunikaci.
  4. V této fázi připojíme všechny potřebné virtuální souborové systémy, které mohou být vyžadovány službami (démony) a procesy. Využijeme přitom uživatelskou funkci mountit() a záznamů v souboru /etc/fstab (viz dále), čímž si zkrátíme zápis příkazů.
  5. Inicializujeme správce souborů zařízení mdev. Nejprve jej zaregistrujeme k odběru událostí jádra generovaných při přidání zařízení, díky čemuž mdev pro každé přidané zařízení, které nalezne v svém konfiguračním souboru, vytvoří odpovídající soubor zařízení. A pak mu přikážeme, aby pro všechny zařízení detekované při startu systému, vytvořil soubory zařízení. Všimněme si použití funkce check_status, která nedělá nic jiného, než že ze proměnné shellu $? vyčte návratovou hodnotu posledního příkazu a podle toho zobrazí na systémové konzoli zprávu o úspěchu nebo selhání posledního příkazu.
  6. K adresáři tmp/ připojíme RAM disk a nastavíme mu potřebná práva přístupu.
  7. Spustíme systémovou službu (démona) syslogd, který vyčítá bufer zpráv z jádra (/proc/kmsg), přijímá zprávy z mnoha jiných programů, filtruje je a ukládá do souboru /var/log/messages. Využíváme k tomu utilitu start-stop-daemon, která je určena pro spouštění a zastavování systémových služeb (démonů).
  8. Nastavíme a spustíme (příkaz ifconfig) lokální síťové rozhraní (lokální síťová smyčku). Pak přidáme záznam do směrovací tabulky (příkaz route) pro tuto síť.
    Nastavíme a spustíme síťové rozhraní počítače. Uvedená IP adresa je IP adresou našeho počítače. Abychom mohli komunikovat mimo naši síť, musíme přidat výchozí směrovací tabulku s uvedením síťové brány, přes kterou je tato síť dosažitelná.
  9. Spustíme telnetový server, takže se bude možné k našemu počítači připojit pomocí telnetového klienta.
  10. Připojíme všechny zbývající souborové systémy, které jsou uvedeny v souboru /etc/fstab a které nebyly dosud připojeny.
  11. Zobrazíme přihlašovací obrazovku. Tím provádění inicializačního skriptu končí. Proces init otevře virtuální terminály a bude čekat na přihlášení uživatele (nebo rovnou spustí instanci shellu, pokud není přihlášení vyžadováno).

Skript /etc/init.d/rcK

Ukončovací skript /etc/init.d/rcK je procesem init volán v případě vypínání systému. Je víceméně opakem inicializačního skriptu /etc/init.d/rcS, byť ne všechny aktivity provedené inicializačním skriptem musí být explicitně v ukončovacím skriptu ukončeny.
Obsah souboru:
#!/bin/sh
​
# /etc/init.d/rcK: The script called on shutdown
​
# 1: print byebye message
echo 
echo 
echo "Bye bye"
echo
​
# 2: stop services
echo -e "Stopping daemons...\t\t\t[done]"
start-stop-daemon -K -q -x syslogd
start-stop-daemon -K -q -x telnetd
​
# 3: flush disk buffers
sync
​
# 4: umount file systems if neccessary (CDROMs, hotplug, etc.)
echo -e "Umounting file systems...\t\t[done]" 
umount -a -r 2>/dev/null
Vysvětlivky (body odpovídají číslům v komentářích):
  1. Zobrazíme zprávu u ukončování běhu systému
  2. Zastavíme všechny systémové služby, které běží.
    Poznámka: Pokud se pokusíme zastavit systémovou službu, která neběží, nic se nestane. Proto nemá smysl, řešit nějaký mechanismu, který by evidoval, která služba byla při startu systému spuštěna a která ne.
  3. Příkaz flush zajistí, že obsah všech buferů se zapíše na připojené harddisky.
  4. Posledním krokem je odpojení všech připojených souborových systémů. U těch, u kterých se to nepodaří (např. protože má nějaký program otevřený soubor), se příkaz umount pokusí je připojit v režimu pouze pro čtení. Odpojování souborových systému má zabránit porušení jejich konzistence.