Avertisment :
Acest document nu este valid ş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 sistemului 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
transferată 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ă conectivitatea reţelei şi single este utilizat când
se repară sistemul.
Utilizarea Script-urilor de Iniţializare
Script-urile pe care procesul rc le porneşte sunt denumite script-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 (în 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 unei 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.
Sintaxa script-urilor de iniţializare din Gentoo este bazată pe Bourne Again
Shell (bash), deci puteţi utiliza construcţii compatibile cu bash în
interiorul script-ului de iniţializare.
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ă pornească
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 |
# 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 |
|
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" în loc să
definiţi un al doilea nivel "default".
[ << ]
[ < ]
[ Acasă ]
[ > ]
[ >> ]
Conţinutul acestui document este publicat sub licenţa Creative Commons -
Attribution / Share Alike.
|