``Si, anch'io voglio fare il sistemista!!''

OK, diciamo la verità: ci siete cascati, è come la diane-verde-che-porta-sfiga ma non potete passarla al compagno di banco toccandolo sulla spalla, vi tocca organizzare un intero corso; ritentate, vi andrà meglio la prossima volta...

Adesso, piangete, strappatevi i capelli, telefonate alla mamma, poi tirate un profondo respiro, e leggete cosa dicono su alt.sysadmin.recovery riguardo al quesito fondamentale di un sistemista:

D: Come posso convincere i miei computer a comportarsi bene?

R: Alcuni preferiscono il bastone, altri la carota, altri ancora entrambi. Chi opta per la carota offre maggiore memoria o CPU più veloci; chi va per il bastone usa un frustino. Molti computer si ingannano facilmente, quindi una fotografia davanti al monitor farà spesso credere al computer che tu sei veramente seduto lì davanti ed avrà troppa paura per sgarrare.

Ricordate che se i computer sono in rete, possono parlarsi gli uni con gli altri. Questo significa che se date una lezione esemplare ad uno, gli altri staranno a guardare (e forse impareranno...)

Nel seguito, assumo una conoscenza di GNU/Linux almeno come utente, una certa familiarità con i principali servizi di rete (WWW, FTP, ...), ed una buona dose di pazienza.

Chi non fosse mai stato utente può leggere la ``Guida dell'Utente Linux'' di Larry Greenfield, tradotta da Eugenia Franzoni oppure UNIXhelp for Users (a cura dell'Università di Edinburgo).

Tutta la documentazione locale di poisson si può consultare dalla rete all'indirizzo http://www-studenti.dm.unipi.it/doc/dwww.html ...

Ho cercato di evitare (per quanto mi è stato possibile) il ricorso al gergo; per i termini ancora dubbi, c'è un piccolo glossario che spero riesca a gettare fumo negli occhi.

Fatemi un servizio...

Lo scopo di un computer è di fornire servizi al resto del mondo. (I computer più modesti si accontentano di offrire servigi a chi si siede davanti a loro, ma noi siamo dei gonfi)

Da bravi matematici partiamo dal caso più semplice: consideriamo un computer perfettamente sferico, chiuso da solo in una stanza cubica e collegato al resto del mondo con un cavo di rete sottile... A questo computer si può accedere solo attraverso la rete, ed attiva un solo servizio: il WWW. (si dice che questo computer è un server WWW dedicato ). Questo computer lo chiameremo inky .

Cosa significa in pratica che un solo servizio è attivo su questa macchina? Possiamo dividere i servizi dei computer in due grandi categorie: servizi locali, cioè quelli che possono essere utilizzati da chi proprio è seduto davanti al computer, e servizi remoti, cioè quelli a cui si accede tramite la rete. Tralasciamo per ora i servizi locali, che essenzialmente consistono nel poter utilizzare la macchina per eseguirvi programmi, perchè inky non ha utenti; ci concentriamo allora sui servizi di rete.

Il sistema di comunicazione della rete paragona un po' i computer a dei palazzi: ogni computer ha delle porte, ogni porta è numerata (ce ne sono circa 32000) ed un programma può mettersi ad aspettare dietro le porte che vuole (si dice che è un server ); i programmi degli altri computer possono andare a bussare ad una specifica porta per chiedere un accesso: se il programma server risponde, si dice che è stabilita una connessione. Alcune porte sono riservate a specifici servizi: il server HTTP risponde sempre e solo alle chiamate sulla porta 80.

Servizi e Processi

Ogni compito svolto da un computer è guidato da una serie di istruzioni, contenute in un programma; dunque ogni servizio attivato da un computer è condotto da un programma. Nella terminologia UNIX si dice processo un programma in esecuzione; si dice che il processo è un'istanza di un certo programma, e che questo programma è un'immagine del processo. Limiteremo la dizione programma ai file: un file che contiene codice eseguibile è un programma, ma la sua copia in memoria, quella che viene eseguita, avrà sempre il nome di processo.

Per ispezionare i processi in corso si usa il comando ps:

murri@inky ~$ ps aufx

