Gentoo Logo

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 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() {
  (Informaţia despre dependenţe)
}

start() {
  (Comenzi necesare pentru a porni serviciul)
}

stop() {
  (Comenzi necesare pentru a opri serviciul)
}

restart() {
  (Comenzi necesare pentru a reporni serviciul)
}

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    # Wait 3 seconds before starting again
  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

(Copiaţi toate serviciile din nivelul default în nivelul offline)
# cd /etc/runlevels/default
# for service in *; do rc-update add $service offline; done
(Ştergeţi serviciile nedorite din nivelul offline)
# rc-update del net.eth0 offline
(Afişaţi serviciile active din nivelul offline)
# rc-update show offline
(Exemplu de afişare parţial)
               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ă ] [ > ] [ >> ]


Imprimare

View all

Actualizat la 9 Iunie 2005

Această traducere nu mai este întreţinută

Sumar: Gentoo utilizează un tipar de script de iniţializare care, dintre toate caracteristicile, permite decizii în funcţie de dependenţe şi script-uri de iniţializare virtuale. Acest capitol explică toate aceste aspecte şi explică cum să manipulaţi aceste script-uri.

Sven Vermeulen
Autor

Roy Marples
Autor

Daniel Robbins
Autor

Chris Houser
Autor

Jerry Alexandratos
Autor

Seemant Kulleen
Dezvoltator Gentoo x86

Tavis Ormandy
Dezvoltator Gentoo Alpha

Jason Huebel
Dezvoltator Gentoo x86

Guy Martin
Dezvoltator Gentoo HPPA

Pieter Van den Abeele
Dezvoltator Gentoo PPC

Joe Kallar
Dezvoltator Gentoo SPARC

John P. Davis
Editor

Pierre-Henri Jondot
Editor

Eric Stockbridge
Editor

Rajiv Manglani
Editor

Jungmin Seo
Editor

Stoyan Zhekov
Editor

Jared Hudson
Editor

Colin Morey
Editor

Jorge Paulo
Editor

Carl Anderson
Editor

Jon Portnoy
Editor

Zack Gilburd
Editor

Jack Morgan
Editor

Benny Chuang
Editor

Erwin
Editor

Joshua Kinard
Editor

Tobias Scherbaum
Editor

Lars Weiler
Editor

Jochen Maes
Editor

Grant Goodyear
Corector

Gerald J. Normandin Jr.
Corector

Donnie Berkholz
Corector

Ken Nowack
Corector

Alin Dobre
Translator Responsabil

Ion Mudreac
Translator

Teddy Drăguţă
Translator

Talos Teodor
Translator

Dragoş Toma
Translator

Muntean Alex
Translator

George Nistorică
Translator

Emil Sîrbu
Translator

Donate to support our development efforts.

Copyright 2001-2013 Gentoo Foundation, Inc. Questions, Comments? Contact us.