Avertisment :
Acest manual a fost înlocuit cu o versiune mai nouă şi nu mai este întreţinut.
|
[ << ]
[ < ]
[ Acasă ]
[ > ]
[ >> ]
4. Script-urile de Iniţializare
Conţinut:
4.a. Nivele de execuţie
Pornirea Sistemului
La procesul de boot al sistemului, veţi observa mult text defilând. Dacă acordaţi o mică atenţie, veţi observa că acest text este acelaşi de fiecare dată când reporniţi sistemul. Secvenţa tuturor acestor acţiuni este denumită secvenţa de boot şi este (mai mult sau mai puţin) definită static.
Mai întâi, aplicaţia boot loader va încărca imaginea de kernel, definită în configurarea acesteia, în memorie după ce-i specifică CPU-ului să ruleze kernel-ul. Când kernel-ul este încărcat şi rulează, acesta iniţializează toate structurile şi sarcinile specifice kernel-ului şi rulează procesul init.
Apoi, acest proces se asigură că toate sistemele de fişiere (definite în /etc/fstab) sunt mount-ate şi gata de utilizare. Apoi, execută unele script-uri localizate în /etc/init.d, care vor porni serviciile necesare pentru a avea un sistem ce a trecut cu succes procesului de boot.
În final, când toate script-urile sunt executate, init activează terminalele (în majoritatea cazurilor doar consolele virtuale ce se ascund în spatele combinaţiilor Alt-F1, Alt-F2, etc.) ataşându-le un proces special numit agetty. Acest proces va asigura procesul de login prin intermediul acestor terminale prin rularea login.
Script-uri de Iniţializare
Acum, init nu doar execută script-urile din /etc/init.d în mod aleator. Mai mult, nu rulează toate script-urile din /etc/init.d, ci doar script-urile care îi sunt specificate spre execuţie. El decide ce script-uri sa execute prin analizarea /etc/runlevels.
Mai întâi, init rulează script-urile din /etc/init.d ce au link-uri simbolice în /etc/runlevels/boot. De obicei, va rula script-urile în ordine alfabetică, dar unele script-uri conţin informaţii despre dependenţe, specificând sustemului că un alt script trebuie rulat înainte ca ele să fie pornite.
Când sunt executate toate script-urile ce deţin referinţe în /etc/runlevels/boot, init va continua să ruleze script-uri ce au link-uri simbolice spre ele în /etc/runlevels/default. Din nou, va utiliza ordinea alfabetică pentru a decide ce script să ruleze mai întâi, doar dacă un script conţine o informaţie despre dependenţe, caz în care ordinea este schimbată pentru a oferi o secvenţă de pornire validă.
Cum Funcţionează Init
Bineînţeles, init nu decide totul singur. El necesită un fişier de configurare ce specifică ce acţiuni trebuie să întreprindă. Acest fişier de configurare este /etc/inittab.
Dacă vă amintiţi secvenţa de boot ce tocmai am descris-o, vă veţi aminti că prima acţiune a init este mount-area tuturor sistemelor de fişiere. Acest lucru este definit în următoarea linie din /etc/inittab:
Cod 1.1: Linia de iniţializare a sistemului din /etc/inittab |
si::sysinit:/sbin/rc sysinit
|
Această linie îi specifică aplicaţiei init faptul că trebuie să ruleze /sbin/rc sysinit pentru a iniţializa sistemul. Script-ul /sbin/rc are ca scop iniţializarea sistemului, deci aţi putea afirma că init nu execută prea multe acţiuni -- el delegă sarcina de iniţializare a sistemului altui proces.
Apoi, init execută toate script-urile ce au conţinute link-uri simbolice în /etc/runlevels/boot. Această acţiune este definită de următoare linie:
Cod 1.2: Iniţializarea sistemului, continuată |
rc::bootwait:/sbin/rc boot
|
Din nou, script-ul rc execută sarcinile necesare. Notaţi că opţiunea tranferată lui rc (boot) este aceeaşi ca subdirectorul din /etc/runlevels ce este utilizat.
Acum, init îşi verifică fişierul de configurare pentru a analiza ce nivel de execuţie să ruleze. Pentru a decide această acţiune, citeşte următoarea linie din /etc/inittab:
Cod 1.3: Linia initdefault |
id:3:initdefault:
|
În acest caz (pentru care majoritatea utilizatorilor Gentoo îl vor folosi), identificatorul nivelului de execuţie este 3. Utilizând această informaţie, init verifică ceea ce trebuie să ruleze pentru a porni nivelul de execuţie 3:
Cod 1.4: Definiţiile nivelului de execuţie |
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
|
Linia ce defineşte nivelul 3, din nou, utilizează script-ul rc pentru a porni serviciile (acum cu argumentul default). Din nou, notaţi că argumentul lui rc este acelaşi ca subdirectorul din /etc/runlevels.
Când rc este terminat, init decide ce console virtuale să activeze şi ce comenzi trebuie rulate pentru fiecare consolă:
Cod 1.5: Definirea consolelor virtuale |
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
|
Ce este un nivel de execuţie?
Aţi observat că init utilizează o schemă de numerotare pentru a decide ce nivel de execuţie trebuie să activeze. Un nivel de execuţie este un stadiu în care sistemul rulează şi conţine o colecţie de script-uri (scripturi de nivele de execuţie sau initscipt-uri) ce trebuie executate când intraţi în sau ieşiţi dintr-un nivel de execuţie.
În Gentoo, există şapte nivele de execuţie: trei nivele de execuţie interne, şi patru nivele de execuţie definite de utilizatori. Nivelele interne sunt denumite sysinit, shutdown şi reboot şi execută acelaşi lucru ca numele lor: iniţializarea sistemului, oprirea sistemului, repornirea sistemului.
Nivelele de execuţie definite de utilizator sunt cele ce sunt localizate în subdirectorul /etc/runlevels: boot, default, nonetwork şi single. Nivelul de execuţie boot rulează toate serviciile necesare sistemului utilizate de toate celelalte nivele de execuţie. Cele trei nivele de execuţie diferă prin serviciile care le pornesc: default este pentru utilizarea zilnică, nonetwork este utilizat în cazul în care nu este necesară conctivitatea reţelei şi single este utilizat când se repară sistemul.
Utilizarea Script-urilor de Iniţializare
Scrip-urile pe care procesul rc le porneşte sunt denumite scrip-uri de iniţializare. Fiecare script în /etc/init.d poate fi executat cu argumentele start, stop, restart, pause, zap, status, ineed, iuse, needsme, usesme sau broken.
Pentru a porni, opri sau reporni un serviciu (şi toate serviciile dependente), trebuie utilizaţi parametrii start, stop şi restart:
Cod 1.6: Pornirea Postfix |
# /etc/init.d/postfix start
|
Notă:
Doar serviciile ce necesită serviciul dat prin declaraţia need sunt oprite sau repornite. Alte servicii dependente (cele care depind prin declaraţia use de serviciu dar nu îl necesită) nu sunt afectate.
|
Dacă doriţi să opriţi un serviciu, dar nu şi serviciile ce depind de el, puteţi utiliza argumentul pause:
Cod 1.7: Oprirea Postfix dar păstrarea serviciilor dependente pornite |
# /etc/init.d/postfix pause
|
Dacă doriţi să analizaţi în ce stadiu se află un serviciu (in starea started, stopped, paused, ...) puteţi utiliza argumentul status:
Cod 1.8: Informaţia despre starea serviciului postfix |
# /etc/init.d/postfix status
|
Dacă informaţia de stare precizează că serviciul rulează, dar ştiţi sigur că nu rulează, puteţi reseta informaţia de stare ca "stopped" cu argumentul zap:
Cod 1.9: Resetarea informaţiei de stare pentru postfix |
# /etc/init.d/postfix zap
|
Pentru a interoga în scopul vizualizării dependenţelor unui serviciu, puteţi utiliza iuse sau ineed. Cu ineed puteţi vizualiza serviciile ce chiar sunt necesare pentru funcţionarea corectă a serviciului. Pe de altă parte iuse afişează serviciile ce pot fi folosite de serviciu, dar nu sunt necesare pentru funcţionarea corectă.
Cod 1.10: Interogarea în scopul obţinerii unei liste de servicii de care depinde Postfix |
# /etc/init.d/postfix ineed
|
În mod similar, puteţi interoga în scopul obţinerii serviciilor ce necesită serviciul (needsme) sau îl pot utiliza (usesme):
Cod 1.11: Interogarea în scopul vizualizării unel liste a tuturor serviciilor ce necesită Postfix |
# /etc/init.d/postfix needsme
|
În final, puteţi interoga în scopul vizualizării dependenţelor lipsă a unui serviciu:
Cod 1.12: Interogarea în scopul obţinerii lista dependenţelor lipsă pentru Postfix |
# /etc/init.d/postfix broken
|
4.b. Utilizarea rc-update
Ce este rc-update?
Sistemul de iniţializare Gentoo utilizează o structură de dependenţe pentru a decide ce servicii trebuie să fie pornite mai întâi. Cum, aceasta este o sarcină plictisitoare pentru care nu am dori ca utilizatorii noştri să o seteze manual, am creat utilitare ce facilitează administrarea nivelelor de execuţie şi script-urilor de iniţializare.
Cu ajutorul rc-update puteţi adăuga şi scoate script-uri de iniţializare pentru un nivel de execuţie. Utilitarul rc-update va interoga automat script-ul depscan.sh pentru a reconstrui structura de dependenţe.
Adăugarea şi Ştergerea de Servicii
Deja aţi adăugat script-uri de iniţializare nivelului de execuţie "default" în timpul instalării Gentoo. La acea vreme, probabil că nu înţelegeaţi ce reprezintă "default", dar acum ar trebui. Script-ul rc-update necesită un al doilea argument ce defineşte acţiunea: add (adăugare), del (ştergere) sau show (vizualizare).
Pentru a adăuga sau a şterge un script de iniţializare, trebuie doar să pasaţi argumentul add sau del, urmat de script-ul de iniţializare şi de nivelul de execuţie. Spre exemplu:
Cod 2.1: Ştergerea Postfix din nivelul de execuţie default |
# rc-update del postfix default
|
Comanda rc-update show va afişa toate script-urile de iniţializare şi în ce nivele de execuţie vor fi rulate:
Cod 2.2: Receiving init script information |
# rc-update show
|
4.c. Configurarea Serviciilor
De ce Nevoia pentru Configurări Suplimentare?
Script-urile de iniţializare pot fi destul de complexe. De aceea, nu este de dorit ca utilizatorii să editeze script-ul de iniţializare direct, deoarece ar fi mai expus spre erori. Este, cu toate acestea, important să puteţi să configuraţi un asemenea serviciu. Spre exemplu, aţi putea adăuga mai multe opţiuni serviciului în sine.
Un al doilea motiv pentru a avea această configuraţie separat script-ului de iniţializare este să poată actualiza script-urile de iniţializare fără să aibă grija faptului că modificările în configuraţia dvs. vor fi refăcute.
Directorul /etc/conf.d
Gentoo oferă o cale uşoară de a configura un asemenea serviciu: fiecare script de iniţializare ce poate fi configurat are un fişier în /etc/conf.d. Spre exemplu, script-ul de iniţializare apache2 (denumit /etc/init.d/apache2) are un fişier de configurare denumit /etc/conf.d/apache2, ce poate conţine opţiunile ce doriţi să le pasaţi aplicaţiei server Apache 2 în momentul în care este pornit:
Cod 3.1: Variabilă definită în /etc/conf.d/apache2 |
APACHE2_OPTS="-D PHP4"
|
Un asemenea fişier de configurare conţine variabile şi numai variabile (exact ca în cazul /etc/make.conf), facilitând configurarea serviciilor. De asemenea, permite oferirea unor informaţii mai detaliate în despre variabile (sub forma comentariilor).
4.d. Scrierea de Script-uri de Iniţializare
Chiar Trebuie?
Nu, scrierea unui script de iniţializare nu este, de obicei, necesară, deoarece Gentoo oferă script-uri de iniţializare gata-de-utilizare pentru toate serviciile oferite. În orice caz, puteţi avea instalat un serviciu fără a fi utilizat Portage, caz în care veţi dori să creaţi un script de iniţializare.
Nu utilizaţi un script de iniţializare oferit de un serviciu dacă nu este scris explicit pentru Gentoo: Script-urile de iniţializare din Gentoo nu sunt compatibile cu script-urile de iniţializare din alte distribuţii!
Schema
Schema de bază pentru un script de iniţializare poate fi vizualizată mai jos.
Cod 4.1: Schema de bază pentru un script de iniţializare |
#!/sbin/runscript
depend() {
}
start() {
}
stop() {
}
restart() {
}
|
Orice script de iniţializare necesită definirea funcţiei start. Toate celelalte secţiuni sunt opţionale.
Dependendenţe
Există două dependenţe ce le puteţi defini: use şi need. Aşa cum am menţionat anterior, dependenţa need este mai strictă decât dependenţa use. Urmărind acest tip de dependenţă puteţi manipula serviciul de care depindeţi, sau dependenţa virtuală.
O dependenţă virtuală este o dependenţă oferită de un serviciu, dar nu este oferită doar de acel serviciu. Script-ul dvs. de iniţializare poate depinde de o aplicaţie de tip logger de sistem, dar sunt multe aplicaţii de acest tip disponibile (metalogd, syslog-ng, sysklogd, ...). Cum, nu puteţi depinde de fiecare din acestea prin declaraţia need (nici un sistem nu are toate aplicaţiile de tip logger de sistem instalate si rulând), ne asigurăm că toate aceste servicii oferă prin declaraţia provide o dependenţă virtuală.
Să aruncăm o privire asupra informaţiilor despre dependenţe pentru serviciul postfix.
Cod 4.2: Informaţia despre dependenţe pentru Postfix |
depend() {
need net
use logger dns
provide mta
}
|
După cum observaţi, serviciul postfix:
- Necesită dependenţa (virtuală) net (ce este oferită, spre exemplu, de /etc/init.d/net.eth0)
- utilizează dependenţa (virtuală) logger (care este oferită, spre exemplu, de /etc/init.d/syslog-ng)
- utilizează dependenţa (virtuală) dns (care este oferită, spre exemplu, de /etc/init.d/named)
- oferă dependenţa (virtuală) mta (ce este comună pentru toate aplicaţiile de tip server de mail)
Controlarea Ordinii
În unele cazuri, nu veţi dori să cereţi rularea unui serviciu, dar veţi dori ca serviciul dvs. să fie pornit înaintea altui serviciu, prin declararea before (sau înaintea, prin declararea after) doar dacă este disponibil în sistem (notaţi condiţia - aceasta nu mai reprezintă dependenţă) şi dacă rulează în acelaşi nivel de execuţie (notaţi condiţia - pot fi invocate doar serviciile din acelaşi nivel de execuţie). Puteţi oferi această informaţie utilizând setările before sau after.
Ca exemplu, vom vizualiza setările serviciului Portmap:
Cod 4.3: Funcţia depend() în serviciul Portmap |
depend() {
need net
before inetd
before xinetd
}
|
Puteţi utiliza generalizarea "*" pentru a invoca toate serviciile din acelaşi nivel de execuţie, deşi nu este indicat.
Cod 4.4: Rularea unui script de iniţializare ca fiind primul script din nivelul de execuţie |
depend() {
before *
}
|
Funcţii Standard
Alături de funcţionalitatea depend(), puteţi avea nevoie să definiţi funcţia start(). Aceasta conţine toate comenzile necesare pentru a iniţializa serviciul. Este indicat să utilizaţi funcţiile ebegin şi eend pentru a informa utilizatorul asupra a ceea ce se întâmplă:
Cod 4.5: Exemplu pentru funcţia start() |
start() {
ebegin "Starting my_service"
start-stop-daemon --start --quiet --exec /path/to/my_service
eend $?
}
|
Dacă doriţi mai multe exemple ale funcţiei start(), vă rugăm să citiţi codul sursă disponibil în script-urile de iniţializare din directorul /etc/init.d. Cât despre start-stop-daemon, există o excelentă pagină de manual disponibilă dacă doriţi informaţii suplimentare:
Cod 4.6: Afişarea paginii de manual pentru start-stop-daemon |
# man start-stop-daemon
|
Alte funcţii ce le puteţi defini sunt: stop() şi restart(). Nu sunteţi obligat să definiţi aceste funcţii! Sistemul nostru de iniţializare este destul de inteligent pentru a completa aceste funcţii singur dacă utilizaţi start-stop-daemon.
Adăugarea de Opţiuni Personalizate
Dacă doriţi ca script-urile de iniţializare să suporte mai multe funcţii decât cele deja definite, va trebui să adăugaţi variabila opts şi să creaţi o funcţie cu acelaşi nume ca opţiunea. Spre exemplu, pentru a suporta o opţiune numită restartdelay:
Cod 4.7: Suportarea opţiunii restartdelay |
opts="${opts} restartdelay"
restartdelay() {
stop()
sleep 3
start()
}
|
Variabilele de Configurare pentru Serviciu
Nu trebuie să întreprindeţi nimic pentru a suporta un fişier de configurare în /etc/conf.d: dacă script-ul de iniţializare este executat, următoarele fişiere sunt interpretate automat (spre ex. variabilele sunt disponibile spre utilizare):
- /etc/conf.d/<your init script>
- /etc/conf.d/basic
- /etc/rc.conf
De asemenea, dacă script-ul dvs. de iniţializare oferă o dependenţă virtuală (cum ar fi net), fişierul asociat cu acea dependenţă (cum ar fi /etc/conf.d/net) va fi interpretat, de asemenea.
4.e. Schimbarea Comportamentului Nivelului de Execuţie
Cine ar putea beneficia de această funcţionalitate?
Mulţi utilizatori de laptop cunosc situaţia: acasă trebuie să ponească net.eth0, în timp ce în timpul călătoriei nu doresc să pornească net.eth0 (deoarece reţeaua nu este disponibilă). Cu Gentoo, puteţi modifica comportamentul nivelului de execuţie în concordanţă cu nevoile proprii.
Spre exemplu, puteţi crea un al doilea nivel de execuţie "default" în care să porniţi şi care are atribuite alte script-uri de iniţializare. Puteţi selecta la boot ce nivel de execuţie implicit să utilizaţi.
Utilizarea SOFTLEVEL
Mai întâi de toate, creaţi un director corespunzător nivelului de execuţie pentru cel de-al doilea nivel de execuţie "default" al dvs. Ca un exemplu, putem crea nivelul de execuţie offline:
Cod 5.1: Crearea unui director corespunzător unui nivel de execuţie |
# mkdir /etc/runlevels/offline
|
Adăugaţi script-urile de iniţializare noilor create nivele de execuţie. Spre exemplu, dacă doriţi să aveţi o copie exactă a nivelului de execuţie default, dar fără net.eth0:
Cod 5.2: Adăugarea script-urilor de iniţializare necesare |
# ls /etc/runlevels/default
acpid domainname local net.eth0 netmount postfix syslog-ng vixie-cron
# rc-update add acpid offline
# rc-update add domainname offline
# rc-update add local offline
# rc-update add syslog-ng offline
# rc-update add vixie-cron offline
|
Acum, editaţi configurarea aplicaţiei bootloader şi adăugaţi o nouă intrare pentru nivelul de execuţie offline. Spre exemplu, în /boot/grub/grub.conf:
Cod 5.3: Adăugarea unei intrări pentru nivelul de execuţie offline |
title Gentoo Linux Offline Usage
root (hd0,0)
kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offline
|
Iată că totul este setat, acum. Dacă veţi porni sistemul şi selecta noua intrare la boot, nivelul de execuţie offline va fi rulat în locul celui implicit, default.
Utilizarea BOOTLEVEL
Utilizarea bootlevel este complet analoagă cu cea softlevel. Singura diferenţă este că definiţi un nou nivel de execuţie "boot" in loc să definiti un al doilea nivel "default".
[ << ]
[ < ]
[ Acasă ]
[ > ]
[ >> ]
Conţinutul acestui document este publicat sub licenţa Creative Commons -
Attribution / Share Alike.
|