USER       PID %CPU %MEM  SIZE   RSS TTY STAT START   TIME COMMAND
root         1  0.0  0.1   792    68  ?  S   Nov  7   0:04 init [5] 
root         2  0.0  0.0     0     0  ?  SW  Nov  7   0:00 (kflushd)
root         3  0.0  0.0     0     0  ?  SW< Nov  7   0:01 (kswapd)
root        10  0.0  0.0   744    28  ?  S   Nov  7   0:01 update 
root       289  0.0  0.2  2000   172  ?  S   Nov  7   0:00 /usr/sbin/apache 
www-data   882  0.0  1.0  2040   684  ?  S   Nov  8   0:10  \_ /usr/sbin/apache 
www-data 23243  0.0  1.0  2040   696  ?  S   Nov  8   0:10  \_ /usr/sbin/apache 
murri     2898  0.0  1.7  1796  1096  p0 S    22:26   0:00 -sh 
murri     3007  0.0  0.9   968   624  p0 R    23:18   0:00  \_ ps aufxww 
    
Questa tabella indica per ogni processo: la percentuale di memoria utilizzata complessivamente (%MEM), la quantità di memoria usata complessivamente (SIZE), la percentuale di tempo macchina usata finora (%CPU), il tempo macchina complessivo (ovvero quanto tempo il processore ha effettivamente dedicato a quel processo finora, colonna TIME), la data in cui il processo ha iniziato ad essere eseguito (si dice: "è stato lanciato", colonna START), più altri parametri incomprensibili...

Notiamo alcune cose:

E il processo apache? Proprio lui risponde alle connessioni di rete per fornire il servizio WWW ( HTTP server ): quando un programma come ad esempio netscape chiede l'accesso ad una pagina, il server HTTP cerca sul disco di inky il file che contiene quella pagina, e ne "spara" il contenuto sulla rete.

Possiamo affermare, in generale, che ogni servizio e` attivato da un almeno un processo. Nel caso del programma apache, occorrono 3 processi per svolgere un servizio: i vari processi figli si alternano, nel rispondere alle chiamate dall'esterno (proprio come se fossero i commessi di un negozio, questo permette di minimizzare i tempi di attesa...)

File, Directory e la Rete

Ogni pagina del WWW corrisponde (più o meno) ad un file tenuto sul disco di inky; c'è una analoga corrispondenza con le directory:


 Name Last modified Size Description
[DIR] Parent Directory 12-Nov-1998 10:32 0k [DIR] HTML/ 25-May-1997 00:09 0k [TXT] NoteSullaTraduzione.h..29-Mar-1997 16:24 3k Note sulla traduzione... [TXT] bookmarks.html 29-Mar-1997 16:25 15k Riccardo Murri's Bookmarks... [TXT] intro.html 12-Nov-1998 23:33 6k Si, anch'io voglio fare... [DIR] pictures/ 15-Apr-1997 13:22 0k
Ecco cosa si può ottenere dando direttamente il comando di lista della directory (elenco, in italiano, ma nessuno lo usa...):
murri@inky /var/www/people/murri$ ls -lF
total 39
drwxrwxrwx   3 murri    200          1024 May 25  1997 HTML/
-rw-r--r--   1 murri    60           2847 Mar 29  1997 NoteSullaTraduzione.html
-rw-r--r--   1 murri    60          15561 Mar 29  1997 bookmarks.html
-rw-r--r--   1 murri    murri        6522 Nov 12 23:33 intro.html
drwxr-xr-x   2 murri    60           1024 Apr 15  1997 pictures/
Corrisponde perfettamente... :-) A questo punto, se uno clicca su pictures/, vede un analogo listato di directory, e si può verificare che corrisponde a quello che si ottiene con ls -l.

Dunque il server HTTP permette di leggere file e directory che risiedono fisicamente su un altro computer. Questo pone il primo problema di sicurezza del computer: quali file sono accessibili dall'esterno tramite il server HTTP? Se tutti i file fossero visibili, non si potrebbe tenere nascosto nulla a nessuno sulla rete... Ora, il programma apache ha una vasta scelta di meccanismi per restringere gli accessi a certi file e certe zone dello spazio WWW (webspace), ma parleremo solo del meccanismo più elementare: la restrizione per discesa delle directory.

Una directory è un file speciale il cui contenuto sono altri file; ovviamente ogni directory può contenerne altre, e così via, come in un gioco di scatole cinesi. Graficamente, possiamo rappresentare la struttura delle directory come un albero: la directory in cima (root o /) è la base del tronco e tutte le altre sono rami che se ne dipartono.

murri@inky ~$ tree -adx /
/
|-- bin
|-- boot
|-- dev
|-- etc
|   |-- apache
|   |-- ftpd
|   |-- rc.boot
|   |-- skel
|   `-- X11
|       |-- fvwm2
|       |-- twm
|       |-- xdm
|       `-- xserver
|-- home
|-- lib
|-- mnt
|-- proc
|-- root
|-- sbin
|-- tmp
|-- usr
|-- var
|   |-- cache
|   |-- lib
|   |-- www
|       |-- cgi-bin
|       |-- people
|       |   `-- murri -> /home/murri/public_html
|       `-- public_html
`-- vol
Allora apache permette l'accesso solo ai file ed alle directory che partono dal ramo /var/www: l'intero spazio WWW della macchina inky si trova sotto /var/www! Le directory sono nate per permettere di raggruppare insieme i file logicamente correlati, e UNIX estremizza questo concetto e tende ad organizzare ogni sistema di dati come ramo del suo albero delle directory; così:

