Het init process van Slackware

Peter Kaagman

Wijzigingen
Herziening v0.9 sep. 2002 bilbo

Samenvatting

In dit document wordt aan de hand van de scripts en de man pages het init process van slackware op de voet gevolgt.


Inhoudsopgave

Dit hoort er ook bij
Disclaimer
Copyright
Inleiding.
Init
Runlevels.
Init, de moeder van alle processen.
/etc/inittab
Het start commentaar
De Slackware runlevels
Het default runlevel
Systeem initialisatie
De runlevel scripts
Bijzondere omstandigheden
Inloggen
Andere manieren om in te loggen.
En we hebben X ook nog.
Een samenvatting zover
De scripts
/etc/rc.d/rc.S
/etc/rc.d/rc.0 en /etc/rc.d.rc.6
/etc/rc.d/rc.K
/etc/rc.d/rc.M

Dit hoort er ook bij

Disclaimer

Dit document wordt verspreid met de hoop dat het nuttig zal zijn. Alhoewel ik alle mogelijke moeite heb gedaan om fouten in dit document te voorkomen, geef ik geen enkele garantie voor de juistheid van de hier gepubliceerde informatie. De hier gegeven informatie is gebasseerd op persoonlijke ervaring en lijkt voor mij te werken.

Copyright

Copyright (c) Peter Kaagman 2002

Dit document is het intelectuele eigendom van Peter Kaagman en wordt mag verspreid worden volgens de voorwaarden zoals die zijn uiteengezet in de GPL licentie. De GPL licentie kunt u nalezen op http://users.skynet.be/xterm/gpld.txt

Inleiding.

Ik heb bij IBM een keer een docent gehad die had de volgende statement: "Het booten is het moeilijkste van heel Linux. Echter zodra de kernel geladen is en init het systeem overneemt; dan is er niets meer aan de hand. Vanaf dat moment kun je alles wat er gebeurt terug lezen in scripts en man pages".

Uiteraard heeft hij gelijk. Opstarten van een Linux systeem is niet geheimzinnig. Alles is terug te lezen in ASCII bestanden. Het is echter gemakkelijk de draad kwijt te raken in al die scripts. Slackware wijkt hierin nog af van andere distributies omdat Slackware vasthoudt aan een "BSD like" init terwijl andere distributies Sys V init gebruiken.

Sys V init is een init systeem waar alle opstart scripts in /etc/rc.d staan. En voor elk runlevel links naar de opstart scripts die voor dat runlevel moeten draaien in de directorie voor dat runlevel (/etc/rc.1, /etc/rc.2 enz.). Er is 1 groot script die alle links in die directories afloopt voor de de starten (of te stoppen) runlevel.

Het in detail beschrijven van een Sys V init zoals die o.a. gebruikt wordt door Suse en RedHat laat ik over aan iemand die de beschikking heeft over een referentie systeem. Ik ben bang dat ik zeer snel verzand in de details :D.

De manier waarop Sys V init werkt wordt door slackers als complex en slecht onderhoudbaar ervaren. Eerlijkheid gebied me te zeggen dat b.v. een Redhat gebruiker juist Slackware complex vindt. Maar blijf bij me en oordeel zelf.

In dit document zal ik trachten om de IBM docent z'n gelijk te geven. Ik zal het init process van een Slackware (8.1) machine volgen aan de hand van de scripts en de manpages. Veel quotes dus en weinig tekst :D.

Init

Runlevels.

Misschien is het nu wel handig om te weten wat nu eigenlijk een runlevel is. Een runlevel is een *nix systeem om het service niveau van een machine te bepalen. Per runlevel wordt gedefinieert welke services in dat runlevel aktief zullen zijn. In princiepe kunnen er erg veel runlevels zijn. In de praktijk is dit echter beperkt tot 5:

  • Een single user runlevel waarin een absoluut minimum aan services draait. Dit runlevel wordt meestal gebruikt voor systeem onderhoud.

  • Een multi user runlevel waarin alle te bieden services draaien. Deze services kan een http server zijn, e-mail server, SQL server of wat dan ook. Net wat de systeembeheerder (jij dus) wil.

  • Een multi user runlevel, hetzelfde als het vorige. Echter met een grafishce inlog manager.

Een van de multiuser runlevels is de normale staat van het systeem.

Naast deze runlevels zijn er nog 2 bijzondere runlevels:

  • Een runlevel om het systeem te stoppen.

  • Een runlevel om het systeem te re-booten.

Init, de moeder van alle processen.

Indien ik een tree overzicht opvraag van alle processen op mijn bak, dan krijg ik dit:

bilbo@bilbo:~$ pstree
init-+-4*[agetty]
     |-atd
     |-bash
     |-bash---startx---xinit-+-X
     |                       `-xinitrc-+-bbmail
     |                                 `-blackbox-+-mozilla-bin---mozilla-bin---4+
     |                                            `-rxvt---bash---pstree
     |-crond
     |-dhcpcd
     |-fetchmail
     |-gpm
     |-gvim
     |-httpd---7*[httpd]
     |-inetd---in.identd---in.identd---5*[in.identd]
     |-keventd
     |-khubd
     |-klogd
     |-kreiserfsd
     |-loop0
     |-loop1
     |-lpd
     |-mdrecoveryd
     |-named
     |-2*[sendmail]
     `-syslogd
bilbo@bilbo:~$ 


