File System Distribuiti

Un FS e' una implementazione di memoria permanente che consente la condivisione dei dati:

Non e' l'unica implementazione possibile: anche le basi di dati ed altri meccanismi (oggetti persistenti ecc.) hanno caratteristiche analoghe. Hanno pero' diversi

Uso di un FS piuttosto che un DB:

Evoluzione (non storica) dei file system:

1. Singolo utente, singolo sito, singolo processo (MS-DOS)

Problemi di naming:

Interfaccia verso le applicazioni:

Supporti fisici:

Integrita'

2. Singolo utente, singolo sito, molti processi (OS/2)

Controllo della concorrenza

3. Singolo sito, molti utenti (Unix)

Sicurezza

4. Molti utenti, molti siti

??? un FS che somigli a Unix ma con caratteristiche implementative differenti

Per realizzare un FS distribuito, ci sono tutti i problemi precedenti da risolvere in un contesto differente, con in piu' NUOVI Problemi:

localizzazione (e naming)

Disponibilita' (availability)

Proprieta' dei file:

per quanto tempo serve un file?

Condivisione dei file:

Primo tentativo di FS distribuito: FTP (~1975!)

E' ancora troppo primitivo x essere considerato un vero FS distribuito!!!

Principi di progettazione dei FS distribuiti:

Buone Idee Implementative:

NFS

Network File System e' una specifica x accedere a file remoti su LAN, ed anche una sua implementazione (entro SunOS). Si basa sul protocollo UDP e su Ethernet.

Caratteristiche:

Si ha un insieme di workstation indipendenti, ciascuna con un proprio FS, che vogliono poter condividere dei file. L'idea e' di poter considerare ogni macchina come client e server, relativamente ai file che "possiede". Non esiste quindi un "FS globale", ma solo file che un client accede in remoto.

Per poter usare su un client una directory remota, occorre poterla "montare". L'operazione e' lecita solo al superuser (della macchina client) e non e' trasparente, nel senso che occorre esplicitare la macchina host. Dopodiche' ogni accesso da tale client e' trasparente.

