Avanti Indietro Indice

6. Introduzione al boot via rete e all'Etherboot

Questo capitolo è stato scritto da Ken Yap e spiega come avviare il proprio computer da un programma immagazzinato in una memoria non volatile senza accedere al proprio disco rigido. È una tecnica ideale per gestire e configurare una "fattoria" di macchine linux.

6.1 Cos'è il boot via rete?

Il boot via rete è una vecchia idea; l'idea di base è che il computer abbia un qualche codice di bootstrap nella memoria non volatile, cioè un chip ROM, che gli permetterà di contattare un server per ottenere i file di sistema attraverso un collegamento di rete.

6.2 Come funziona

Perché sia possibile un boot attraverso la rete il computer deve ricevere:

  1. un'identità,
  2. un'immagine del sistema operativo e,
  3. di solito, un file system funzionante.

Consideriamo un computer diskless (DC) che abbia una ROM per il boot via rete. Potrebbe essere uno di vari DC identici, come possiamo distinguere questo computer dagli altri? C'è una informazione che è unica per quel computer (in realtà per il suo adattatore di rete) ed è il suo indirizzo Ethernet. Ogni adattatore Ethernet nel mondo ha un indirizzo Ethernet univoco di 48 bit; ciò perché ad ogni costruttore di hardware Ethernet sono stati assegnati dei blocchi di indirizzi. Per convenzione tali indirizzi sono scritti con cifre esadecimali, con i due punti che separano ogni gruppo di due cifre; ad esempio: 00:60:08:C7:A3:D8.