Wat hier getoond wordt is een "boomstructuur" van alle processen op mijn machine. Wat opbouw betreft lijkt het een beetje op een directorie structuur. Wat direct opvalt is dat de "root" in dit overzicht "init" is. Init is hier de moeder van alle processen. En dat is geen toeval!

Uit de manpage:

INIT(8)        Linux System Administrator's Manual        INIT(8)

NAME
       init, telinit - process control initialization

SYNOPSIS
       /sbin/init [ -a ] [ -s ] [ -b ] [ -z xxx ] [ 0123456Ss ]
       /sbin/telinit [ -t sec ] [ 0123456sSQqabcUu ]

DESCRIPTION
   Init
       Init  is the parent of all processes.  Its primary role is
       to create processes from  a  script  stored  in  the  file
       /etc/inittab  (see  inittab(5)).   This  file  usually has
       entries which cause init to spawn gettys on each line that
       users  can  log in.  It also controls autonomous processes
       required by any particular system.


Hier staan een aantal belangrijke opmerkingen:

  • Init is de parent van alle processen.

  • Init start processen van uit een bestand /etc/inittab.

  • Init beheert autonome processen (daemons).

In het bovenstaande pstree overzicht kun je die autonome processen ook zien. Het zijn allemaal directe kinderen van init. Onder hun zijn agetty (4x), sendmail (2x), lpd, syslogd om er maar een paar te noemen.

Maar waarom is init dan de moeder van alle processen?

Uit de manpage (regel 43)

BOOTING
       After  init  is  invoked  as  the  last  step  of  the kernel boot
       sequence, it looks for the file /etc/inittab to see if there is an
       entry  of  the  type initdefault (see inittab(5)). The initdefault
       entry determines the initial runlevel of the system.  If there  is
       no  such  entry  (or  no  /etc/inittab at all), a runlevel must be
       entered at the system console.


Het laatste wat een kernel doet als hij boot is dus init starten. Init zal vervolgens het bestand /etc/inittab gaan verwerken.

Er staan nog veel meer wetenswaardigheden in de man page van init. Voor ons is het echter tijd om verder te gaan met /etc/inittab. Dit is blijkbaar een belangrijk bestand.

/etc/inittab

Uit de manpage:

INITTAB(5)     Linux System Administrator's Manual     INITTAB(5)

NAME
       inittab  -  format of the inittab file used by the sysv-compatible
       init process

DESCRIPTION
       The inittab file describes which processes are started  at  bootup
       and    during    normal    operation    (e.g.    /etc/init.d/boot,
       /etc/init.d/rc, gettys...).  Init(8) distinguishes  multiple  run-
       levels,  each  of which can have its own set of processes that are
       started.  Valid runlevels are 0-6 plus A, B, and  C  for  ondemand
       entries.  An entry in the inittab file has the following format:

              id:runlevels:action:process


Whoha, is dat even schrikken. Daar staat: "used by the sysv-compatible init process". En dit was toch Slackware?

Ja dit is Slackware, en Slackware gebruikt Sys V init. Voor de grap even kijken naar de package description van Slackware?

bilbo@bilbo:~$ head -n 14 /var/log/packages/sysvinit-2.84-i386-18 
PACKAGE NAME:     sysvinit-2.84-i386-18
COMPRESSED PACKAGE SIZE:     232 K
UNCOMPRESSED PACKAGE SIZE:     560 K
PACKAGE LOCATION: /var/log/mount/slackware/a/sysvinit-2.84-i386-18.tgz
PACKAGE DESCRIPTION:
sysvinit: sysvinit (init, the parent of all processes)
sysvinit:
sysvinit: System V style init programs by Miquel van Smoorenburg that control
sysvinit: the booting and shutdown of your system.  These support a number of
sysvinit: system runlevels, each with a specific set of utilities spawned.
sysvinit: For example, the normal system runlevel is 3, which starts agetty
sysvinit: on virtual consoles tty1 - tty6.  Runlevel 4 starts xdm.
sysvinit: Runlevel 0 shuts the system down.
sysvinit:
bilbo@bilbo:~$ 


Laat je dus nooit meer wijs maken dat Slackware geen Sys V init gebruikt. Het gebruikt Sys V init echter wel in "BSD style".

Genoeg gein.... laten we de format van het bestand eens bekijken:

Weer uit de man page:

              id:runlevels:action:process
        Lines beginning with `#' are ignored.

        id     is a unique sequence of 1-4 characters which  iden-
               tifies   an  entry  in  inittab  (for  versions  of
               sysvinit compiled with libraries < 5.2.18 or  a.out
               libraries the limit is 2 characters).

               Note:  For  gettys or other login processes, the id
               field should be the tty suffix of the corresponding
               tty,   e.g.  1  for  tty1.   Otherwise,  the  login
               accounting might not work correctly.

        runlevels
               lists the runlevels for which the specified  action
               should be taken.

        action describes which action should be taken.

        process
               specifies  the process to be executed.  If the pro-
               cess field starts with a `+' character,  init  will
               not  do  utmp and wtmp accounting for that process.
               This is needed for  gettys  that  insist  on  doing
               their  own  utmp/wtmp housekeeping.  This is also a
               historic bug.


