[ << ]
[ < ]
[ Etusivu ]
[ > ]
[ >> ]
4. Initskriptit
Sisällysluettelo:
4.a. Runlevelit
Järjestelmän käynnistys
Järjestelmän käynnistyessä liuta tekstiä soljunee ohitse. Jos katsot tarkkaan,
ilmoitukset ovat samoja joka kerta. Tätä toimintojen sarjaa kutsutaan
käynnistyssekvenssiksi ja se on (enimmäkseen) staattisesti määrätty.
Ensimmäisenä käynnistyslatain lataa asetustenmukaisen ytimen muistiin, jonka
jälkeen suorittimelle annetaan käsky ytimen ajamisesta. Ytimen latauduttua
se käynnistää omat rakenteensa ja ajaa init-prosessin.
Tämä prosessi varmistaa (/etc/fstabissa) määriteltyjen
tiedostojärjestelmien liitokset ja käyttäkelpoisuuden. Tämän jälkeen
suoritetaan hakemistossa /etc/init.d sijaitsevia palveluita
jotka ovat käynnistykselle välttämättömiä.
Kun kaikki skriptit on vihdoin ajettu, init aktivoi terminaalit (yleensä,
virtuaalikonsolit jotka löytyvät näppäilemällä Alt-F1,
Alt-F2, jne.) liittämällä agetty-prosessin niihin. Tämä prosessi
huolehtii kirjautumismuodollisuuksista ajamalla komennon login.
Initskriptit
init ei tietenkään suorita satunnaisesti skriptejä hakemistosta
/etc/init.d. Se ei edes suorita kaikkia /etc/init.d:n
skriptejä, vaan vain ne jotka on määrätty. Suoritettaviksi määrätyt skriptit
löytyvät hakemistosta /etc/runlevels.
Ensiksi init ajaa kaikki /etc/runlevels/bootiin linkitetyt
skriptit hakemistosta /etc/init.d. Yleensä suoritusjärjestys
noudattaa aakkostusta, mutta joissakin skripteissä
on riippuvuustietoja jotka käskevät järjestelmää käynnistämään muita ennen
itseään.
Huomaa:
Aakkosjärjestys jota noudatetaan on useissa tilanteissa POSIX-määritelmän
mukainen, siis ääkköset eivät ole järjestyksessä ja aakkoset a-z esiintyvät
tunnetussa järjestyksessä.
|
Kun kaikki /etc/runlevels/bootin skriptit on suoritettu,
init jatkaa ajamalla skriptejä joihin on linkit hakemistossa
/etc/runlevels/default. Järjestys vastaa jälleen aakkostettua
riippuvuustietojen muokkaamaa käynnistyssarjaa.
Kuinka init toimii?
Tietenkään init ei päätä kaikkea itsestään. Se käyttää asetustiedostoja
ratkaistessaan mitä toimintoja tulee suorittaa. Asetustiedosto löytyy
sijainnista /etc/inittab.
Jos muistelet mitä käynnistyssekvenssistä kerrottiin äsken, niin ensimmäisenähän
init liitti kaikki tiedostojärjestelmät. Tämän määrää asetustiedoston
/etc/inittab seuraavannäköinen rivi:
Koodilistaus 1.1: Järjestelmän alustus tiedostossa /etc/inittab |
si::sysinit:/sbin/rc sysinit
|
Rivillä käsketään initiä ajamaan komento /sbin/rc sysinit
järjestelmän alustamiseksi. Skripti /sbin/rc pitää pitkälti
huolen alustuskuvioista, joten voisi sanoa ettei initille jää paljoakaan
tehtävää -- sehän vain delegoi alustustoiminnot muille prosesseille.
Seuraavaksi init suoritti kaikki ne skriptit joihin oli symboliset
linkit hakemistossa /etc/runlevels/boot. Tästä toiminnosta määrää
rivi:
Koodilistaus 1.2: Jatkoa järjestelmän alustukselle |
rc::bootwait:/sbin/rc boot
|
Taas kutsutaan rc-skriptiä tekemään tehtäviä. Huomaa, että rc:lle
annettu parametri (boot) on sama kuin /etc/runlevels:in
alihakemisto jota käytetään.
Seuraavaksi init etsii asetustiedostosta runlevelin joka ajetaan.
Tästä kerrotaan /etc/inittabissa rivillä:
Koodilistaus 1.3: Initdefault-rivi |
id:3:initdefault:
|
Tässä tapauksessa (kuten valtaosassa Gentoita yleensä) runlevelin
tunnus on 3. Tämän tiedon avulla init voi tarkastaa mitä tarvitaan
runlevel 3:n käynnistämiseksi:
Koodilistaus 1.4: Runlevelien määritelmät |
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
|
Kolmatta leveliä määrittävä rivi, jälleen kerran, käyttää rc-skriptiä
palveluiden käynnistämiseen (tällä kertaa parametriksi tarjoillaan
default). Jälleen huomaa että rc:n parametri on
/etc/runlevelsin alihakemisto
rc:n lopetettua init päättää aktivoitavat virtuaalikonsolit ja
niillä suoritettavat komennot:
Koodilistaus 1.5: Virtuaalikonsolien määritelmät |
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
|
Mikä on runlevel?
Edellä huomattiin että init käyttää numeroita runlevelien
tunnistamiseen. Runlevel on tila jota järjestelmä suorittaa, ja
se sisältää joukon skriptejä (runlevel-skriptejä tai initskriptejä)
jotka täytyy suorittaa tiloihin tullessa ja poistuttaessa.
Gentoossa on seitsemän runleveliä: kolme sisäiseen käyttöön ja neljä
käyttäjän määriteltäviksi. Sisäiset ovat sysinit, shutdown
sekä reboot ja ne toimivat kuten nimet antavat ymmärtää:
käynnistävät järjestelmän, sammuttavat koneen ja uudelleenkäynnistävät.
Käyttäjän määrittelemät ovat ne, joihin liittyy
/etc/runlevelsin alihakemistot: boot,
default, nonetwork ja single.
boot käynnistää kaikki järjestelmälle tarpeelliset palvelut
joita muut runlevelitkin käyttävät. Jäljellä olevat kolme käynnistävät eri
joukot palveluita: default liittyy päivittäiseen käyttöön,
nonetwork verkottomaan ja single
järjesetelmän korjailemiseen.
Initskriptien käsitteleminen
rc:n käynnistämiä skriptejä kustutaan initskripteiksi.
Kaikki hakemiston /etc/init.d skriptit ymmärätävät parametreja
start, stop, restart, pause, zap,
status, ineed, iuse, needsme, usesme ja
broken.
Palvelun käynnistämiseen, pysäyttämiseen ja uudelleenkäynnistämiseen käytetään
parametreja start, stop ja restart vastaavasti:
Koodilistaus 1.6: Postfixin käynnistys |
# /etc/init.d/postfix start
|
Huomaa:
Vain palvelut jotka tarvitsevat (need) tätä palvelua pysähtyvät
tai uudelleenkäynnistyvät. Muut riippuvaiset palvelut (ne jotka käyttävät
(use) tätä palvelua) jäävät koskematta.
|
Pysäyttääksesi vain yhden palvelun jättäen siitä riippuvat palvelut käyntiin
käytät komentoa pause:
Koodilistaus 1.7: Postfixin pysäytys pysäyttämättä riippuvia palveluja |
# /etc/init.d/postfix pause
|
Jos haluat nähdä missä tilassa jokin palvelu on (käynnissä, pysäytetty, pause,
...), käytä komentoa status:
Koodilistaus 1.8: Postfixin tila |
# /etc/init.d/postfix status
|
Jos tila näyttää siltä että palvelu olisi käynnissä vaikka tiedät sen olevan
poissa päältä, voit nollata tilatiedon pysähtyneeksi komennolla
zap:
Koodilistaus 1.9: Postfixin tilatiedon nollaus |
# /etc/init.d/postfix zap
|
Riippuvuuksia saa selville parametreillä iuse ja ineed.
ineed kertoo toiminnalle välttämättömät riippuvuudet, iuse
taas palvelut joita voi käyttää hyväksi, mutta jotka eivät ole välttämättömiä.
Koodilistaus 1.10: Postfixin välttämättömien riippuvuuksien tarkastelu |
# /etc/init.d/postfix ineed
|
Samoin voidaan katsella mitkä palvelut tarvitsevat annettua palvelua
(needsme) tai mitkä voivat käyttää sitä (useme):
Koodilistaus 1.11: Postfixia tarvitsevien palvelujen tarkastelu |
# /etc/init.d/postfix needsme
|
Lopulta voidaan tarkstella mitkä tarpeelliset riippuvuudet puuttuvat:
Koodilistaus 1.12: Postfixin puuttuvien riippuvuuksien tarkastelu |
# /etc/init.d/postfix broken
|
4.b. Rc-updaten käyttäminen
Mikä on rc-update?
Gentoon käynnistysjärjestelmä käyttää riippuvuuspuuta päättääkseen palvelujen
käynnistysjärjestyksen. Tehtävä on hankala, joten käyttäjiltä on säästetty
sen tekemisen vaivaa; tekemämme työkalut helpottavat runlevelien ja
initskriptien ylläpitoa.
Komennolla rc-update voit lisätä ja poistaa initskriptejä runleveliltä.
rc-update päivittää riippuvuuspuun automaattisesti komennolla
depscan.sh.
Palveluiden lisäys ja poisto
Asennuksen aikaan olet jo lisännyt default-runlevelille joitain initskriptejä.
Silloin defaultin merkitys ei kai ollut vielä selvä, mutta nyt varmaan
tiedetään tarkemmin mitä se tekee. rc-updaten toiseksi komennoksi pitää
antaa toiminnon nimi: add, del tai show.
Skriptin lisäyksessä ja poistossa rc-updatelle annetaan
komennot add ja del, vastaavasti, ja perään skriptin nimi ja
runlevelin nimi. Esimerkiksi:
Koodilistaus 2.1: Postfixin poisto default runlevelistä |
# rc-update del postfix default
|
Komennolla rc-update -v show saadaan esiin listaus initskripteistä ja
niihin liitetyistä runleveleistä:
Koodilistaus 2.2: Initskriptien tietojen tarkastelu |
# rc-update -v show
|
Komennolla rc-update show ilman -v:tä näkee päällä olevat
initskriptit runleveleineen.
4.c. Palvelujen asettaminen
Mihin tarvitaan ylimääräisia asetuksia?
Initskriptit voivat olla kovinkin monimutkaisia. Siksi ei varmaankaan ole
mielekästä ihmisten suoraan niitä editoida, se lisäisi virhealttiuttakin
huomattavasti. On kuitenkin tärkeää että palvelun asetuksia voi muuttaa,
esimerkiksi niille voi tarvita antaa lisäparametreja.
Toinen syy erillisiin asetustiedostoihin on initskriptien päivitettävyyden
mahdollistaminen sotkematta käyttäjän asetuksia.
Hakemisto /etc/conf.d
Gentoossa palvelujen asetukset on helppo tehdä: jokaisella asetettavissa
olevalla skriptillä on asetustiedosto hakemistossa /etc/conf.d.
Esimerkiksi apache2:n initskripti (/etc/init.d/apache2) tottelee
asetuksia tiedostossa /etc/conf.d/apache2, mikä sisältää
Apache 2 -palvelimelle meneviä käynnistysasetuksia:
Koodilistaus 3.1: Muuttuja tiedostossa /etc/conf.d/apache2 |
APACHE2_OPTS="-D PHP5"
|
Tällainen asetustiedosto sisältää vain ja ainoastaan muuttujia (aivan kuten
/etc/make.conf), joten sitä on erittäin helppo säätää. Se
myöskin mahdollistaa muuttujien toiminnan informatiivisen kommentoinnin.
4.d. Initskriptien kirjoittaminen
Onko se pakollista?
Skriptejä ei täydy kirjoittaa. Gentoo tarjoaa valmiiksi käyttöön jo skriptit
kaikilla käytetyillä
palveluille, joten omien kirjoittaminen ei useinkaan ole tarpeen. Kuitenkin,
jos vaikkapa asensit palvelun Portagen ulkopuolelta saattaa olla tarpeellista
luoda sille initskripti.
Älä käytä palvelujen omia initskriptejä jollei niitä ole erikseen kirjoitettu
Gentoota varten; Gentoon initskriptit eivät ole yhteensopivia muiden jakeluiden
initskriptien kanssa!
Sisällöt
Initskriptin perussisältö näyttää seuraavalta:
Koodilistaus 4.1: Initskriptin perussisältö |
#!/sbin/runscript
depend() {
}
start() {
}
stop() {
}
restart() {
}
|
Kaikissa initskripteissä pitää olla start()-funktio. Muut ovat
vapaaehtoisia.
Riippuvuudet
Voidaan määritellä kahdentyyppisiä riippuvuuksia: use ja need.
Kuten aiempana mainittiin, need on tiukempi vaatimus kuin use.
Tällä riippuvuudella määritellään tarvittu palvelu tai
virtuaalinen riippuvuus.
Virtuaalinen riippuvuus on sellainen jonka jokin palvelu täyttää, mutta
sen täyttäviä palveluita on olemassa useampia. Initskripti voisi olla
riippuvainen järjestelmälokista, mutta niitä on useita (metalogd, syslog-ng,
sysklogd, ...). Koska ei ole mahdollista tarvita (need) jokaista niistä
(eihän missään järjestelmässä kaikkia järjestelmälokeja ole käytössä), nämä
palvelut varmasti tarjoavat (provide) sopivan virtuaalisen riippuvuuden.
Katsokaamme esimerkiksi postfixin riippuvuuksia.
Koodilistaus 4.2: Postfixin riippuvuudet |
depend() {
need net
use logger dns
provide mta
}
|
Kuten näet, postfix:
-
vaatii toimivan (virtuaalisen) net-riippuvuuden (jonka voi tarjota
vaikkapa /etc/init.d/net.eth0)
-
käyttää (virtuaalista) logger-riippuvuutta (jonka esimerkiksi
/etc/init.d/syslog-ng tarjoaa)
-
käyttää (virtuaalista) dns-riippuvuutta (jonka esimerkiksi
/etc/init.d/named tarjoaa)
-
tarjoaa (virtuaalisen) mta riippuvuuden (joka liittyy kaikkiin
postipalvelimiin)
Järjestyksen määrittäminen
Joissain tapauksissa ei ole tarpeellista vaatia jotain palvelua, vaan saada
vain se käynnistämään ennen (before) tai jälkeen (after)
määrättyä palvelua, jos sellainen järjestelmästä löytyy (ja vain jos
löytyy - kyseessä ei ole enää riippuvuus), ja jos se on samalla
runlevelillä (ja vain jos runlevel on sama - muihin ei puututa). Nämä tiedot
voidaan laittaa asetuksiin before ja after.
Esimerkkinä tarkastelemme Portmapin asetuksia:
Koodilistaus 4.3: Portmapin depend()-funktio |
depend() {
need net
before inetd
before xinetd
}
|
Jokerimerkillä "*" valitaan kaikki samalla runlevelillä olevat toiminnot,
tämän käyttö ei kuitenkaan ole suositeltavaa.
Koodilistaus 4.4: Initskriptin ajaminen runlevelin ensimmäisenä |
depend() {
before *
}
|
Standardifunktiot
Seuraavaksi toiminnallisuuden depend() jälkeen täytyy määritellä
start()-funktio. Se sisältää kaikki palvelun käynnistämiseen tarvittavat
komennot. On järkevää kertoa käyttäjälle tapahtumista käskyillä
ebegin ja eend:
Jos palvelun pitää kirjoittaa levylle, se tarvitsee localmountin. Jos
palvelu kirjoittaa /var/runiin jotain, kuten pidin, se
käynnistetään bootmiscin jälkeen:
Koodilistaus 4.5: depend()-esimerkki |
depend() {
need localmount
after bootmisc
}
|
Koodilistaus 4.6: start()-esimerkki |
start() {
ebegin "Palvelu käynnistyy"
start-stop-daemon --start --quiet --exec /hakemisto/polku/palveluun
eend $?
}
|
Valitsimet --exec ja --pidfile yleensä tarvitaan sekä
startissa että stopissa. Jos palvelu ei kirjoita pidiään tiedostoon,
valitsin --make-pidfile auttaa, mutta tämä kannattaa testata
varmuuden varaksi. Muussa tapauksessa ei kannata käyttää pid-tiedostoja.
start-stop-daemonille voi myös antaa valitsimen --quiet,
mutta tämä ei ole suositeltavaa, ellei palvelu tulosta suurta määrää
tietoja. --quiet-valitsimen käyttö haittaa vianetsintää, jos
palvelu ei käynnisty.
Huomaa:
Varmista, että --exec osoittaa palveluun, eikä esimerkiksi
kuoriskriptiin, joka käynnistää palvelun ja loppuu, sillä se on
initskriptin tehtävä.
|
Lisäesimerkkejä start()-funktion toteutuksista löytyy
valmiista skripteistä hakemistossa /etc/init.d/.
Muut määriteltävät funktiot ovat stop() ja restart(). Näitä
ei ole pakko määritellä! Init-järjestelmämme pystyy täyttämään nämä kohdat
itsekin jos komentoa start-stop-daemon on käytetty.
Vaikka stop() ei ole pakollinen, tässä on esimerkki:
Koodilistaus 4.7: stop()-esimerkki |
stop() {
ebegin "Stopping my_service"
start-stop-daemon --stop --exec /path/to/my_service \
--pidfile /path/to/my_pidfile
eend $?
}
|
Jos palvelu suorittaa muita skriptejä (vaikkapa bashia, pythonia tai perliä)
ja skripti muuttaa nimeään (vaikkapa foo.py:stä fooksi),
lisää valitsin --name start-stop-daemonille. Täsää kerrotaan
nimi, joksi skripti muuttuu. Tässä esimerkissä palvelu käynnistyy
foo.pynä ja muuttuu fooksi.
Koodilistaus 4.8: Palvelu joka käyttää foo-skriptiä |
start() {
ebegin "Starting my_script"
start-stop-daemon --start --exec /path/to/my_script \
--pidfile /path/to/my_pidfile --name foo
eend $?
}
|
Start-stop-daemonilla on loistava ohje-sivu:
Koodilistaus 4.9: Start-stop-daemonin ohjesivun lukeminen |
$ man start-stop-daemon
|
Gentoon initskriptit ovat syntaksiltaan lähinnä bashia (Bourne Again Shell),
joten niissä voi käyttää bashmaisia rakenteita missä vain.
Mukailtujen asetusten lisäily
Jos tarvitset initskriptiin enemmän parametrejä kun mihin me olemme
törmänneet, lisää nimi opts-muuttujaan ja tee nimeä vastaava funktio.
Esimerkiksi tuki restartdelay-komennolle lisättäisiin seuraavasti:
Koodilistaus 4.10: Tuki restartdelay-komennolle |
opts="${opts} restartdelay"
restartdelay() {
stop
sleep 3
start
}
|
Palvelujen asetusmuuttujat
Hakemistossa /etc/conf.d sijaitsevien asetustietojen tukemiseen
ei tarvita mitään muuta: kun initskripti käynnistyy nämä tiedostot sourcetetaan
(eli niiden muuttujat tulevat käytettäviksi):
- /etc/conf.d/<initskriptisi>
- /etc/conf.d/basic
- /etc/rc.conf
Lisäksi jos initskripti tarjoaa virtuaalisen riippuvuuden (kuten netin),
siihen liittyvä tiedostokin (kuten /etc/conf.d/net) sourcetetaan.
4.e. Runlevelin toiminnan muuttaminen
Kuka tällaisesta hyötyisi?
Useille kannettavien käyttäjille tuttu tilanne: kotona ollessa pitää
saada käyntiin net.eth0 kun taas matkoilla ei (kun ei verkkoakaan
ole saatavilla). Gentoossa runleveleitä voi muokata mielensä mukaan.
Esimerkiksi voisi luoda toisen käynnistyvän default-runlevelin, joka ajaisi
erilaiset initskriptit. Sitten käynnistysaikaisesti voisi valit minkä runlevelin
haluaa.
Softlevelin käyttö
Aloita tekemällä runlevel toista defaulttia varten. Esimerkkinä käytämme
offlineä:
Koodilistaus 5.1: Runlevel-hakemiston luonti |
# mkdir /etc/runlevels/offline
|
Lisää tarvittavat initskriptit uusille runleveleille. Esimerkiksi
yksityiskohtainen kopio nykyisestä defaultista ilman net.eth0:aa
saadaan aikaan näin:
Koodilistaus 5.2: Tarvittavien initskriptien lisäys |
# 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 |
|
Vakka net.eth0 ei ole offline-runlevelillä, udev yrittää
käynnistää sen joka tapauksessa kun huomaa laitteen. Siksi on tarpeellista
lisätä verkkolaitteet, joita ei käynnistetä (sekä muut asiat, joita ei
käynnistä udeviltä) tiedostoon /etc/conf.d/rc seuraavasti:
Koodilistaus 5.3: Palvelujen poisto tiedostosta /etc/conf.d/rc |
RC_COLDPLUG="yes"
RC_PLUG_SERVICES="!net.eth0"
|
Huomaa:
Lisätietoja palveluista on tiedoston kommenteissa.
|
Seuraavaksi editoidaan käynnistyslataimen asetustiedostoon kohta
offline-runlevelille. Esimerkiksi tiedostoon
/boot/grub/grub.conf:
Koodilistaus 5.4: Offlinen lisäys |
title Gentoo Linux ilman verkkoa
root (hd0,0)
kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offline
|
Ja sitten kaikki olikin valmista. Jos nyt uudelleenkäynnistät järjestelmän ja
valitset uuden valikkokohdan, offline-runlevel ajetaan defaultin
asemesta.
Bootlevelin käyttö
bootleveliä käytetään täysin samoin kuin softleveliäkin. Ainoa
ero on että tässä määriteltäisiin toinen boot-runlevel eikä toista
defaulttia.
[ << ]
[ < ]
[ Etusivu ]
[ > ]
[ >> ]
Tämän sivun sisältö ja suomennos kuuluvat
Creative Commons - Nimi mainittava-Sama lisenssi 2.5 -lisenssin alle.
Sivun sisältöä koskee myös
Gentoo Name and
Logo Usage Guidelines.
|