I link simbolici

E se uno deve per forza mettere i file in directory che non discendono tutte dallo stesso ramo? Esiste una soluzione a questo: i link simbolici (symlink o soft link). Osserviamo:

[...]
|   |-- www
|       |-- cgi-bin
|       |-- people
|       |   `-- murri -> /home/murri/public_html
[....]
Il simbolo -> indica che /var/www/people/murri è in realtà una deviazione verso /home/murri/public_html; ogni accesso a /var/www/people/murri verrà automaticamente deviato (dal sistema Linux, non da apache!) ad un accesso a /home/murri/public_html. Poichè /home/murri/public_html è una directory, /var/www/people/murri viene vista dal sistema come directory: in pratica un link simbolico costituisce un altro punto di accesso ad una directory o ad un file, con un nome diverso e (possibilmente) da tutto un altro ramo dell'albero.

Piu` tecnicamente, l'algoritmo di risoluzione dei nomi dei file (cioe` dal nome di un file, trovare la effettiva collocazione dei suoi dati sul disco) e` ricorsivo: il sistema Linux entrera` in ogni directory di un percorso, spostandosi poi bruscamente di ramo quando incontra un link simbolico, seguendo il percorso puntato dal link.

Esempio

Per risolvere /var/www/people il sistema cerchera` prima la directory var sotto /, poi www dentro var, infine people in www. Allora, se /var/www/people/murri e` un link simbolico a /home/murri/public_html, il sistema, dopo aver risolto /var/www/people, vi cerchera` dentro murri, nota che e` un link simbolico e risolvera` quindi il contenuto del link, cioe` /home/murri/public_html.

Non siamo soli nell'universo

Adesso siamo pronti per dare uno sguardo nel mondo intorno a noi; complichiamo un po' la situazione e consideriamo un computer che fa da server FTP. FTP è un protocollo che, come HTTP, permette di accedere a file posti su computer remoti; a differenza di HTTP, però, permette anche di sovrascrivere un file e non solo di leggerlo. Questo pone ulteriori problemi di sicurezza del sistema...

Prendiamo ad esempio una macchina del dipartimento; Ci colleghiamo subito a paley:

murri@poisson ~> ftp paley
Connected to paley.dm.unipi.it

220 paley FTP server (Version wu-2.4(1) Fri Aug 1 11:52:45 MET DST 1997) ready.
Name (paley:murri): murri
Password:  
Qui compare già la prima grande differenza con HTTP : viene chiesto il nome ed una password! Evidentemente FTP distingue in qualche modo fra i diversi utenti che si possono collegare. In che modo tutto questo si riversa sui file? Facciamo una necessaria premessa: ora che mi sono identificato come utente 'murri' il sistema mi può (e deve) distinguere da ogni altro utente. Proviamo ad esempio ad andare nella home dell'utente 'op':
ftp> cd /op
250 CWD command successful.
ftp> ls -l
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 6
drwxr-xr-x   4 op       users        1024 Mar  6  1997 .
drwxr-xr-x  34 root     root         1024 Oct  2 11:45 ..
-rw-r--r--   1 op       users         178 Jun 29  1997 .bash_history
-rw-r--r--   1 op       users          12 Mar  6  1997 .forward
drwxr-xr-x   2 op       users        1024 Feb 21  1997 .ssh
drwx------   2 op       users        1024 Mar  6  1997 mbox
226 Transfer complete.
    
