<?xml version="1.0" encoding="ISO-8859-1"?>
<chapter id="phase4">
  <title>Controleren en mounten van disks</title>

  <sect1>
    <title>Analyse</title>

<para>In de vorige fase van het project voegden we een boel nieuwe opdrachten
toe en als resultaat biedt de rootdisk veel meer functionaliteit. Maar 
er ontbreekt nog steeds het een en ander. Wat er echt uitspringt
is dat er geen manier is om disks te mounten. Om een read-write root
bestandssysteem te krijgen, moesten we onze toevlucht nemen tot het via
LILO doorgeven van de kernelparameter <parameter>rw</parameter>. 
Dit is prima voor een noodsituatie, maar in een normaal systeembootproces 
zou het anders gaan.
    </para>

    <para>De meeste GNU/Linux distributies nemen verscheidene stappen om
bestandssystemen te mounten. Het bekijken van het bootproces of het spitten
in de opstartscripts van &eacute;&eacute;n van de populaire Linux
distributies onthult de volgende reeks gebeurtenissen:
    </para>

    <orderedlist>
      <listitem>
        <para>De kernel mount het rootbestandssysteem automatisch
        read-only.</para>
      </listitem>

      <listitem>
        <para>Alle lokale bestandssystemen worden gecontroleerd op fouten.</para>
      </listitem>

      <listitem>
        <para>root wordt opnieuw gemount als read-write, als  
er geen fouten in de bestandssystemen worden gedetecteerd.</para>
      </listitem>

      <listitem>
        <para>De rest van de lokale bestandssystemen wordt gemount.</para>
      </listitem>

      <listitem>
        <para>Netwerkbestandssystemen worden gemount.</para>
      </listitem>
    </orderedlist>

    <para>Tot dusverre kan ons Pocket Linux systeem stap &eacute;&eacute;n
en dat is het. Als we een professioneel uitziende boot/root disketteset
willen, dan moeten we het beter doen dan &eacute;&eacute;n uit vijf.
    In deze fase van het project zullen we aan de
stappen twee en drie gaan werken. De stappen vier en vijf kunnen wachten.
    Aangezien dit een systeem gebaseerd op diskettes is, zijn er
naast root helemaal geen andere bestandssystemen te mounten.
    </para>

    <para>Rekening houdend met alle bovenstaande informatie, zijn de doelen
voor deze fase als volgt gedefinieerd:
    </para>

    <itemizedlist>
      <listitem>
        <para>Een manier om de volledigheid van het bestandssysteem te 
controleren.
</para>
      </listitem>

      <listitem>
        <para>De mogelijkheid om bestandssystemen te mounten.</para>
      </listitem>

      <listitem>
        <para>Een script om de controle en het mounten van lokale
bestandssystemen te automatiseren.</para>
      </listitem>
    </itemizedlist>
  </sect1>

  <sect1>
    <title>Ontwerp</title>

    <sect2>
      <title>Vaststellen van de benodigde utility's.</title>

      <para>We kunnen het Filesystem Hierarchy Standard (FHS) document 
gebruiken als hulp in het vinden van de namen van utility's die we nodig 
hebben en waar ze in de directorystructuur thuishoren. De FHS 
<filename>/bin</filename> directory toont <command>fsck</command> en iets met 
de naam <command>fsck.*</command> voor het controleren van bestandssystemen.
Aangezien we voor ons doel gebruik maken van een Second Extended (ext2) 
bestandssysteem wordt <command>fsck.*</command> <command>fsck.ext2</command>. 
Het mounten van bestandssystemen
wordt bewerkstelligd met de opdrachten <command>mount</command> en 
<command>umount</command> in de <filename>/bin</filename>
directory. Echter de naam van een script om automatisch lokale
bestandssystemen te mounten is niet te vinden. Op de meeste systemen staat
dit type script in de <filename>/etc</filename> directory, maar ondanks 
dat de FHS vereisten voor <filename>/etc</filename> opsomt, geeft het 
thans geen aanbevelingen voor opstartscripts. Verscheidene GNU/Linux 
distributies maken gebruik van <filename>/etc/init.d</filename> als
lokatie van opstartscripts, dus we zullen ons script om bestandssystemen
te mounten daar plaatsen.
      </para>
    </sect2>

    <sect2>
      <title>Opsporen van de broncode</title>

      <para>Als we Ibiblio&#39;s Linux Software Map (LSM) op <ulink
      url="http://www.ibiblio.org/pub/linux/">http://www.ibiblio.org/pub/Linux/</ulink>