Het bestand bestaat dus uit een aantal regels steeds 4 velden gescheiden door een ":"

  • id - een identifier voor de regel

  • runlevels - een lijst met nul 1 of meerdere runlevels waar deze aktie voor moet plaats vinden

  • action - de aktie die moet plaats vinden, je vind ze opgesomt in de man page van inittab. Ik zal de manpage quoten zodra zze aan de orde komen.

  • process - het process wat door init gestart zal worden

Complex? Valt wel mee..... hier heb je mijn /etc/inittab

bilbo@bilbo:~$ cat /etc/inittab 
#
# inittab       This file describes how the INIT process should set up
#               the system in a certain run-level.
#
# Version:      @(#)inittab             2.04    17/05/93        MvS
#                                       2.10    02/10/95        PV
#                                       3.00    02/06/1999      PV
#                                       4.00    04/10/2002      PV
#
# Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified by:  Patrick J. Volkerding, <volkerdi@slackware.com>
#

# These are the default runlevels in Slackware:
#   0 = halt
#   1 = single user mode
#   2 = unused (but configured the same as runlevel 3)
#   3 = multiuser mode (default Slackware runlevel)
#   4 = X11 with KDM/GDM/XDM (session managers)
#   5 = unused (but configured the same as runlevel 3)
#   6 = reboot

# Default runlevel. (Do not set to 0 or 6)
id:3:initdefault:

# System initialization (runs when system boots).
si:S:sysinit:/etc/rc.d/rc.S

# Script to run when going single user (runlevel 1).
su:1S:wait:/etc/rc.d/rc.K

# Script to run when going multi user.
rc:2345:wait:/etc/rc.d/rc.M

# What to do at the "Three Finger Salute".
ca::ctrlaltdel:/sbin/shutdown -t5 -r now

# Runlevel 0 halts the system.
l0:0:wait:/etc/rc.d/rc.0

# Runlevel 6 reboots the system.
l6:6:wait:/etc/rc.d/rc.6

# What to do when power fails.
pf::powerfail:/sbin/genpowerfail start

# If power is back, cancel the running shutdown.
pg::powerokwait:/sbin/genpowerfail stop

# These are the standard console login getties in multiuser mode:
c1:1235:respawn:/sbin/agetty 38400 tty1 linux
c2:1235:respawn:/sbin/agetty 38400 tty2 linux
c3:1235:respawn:/sbin/agetty 38400 tty3 linux
c4:1235:respawn:/sbin/agetty 38400 tty4 linux
c5:1235:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux

# Local serial lines:
#s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100
#s2:12345:respawn:/sbin/agetty -L ttyS1 9600 vt100

# Dialup lines:
#d1:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS0 vt100
#d2:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS1 vt100

# Runlevel 4 used to be for an X window only system, until we discovered
# that it throws init into a loop that keeps your load avg at least 1 all 
# the time. Thus, there is now one getty opened on tty6. Hopefully no one
# will notice. ;^)
# It might not be bad to have one text console anyway, in case something 
# happens to X.
x1:4:wait:/etc/rc.d/rc.4

# End of /etc/inittab
bilbo@bilbo:~$ 


Het zijn maar 74 regels (net een A4tje (ok foliotje)), zonder de commentaar regels hou je maar 16 regels over! Maar eerlijk gezegt is het commentaar vaak wel het lezen waard.

Ik zal het bestand eens uit splitsen:

Het start commentaar

# Author:       Miquel van Smoorenburg, <miquels@drinkel.nl.mugnet.org>
# Modified by:  Patrick J. Volkerding, <volkerdi@slackware.com>


De laatste versie van het script is gemaakt door Miquel van Smoorenburg (lijkt me een nederlander) en het is aangepast voor Slackware door Patrick Volkerding (de samensteller van Slackware (yep Slackware is een one mans job)). Het doet niets, maar hoort erin, GPL aan het werk zullen we maar zeggen.

De Slackware runlevels

# These are the default runlevels in Slackware:
#   0 = halt
#   1 = single user mode
#   2 = unused (but configured the same as runlevel 3)
#   3 = multiuser mode (default Slackware runlevel)
#   4 = X11 with KDM/GDM/XDM (session managers)
#   5 = unused (but configured the same as runlevel 3)
#   6 = reboot


Het volgende stuk is weer commentaar. Het doet uiteraard ook niets, maar het maakt dat wat volgt wel een stuk beter te volgen. Je ziet hier 7 runlevels genoemd. Runlevels 2 en 5 worden feitelijk niet gebruikt, je zal straks zien dan voor deze runlevels dezelfde script gebruikt worden als voor respectievelijk runlevels 2 en 3.

Het default runlevel

# Default runlevel. (Do not set to 0 or 6)
id:3:initdefault:


Dit is voor het eerst dat er daadwerkelijk iets gedaan wordt. Het is een standaard inittab regel; 4 velden gescheiden door een ":". De aktie hier is "initdefault", vlgs de manpage:

       initdefault
              An initdefault entry specifies the runlevel which should be entered after system boot.
              If none exists, init will ask for a runlevel on the console. The process field is ignored.


Hier wordt de default runlevel ingesteld. Maar dat stond natuurlijk ook al in het commentaar. De default runlevel voor een Slackware systeem is dus runlevel 3; oftewel een multi-user runlevel met een tekst inlog scherm.

Systeem initialisatie

# System initialization (runs when system boots).
si:S:sysinit:/etc/rc.d/rc.S