Effettivamente, pare che in qualche io non abbia il permesso di leggere alcuni file o directory dell'utente 'op':
ftp> cd mbox
550 mbox: Permission denied.
ftp> cd .ssh
250 CWD command successful.
ftp> ls
200 PORT command successful.
150 Opening ASCII mode data connection for /bin/ls.
total 3
drwxr-xr-x   2 op       users        1024 Feb 21  1997 .
drwxr-xr-x   4 op       users        1024 Mar  6  1997 ..
-rw-------   1 op       users         512 Feb 21  1997 random_seed
226 Transfer complete.
ftp> get random_seed
local: random_seed remote: random_seed
200 PORT command successful.
550 random_seed: Permission denied.
Sappiamo che ad ogni servizio attivo deve corrispondere almeno un processo; qual è quello che ha gestito tutta la sessione FTP?
murri@paley $ ps ufxw
USER       PID %CPU %MEM  SIZE   RSS TTY STAT START   TIME COMMAND
murri    26340  0.3  2.6  1160   832  ?  S   23:19   0:00 ftpd: poisson.dm.unipi.it: murri: IDLE
murri    26416  0.5  2.1  1216   680  p0 S   23:20   0:00 -bash
murri    26457  0.0  1.3   920   424  p0 R   23:20   0:00  \_ ps ufxwww
Dunque il processo ftpd è associato in qualche modo all'utente 'murri'. UNIX in realtà assegna ad ogni utente un codice, un numero positivo, detto User ID o UID. Un analogo codice viene assegnato ad ogni gruppo, e si chiama Group ID o GID. Ogni utente appartiene ad almeno un gruppo, ma possibilmente più d'uno, ed ogni gruppo può avere zero o più membri. Il nucleo del sistema porta in sé questa divisione per utenti e gruppi: quando un utente accede al sistema, per mezzo di un apposito programma di accesso (ad esempio login, xdm, oppure apppunto ftpd) ogni processo che il computer eseguirà per suo conto sarà contrassegnato con lo UID e il GID di quell'utente e non potrà cambiarli. (Ci sono alcune eccezioni.) Si dice che l'utente è il proprietario del processo. Anche ogni file ha un proprietario ed un gruppo proprietario. Il processo eredita tutti i privilegi e le restrizioni dell'utente che ne è proprietario: ogni file creato o da questo processo eredita quegli stessi UID e GID. (Anche qui ci sono eccezioni.)

Il file /etc/passwd contiene una corrispondenza tra i nomi degli utenti ed i loro GID, ed anche altre informazioni, che però non sono essenziali al funzionamento del sistema.

root:x:0:0:root:/root:/bin/bash
[...]
astud:x:106:103:NFS server Aula Studenti:/home/astud:/bin/false
[...]
pippo:x:10238:10238:Pippo (chi altri?):/home/sophie/pippo:/usr/bin/lshells/tcsh
pluto:x:10287:10287:Pluto - il cane di Topolino:/home/sophie/pluto:/usr/bin/lshells/tcsh
topolino:x:10239:10239:Topolino - il famoso investigatore:/home/sophie/topolino:/usr/bin/lshells/tcsh
gamba:x:11056:11056:Pietro Gambadilegno:/home/sophie/gamba:/usr/bin/lshells/tcsh
Le colonne sono separate da :, la prima contiene il nome, la seconda la password criptata oppure x se la password è nascosta, terza e quarta colonna contengono UID e GID rispettivamente... Notiamo due cose:

Analogamente, il file /etc/group contiene una corrispondenza tra i nomi dei gruppi, i GID e gli utenti membri:

staff:x:50:murri,ghiggini,cerulli,jama,maracci,botti
emu:x:106:murri,baccetti,pallotti
nfs:x:103:astud,daemon
cgi-bin:x:104:dwww
[...]
topolinia::10051:
[...]
nogroup:x:65534:

Attenzione! Un utente è comunque sempre membro del gruppo il cui GID è indicato nella sua riga in /etc/passwd, anche se non figura tra i membri di quel gruppo elencati in /etc/group; però può (dopo il processo di autenticazione) cambiare il proprio GID con quello di uno qualunque dei gruppi di cui risulta membro secondo /etc/group.

Confrontiamo ora la sessione FTP con una analoga sessione eseguita in locale su paley:

UNIVERSITÀ DI PISA
DIPARTIMENTO DI MATEMATICA "LEONIDA TONELLI"
CENTRO DI CALCOLO



paley.dm.unipi.it login: murri
Password:
    