doorzoeken op het trefwoord &#34;fsck&#34; dan krijgen we een groot aantal
overeenkomsten. Aangezien we gebruik maken van het Second
      Extended filesystem, afgekort tot ext2, kunnen we de zoekopdracht
verfijnen met het trefwoord &#34;ext2&#34;. Beide trefwoorden aanleveren
bij de LSM zoekmachine levert een package op met de naam e2fsprogs. 
Het LSM record bekijkend van e2fsprogs komen we erachter dat 
dit package de utility's <command>e2fsck</command>, <command>mke2fs</command>, 
<command>dumpe2fs</command>, <command>fsck</command> en meer bevat.
We komen er ook achter dat het LSM record van e2fsprogs sinds 1999 niet meer
is bijgewerkt.  Het is vrijwel zeker dat er ergens een nieuwere versie
in omloop is. Een andere goede Internetbron voor broncode is SourceForge
op <ulink url="http://sourceforge.net">http://sourceforge.net</ulink>.
Het gebruik van het trefwoord &#34;e2fsprogs&#34; in de zoekmachine
van SourceForge resulteert in een veel nieuwere versie van e2fsprogs.</para>

<para>Het was een heel avontuur om <command>fsck</command> te vinden, maar 
we kunnen nu verdergaan met het zoeken naar <command>mount</command> en 
<command>umount</command>. Een zoekopdracht op LSM
levert een aantal overeenkomsten op, maar de meeste daarvan verwijzen naar
diverse versies van een package genaamd util-linux. We hoeven er alleen
doorheen te scrollen en de meest recente release uit te kiezen.
Afgezien van slechts mount en umount wordt in het LSM record een opsomming
van nog heel veel andere utility's gegeven. We zouden beslist de lijst
door moeten nemen om te zien of er nog een van de andere util-linux
opdrachten tevoorschijn komen in de FHS vereisten voor
<filename>/bin</filename> en <filename>/sbin</filename>.
</para>

<para>Hieronder staat een lijst met packages die we tot dusverre hebben
verzameld en de utility's die overeenkomen met de FHS.
</para>

      <itemizedlist>
        <listitem>
          <para>e2fsprogs -- <command>fsck</command>, <command>fsck.ext2</command> (<command>e2fsck</command>), <command>mkfs.ext2</command> 
(<command>mke2fs</command>)</para>
        </listitem>

        <listitem>
          <para>util-linux -- <command>dmesg</command>, <command>getty</command> (<command>agetty</command>), <command>kill</command>, <command>login</command>, <command>mount</command>, <command>swapon</command>, <command>umount</command></para>
        </listitem>
      </itemizedlist>
    </sect2>

    <sect2>
      <title>Automatiseren van fsck en mount</title>