De aktie hier is "sysinit" en spreekt eigenlijk voor zich, maar laten we toch maar even kijken wat de man page er over te zeggen heeft:

       sysinit
             The process will be executed during system boot. It will be executed before any boot or
             bootwait entries. The runlevels field is ignored.


Het runlevel "S" wordt wel genoemd maar wordt dus feitelijk genegeert door init. Het programma wat uitgevoerd zal gaan worden (in dit geval een script) is /etc/rc.d/rc.S. Je zal zien dat alle opstart scripts van Slackware in de directorie /etc/rc.d staan. In /etc/rc.d/rc.S wordt het systeem geinitialiseerd zoals we straks in de bespreking van het script zullen zien.

De runlevel scripts

# Script to run when going single user (runlevel 1).
su:1S:wait:/etc/rc.d/rc.K


De aktie hier is wait:

       wait   The process will be started once when the specified runlevel is entered and init will wait for its
              termination.


Het script (want dat is het) /etc/rc.d/rc.K zal aangeroepen worden bij het binnen gaan van runlevels 1 en S (eerlijk gezegt weet ik niet waarom die S daar staat). De aktie "wait" bepaalt dus dat init zal wachten tot het script klaar is. In /etc/rc.d/rc.K worden de services gestart die nodig zijn voor de singel user runlevel. Zoals we straks zullen zien zijn dit er niet erg veel.

# Script to run when going multi user.
rc:2345:wait:/etc/rc.d/rc.M


De aktie "wait" hebben we net al gezien. Het script /etc/rc.d/rc.M wordt dus aangeroepen voor de runlevels 2, 3, 4 en 5. Dus eigenlijk voor alle runlevels behalve runlevel 1. In /etc/rc.d/rc.M worden de services gestart voor de multi user runlevels. Een veel omvattend script zoals we zo zullen zien.

De regels die we tot nu toe gezien hebben bepalen wat er gebeurt bij het starten van het systeem. In alle gevallen zal init wachten op beeindiging van het gestarte process (een script). De nu volgende regels zijn akties die init neemt in bijzondere gevallen en horen niet echt bij een runlevel.

Bijzondere omstandigheden

# What to do at the "Three Finger Salute".
ca::ctrlaltdel:/sbin/shutdown -t5 -r now


Niet alleen MS kent het 3 vinger saluut. Echter bij Linux is de aktie zelf te bepalen. Voor de volledigheid de man page over de aktie:

       ctrlaltdel
              The process will be executed when init receives the SIGINT signal. This means that someone on the
              system console has pressed the CTRL-ALT-DEL key combination. Typically one wants to execute some sort
              of shutdown either to get into single-user level or to reboot the machine.
                                                  



Bij Slackware wordt dus `/sbin/shutdown -t5 -r now` uitgevoerd.

SHUTDOWN(8)    Linux System Administrator's Manual    SHUTDOWN(8)



NAME
       shutdown - bring the system down

SYNOPSIS
       /sbin/shutdown [-t sec] [-arkhncfF] time [warning-message]

DESCRIPTION
       shutdown brings the system down  in  a  secure  way.   All
       logged-in  users  are  notified  that  the system is going
       down, and login(1) is blocked.  It is possible to shut the
       system  down  immediately or after a specified delay.  All
       processes are first notified that the system is going down
       by the signal SIGTERM.  This gives programs like vi(1) the
       time to save the file being edited, mail and news process-
       ing programs a chance to exit cleanly, etc.  shutdown does
       its job by signalling  the  init  process,  asking  it  to
       change  the runlevel.  Runlevel 0 is used to halt the sys-
       tem, runlevel 6 is used to reboot the system, and runlevel
       1  is used to put to system into a state where administra-
       tive tasks can be performed; this is the default  if  nei-
       ther the -h or -r flag is given to shutdown.  To see which
       actions are taken on halt or reboot  see  the  appropriate
       entries for these runlevels in the file /etc/inittab.


De -r wil zeggen dat er een reboot zal plaats vinden door init de opdracht te geven naar runlevel 6 te gaan. De vertraging is 5 seconden na nu. Als je een uptime junkie bent dan kun je natuurlijk iets heel anders laten plaats vinden als reaktie op de 3 vinger saluut.

Het 2e veld voor de runlevels heeft natuurlijk geen zin hier. Init reageert hier op een signaal van buiten af.

# Runlevel 0 halts the system.
l0:0:wait:/etc/rc.d/rc.0


De aktie is weer wait, init zal dus wachten op het beeindigen van het script. Bij het binnen gaan van runlevel 0 zal dus /etc/rc.d/rc.0 (dat is een nul ;)) dus uitgevoerd worden. Wat dit script doet is alle gestarte processen op een veilige manier down brengen. Niet elk programma vindt het echt leuk als je stekker er uit trekt. Als laatste zal het script poweroff aanroepen en kan de computer uitgezet worden.

# Runlevel 6 reboots the system.
l6:6:wait:/etc/rc.d/rc.6


De entry is erg vergelijkbaar met de vorige entry. Zo erg zelfs dat /etc/rc.d/rc.0 feitelijk een symbolic link is naar /etc/rc.d/rc.6. Het zijn in weze dezelfde bestanden. De manier waarop het script is aangeroepen bepaalt wat de laatste stap is. In het geval van het binnengaan van runlevel 6 (dit geval dus) zal het laatste commando reboot zijn.