ATTENZIONE: siccome ogni client "monta" cio' che vuole, in generale client diversi avranno una visione del FS diversa (a meno di non porre particolare attenzione a renderle coerenti, cosa che si fa abitualmente, ma richiede un certo lavoro!!!). Se il FS condiviso e' montato sulla home degli utenti, allora gli utenti potranno collegarsi indifferentemente da una qualsiasi ws e vedranno sempre la loro home (mobilita' degli utenti, ma solo per convenzione ed a prezzo di particolari sforzi del sistemista). In particolare, potranno essere utilizzate ws diskless.

L'idea alla base di NFS e' l'interoperabilita' dei FS anche di ws differenti (eterogeneita'). Esistono FS differenti, su macchine di architettura diversa, che supportano NFS e quindi possono "montare" directory remote. L'indipendenza dall'architettura e' ottenuta mediante un protocollo unico di rappresentazione dei dati (XDR) e chiamate di procedura remota (RPC).

Servizi di NFS

Sono previsti due servizi di genere diverso:

Per protocollo si intende un insieme di RPC, che costituiscono un insieme di operazioni su file trasparenti.

Protocollo di mount

Supponiamo di avere tre macchine, client, server1 e server2. Inizialmente hanno tre FS indipendenti.

Adesso montiamo server1:usr/shared sopra client:/usr/local

Questa figura illustra cio' che vede localmente la macchina client. Tutti i file e le directory presenti su server1 al di sotto di dir1 sono visibili con il "prefisso" usr/local/dir1. Se c'erano dei file locali in /usr/local, su client non sono piu' visibili.

Notiamo che e' possibile montare FS a cascata: client puo' adesso montare server2:/dir2/dir3 sopra client:/usr/local/dir1 (anche se quest'ultima e' una directory remota).

Adesso i file in dir3 sono accessibili dalla macchina client come /usr/local/dir1/dir3.

L'operazione che abbiamo visto per seconda NON ha assolutamente nessun effetto su server1, da questa macchina i file al di sotto di dir1 continuano ad essere visibili (salvo mount effettuati dal superuser di server1, ovviamente). Analogamente, mount effettuati dal superuser di server1 sulla directory dir1 non sono visibili da client, sempre che non siano "duplicati" dal superuser di client (mount NON e' transitivo!!). In altre parole, la visione del FS e' tutt'altro che univoca da parte delle varie ws (salvo che eseguano tutte uno stesso script iniziale), in compenso la visione locale del FS non richiede un particolare "ordine" di accensione delle macchine tra loro.

Il server mantiene un file (/etc/exports) che specifica quali directory locali possono essere montati in remoto, e un elenco di macchine a cui e' consentito montarli. Una particolare ws a cui e' consentito montare ad es. la directory dirdir puo' montare (anche/invece) una qualsiasi sottodirectory di dirdir. Al momento della richiesta di mount, il server controlla i permessi e restituisce una struttura detta handle che sara' utilizzata per tutti gli accessi futuri (per Unix, FS identifier e numero di inode in modo da identificare esattamente quale dir si e' montata in remoto).

Il server mantiene anche una lista di client e directory esportate, istante per istante, ma sostanzialmente non utilizza queste informazioni se non in casi di shutdown (per avvisare i client dello shutdown). Ovviamente esiste l'operazione di umount, che si limita a cancellare una entry da questa lista.

Protocollo NFS

Fornisce le seguenti operazioni:

Queste funzioni sono lecite solo dopo una mount, ovvero quando si possiede l'handle del FS remoto.

ATTENZIONE: non ci sono operazoni di open / close. La cosa e' voluta e serve per avere un protocollo NFS privo di stato (stateless). L'unica eccezione sarebbe la lista delle directory esportate, ma in realta' se fosse cancellata o errata il sistema funzionerebbe lo stesso.

Il fatto che tutte le operazioni siano RPC e quindi sincronizzino client e server implica che ogni operazione e' eseguita sul server (comprese le scritture su disco dei blocchi indiretti!) prima di ripassare il controllo al client, quindi in caso di fallimenti lo stato del FS e' sempre consistente.

Un'altra conseguenza della scelta stateless e' che non esistono meccanismi di controllo della concorrenza come lock dei file. Se gli utenti ne hanno bisogno, devono rivolgersi ad un diverso servizio (es. un database).

Implementazione su SunOS

Per motivi di efficienza NFS e' integrato nel kernel ma cio' non e' indispensabile.

Viene inserito uno strato intermedio detto VFS, virtual file system. Esso fornisce una interfaccia verso altri file system (come Ext2 o FAT), ed inoltre gestisce una struttura detta Vnode. I Vnode sono unici nel sistema (mentre gli inode sono unici per ogni singola macchina!!).

Per ogni file, il Vnode e la mount table sono in grado di identificare il FS a cui appartiene, e quello sopra cui e' montato, in altre parole se il file e' locale o remoto, e se e' locale di che tipo di FS si tratta. Il VFS chiama direttamente le operazioni locali e chiama il protocollo NFS per le operazioni remote, ciascuna con gli handle opportuni.

La figura illustra cosa accade per una operazione su un file remoto gia' aperto (es. read).

Per risolvere i pathname, viene inviata una richiesta di lookup per ogni componente del path al server corrispondente (quindi e' una sequenza di chiamate NFS distinte, ed in generale e' molto costosa). Lo schema costoso e' indispensabile perche' ogni client puo' avere una diversa visione del FS sul server che dipende da quali mount ha effettivamente eseguito, quindi non e' detto che il server sappia risolvere tutto il path correttamente (non avendo stato).

Per velocizzare la richiesta. una volta risolto un pathname esso viene memorizzato in una cache locale, trattata come hint. Si prova in seguito ad accedere tramite l'hint, ma se un hint e' sbagliato, si ripercorre la sequenza di richieste.

Coda

Il FS Coda e' un sistema sperimentale sviluppato alla Carnegie-Mellon University. Il suo "predecessore" era chiamato Andrew (AFS) ed e' stato utilizzato dagli anni'80 sulla rete dipartimentale. Aveva migliaia di ws client, ma in una rete cosi' grossa c'era sempre qualche macchina guasta, o un ramo di rete disconnesso: cio' provocava seri guai alla sua operativita'. Coda inserisce esplicitamente la modalita' di funzionamento disconnesso (piuttosto che considerarla un errore!!) e riesce a superare questo limite di AFS.

Caratteristiche:

supporto per client mobili

sopravvivenza ai guasti

Prestazioni e scalabilita'

Sicurezza

Condivisione tra utenti

Organizzazione del sistema

I file sono memorizzati su uno o piu' server, che li rendono accessibili ad altri computer detti client. In linea di principio esiste quindi un'unica locazione per ogni file, e farne una backup e' quindi piu' semplice. Si possono condividere sia file di dati sia applicazioni, centralizzandone l'amministrazione. I dischi dei client sono sostanzialmente delle grandi cache locali di file (non e' detto che esista un FS locale, anche se le ws non sono diskless)

Un client solitamente vede un file system di tipo Coda montato nella directory /coda. Tutti i client vedono esattamente la stessa directory e non sanno su quali server e' distribuita la directory /coda. (DIVERSO da NFS!!!) Questa organizzazione consente di "scalare" meglio su installazioni veramente grandi, con migliaia di client, rispetto a NFS: se si aggiunge una nuova directory con nuovi file dati o applicazioni, la si trova da qualche parte sotto /coda.

Se l'utente digita more /coda/tmp/foo, occorre aprire il file e bisogna procurarsi il suo inode e un file handle. Questo avviene passando al modulo VFS nel kernel, che si accorge di una richiesta per un file Coda e la passa al modulo Coda del kernel. Quest'ultimo gestisce una cache delle richieste piu' recenti, se la richiesta non c'e' la passa al gestore della cache di Coda, detto Venus. A questo punto Venus "in qualche modo" si organizza per procurarsi il file: controlla se il file tmp/foo e' presente nella cache locale, altrimenti lo richiede al server opportuno, oppure lavora in modo disconnesso (ad esempio se la rete e' caduta). Quando il file e' stato ricuperato, Venus ritorna al kernel, che a sua volta ritorna dalla system call.

La prima richiesta al kernel sara' una open del file: a questo punto Venus si procura tutto il file dal server attraverso RPC, e lo memorizza in /usr/coda/venus.cache/. Il file adesso e' locale e altre richieste (read ecc.) saranno gestite dal FS locale senza altri costi di trasmissione, anche per aperture successive da parte di altri processi, ed andranno alla stessa velocita' delle richieste locali. Si procede analogamente per mantenere in cache intere directory (che sono file!) e attributi dei file quali permessi, dimensioni e proprietario.

Se e' stata modificata la struttura del FS (aggiungere directory, link ecc.) o se si chiude un file modificato, allora Venus propaga la modifica al server.

Operazioni disconnesse

Quando un client ha completato un aggiornamento su un file cached, l'aggiornamento deve essere propagato al server, ma se c'e' un guasto sulla rete o sul server, il client se ne accorge perche' scattera' un time-out, e sara' impossibile propagare l'aggiornamento. In alcuni casi si puo' soltanto riferire l'errore al processo richiedente (es. richiesta di aprire un file non in cache), in altri si riesce ad operare in modalita' disconnessa.

In modalita' disconnessa, tutte le modifiche sono registrare in un file di log detto CML (Client Modification Log) che e' mantenuto su disco. L'utente non percepisce nessuna differenza rispetto al comportamento normale; quando il server e' nuovamente disponibile, tutte le modifiche del CML vengono applicate sul server (in realta' il CML e' ottimizzato, se una modifica e' annullata da una successiva modifica, sul server non verra' effettuata).

Punti da approfondire:

Hoarding (letteralmente: tesaurizzare): analizzando il comportamento dell'utente, Venus puo' "capire" che certi files sono molto piu' utili di altri, e puo' procurarsene automaticamente una copia aggiornata anche se l'utente non l'ha chiesta. In questo modo anche se successivamente il server fosse disconnesso, l'utente avrebbe in cache l'ultima versione nel momento in cui ne ha bisogno; o comunque, eviterebbe di attendere che il file sia ricuperato. L'insieme dei file cosi' gestiti e' detto hoard database, l'aggiornamento effettuato senza richieste dell'utente e' detto hoard walk.

Riconnessione: puo' capitare che dopo una disconnessione, si scopra che un file in cache e' stato modificato, mentre altri utenti hanno aggiornato il file sul server. Questo fenomeno, detto conflitto locale/globale, puo' essere risolto automaticamente dalle applicazioni coinvolte, o piu' raramente puo' richiedere un intervento utente.

Organizzazione dei file sul server

Un server Coda non ha un file system "tradizionale". I server hanno diverse partizioni, ciascuna delle quali e' suddivisa in volumi. Ogni volume e' una specie di FS a se' stante, con radice e sottodirectory varie, che costituiscono un gruppo "logico" di file, una quantita' intermedia tra la partizione e la directory. Un esempio tipico e' la home di ogni utente, oppure il volume dei sorgenti del FS, per fissare le idee possimo pensare a qualcosa come 10-20 MB. I punti di mount possono essere solo volumi e non semplici directory.

I server gestiscono informazioni di volume, directory e liste di controllo degli accessi in partizioni dei dischi, mediante un package specifico detto RVM (Recoverable Virtual Memory), basato su transazioni: in caso di crash del server e' relativamente semplice riportare il FS ad uno stato consistente. Un volume ha un nome e un Id specifico entro Coda, che crea una directory apposita al momento del mount (si evita la confusione di Unix in cui si "perde" il contenuto della directory su cui avviene il mount). Dopo che e' stato montato, un volume e' quindi una "semplice" directory qualsiasi sotto /coda (gli utenti non sanno della distinzione tra volumi e directory qualsiasi).

Un file e' identificato dentro Coda da un Fid, composto da tre interi a 32 bit: VolumeId, VnodeId e Uniquifier. Il VnodeId e' il numero di inode del file, e grazie all'Uniquifier si e' certi che un Fid sia unico nell'insieme di tutti i server Coda.

In genere i server gestiscono volumi replicati, in modo da aumentare la disponibilita' dei dati: quando un server fallisce, i dati su di esso non sono inaccessibili agli utenti in quanto subentrera' una replica. Ogni volume quindi non sta su un server solo ma su un gruppo di server che costituiscono il suo VSG (Volume Storage Group). Il VolumeId in questo caso e' replicato ed e' associato ad un VSG ed alla lista dei rispettivi volumi locali ad ogni server.

Quando un utente accede ad un file che sta in un volume replicato, il primo accesso di Venus al volume e' quindi piu' costoso, in quanto occorre gestire un VSG. Il significato di questo gruppo e' "read one, write many", cioe' si accede al volume replicato piu' vicino, in lettura, e si modificano tutte le repliche in scrittura. Coda esegue queste modifiche di gruppo attraverso RPC particolari che effettuano un multicast. In realta' per il problema dei possibili fallimenti, le repliche aggiornate saranno in generale solo quelle dell'AVSG, ovvero il sottoinsieme del VSG contenente i server disponibili (Available).

Al momento della riconnessione dei server, potrebbero sorgere inconsistenze tra le copie possedute dai server. Queste vengono gestite automaticamente alla prima richiesta di un file da parte di un qualsiasi utente: Venus infatti ricevera' degli "stamp" di versione diversi dai server del gruppo, e iniziera' automaticamente a risolvere i conflitti. Lo stesso meccanismo scatta quando un server viene riparato, o si aggiunge un nuovo server al gruppo.