<para>Nu we <command>fsck</command> en <command>mount</command> opdrachten hebben, moeten we met een 
shellscript komen voor het automatisch controleren en mounten van de lokale
bestandssystemen. Een makkelijke manier om dit te doen zou zijn om een
kort, tweeregelig script te schrijven dat <command>fsck</command> en 
dan <command>mount</command> aanroept. Maar
wat als de bestandssystemen niet zuiver zijn? Het systeem zou beslist
geen beschadigd bestandssysteem moeten proberen te mounten. Daarom 
moeten we een middel zien te verzinnen hoe de status van de bestandssystemen
vast te stellen voordat ze worden gemount. De manpage van 
<command>fsck</command> geeft inzicht in hoe dit kan worden bewerkstelligd 
met behulp van returncodes. Een returncode van nul of &eacute;&eacute;n 
betekent dat het bestandssysteem in orde is en twee of groter betekent dat 
een of andere handmatige tussenkomst nodig is. Een simpel if-then statement 
zou de returncode van <command>fsck</command> kunnen
evalueren om vast te stellen of het bestandssysteem wel of niet kan
worden gemount. Voor hulp bij het
schrijven van shellscripts kunnen we ons wenden tot de
      BASH(1) manpage en de Advanced BASH
      Scripting Guide (<ulink url="http://www.tldp.org/guides.html">http://www.tldp.org/guides.html</ulink>).
      Beide referenties zijn vrij verkrijgbaar vanaf het Linux Documentatie
Project.
      </para>
    </sect2>

    <sect2>
      <title>Bestandsafhankelijkheden</title>

      <para>Wat we als laatste nog moeten doen is uitzoeken of er afgezien
van de binary's nog andere bestanden nodig zijn. We leerden het gebruik van
<command>ldd</command> om te controleren op library afhankelijkheden in de 
laatste fase van het project en we zullen het ook gebruiken om in deze fase 
de utility's te controleren. Er zijn ook nog een aantal andere bestanden die 
<command>fsck</command> en <command>mount</command> nodig zullen hebben en 
de manpages fsck(8) en mount(8) geven wat inzicht in welke bestanden dit zijn. 
Het gaat om <filename>/etc/fstab</filename> waarin devices worden opgesomd 
met bijbehorende mountpoints, <filename>/etc/mtab</filename> waarin
wordt bijgehouden wat is gemount en de devicebestanden die de diverse
disks voorstellen. We zullen die voor de juiste werking op moeten nemen.
      </para>

<para>
Het <filename>/etc/fstab</filename> bestand is slechts een simpel tekstbestand 
dat met iedere willekeurige editor kan worden aangemaakt. We zullen een regel
nodig hebben voor het root bestandssysteem en voor het proc bestandssysteem.
De reden voor de regel met het proc bestandssysteem is dat we 
<filename>/etc/mtab</filename> als een symlink die verwijst naar 
<filename>/proc/mounts</filename> aan kunnen maken. Het
bestand <filename>/proc/mounts</filename> bevat bijna exact dezelfde 
informatie als het traditionele <filename>/etc/mtab</filename> bestand. 
We moeten er gewoon voor zorgen dat het proc bestandssysteem voor ieder 
ander wordt gemount. Het enige dat er overblijft is de aanmaak van 
devicebestanden. We zullen <filename>/dev/ram0</filename> nodig hebben, omdat
daar het root bestandssysteem is te vinden. We hebben ook 
<filename>/dev/fd0</filename> nodig om andere diskettes te mounten en 
<filename>/dev/null</filename>.
      </para>
    </sect2>
  </sect1>

  <sect1>
    <title>Constructie</title>

    <sect2>
      <title>Installeer utility's uit e2fsprogs</title>

      <para><programlisting>
<prompt>bash#</prompt> cd /usr/src/e2fsprogs-1.29
<prompt>bash#</prompt> ./configure --host=i386-pc-linux-gnu
<prompt>bash#</prompt> make
<prompt>bash#</prompt> cd e2fsck
<prompt>bash#</prompt> cp e2fsck.shared ~/fase/sbin/e2fsck
<prompt>bash#</prompt> ln -s e2fsck ~/fase/sbin/fsck.ext2
<prompt>bash#</prompt> cd ../misc
<prompt>bash#</prompt> cp fsck mke2fs ~/fase/sbin
<prompt>bash#</prompt> ln -s mke2fs ~/fase/sbin/mkfs.ext2</programlisting></para>
    </sect2>

    <sect2>
      <title>Installeer utility's uit util-linux</title>

      <para><programlisting>
<prompt>bash#</prompt> cd /usr/src/util-linux-2.11u</programlisting></para>

      <para>Gebruik een teksteditor om de volgende wijzigingen aan te brengen
in <filename>MCONFIG</filename>:</para>

      <itemizedlist>
        <listitem>
          <para>Wijzig &#34;CPU=$(shell uname -m)&#34; in &#34;CPU=i386&#34;</para>
        </listitem>

        <listitem>
          <para>Wijzig &#34;HAVE_SHADOW=yes&#34; in &#34;HAVE_SHADOW=no&#34;</para>
        </listitem>
      </itemizedlist>

      <para><programlisting>
<prompt>bash#</prompt> ./configure
<prompt>bash#</prompt> make
<prompt>bash#</prompt> cp disk-utils/mkfs ~/fase/sbin
<prompt>bash#</prompt> cp fdisk/fdisk ~/fase/sbin
<prompt>bash#</prompt> cp login-utils/agetty ~/fase/sbin
<prompt>bash#</prompt> ln -s agetty ~/fase/sbin/getty
<prompt>bash#</prompt> cp login-utils/login ~/fase/bin
<prompt>bash#</prompt> cp misc-utils/kill ~/fase/bin
<prompt>bash#</prompt> cp mount/mount ~/fase/bin
<prompt>bash#</prompt> cp mount/umount ~/fase/bin
<prompt>bash#</prompt> cp mount/swapon ~/fase/sbin
<prompt>bash#</prompt> cp sys-utils/dmesg ~/fase/bin</programlisting></para>
    </sect2>

    <sect2>
      <title>Controleer op library benodigdheden</title>

      <para><programlisting>
<prompt>bash#</prompt> ldd ~/fase/bin/* | more
<prompt>bash#</prompt> ldd ~/fase/sbin/* | more
<prompt>bash#</prompt> ls ~/fase/lib</programlisting></para>

<para>
Alle afhankelijkheden onthuld door de opdracht <command>ldd</command>,
zijn voor library's die reeds aanwezig zijn in het fasegebied, dus er hoeft
niets nieuws te worden gekopieerd.</para>
    </sect2>

    <sect2>
      <title>Strip binary's om ruimte te besparen</title>

      <para><programlisting><prompt>bash#</prompt> strip ~/fase/bin/*
<prompt>bash#</prompt> strip ~/fase/sbin/*</programlisting></para>
    </sect2>

    <sect2>
      <title>Maak extra devicebestanden aan</title>

      <para><programlisting>
<prompt>bash#</prompt> mknod ~/fase/dev/ram0 b 1 0
<prompt>bash#</prompt> mknod ~/fase/dev/fd0 b 2 0
<prompt>bash#</prompt> mknod ~/fase/dev/null c 1 3</programlisting></para>
    </sect2>

    <sect2>
      <title>Maak de bestanden mtab en fstab aan</title>

      <para><programlisting>
<prompt>bash#</prompt> cd ~/fase/etc
<prompt>bash#</prompt> ln -s /proc/mounts mtab</programlisting></para>

      <para>Gebruik een editor als vi, emacs of pico om het volgende bestand
aan te maken het sla het op als <filename>~/fase/etc/fstab</filename>.</para>

      <para><programlisting>proc		/proc	proc	noauto		0	0
/dev/ram0	/	ext2	defaults	1	1</programlisting></para>
    </sect2>

    <sect2>
      <title>Schrijf een script om het proc bestandssysteem te mounten</title>

<para>
<programlisting>
<prompt>bash#</prompt> mkdir ~/fase/etc/init.d
<prompt>bash#</prompt> cd ~/fase/etc/init.d
</programlisting></para>

      <para>Gebruik een editor om het volgende shellscript aan te maken en
sla het op als <filename>~/fase/etc/init.d/proc_fs</filename>:</para>

      <para><programlisting>#!/bin/sh
#
# proc_fs - mount het proc bestandssysteem
#
PATH=/sbin:/bin ; export PATH

mount -t proc proc /proc
#
# einde van proc_fs</programlisting></para>
    </sect2>

    <sect2>
      <title>Schrijf een script dat lokale bestandssystemen controleert en mount</title>

      <para>Gebruik een editor om het volgende shellscript aan te maken en
sla het op als <filename>~/fase/etc/init.d/local_fs</filename>:</para>

      <para><programlisting>#!/bin/sh
#
# local_fs - controleer en mount lokale bestandssystemen
#
PATH=/sbin:/bin ; export PATH

fsck -ATCp
if [ $(($?)) -gt $((1)) ]; then
  echo &#34;Filesystem errors still exist!  Manual intervention required.&#34;
  /bin/sh
else
  echo &#34;Remounting / as read-write.&#34;
  mount -o remount,rw /
  echo &#34;Mounting local filesystems.&#34;
  mount -a
fi
#
# einde van local_fs</programlisting></para>

      <para>Stel uitvoerpermissies in op de scripts.</para>

      <para><programlisting>
<prompt>bash#</prompt> chmod +x proc_fs
<prompt>bash#</prompt> chmod +x local_fs</programlisting></para>
    </sect2>

    <sect2>
      <title>Maak een gecomprimeerd rootdiskimage aan</title>

      <para><programlisting>
<prompt>bash#</prompt> cd /
<prompt>bash#</prompt> dd if=/dev/zero of=/dev/ram7 bs=1k count=4096
<prompt>bash#</prompt> mke2fs -m0 /dev/ram7
<prompt>bash#</prompt> mount /dev/ram7 /mnt
<prompt>bash#</prompt> cp -dpR ~/fase/* /mnt
<prompt>bash#</prompt> umount /dev/ram7
<prompt>bash#</prompt> dd if=/dev/ram7 of=~/phase4-image bs=1k
<prompt>bash#</prompt> gzip -9 ~/phase4-image</programlisting></para>
    </sect2>

    <sect2>
      <title>Schrijf het rootdiskimage naar diskette</title>

      <para>Doe de diskette met het label &#34;rootdisk&#34; in het
diskettestation fd0.</para>

      <para><programlisting>
<prompt>bash#</prompt> dd if=~/phase4-image.gz of=/dev/fd0 bs=1k</programlisting></para>
    </sect2>
  </sect1>

  <sect1>
    <title>Implementatie</title>

    <sect2>
      <title>Systeemstart</title>

      <para>Start het systeem volgens de volgende procedure:</para>

      <itemizedlist>
        <listitem>
          <para>Boot de PC met behulp van de diskette met het label 
&#34;bootdisk&#34;.</para>
        </listitem>

        <listitem>
          <para>Typ <userinput>bootdisk init=/bin/sh</userinput> 
          achter de LILO-prompt.</para>
        </listitem>

        <listitem>
          <para>Doe de recent aangemaakte rootdisk in het diskettestation
wanneer dit wordt aangegeven.</para>
        </listitem>
      </itemizedlist>

      <para>De uitvoer zou het onderstaand voorbeeld moeten weerspiegelen:
</para>

      <para><screen>boot: bootdisk init=/bin/sh
Loading bootdisk
Uncompressing Linux... Ok, booting kernel.
..
.. [diverse kernelmeldingen]
..
VFS: Insert root floppy to be loaded into RAM disk and press ENTER
RAMDISK: Compressed image found at block 0
VFS: Mounted root (ext2 filesystem) readonly.
Freeing unused kernel memory: 178k freed
# _</screen></para>
    </sect2>

    <sect2>
      <title>Test proc_fs en local_fs scripts</title>

      <para>Voer de scripts uit door de volgende opdrachten achter de
shellprompt in te tikken:
      </para>

<para><programlisting>
<prompt>bash#</prompt> PATH=/sbin:/bin:/etc/init.d ; export PATH
<prompt>bash#</prompt> proc_fs
<prompt>bash#</prompt> cat /etc/mtab
<prompt>bash#</prompt> local_fs
Remounting / as read-write.
Mounting local filesystems
<prompt>bash#</prompt> df</programlisting></para>

      <para>De schermuitvoer zou er ongeveer uit moeten zien als in 
onderstaand voorbeeld als alles naar behoren werkt.
      </para>

      <para><screen>
<prompt>bash#</prompt> PATH=/sbin:/bin:/etc/init.d ; export PATH
<prompt>bash#</prompt> proc_fs
<prompt>bash#</prompt> cat /etc/mtab
/dev/root / ext2 ro 0 0
proc /proc proc rw 0 0
<prompt>bash#</prompt> local_fs
/dev/ram0: clean 74/1024 files 3178/4096 blocks
<prompt>bash#</prompt> df
Filesystem      1k-blocks       Used Available Use% Mounted on
/dev/root       3963            3045 918        77% /
</screen></para>
    </sect2>

    <sect2>
      <title>Maak extra bestandssystemen aan en mount deze</title>

      <para>Verwijder de rootdisk diskette en doe een lege diskette
met het label &#34;home&#34; in het diskettestation. 
Typ dan de volgende opdrachten:</para>

      <para><programlisting>
<prompt>bash#</prompt> mkfs /dev/fd0
<prompt>bash#</prompt> fsck /dev/fd0
<prompt>bash#</prompt> mount /dev/fd0 /home
<prompt>bash#</prompt> mkdir /home/floyd
<prompt>bash#</prompt> cd /home/floyd
<prompt>bash#</prompt> echo &#34;Goodbye cruel world.&#34; &#62; goodbye.txt
<prompt>bash#</prompt> cat goodbye.txt</programlisting></para>
    </sect2>

    <sect2>
      <title>Systeem afsluiten</title>

      <para><programlisting>
<prompt>bash#</prompt> cd /
<prompt>bash#</prompt> umount /dev/fd0
<prompt>bash#</prompt> sync</programlisting></para>

      <para>Verwijder de diskette uit fd0 en herstart het systeem met
      <keycap>CTRL</keycap>-<keycap>ALT</keycap>-<keycap>DELETE</keycap>.</para>
    </sect2>
  </sect1>
</chapter>