# What to do when power fails.
pf::powerfail:/sbin/genpowerfail start

# If power is back, cancel the running shutdown.
pg::powerokwait:/sbin/genpowerfail stop


Deze volgende 2 kunnen we in 1 keer behandelen. Ze hebben erg veel met elkaar te maken. De akties zijn de volgende:

       powerokwait
              This process will be executed as soon as init is
              informormed that the power has been restored.

       powerfailnow
              This  process  will  be  executed when init is told
              that the battery of  the  external  UPS  is  almost
              empty  and  the power is failing (provided that the
              external UPS and the monitoring process are able to
              detect this condition).


Beide regels hebben dus te maken met aktie die ondernomen moet worden naar aanleiding van een stroomstoring (of eigenlijk leegraken van de UPS batterijen). `/sbin/genpowerfail start` begint met het down brengen van het syteem, `/sbin/genpowerfail stop` tracht dit process te onderbreken indien de spanning weer terug is. /sbin/genpowerfail is een shell script wat gebruikt maakt van `shutdown`, als je een UPS hebt dan moet je het maar eens nalezen.

Inloggen

We hebben inmiddels het punt bereikt dat het systeem vrijwel operationeel is. Het sysinit script heeft gedraaid. De bij het runlevel behorende script heeft gedraait, /etc/rc.d/rc.K voor het single user runlevel 1 en /etc/rc.d/rc.M voor de multi user runlevel 2,3,4 en 5. Alle daemons draaien. En in het multi user runlevel kan er aangelogt worden met ssh of telnet, mit deze daemons gestart zijn tenminste. Als je een server zou hebben zonder monitor en toetsenbord, dan zou je het hier zelfs bij kunnen laten.

Wat nog niet kan is aanloggen op de computer zelf. En dat is af en toe wel zo gemakkelijk. Dat is de volgende taak van init.

# These are the standard console login getties in multiuser mode:
c1:1235:respawn:/sbin/agetty 38400 tty1 linux
c2:1235:respawn:/sbin/agetty 38400 tty2 linux
c3:1235:respawn:/sbin/agetty 38400 tty3 linux
c4:1235:respawn:/sbin/agetty 38400 tty4 linux
c5:1235:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux


En we hebben meteen een nieuwe aktie te pakken, de man page:

       respawn
              The  process  will  be restarted whenever it termi-
              nates (e.g. getty).


Het gestarte process, /sbin/agetty, zal dus opnieuw gestart worden als het beeindigt wordt. En schijnbaar worden er agetty's gestart voor de virtual consoles tty1 t/m tty6 voor de runlevels 1, 2, 3 en 5. Dit zijn de runlevels zonder X. Behalve de agetty op tty6, die wordt ook gestart voor runlevel 4. Het runlevel met X.

In de man page kunnen we lezen wat agetty eigenlijk doet.


AGETTY(8)                                               AGETTY(8)

NAME
       agetty - alternative Linux getty
       
SYNOPSIS
       agetty  [-ihLmnw]  [-f  issue_file] [-l login_program] [-I
       init] [-t  timeout]  [-H  login_host]  port  baud_rate,...
       [term]
       agetty  [-ihLmnw]  [-f  issue_file] [-l login_program] [-I
       init] [-t timeout]  [-H  login_host]  baud_rate,...   port
       [term]
                                                 
DESCRIPTION
       agetty  opens  a  tty  port,  prompts for a login name and
       invokes the /bin/login command. It is normally invoked  by
       init(8).


Agetty wacht dus op een tty poort tot er iemand aanlogt, en start dan /bin/login.

LOGIN(1)                                                 LOGIN(1)

NAME
       login - begin session on the system
       
 SYNOPSIS
       login [-p] [username] [ENV=VAR ...]
       login [-p] [-h host] [-f username]
       login [-p] -r host
                            
DESCRIPTION
       login  is used to establish a new session with the system.
       It is normally invoked automatically by responding to  the
       login:  prompt  on the user's terminal.  login may be spe-
       cial to the shell and may not be invoked as a sub-process.
       Typically,  login  is  treated  by the shell as exec login
       which causes the user to  exit  from  the  current  shell.
       Attempting  to  execute login from any shell but the login
       shell will produce an error message.


En met login begint dus een nieuwe sessie op het systeem.

Even terug kijken naar de output van mijn pstree:

