Gentoo Logo

[ << ] [ < ] [ 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() {
  (Tiedot riippuvuuksista)
}

start() {
  (Käynnistyskomennot)
}

stop() {
  (Sulkemiskomennot)
}

restart() {
  (Uudelleenkäynnistyskomennot)
}

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    # Odota uudelleenkäynnistysta 3 sekuntia
  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

(Kopioi kaikki palvelut oletusrunleveliltä offlineen)
# cd /etc/runlevels/default
# for service in *; do rc-update add $service offline; done
(Poista tarpeettomat)
# rc-update del net.eth0 offline
(Katso offlinen aktiiviset palvelut)
# rc-update show offline
(Pätkä esimerkkitulostetta)
               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"
(Kirjoitetaan palvelut, joita ei käynnistetä)
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 ] [ > ] [ >> ]


Tulostettava muoto

Näytä kaikki

Tämä sivu on viimeksi päivitetty 6. heinäkuuta 2008

Tätä käännöstä ei enää ylläpidetä

Tiivistelmä: Gentoo käyttää erityistä initscript-muotoa, joka tukee esimerkiksi riippuvuuksia ja virtuaalisia initskriptejä. Tämä kappale kertoo kaiken näistä toiminnallisuuksista ja selittää miten käyttää tällaisia komentojonotiedostoja.

Sven Vermeulen
Tekijä

Joshua Saddler
Tekijä

Daniel Robbins
Tekijä

Chris Houser
Tekijä

Jerry Alexandratos
Tekijä

Seemant Kulleen
Gentoon x86-kehittäjä

Tavis Ormandy
Gentoon alpha-kehittäjä

Aron Griffis
Gentoon alpha-kehittäjä

Brad House
Gentoon AMD64-kehittäjä

Guy Martin
Gentoon HPPA-kehittäjä

Pieter Van den Abeele
Gentoon PPC-kehittäjä

Joe Kallar
Gentoon SPARC-kehittäjä

Shyam Mani
Toimittaja

John P. Davis
Toimittaja

Pierre-Henri Jondot
Toimittaja

Eric Stockbridge
Toimittaja

Rajiv Manglani
Toimittaja

Jungmin Seo
Toimittaja

Stoyan Zhekov
Toimittaja

Jared Hudson
Toimittaja

Colin Morey
Toimittaja

Jorge Paulo
Toimittaja

Carl Anderson
Toimittaja

Jon Portnoy
Toimittaja

Zack Gilburd
Toimittaja

Jack Morgan
Toimittaja

Benny Chuang
Toimittaja

Erwin
Toimittaja

Joshua Kinard
Toimittaja

Xavier Neys
Toimittaja

Grant Goodyear
Katselmoija

Gerald J. Normandin Jr.
Katselmoija

Donnie Berkholz
Katselmoija

Ken Nowack
Katselmoija

Lars Weiler
Kirjoittaja

Flammie Pirinen
Vastuullinen kääntäjä

Jouni Hätinen
Käännöksen laatutarkistaja

Donate to support our development efforts.

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