(Accesso autenticato al sistema: qui è effettuato dal programma login anzichè ftpd, ma anche il login consulta i file /etc/passwd ed /etc/group)
Last login: Mon Nov 16 23:20:08 on ttyp0 from poisson.dm.unipi.
[murri@paley /paley/laurea/murri]$ cd /op
[murri@paley /op]$ ls -lA
total 4
-rw-r--r--   1 op       users         178 Jun 29  1997 .bash_history
-rw-r--r--   1 op       users          12 Mar  6  1997 .forward
drwxr-xr-x   2 op       users        1024 Feb 21  1997 .ssh/
drwx------   2 op       users        1024 Mar  6  1997 mbox/
[murri@paley /op]$ cd mbox
bash: mbox: Permission denied
[murri@paley /op]$ cd .ssh
[murri@paley /op/.ssh]$ ls -lA
total 1
-rw-------   1 op       users         512 Feb 21  1997 random_seed
[murri@paley /op/.ssh]$ cat random_seed
cat: random_seed: Permission denied
    

Dunque vediamo che abbiamo gli stessi diritti di accesso ai file sia in locale (con una sessione iniziata da login ) che in remoto (con una sessione ftp ): non è quindi il programma ftpd ad implementare un meccanismo di controllo degli accessi ai file (come fa ad esempio il server HTTP ), bensì il sistema operativo stesso!

Vediamo di capirci qualcosa:

  1. il programma ftpd autentica un utente all'inizio della sessione; da quel punto in poi quell'utente diventa proprietario del processo ftpd.
  2. ftpd tenta di accedere ad un file per conto dell'utente remoto che si è identificato con nome e password, ma il nucleo del sistema impedisce certe operazioni.
Come si collega la distinzione tra gli utenti con le restrizioni di accesso ai file? Per UNIX, ogni file deve avere:
  1. un proprietario;
  2. un gruppo proprietario;
  3. tre gruppi di permessi di lettura/scrittura.
Queste informazioni collegate al file vengono dette i suoi attributi. Il comando ls -l ci fornisce le informazioni del caso:
-rw-------   1 op             users     512  Feb 21 1997  random_seed
^^^^^^^^^^     ^^             ^^^^^
permessi       proprietario   gruppo proprietario

I permessi sono organizzati a gruppi di tre:

-rwxrwxrwx
sono i permessi del proprietario,
-rwxrwxrwx
sono i permessi del gruppo proprietario, e
-rwxrwxrwx
sono i permessi validi per il resto degli utenti (il mondo è il termine tecnico).
- r w x
File Leggere il file Scrivere sul file o cambiarne gli attributi Eseguire il file come programma
Directory Elencare il contenuto Creare o rimuovere file dalla directory Entrare nelle sotto-directory
Attenzione: Il permesso x per una directory corrisponde alla possibilità (detta directory traversal) di discendere lungo il ramo l'albero delle sottodirectory. In altre parole, perchè abbia effetto il comando:
murri@poisson$ ls /var/spool/lpd/cdc3
occorre avere permesso 'x' sulle directory var, spool, lpd e permesso 'r' nella directory cdc3.

Ci sono altri tipi di permessi, di interesse soprattutto per l'Amministratore di Sistema.
g+s (SGID o set-GID) I file creati in questa directory non ereditano il GID del processo che li crea, bensì quello della directory stessa.
t (sticky) Un utente non può cancellare o cambiare nome ai file degli altri che risiedono in questa directory. Ha ovviamente pieno potere sui suoi file.

Il permesso sticky serve per proteggere le directory dove un gran numero di utenti ha necessità di scrivere (per esempio /tmp o /var/tmp); si elimina così il rischio che un utente possa compromettere dati di un altro.

Il permesso SGID si usa sulle directory comuni di un progetto: in questo modo ogni file creato in quelle directory sarà sempre di proprietà del gruppo che possiede la directory, evitando che la distrazione di una persona possa bloccare l'accesso ai file da parte di tutti gli altri.
u+s (SUID o set-UID) Questo programma andrà in esecuzione sempre con proprietario = (proprietario del file eseguibile), indipendentemente da quale utente lo stia lanciando.
g+s (SGID o set-GID) Questo programma andrà in esecuzione sempre con (gruppo proprietario) = (gruppo proprietario del file eseguibile), indipendentemente da quale utente lo stia lanciando.
Spieghiamo meglio: ogni processo ha un proprietario ed un gruppo proprietario, che solitamente sono quelli dell'utente che lancia il programma. Un processo non può cambiare proprietario né gruppo, tranne che in due casi:

  1. Il programma è SUID (risp. SGID); allora il processo è autorizzato dall sistema a scambiare il suo proprietario (risp. gruppo) col proprietario del programma, cioè del file che contiene il codice che il processo esegue.
  2. Il proprietario è il SuperUtente ...