bilbo@bilbo:~$ pstree
init-+-4*[agetty]
     |-atd
     |-bash
     |-bash---startx---xinit-+-X
     |                       `-xinitrc-+-bbmail
     |                                 `-blackbox-+-mozilla-bin---mozilla-bin---4+
     |                                            `-rxvt---bash---pstree


Fuik! Er zouden toch 6 agetty's moeten zijn?

Klopt! die waren er ooit wel alle 6. Maar schijnbaar heb ik 2x ingelogt op een virtual console. Ik zie tenminste 2x een bash. 1x Zonder dat er verdere programma's gestart zijn, en 1x een bash waaronder startx draait en dan xinit en dan ...., een X sessie dus.

Agetty start pas weer voor een console als ik uitlog, met die respawn. Zou hij eerder al starten, dan zou je de wel vreemde situatie krijgen dat en meerdere mensen kunnen inloggen op een console.

Andere manieren om in te loggen.

Van oudsher geeft *nix de mogelijkheid om op verschillende manieren verbinding te maken met het systeem. We hebben er inmiddel al 2 gehad.

  • Via het netwerk - met telnet ssh of iets dergelijks

  • Via de console - het toetsenbord, monitor e.d. aan de computer

Maar *nix heeft nog meer manieren om verbinding te maken:

# Local serial lines:
#s1:12345:respawn:/sbin/agetty -L ttyS0 9600 vt100
#s2:12345:respawn:/sbin/agetty -L ttyS1 9600 vt100

# Dialup lines:
#d1:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS0 vt100
#d2:12345:respawn:/sbin/agetty -mt60 38400,19200,9600,2400,1200 ttyS1 vt100


De bovenstaande 2 blokken zijn voorbeelden voor het starten van agetty's voor de serieele poorten (terminals) en voor inbel verbindingen via modems.

En we hebben X ook nog.

En tot slot komt X ook nog een keer kijken voor het grafische runlevel

# Runlevel 4 used to be for an X window only system, until we discovered
# that it throws init into a loop that keeps your load avg at least 1 all 
# the time. Thus, there is now one getty opened on tty6. Hopefully no one
# will notice. ;^)
# It might not be bad to have one text console anyway, in case something 
# happens to X.
x1:4:wait:/etc/rc.d/rc.4


In het commentaar wordt allereerst een verklaring gegeven voor die ene agetty die in runlevel 4 draait op tty6.

Het is een "wait" aktie die /etc/rc.d/rc.4 uitvoert. Dit script zoekt achtereenvolgens naar kdm (de kde inlog manager), gdm (de gnome inlog manager) en als laatste naar xdm (de standaart inlog manager die bij X hoort). De inlog managers zijn vergelijkbaar met agetty in dat ze wachten op het inloggen van een gebruiker en na het uitloggen zichzelf weer starten.

bilbo@bilbo:~$ man kdm
No manual entry for kdm
bilbo@bilbo:~$ 


Tot zover de man page van kdm (zover zijn ze bij KDE schijnbaar nog niet gekomen)

bilbo@bilbo:~$ man gdm
No manual entry for gdm
bilbo@bilbo:~$ 


Tot zover de man page van gdm (en Gnome is net zo ver?)

XDM(1)                                                     XDM(1)

NAME
       xdm  -  X  Display  Manager  with  support for XDMCP, host
       chooser

 SYNOPSIS
       xdm [ -config configuration_file ] [ -nodaemon ] [  -debug
       debug_level  ]  [  -error  error_log_file  ]  [ -resources
       resource_file ] [ -server server_entry ] [  -session  ses-
       sion_program ]

DESCRIPTION
       Xdm  manages  a  collection of X displays, which may be on
       the local host or remote servers.  The design of  xdm  was
       guided  by  the  needs  of X terminals as well as The Open
       Group standard XDMCP, the X Display Manager Control Proto-
       col.   Xdm  provides services similar to those provided by
       init, getty and login on  character  terminals:  prompting
       for  login name and password, authenticating the user, and
       running a ``session.''


En hier die van xdm. Ik kan je er verder weinig van vertellen. Ik zit altijd in runlevel 3, en gebruik dus geen grafische inlog managers.

Een samenvatting zover

We hebben gezien dat "init" als moeder van processen de controle over de machine krijgt van de kernal. "Init" zal vervolgens het bestand "/etc/inittab" gaan verwerken. Aan de hand van "inittab" zal "init" achtereenvolgens:

  • De default runlevel instellen.

  • Het initialisatie script /etc/rc.d/rc.S draaien, en wachten op z'n beeindiging.

  • De scipts voor de desbetreffende runlevel bepalen, en wachten op z'n beeindiging als ze draaien.

    • /etc/rc.d/rc.K voor het single user runlevel 1

    • /etc/rc.d/rc.M voor de multi user runlevels 2,3,4 en 5

    • /etc/rc.d/rc.0 voor runlevel 0 (system halt)

    • /etc/rc.d/rc.6 voor runlevel 6 (system reboot)

  • Bepalen welke aktie moet plaats vinden in bijzondere situaties; ctrl-alt-del en power faillure.

  • Voor de runlevels 1, 2, 3 en 5 het programma agetty starten op de consoles zodate gebruiker in kunnen logen. (En 1 voor runlevel 4 op de console 6, maar dat heeft een speciale reden)

  • Eventueel agetty's starten voor serieele verbindingen.

  • De grafische inlog manager starten voor runlevel 4.

In feite is dit het init process. Verder zullen er dus "alleen maar" scripts starten. Maar het is wel leuk om daar ook even naar te kijken; anders weet je nog niet waar je modules geladen worden en het netwerk gestart.

De scripts

Ik zal de scripts niet zo uitgebreid analyseren als ik gedaan heb met /etc/inittab. Sommige scripts, zoals /etc/rc.d/rc.M, zijn erg uitgebreid. Bovendien zij ze met een beetje goede wil best te volgen. Bovendien zijn er in de scripts dingen die ik ook niet snap :D.

Ik zal beginnen met het systeem inistialisatie script /etc/rc.d/rc.S en het stop script /etc/rc.d/rc.6. Zoals je zult zien zij deze scripts maatjes van elkaar, ze complementeren elkaar.

/etc/rc.d/rc.S

#!/bin/sh
#
# /etc/rc.d/rc.S:  System initialization script.
#
# Mostly written by:  Patrick J. Volkerding, <volkerdi@slackware.com>
#

PATH=/sbin:/usr/sbin:/bin:/usr/bin

# Start devfsd if necessary
if [ -r /dev/.devfsd ]; then
  if [ -x /sbin/devfsd ]; then
    echo "Starting devfs daemon:  /sbin/devfsd /dev"
    /sbin/devfsd /dev
  fi
fi

# enable swapping
/sbin/swapon -a

# Test to see if the root partition is read-only, like it ought to be.
READWRITE=no
if echo -n >> "Testing filesystem status"; then
  rm -f "Testing filesystem status"
  READWRITE=yes
fi

# See if a forced filesystem check was requested at shutdown:
if [ -r /etc/forcefsck ]; then
  FORCEFSCK="-f"
fi

# Check the root filesystem:
if [ ! $READWRITE = yes ]; then
  if [ ! -r /etc/fastboot ]; then
    echo "Checking root filesystem:"
    /sbin/fsck $FORCEFSCK -C -a /
  fi
  # If there was a failure, drop into single-user mode.
  if [ $? -gt 1 ] ; then
    echo
    echo
    echo "***********************************************************"
    echo "*** An error occurred during the root filesystem check. ***"
    echo "*** You will now be given a chance to log into the      ***"
    echo "*** system in single-user mode to fix the problem.      ***"
    echo "***                                                     ***"
    echo "*** If you are using the ext2 filesystem, running       ***"
    echo "*** 'e2fsck -v -y <partition>' might help.              ***"
    echo "***********************************************************"
    echo
    echo "Once you exit the single-user shell, the system will reboot."
    echo
    PS1="(Repair filesystem) \#"; export PS1
    sulogin
    echo "Unmounting file systems."
    umount -a -r
    mount -n -o remount,ro /
    echo "Rebooting system."
    sleep 2
    reboot -f
  fi
  # Remount the root filesystem in read-write mode
  echo "Remounting root device with read-write enabled."
  /sbin/mount -w -v -n -o remount /
  if [ $? -gt 0 ] ; then
    echo
    echo "Attempt to remount root device as read-write failed!  This is going to"
    echo "cause serious problems."
    echo 
    echo "If you're using the UMSDOS filesystem, you **MUST** mount the root partition"
    echo "read-write!  You can make sure the root filesystem is getting mounted "
    echo "read-write with the 'rw' flag to Loadlin:"
    echo
    echo "loadlin vmlinuz root=/dev/hda1 rw   (replace /dev/hda1 with your root device)"
    echo
    echo "Normal bootdisks can be made to mount a system read-write with the rdev command:"
    echo
    echo "rdev -R /dev/fd0 0"
    echo
    echo "You can also get into your system by using a boot disk with a command like this"
    echo "on the LILO prompt line:  (change the root partition name as needed)"
    echo 
    echo "LILO: mount root=/dev/hda1 rw"
    echo
    echo "Please press ENTER to continue, then reboot and use one of the above methods to"
    echo -n "get into your machine and start looking for the problem. " 
    read junk; 
  fi
else
  echo "Testing filesystem status: read-write filesystem"
  if cat /etc/fstab | grep ' / ' | grep umsdos 1> /dev/null 2> /dev/null ; then
    ROOTTYPE="umsdos"
  fi
  if [ ! "$ROOTTYPE" = "umsdos" ]; then # no warn for UMSDOS
    echo
    echo "*** ERROR: Root partition has already been mounted read-write. Cannot check!"
    echo
    echo "For filesystem checking to work properly, your system must initially mount"
    echo "the root partition as read only. Please modify your kernel with 'rdev' so that"
    echo "it does this. If you're booting with LILO, add a line:"
    echo
    echo "   read-only"
    echo
    echo "to the Linux section in your /etc/lilo.conf and type 'lilo' to reinstall it."
    echo
    echo "If you boot from a kernel on a floppy disk, put it in the drive and type:"
    echo "   rdev -R /dev/fd0 1"
    echo
    echo "If you boot from a bootdisk, or with Loadlin, you can add the 'ro' flag."
    echo
    echo "This will fix the problem *AND* eliminate this annoying message. :^)"
    echo
    echo -n "Press ENTER to continue. "
    read junk;
  fi
fi # Done checking root filesystem

# Any /etc/mtab that exists here is old, so we delete it to start over:
/bin/rm -f /etc/mtab*
# Remounting the / partition will initialize the new /etc/mtab:
/sbin/mount -w -o remount /

# Initialize the Logical Volume Manager.
# This won't start unless /etc/lvmtab is found, which is created by /sbin/vgscan.
# Therefore, to use LVM you must run /sbin/vgscan yourself the first time.
if [ -r /etc/lvmtab ]; then
  # Mount /proc early (it's needed for vgscan):
  /sbin/mount -a -t proc
  # Scan for new volume groups:
  /sbin/vgscan
  if [ $? = 0 ]; then
    # Make volume groups available to the kernel:
    /sbin/vgchange -ay
  fi
fi

# Check all the non-root filesystems:
if [ ! -r /etc/fastboot ]; then
  echo "Checking non-root filesystems:"
  /sbin/fsck $FORCEFSCK -C -R -A -a
fi

# mount non-root file systems in fstab (but not NFS or SMB 
# because TCP/IP is not yet configured):
/sbin/mount -a -v -t nonfs,nosmbfs

# Clean up some temporary files:
( cd /var/log/setup/tmp && rm -rf * )
/bin/rm -f /var/run/utmp /var/run/*pid /etc/nologin /var/run/lpd* \
  /var/run/ppp* /etc/dhcpc/dhcpcd-eth0.pid /etc/forcefsck /etc/fastboot

# Create a fresh utmp file:
cat /dev/null > /var/run/utmp

if [ "$ROOTTYPE" = "umsdos" ]; then # we need to update any files added in DOS:
  echo "Synchronizing UMSDOS directory structure:"
  echo "  umssync -r99 -v- /"
  umssync -r99 -v- /
fi

# Setup the /etc/motd to reflect the current kernel level:
# THIS WIPES ANY CHANGES YOU MAKE TO /ETC/MOTD WITH EACH BOOT.
# COMMENT THIS OUT IF YOU WANT TO MAKE A CUSTOM VERSION.
echo "`/bin/uname -sr`." > /etc/motd

# Configure ISA Plug-and-Play devices:
if [ -r /etc/isapnp.conf ]; then
  if [ -x /sbin/isapnp ]; then
    /sbin/isapnp /etc/isapnp.conf
  fi
fi

# Set the system time from the hardware clock using hwclock --hctosys.
# Detect SGI Visual Workstation, since hwclock will make those freeze up:
if fgrep -l Cobalt-APIC /proc/interrupts 1> /dev/null 2> /dev/null ; then
  echo "SGI Visual Workstation detected.  Not running hwclock."
elif [ -x /sbin/hwclock ]; then
  if grep "^UTC" /etc/hardwareclock 1> /dev/null 2> /dev/null ; then
    echo "Setting system time from the hardware clock (UTC)."
    /sbin/hwclock --utc --hctosys
  else
    echo "Setting system time from the hardware clock (localtime)."
    /sbin/hwclock --localtime --hctosys
  fi
fi

# This loads any kernel modules that are needed.  These might be required to
# use your CD-ROM drive, bus mouse, ethernet card, or other optional hardware.
if [ -x /etc/rc.d/rc.modules ]; then
  . /etc/rc.d/rc.modules
fi

# Run serial port setup script:
# (CAREFUL! This can make some systems hang if the rc.serial script isn't
# set up correctly. If this happens, you may have to edit the file from a
# boot disk)
#
# . /etc/rc.d/rc.serial

# Carry an entropy pool between reboots to improve randomness.
# Load and then save 512 bytes, which is the size of the entropy pool.
if [ -f /etc/random-seed ]; then
  echo "Using /etc/random-seed to initialize /dev/urandom."
  cat /etc/random-seed >/dev/urandom
fi
dd if=/dev/urandom of=/etc/random-seed count=1 bs=512 2> /dev/null
Feitelijk is dit het belangrijkste opstart script. In /etc/rc.d/rc.S wordt de integriteit van het systeem gewaarborgt en de voor het systeem belangrijke services gestart. Alles wat in dit script gebeurt is runlevel onafhankelijk. Het is noodzakelijk voor de juiste werking van het systeem in welk runlevel dan ook.

Achtereenvolgens zal het volgende plaatsvinden:

  • Inien noodzakelijk wordt devfsd gestart. Dit is een optionele daemon voor het beheren van het /dev filesysteem. Slackware gebruikt dit standaart niet.

  • Swapping wordt aangezet

  • De integriteit van het /root filesysteem wordt gechecked. Indien er problemen gevonden worden dan worden deze gerapporteerd met wat aanwijzingen om de fout te herstellen.

  • Het bestand /etc/mtab wordt leeg gemaakt. In dit bestand worden de gemounte filesystemen bijgehouden. Aangezien er op dit moment nog geen filesystemen gemount zijn, kan dit bestand leeg gemaakt worden.

  • De Logical Volume Manager wordt geinitialiseerd. LVM kan gebruikt worden om verschillende schijven te doen voorkomen als 1 schijf.

  • Alle locale filesystemen worden gemount.

  • Verschillende bestanden zoals /etc/motd worden geinitialiseerd

  • De systeemtijd wordt ingesteld door de hardware klok uit te lezen

  • Het script /etc/rc.d/rc.modules wordt aangeroepen. In dit script worden de benodigde kernel modules geladen. Dit de plek bij uitstek om ondersteuning aan te zetten voor je hardware zoals b.v. geluidskaarten, netwerkkaaren en USB.

  • Het script /etc/rc.d/rc.serial wordt aangeroepen. In dit script worden de settings gemaakt voor de serieele poorten.

  • Als laatste zal het random device ingesteld worden. Eerst wordt er gekeken of er een random seed in /etc staat van een vorige sessie. Als die er is dan wordt deze gekopieerd naar /dev/urandom. Vervolgens wordt er 512 bytes van uit /dev/urandom naar /etc/random-seed, voor een volgende boot.

/etc/rc.d/rc.0 en /etc/rc.d.rc.6

Feitelijk zijn deze 2 scripts indentiek aan elkaar. /etc/

lrwxrwxrwx    1 root     root            4 Aug  1 20:01 /etc/rc.d/rc.0 -> rc.6
-rwxr-xr-x    1 root     root         4241 Jun 12  2002 /etc/rc.d/rc.6
        

/etc/rc.d/rc.K

ff geduld nog

/etc/rc.d/rc.M

ff geduld nog