I protocolli usati per ottenere un indirizzo IP, dato un indirizzo Ethernet, sono chiamati Boot Protocol (BOOTP) e Dynamic Host Configuration Protocol (DHCP, protocollo di configurazione dinamica dell'host). DHCP è una evoluzione di BOOTP. Nella nostra discussione, salvo ove diversamente specificato, tutto ciò che si applica a BOOTP vale anche per DHCP (in realtà dire che BOOTP e DHCP traducono solo indirizzi Ethernet è una piccola bugia; nella loro lungimiranza, i progettisti hanno dato a BOOTP e DHCP la possibilità di funzionare con qualsiasi tipo di indirizzo hardware, ma Ethernet è quello che verrà usato nella maggioranza dei casi).

Un esempio di scambio BOOTP funziona così:

DC: Salve, il mio indirizzo hardware è 00:60:08:C7:A3:D8, per favore dammi il mio indirizzo IP.

server BOOTP: (guardando nel database degli indirizzi) Il tuo nome è aldebaran, il tuo indirizzo IP è 192.168.1.100, il tuo server è 192.168.1.1, il file da cui effettuare il boot è /tftpboot/vmlinux.nb (più qualche altra informazione).

Ci si potrebbe chiedere come ha fatto il DC a trovare l'indirizzo del server BOOTP la prima volta. La risposta è che non l'ha fatto; la richiesta BOOTP è stata diffusa in broadcast sulla rete locale e qualsiasi server BOOTP in grado di rispondere lo ha fatto.

Dopo aver ottenuto un indirizzo IP, il DC deve scaricare l'immagine di un sistema operativo ed eseguirlo. Qui viene usato un altro protocollo Internet chiamato Trivial File Transfer Protocol (TFTP - protocollo elementare per il trasferimento file). Il TFTP è una specie di versione ridotta dell'FTP --- non c'è autenticazione e funziona sullo User Datagram Protocol (UDP) invece che sul Transmission Control Protocol (TCP). È stato scelto l'UDP al posto del TCP a causa della semplicità; l'implementazione dell'UDP sul DC può essere abbastanza piccola da permettere di farne facilmente entrare il codice in una ROM. Visto che l'UDP è un codice orientato ai blocchi, al contrario di uno orientato al protocollo, il trasferimento avviene blocco per blocco, in questo modo:

DC: Dammi il blocco 1 di /tftpboot/vmlinux.nb.
server TFTP: Eccolo.
DC: Dammi il blocco 2.

...e così via, finché non viene trasferito l'intero file. L'handshaking è basato su una semplice conferma di ogni blocco e la perdita di pacchetti è gestita ritrasmettendo dopo un timeout. Quando sono stati ricevuti tutti i pacchetti la ROM di boot della rete passa il controllo all'entry point dell'immagine del sistema operativo.

Concludendo, per poter eseguire un sistema operativo deve essere fornito un filesystem principale. Il protocollo usato da Linux e da altri Unix di solito è il Network File System (NFS - file system di rete), sebbene siano possibili altre scelte. In questo caso il codice non deve risiedere nella ROM ma può essere parte del sistema operativo che si è appena scaricato. Comunque il sistema operativo deve essere capace di girare con un file system principale che sia un NFS invece che un vero disco. Linux ha le variabili di configurazione necessarie per compilare una versione che possa farlo.

6.3 Il boot via rete in pratica

Il Net Loader è un programmino che gira come estensione del BIOS, di solito su una EPROM nel NIC. Esso gestisce le richieste BOOTP e i caricamenti TFTP e poi trasferisce il controllo all'immagine caricata. Usa i protocolli TCP/IP ma l'immagine caricata non deve necessariamente essere Linux; può essere qualunque cosa, anche DOS. Possono anche essere caricate da un floppy per effettuare delle prove o per provare impostazioni temporanee.

Oltre alle ROM di boot commerciali ci sono DUE fonti di pacchetti per il boot via rete. Implementazioni libere (free) di loader per reti TCP/IP sono:

  1. ETHERBOOT http://www.slug.org.au/etherboot/ e
  2. NETBOOT http://www.han.de/~gero/netboot.html

Innanzi tutto bisogna accertarsi che la propria scheda di rete sia supportata da Etherboot o da Netboot. Eventualmente bisognerà trovare una persona disposta a mettere il codice in una EPROM (Erasable Programmable Read Only Memory) al posto proprio, ma all'inizio si può effettuare il boot via rete da un floppy.

Per creare un floppy di boot nella distribuzione viene fornito uno speciale blocco di boot. Questo piccolo programma di 512 byte carica in memoria i blocchi del disco che lo seguono nel floppy e inizia l'esecuzione. Quindi, per fare un floppy di boot, uno deve solo concatenare il blocco di boot con il binario Etherboot contenente il driver per una scheda di rete, in questo modo:


        # cat floppyload.bin 3c509.lzrom > /dev/fd0

Si prenda il pacchetto nfdboot (disponibile presso il proprio sito mirror Linux preferito nella directory /pub/Linux/system/Linux-boot). Esso contiene una immagine bootprom per le schede di rete (come la wd8013) che può essere scritta direttamente. Vedere anche il sito LTSP presso http://www.ltsp.org

Prima di inserire il floppy per il boot via rete bisogna preparare tre servizi su Linux:

  1. BOOTP (o DHCP)
  2. TFTP e
  3. NFS.

Non è necessario prepararli tutti e tre contemporaneamente, si può farlo un passo alla volta, accertandosi che ogni passo funzioni prima di passare al successivo.

Bootp

Si installi Bootp. Vedere bootp*.rpm sul cdrom Redhat Linux. Vedere anche i pacchetti RPM sul sito LTSP presso http://www.ltsp.org. Vedere anche le pagine di manuale unix 'man 5 bootptab', 'man 8 bootpd', 'man 8 bootpef', 'man 8 bootptest'. Bisogna poi assicurarsi che il server stia aspettando richieste bootp. Il demone può essere lanciato direttamente col comando


       bootpd -s

oppure usando inetd; si editi il file /etc/inetd.conf e si inserisca una riga come la seguente:


bootps dgram   udp     wait    root    /usr/sbin/in.bootpd    bootpd

Inserire o togliere il commento dalle seguenti due righe in /etc/services:
bootps          67/tcp          # server BOOTP
tftp            69/udp          # server TFTP

Se si è dovuto modificare /etc/inetd.conf allora è necessario far ripartire inetd inviando al processo il segnale HUP.


       kill -HUP <id del processo inetd>

Poi, bisogna dare a bootp un database per mappare gli indirizzi Ethernet con indirizzi IP. Questo database è in /etc/bootptab. Bisogna modificarlo inserendo gli indirizzi IP del proprio gateway, del server dns e gli indirizzi ethernet delle proprie macchine diskless. Il database contiene righe aventi la forma:


aldebaran.foo.com:ha=006008C7A3D8:ip=192.168.1.100:bf=/tftpboot/vmlinuz.nb

Possono essere specificate altre informazioni, ma cominceremo nel modo facile.

Un altro esempio di /etc/bootptab è:


  global.prof:\
          :sm=255.255.255.0:\
          :ds=192.168.1.5:\
          :gw=192.168.1.19:\
          :ht=ethernet:\
          :bf=linux:
  machine1:hd=/export/root/machine1:tc=global.prof:ha=0000c0863d7a:ip=192.168.1.140:
  machine2:hd=/export/root/machine2:tc=global.prof:ha=0800110244e1:ip=192.168.1.141:
  machine3:hd=/export/root/machine3:tc=global.prof:ha=0800110244de:ip=192.168.1.142:

global.prof è una generica traccia per le voci di host, in cui:

Dopo di che, ogni macchina deve avere una riga in cui:

Ora si faccia il boot del DC col floppy e questi dovrebbe rilevare la propria scheda Ethernet e diffondere una richiesta BOOTP. Se tutto va bene il server dovrebbe rispondere al DC con l'informazione richiesta. Poiché /tftpboot/vmlinux.nb ancora non esiste, quando proverà a caricare il file fallirà. Ora occorre compilare un kernel speciale, uno in cui sia abilitata l'opzione per montare il filesystem principale dal NFS. Bisogna anche abilitare l'opzione per prendere l'indirizzo IP del kernel dalla risposta BOOTP originale. Si deve compilare il driver Linux per il proprio adattatore di rete dentro al kernel, invece che caricarlo come modulo. È possibile scaricare un ramdisk iniziale di modo che il caricamento dei moduli funzioni, ma questo è qualcosa che si può fare in seguito.

Non si può installare direttamente la zImage risultante dalla compilazione del kernel, deve essere prima convertita in una immagine marcata. Una immagine marcata è una normale immagine del kernel con un header speciale che dice al bootloader di rete dove vanno i byte nella memoria e da quale indirizzo iniziare il programma. Per creare tale immagine marcata va usato un programma chiamato mknbi-linux. Questa utility si trova nella distribuzione Etherboot. Dopo che è stata generata l'immagine la si metta nella directory /tftpboot col nome specificato in /etc/bootptab. Si renda tale file leggibile da tutti perché il server tftp non ha privilegi speciali.

Riguardo TFTP, vedere tftp*.rpm sul cdrom Redhat Linux. Il TFTP (Trivial File Transfer Protocol) è un protocollo per il trasferimento di file, come ftp ma molto più semplice, il che è d'aiuto per codificarlo nelle EPROM. TFTP può essere usato in due modi:

Tftpd viene di solito avviato da inetd con una riga in /etc/inetd.conf simile alla seguente:


tftp dgram udp wait root /usr/sbin/tcpd in.tftpd -s /tftpboot
#tftp   dgram   udp     wait    root    /usr/sbin/in.tftpd     tftpd /export

Di nuovo, si riavvii inetd con un segnale HUP e si riprovi il boot; stavolta dovrebbe scaricare l'immagine del kernel ed eseguirla. Si otterrà che il boot va avanti fino al punto in cui prova a montare un filesystem principale. A questo punto per procedere bisogna configurare ed esportare le partizioni NFS.

Filesystem principale NFS

Per vari motivi, non è una buona idea usare il filesystem principale del server come filesystem principale del DC. Il primo semplicemente è che lì ci sono diversi file di configurazione e in quel modo il DC prenderà l'informazione sbagliata. Un altro è la sicurezza; è pericoloso permettere l'accesso in scrittura alla root del server (e, per diversi motivi, l'accesso in scrittura al filesystem principale è indispensabile). Comunque la buona notizia è che un filesystem principale per il DC non è molto grande, solo 30 MB circa, e buona parte di esso può essere condiviso fra più DC.

Idealmente, per costruire un filesystem principale bisogna sapere quali file si aspetta di vedere lì la vostra distribuzione del sistema operativo. Per il boot sono cruciali i file di device, quelli in /sbin e in /etc. È possibile evitare gran parte del lavoraccio copiando un filesystem principale esistente e modificando alcuni file per il DC. Nella distribuzione Etherboot c'è un tutorial ed alcuni link ad un paio di script di shell che servono per creare un tale filesystem principale per il DC partendo da un filesystem principale esistente su un server. Nella documentazione di Etherboot ci sono anche dei suggerimenti su come risolvere i problemi, visto che questa è spesso la parte più insidiosa della preparazione.

Il kernel Linux fatto su misura per il DC si aspetta di vedere il filesystem principale in /tftpboot/(indirizzo IP del DC), ad esempio: /tftpboot/192.168.1.100 nel suddetto caso. Ciò, volendo, può essere modificato durante la configurazione del kernel.

Ora si crei, o si modifichi, /etc/exports sul server e si aggiunga una riga così fatta:


/tftpboot/192.168.1.100 aldebaran.foo.com(rw,no_root_squash)

L'accesso rw è necessario per vari servizi di sistema. L'attributo no_root_squash impedisce al sistema NFS di mappare l'ID del root su un altro. Se questi non è specificato vari demoni e generatori di log non saranno contenti.

Si avviino, o riavviino, i servizi NFS (rpc.portmap e rpc.mountd) e si riprovi il boot senza dischi. Se va tutto bene il kernel dovrebbe essere in grado di montare un filesystem principale e proseguire il boot fino al prompt di login. Più probabilmente ci si accorgerà che ci sono diverse cose non configurate a dovere. La maggior parte delle distribuzioni Linux sono orientate verso le operazioni su disco e necessitano di un po' di modifiche per andar bene per un boot diskless. La più comune causa di fallimento è dovuta al fatto che il processo di boot fa affidamento ai file sotto /usr, che di solito viene importata da un server più tardi nel processo di boot. Due possibili soluzioni sono:

  1. Fornire i pochi file richiesti sotto una piccola directory /usr sul filesystem principale, che verrà poi sovrascritta quando verrà importato /usr;

  2. Modificare il path in modo che cerchi i file nel filesystem principale. I file da modificare sono sotto /tftpboot/192.168.1.100 (si ricordi che questa è la directory principale del DC).

Si potrebbero voler montare altre directory dal server, come /usr (che può essere esportata in sola lettura).

Scrivere la EPROM

Quando si è ottenuto di poter fare il boot dalla rete senza nessun problema, si potrebbe voler mettere il codice in una EPROM.

6.4 Utilizzi del boot via rete

I terminali X sono un naturale utilizzo del boot via rete. La mancanza di dischi sul terminale lo rende più silenzioso e contribuisce a rendere piacevole l'ambiente di lavoro. La macchina idealmente dovrebbe avere 16MB o più di memoria e la miglior scheda video che si riesce a trovargli. Questo è l'utilizzo ideale per un 486 di fascia alta, o un Pentium di fascia bassa, che è diventato obsoleto a causa dell'evoluzione dell'hardware. Altri usano il boot via rete per cluster di macchine in cui l'uso del DC è leggero e non giustifica la presenza di un disco; cioè un cluster di macchine in un'aula scolastica.

6.5 Per maggiori informazioni

Il primo posto in cui fermarsi è la home page di Etherboot: http://www.slug.org.au/etherboot/

Lì si troveranno link ad altre risorse, inclusa una mailing list a cui iscriversi, in cui vengono discussi problemi e soluzioni.

Documenti correlati:

6.6 Configurazione del Linux Redhat

Il DC richiede di montare /tftpboot/<indirizzo IP del DC> (nella 2.1 e precedenti: /tftpboot/<nome del DC in bootptab>) come sua '/' tramite NFS dal server. Bisogna esportarlo dal server (rw, no_root_squash) perché il DC ci vuole scrivere (file di log, ecc).

La directory di root / deve contenere /sbin, /lib, /etc, /var, /tmp, /root, /dev e /proc.

/sbin, /bin e /lib possono essere una copia di un sistema Linux Redhat esistente. Possono essere condivise tra tutti i DC. Ma solo link fisici. A proposito, non si facciano link agli originali sul server.

/etc, /var e /dev devono essere copie non condivisibili. Si aggiustino ad hoc /etc/sysconfig/network, /etc/sysconfig/network-scripts/ifcfg-eth0, /etc/fstab, /etc/conf.modules e altri. Disabilitare tutti i servizi di rete che non servono. Togliere da /var tutta la roba di cui non si ha bisogno, ad es. i db RPM e i file lpd.

/root e /proc dovrebbero semplicemente esistere. /tmp dovrebbe esistere ed essere mode 1777.

Probabilmente si vorrà creare i mount point /usr e /home. /usr può essere montato ro (read only - a sola lettura).

Dovrebbero bastare circa 10 MB per DC più circa 15 MB per i file condivisi. A proposito: se i propri DC sono identici anche l'immagine del kernel può essere condivisa.

Ecco uno script illustrativo per creare il primo filesystem root:


#!/bin/sh
if [ $# != 1 ]
then
        echo Usage: $0 client-IP-addr
        exit 1
fi

cd /

umask 022

mkdir -p /tftpboot/$1

# facciamo così
for d in home mnt proc tmp usr
do
        mkdir /tftpboot/$1/$d
        done

        chmod 1777 /tftpboot/$1/tmp

        touch /tftpboot/$1/fastboot
        chattr +i /tftpboot/$1/fastboot

        # copiamo questi
        cp -a bin lib sbin dev etc root var /tftpboot/$1

cat <<EOF
Ora, in /tftpboot/$1/etc, editare

                sysconfig/network
                sysconfig/network-scripts/ifcfg-eth0
                fstab
                conf.modules

e configurare

                rc.d/rc3.d
EOF

Ecco uno script illustrativo per duplicare il filesystem root:


#!/bin/sh
if [ $# != 2 ]
then
        echo Usage: $0 olddir newdir
        exit 1
fi

cd /tftpboot

if [ ! -d $1 ]
then
        echo $1 is not a directory
        exit 1
fi

umask 022

mkdir -p $2

# facciamo così
for d in home mnt proc tmp usr
do
        mkdir $2/$d
done

chmod 1777 $2/tmp

touch $2/fastboot
chattr +i $2/fastboot

# linkiamo questi
for d in bin lib sbin
do
        (cd $1; find $d -print | cpio -pl ../$2)
done

# copiamo questi
for d in dev etc root var
do
        cp -a $1/$d $2
done

cat <<EOF
Ora, in /tftpboot/$2/etc, editare

        sysconfig/network
        sysconfig/network-scripts/ifcfg-eth0
        fstab (forse)
        conf.modules (forse)

e configurare

        rc.d/rc3.d
EOF

6.7 X-terminal

Sul server, ci si assicuri che il DC corrisponda ad un'apposita voce in /etc/X11/xdm/Xaccess e si commenti il :0 in /etc/X11/xdm/Xservers. Poi ci si assicuri che xdm venga eseguito dagli script di init.

Sul client, eseguire X -query server

Si otterrà la finestra di login di xdm, dopo di che tutti i propri client X gireranno sul server.

Riguardo l'uso di altre applicazioni, si potrebbe usare la tecnica diskless per router netboot, server di stampa (ma non devono essere server di stampa in spooling), applicazioni standalone, ecc.


Avanti Indietro Indice