Il SuperUtente

Un solo utente è autorizzato a tramutarsi di colpo in ogni altro, ad accedere impunemente ad ogni file degli altri, per cambiarne senza ritegno il contenuto o gli attributi... costui sa, costui può, costui è il superutente. (Nella vita di ogni giorno, come SuperMan si cela sotto le mentite spoglie di Clark Kent, il superutente si nasconde sotto le dimesse spoglie del sistemista e l'enigmatico nome di root...) Il superutente ha UID e GID uguali a 0.

Esempio 1

Le password degli utenti sono in genere contenute nel file /etc/shadow, che è leggibile solo a root, per impedire che un utente maligno possa tentare di scovare le password degli altri. Dunque ogni programma di autenticazione deve avere come proprietario il superutente!

Dopo, che l'autenticazione è stata accertata, il programma cambia il suo proprietario ed il suo gruppo.

Esempio 2

Il programma 'su' permette ad un utente di acquisire momentaneamente privilegi di un altro utente, se conosce la password di accesso. Se 'su' fosse un programma normale non potrebbe cambiare il suo proprietario né il suo gruppo, e così tutti i suoi discendenti: in realtà su è un programma SUID dell'utente root, quindi quando un utente qualsiasi lancia un processo istanza del programma su, questo processo scambia il suo proprietario (l'utente che lo ha lanciato) con root, ed a questo punto è libero di procedere all'autenticazione e poi di cambiare proprietario e gruppo come meglio crede...

Esempio 3

Naturalmente è possibile anche il contrario (cioè che un processo abbandoni i privilegi di root, soprattutto per tutelarsi contro possibili compromissioni della sicurezza. Rivediamo la situazione del server HTTP su pinky:
murri@inky ~$ ps aufx

USER       PID %CPU %MEM  SIZE   RSS TTY STAT START   TIME COMMAND
[...]
root       289  0.0  0.2  2000   172  ?  S   Nov  7   0:00 /usr/sbin/apache 
www-data   882  0.0  1.0  2040   684  ?  S   Nov  8   0:10  \_ /usr/sbin/apache 
www-data 23243  0.0  1.0  2040   696  ?  S   Nov  8   0:10  \_ /usr/sbin/apache
[...]
    
Osserviamo che solo il processo capostipite è di proprietà di root, mentre gli altri sono di uno strano utente www-data: questo è un utente creato appositamente per fare da proprietario al server HTTP - i programmi discendenti del PID 289 sono quelli che effettivamente disbrigano le richieste provenienti dalla rete, e se girano sotto la proprietà di un utente che non possiede file sul disco, questo costituisce un ulteriore livello di protezione, perchè non sarà possibile compromettere il programma apache in modo che modifichi un file vitale del sistema (che sarà di proprietà di root e non scrivibile ad altri) oppure che riveli le password degli utenti (solo root può leggerle) Notate che la presenza di www-data è necessaria nel file delle password, solo per non far comparire un numero nella colonna USER; in realtà www-datanon avrà neanche la possibilità di fare un login sul sistema, e mancherà di una shell o della home-directory... si dice che è un utente di sistema.

Montiamo, è da tanto tempo che non lo facciamo...

Il servizio FTP permette di trasportare file da un computer all'altro ed anche fra computer di architetture diverse (per esempio, tra un PC con Windows ed una Sun con UNIX), ma ha il difetto di richiedere l'attenzione dell'utente per operare e poi non permette l'accesso ad una porzione di un file. Al costo di perdere la trasportabilità fra architetture diverse, i computer UNIX hanno un servizio di rete che rimedia a questi due difetti: il magico mitico e catodico NFS. (Network File Sharing)

Il problemino babilonese

Io Assurdbani-habr, scriba di sua eccellenza il potente Ciro, possa Gal-squisesch preservare la sua barba folta e rigogliosa, oggi terzo dì del mese di Passeh, mentre mi recavo allo Ziqqurat mi imbattei in un villico che mi si accostò con fare furbesco; egli mi disse:
- ``O Sapiente Assurdbani-habr, scriba di sua eccellenza il potente Ciro, possa Gal-squisesch preservare la sua barba folta e rigogliosa, e possa la tua saggezza illuminare questo terzo dì del mese di Passeh la cui mattina mi si apre davanti nella pallida luce del dubbio e si va vieppiù oscurando sotto le fosche nubi del dilemma!''
- ``Oggi terzo dì del mese di Passeh, sei fotunato, o vile villico, perchè ho deciso di prestarti ascolto: orsù dimmi, quale tormentoso dubbio angustia la tua giornata?''
- ``O Sapiente Assurdbani-habr, scriba di sua eccellenza il potente Ciro, possa Gal-squisesch preservare la sua barba folta e rigogliosa, e siano lodati gli spiriti della conoscenza perchè oggi terzo dì del mese di Passeh tu hai deciso di prestarmi ascolto e la tua sapienza saprà scogliere i nodi della mia insipienza e bruciare le stoppie della mia ignoranza! Quale dardo fiammeggiante essa oltrepasserà le spesse mura della mia imperizia ed incendierà la cittadella del sapere; le sue fiamme svetteranno alte...''
- ``Parla, dunque!''
- ``... ed i posteri ricorderanno oggidì, terzo giorno del mese di Passeh, come il numinoso giorno in cui il figlio della luce della conoscenza sconfisse il figlio...''

(Qui la scrittura cuneiforme si fa confusa ed a tratti è rovinata; alcuni interpreti leggono nelle righe ``D..MI, N..OD..NCA.E!!!''. Le righe riprendono poi leggibili col testo del problema)

Poisson ha un disco da 1.2Gb. Il comando df permette di vedere quanto spazio è rimasto libero sui dischi collegati al computer:

murri@poisson ~> df
Filesystem         1024-blocks  Used Available Capacity Mounted on
/dev/hda1              15583   10477     4302     71%   /
/dev/hda6              42279      70    38341      0%   /tmp
/dev/hda7             507423  468713    12504     97%   /usr
/dev/hda8             513241   64126   422605     13%   /var
sophie:/home/sophie  3942330 1406850  2535480     36%   /mnt/sophie/home/sophie
Osserviamo però che:
murri@poisson ~> namei -m /home/sophie/
f: /home/sophie/
 drwxr-xr-x /
 dr-xr-xr-x home
 lrwxrwxrwx sophie -> /mnt/sophie/home/sophie
[...]
Quindi /home/sophie è un link simbolico a /mnt/sophie/home/sophie. (Per chi non si fida: man namei) Dunque, ogni operazione su /home/sophie od un ramo suo discendente viene automaticamente deviata su /mnt/sophie/home/sophie; ma allora sotto /mnt/sophie/home/sophie ci sono 3942330 blocchi da 1Kb liberi, ovvero quasi 4Gb?! (Da qui in poi la tavoletta di argilla è inspiegabilmente smangiata...)

Soluzione

La directory /mnt/sophie/home/sophie di Poisson è montata da sophie tramite NFS.

Che significa in pratica? Pensate come se /mnt/sophie/home/sophie fosse a sua volta un link simbolico, che devia tutti gli accessi, solo verso un ramo dell'albero delle directory di un altro computer: tutte le operazioni che Poisson vuole fare su un file della gerarchia /mnt/sophie/home/sophie vengono in realtà deviate sulla rete e passate a sophie, che fisicamente altera il contenuto dei file sui suoi dischi.

Attenzione! Tramite NFS si possono condividere solo interi rami dell'albero delle directory, non singoli file. Il demone NFS (cioè il programma che, su Sophie, sta accucciato nel buio in attesa di balzare fuori a gestire le richieste NFS che arrivano tramite la rete) di GNU/Linux permette di condividere anche solo porzioni di un ramo: cioè si può esportare una directory, ma escludere esplicitamente alcune sue sottodirectory.

Nell'output del comando df, sophie:/home/sophie appare nella colonna Filesystem. Questo significa che la directory esportata da sophie tramite NFS viene vista come un disco remoto (cioè accessibile tramite la rete): il nucleo del sistema Linux non fa infatti alcuna distinzione fra un disco locale (fisicamente collegato al sistema) ed un disco remoto, esportato tramite NFS. L'operazione con cui si innesta un disco in un punto dell'albero delle directory in modo da formare un nuovo ramo si chiama mount. In particolare, vale anche per i dischi locali l'osservazione precedente: ogni disco può contenere solo un ramo intero dell'albero delle directory.

Di un disco locale che contenga una porzione dell'albero delle directory si dice che ospita un filesystem. (Un filesystem è un sistema di organizzare le informazioni relative ai file su un disco: i dettagli tecinici sono spesso complicati) Quando si prende un nuovo disco, occorre prepararlo ad ospitare un filesystem con una serie di operazioni (vedi man mkfs ) prima di poterlo effettivamente usare; in genere solo il superutente può compiere queste operazioni, ma il vantaggio di GNU/Linux è che ogni periferica del computer può venire vista dal sistema come un file - ad esempio, ecco la lista dei possibili dischi di poisson:

murri@poisson ~> ls /dev/hd*
/dev/hda    /dev/hda3   /dev/hdb15  /dev/hdc    /dev/hdc3   /dev/hdd15
/dev/hda1   /dev/hda4   /dev/hdb16  /dev/hdc1   /dev/hdc4   /dev/hdd16
/dev/hda10  /dev/hda5   /dev/hdb17  /dev/hdc10  /dev/hdc5   /dev/hdd17
/dev/hda11  /dev/hda6   /dev/hdb18  /dev/hdc11  /dev/hdc6   /dev/hdd18
/dev/hda12  /dev/hda7   /dev/hdb19  /dev/hdc12  /dev/hdc7   /dev/hdd19
/dev/hda13  /dev/hda8   /dev/hdb2   /dev/hdc13  /dev/hdc8   /dev/hdd2
/dev/hda14  /dev/hda9   /dev/hdb20  /dev/hdc14  /dev/hdc9   /dev/hdd20
/dev/hda15  /dev/hdb    /dev/hdb3   /dev/hdc15  /dev/hdd    /dev/hdd3
/dev/hda16  /dev/hdb1   /dev/hdb4   /dev/hdc16  /dev/hdd1   /dev/hdd4
/dev/hda17  /dev/hdb10  /dev/hdb5   /dev/hdc17  /dev/hdd10  /dev/hdd5
/dev/hda18  /dev/hdb11  /dev/hdb6   /dev/hdc18  /dev/hdd11  /dev/hdd6
/dev/hda19  /dev/hdb12  /dev/hdb7   /dev/hdc19  /dev/hdd12  /dev/hdd7
/dev/hda2   /dev/hdb13  /dev/hdb8   /dev/hdc2   /dev/hdd13  /dev/hdd8
/dev/hda20  /dev/hdb14  /dev/hdb9   /dev/hdc20  /dev/hdd14  /dev/hdd9
Naturalmente il fatto che compaiano in questo elenco non vuol dire che siano realmente collegati, ma solo che il kernel potrebbe gestirli se ci fossero. In realtà nessun accesso viene tentato a questi file finché non si chiama un programma che ne apre uno: per esempio mount, oppure mkfs: un po' come creare un link simbolico ad un file che non esiste (provare! ). In effetti anche i nomi di questi file potrebbero cambiare: sono frutto di una convenzione arbitraria... I file che rappresentano periferiche sono un tipo speciale, detti device-special files:
murri@poisson ~> ls -l /dev/hda?
brw-rw----   1 root     disk       3,   1 Dec  9  1996 /dev/hda1
brw-rw----   1 root     disk       3,   2 Dec  9  1996 /dev/hda2
brw-rw----   1 root     disk       3,   3 Dec  9  1996 /dev/hda3
brw-rw----   1 root     disk       3,   4 Dec  9  1996 /dev/hda4
brw-rw----   1 root     disk       3,   5 Dec  9  1996 /dev/hda5
brw-rw----   1 root     disk       3,   6 Dec  9  1996 /dev/hda6
brw-rw----   1 root     disk       3,   7 Dec  9  1996 /dev/hda7
brw-rw----   1 root     disk       3,   8 Dec  9  1996 /dev/hda8
brw-rw----   1 root     disk       3,   9 Dec  9  1996 /dev/hda9
La coppia di numeri all'immediata sinistra della data identifica unicamente la periferica nel nucleo.

Spiegare nel dettaglio cosa siano i device-special file è piuttosto lungo; in pratica si può pensare come se un device-special file fosse un link simbolico ad una periferica collegata al sistema: il nucleo provvede ad identificarne il tipo ed a trasformare gli accessi al contenuto del file nelle opportune operazioni di Input/Output sulla periferica (ad esempio: anche il mouse è un file, /dev/mouse, da cui si può solo leggere, e si leggono le coordinate dello spostamento del puntatore; la tastiera è un file, /dev/console, da cui si possono leggere i caratteri battuti, e scrivere quelli che andranno al video in modo testo...)


Riccardo Murri
Last modified: Thu Nov 19 19:02:11 CET 1998