Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


File System: Un'analisi approfondita dell'organizzazione e gestione dei dati, Appunti di Sistemi Operativi

Libro di Michael Dahlin, Thomas Anderson tradotto in italiano (13 capitoli).

Tipologia: Appunti

2017/2018

In vendita dal 09/09/2018

maDave
maDave 🇮🇹

12 documenti

1 / 6

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
- (08/05/18 - Professore)
Capitolo 11
File System: Introduzione ed Overview
I computer dovrebbero permettere di memorizzare i dati in modo affidabile. Foto, file musicali, e directory di
email; i programmatori memorizzano documenti di design e file sorgenti; chi lavora in ufficio memorizza
documenti ed altri. Infatti, per un computer che ha bisogno di memorizzare tutto ciò, ha bisogno di
memorizzare programmi per eseguirli.
Per tutti questi casi, gli utenti richiedono molte cose per i loro dispositivi di memorizzazione:
Affidabilità. I dati utenti dovrebbero essere memorizzati in modo sicuro in tal caso va via la corrente
o il sistema operativo smette di funzionare. Infatti, molti utenti pretendono che i dati esistano ancora
anche se il dispositivo potrebbe essere danneggiato. Per esempio, i più moderni sistemi di
memorizzazione continuano a funzionare anche se uno dei magneti dell’hard disk ha qualche
malfunzionamento o il server sta bruciando.
Grandi capacità e basso costo. Gli utenti e le aziende immagazzinano enormi quantità di dati, così
quindi vorrebbero comprare quanta più memoria possibile spendendo poco. Come risultato delle
necessità in tanti anni di creazioni varie dei dispositivi di memorizzazione si è arrivati ad ottenere
anche 1Tb di spazio per i propri file. Questa è una quantità enorme: Se stampassimo 1Tb di dati su di
un foglio, probabilmente produrremmo uno stack lungo 20 miglia. Al contrario, per meno di $100
può comprare 1Tb di spazio di archiviazione che può essere contenuto in una scatola di scarpe.
Alta performance. Affinché i programmi possano utilizzare i dati, si deve poter permettere
l’accesso ad essi, i quali sono in grandissima quantità, e tale accesso deve avvenire rapidamente. Per
esempio, gli utenti vogliono che i programmi partano in modo istantaneo, un’azienda per esempio
potrebbe processare centinaia o migliaia di ordini al secondi, o un server potrebbe aver bisogno di
condividere un sacco di file video con utenti differenti.
Named Data. Poiché gli utenti utilizzano un grandissima quantità di dati, poiché richiedere alcuni
dati può risultare più lungo di un processo che li crea, e perché i dati devono essere condivisi tra i
programmi, i dispositivi di archiviazione devono fornire un modo per identificare un particolare
dato. Per esempio, se chiamassimo un file (/home/davidemontagno/assignments/hw1.txt) potremmo
trovare il file tra migliori di blocchi nel disco, potrai anche trovarlo dopo che hai chiuso l’editor di
testo, e potrai usare le email per condividere i vari file che hai creato.
Controllo della condivisione. Gli utenti hanno bisogno di condividere dati, ma tale condivisione
deve essere controllata. Per esempio, potresti voler creare un documento grafico il quale può essere
visto o modificato da tutti gli utenti che fanno parte del tuo stesso gruppo, il resto delle persone
invece non può accedervi in nessun modo. Un altro esempio è utile per un sistema per essere in
grado di permettere a ciascun utente di eseguire un programma nel frattempo l’amministratore di
sistema cambia il programma.
Dispositivi di memorizzazione non volatili e file system.
I contenuti di una memoria DRAM principale potrebbe essere perso se un sistema smette di funzionare o non
vi è più corrente, i dispositivi non volatili sono stabili e conservano i loro dati anche in presenza di crash o
malfunzionamenti; tali dispositivi sono anche chiamati persistent storage o stable storage. I dispositivi non
volatili possono avere molta più capacità a minor costo di una DRAM volatile che costituisce la maggior
parte della memoria principale di gran parte del sistema.
Tuttavia, i dispositivi non volatili hanno le loro limitazioni. Per esempio, i correnti dispositivi non volatili
come dischi magnetici e dispositivi flash non permettono l’accesso alle singole parole di archiviazione;
invece, l’accesso deve essere fatto in modo grossolano – 512,2048, o più byte alla volta.
pf3
pf4
pf5

Anteprima parziale del testo

Scarica File System: Un'analisi approfondita dell'organizzazione e gestione dei dati e più Appunti in PDF di Sistemi Operativi solo su Docsity!

- (08/05/18 - Professore)

Capitolo 11

File System: Introduzione ed Overview

I computer dovrebbero permettere di memorizzare i dati in modo affidabile. Foto, file musicali, e directory di email; i programmatori memorizzano documenti di design e file sorgenti; chi lavora in ufficio memorizza documenti ed altri. Infatti, per un computer che ha bisogno di memorizzare tutto ciò, ha bisogno di memorizzare programmi per eseguirli.

Per tutti questi casi, gli utenti richiedono molte cose per i loro dispositivi di memorizzazione:

  • Affidabilità. I dati utenti dovrebbero essere memorizzati in modo sicuro in tal caso va via la corrente o il sistema operativo smette di funzionare. Infatti, molti utenti pretendono che i dati esistano ancora anche se il dispositivo potrebbe essere danneggiato. Per esempio, i più moderni sistemi di memorizzazione continuano a funzionare anche se uno dei magneti dell’hard disk ha qualche malfunzionamento o il server sta bruciando.
  • Grandi capacità e basso costo. Gli utenti e le aziende immagazzinano enormi quantità di dati, così quindi vorrebbero comprare quanta più memoria possibile spendendo poco. Come risultato delle necessità in tanti anni di creazioni varie dei dispositivi di memorizzazione si è arrivati ad ottenere anche 1Tb di spazio per i propri file. Questa è una quantità enorme: Se stampassimo 1Tb di dati su di un foglio, probabilmente produrremmo uno stack lungo 20 miglia. Al contrario, per meno di $ può comprare 1Tb di spazio di archiviazione che può essere contenuto in una scatola di scarpe.
  • Alta performance. Affinché i programmi possano utilizzare i dati, si deve poter permettere l’accesso ad essi, i quali sono in grandissima quantità, e tale accesso deve avvenire rapidamente. Per esempio, gli utenti vogliono che i programmi partano in modo istantaneo, un’azienda per esempio potrebbe processare centinaia o migliaia di ordini al secondi, o un server potrebbe aver bisogno di condividere un sacco di file video con utenti differenti.
  • Named Data. Poiché gli utenti utilizzano un grandissima quantità di dati, poiché richiedere alcuni dati può risultare più lungo di un processo che li crea, e perché i dati devono essere condivisi tra i programmi, i dispositivi di archiviazione devono fornire un modo per identificare un particolare dato. Per esempio, se chiamassimo un file (/home/davidemontagno/assignments/hw1.txt) potremmo trovare il file tra migliori di blocchi nel disco, potrai anche trovarlo dopo che hai chiuso l’editor di testo, e potrai usare le email per condividere i vari file che hai creato.
  • Controllo della condivisione. Gli utenti hanno bisogno di condividere dati, ma tale condivisione deve essere controllata. Per esempio, potresti voler creare un documento grafico il quale può essere visto o modificato da tutti gli utenti che fanno parte del tuo stesso gruppo, il resto delle persone invece non può accedervi in nessun modo. Un altro esempio è utile per un sistema per essere in grado di permettere a ciascun utente di eseguire un programma nel frattempo l’amministratore di sistema cambia il programma.

Dispositivi di memorizzazione non volatili e file system.

I contenuti di una memoria DRAM principale potrebbe essere perso se un sistema smette di funzionare o non vi è più corrente, i dispositivi non volatili sono stabili e conservano i loro dati anche in presenza di crash o malfunzionamenti; tali dispositivi sono anche chiamati persistent storage o stable storage. I dispositivi non volatili possono avere molta più capacità a minor costo di una DRAM volatile che costituisce la maggior parte della memoria principale di gran parte del sistema.

Tuttavia, i dispositivi non volatili hanno le loro limitazioni. Per esempio, i correnti dispositivi non volatili come dischi magnetici e dispositivi flash non permettono l’accesso alle singole parole di archiviazione; invece, l’accesso deve essere fatto in modo grossolano – 512,2048, o più byte alla volta.

Inoltre, questi accessi possono essere più lenti rispetto ad una DRAM; per esempio, leggere un settore da un disco magnetico potrebbe richiedere l’attivazione di un motore per muovere il braccio del disco alla traccia desiderata e di aspettare fin quando tale traccia non sia sotto la testa del braccio rotante. Poiché gli accessi al disco richiedono motori e movimenti, il tempo per un accesso random potrebbe essere di circa 10 ms. Al contrario, la latenza di una DRAM potrebbe essere sotto i 100 nanosecondi. Questa enorme differenza indirizza il sistema operativo ad organizzare e usare i dispositivi di memorizzazione persistenti in modo differente rispetto alla memoria principale.

I file system sono un’astrazione del sistema operativo per permettere alle applicazioni di accedere ai dispositivi di memorizzazione non volatili. I file system usano un numero di tecniche per far fronte alle limitazione fisiche di tali dispositivi e forniscono un’astrazione migliore per gli utenti.

  • Performance. I file system ammortizzano il costo di costate operazione di inizializzazione – come muovere un braccio del disco o cancellare un blocco di una memoria a stato solido – raggruppando la posizione dei dati in modo che tali operazioni abbiano accesso a grandi dimensioni, e a range sequenziali di memorizzazione.
  • Naming. Il gruppo di file system raggruppa i dati insieme in directory e file e fornisce dei nomi per far accedere a tali dati. Questi nomi per i dati rimangono significativi anche dopo che il programma che i dati di uscita. aiutano gli utenti ad organizzare un gran numero di dati, e permette agli utenti di usare programmi differenti per creare, leggere, e editare i loro dati.
  • Controllo della condivisione. I file system includono metadati su chi sono i proprietari dei file e quali utenti sono abilitati a leggere, scrivere, o eseguire dati o programmi.
  • Affidabilità. I file system usano transazioni per aggiornare atomicamente blocchi di memoria persistente, similmente a ciò che fa il sistema operativo quando aggiorna le strutture dati all’interno di sezioni critiche.

Per migliorare ulteriormente l’affidabilità, i file system memorizzano dei checksum con i dati per individuare i blocchi corrotti, e replicare i dati tra device di memorizzazioni multipli per recuperarli in caso di guasti.

Impatto sulla scrittura delle applicazioni. Capire le proprietà dell’affidabilità e di performance dell’hardware di memorizzazione e dei file system è importante anche se tu non stai costruendo un file system da zero. Poiché esistono delle fondamentali limitazione nei dispositivi di memorizzazione, le illusioni di affidabilità e di performance fornita ad alto livello sono imperfette.

Per esempio, supponiamo di editare un grande documento con molte immagini e che il processore salva periodicamente in modo automatico tale file in modo tale che di non perdere molte modiche se il sistema dovesse crashare. Se le applicazioni usassero il file system in modo semplice, potrebbero accadere cose inaspettate.

  • Poor performance. Per prima cosa, sebbene il sistema operativo permettere di sovrascrivere byte di un file già esistente con nuovi valori, quest’ultimi non dovrebbero essere inseriti nel mezzo dei byte già esistenti. Così, anche un piccolo aggiornamento al file richiederebbe la l’overwriting dell’intero file dall’inizio alla fine. Per file di grandi dimensioni, ogni auto-save potrebbe portare via molti secondi del processore.
  • File corrotti. Se le applicazioni semplicemente sovrascrivessero i file esistenti con dati aggiornanti, un crash potrebbe lasciare uno stato inconsistente, contenendo un mix di dati tra vecchi e nuovi. Per esempio, se una sezione è tagliata da un posto e incollata in un'altra, se venisse causato un crash potrebbe accadere che tale sezione sia presente in entrambe le parti, in una sola, o in nessuna delle due; o finirebbe in una regione che è un mix tra la vecchia e la nuova.

I programmi usano un range di tecniche per trattare questi tipi di problemi. Per esempio, molti strutturano il loro codice per avvantaggiare la semantica del sistema operativo. Per esempio, molti sistemi operativi garantiscono che quando un file è rinominato con un nome uguale ad uno già esistente, tale nome

Nella figura soprastante, poiché le directory possono includere nomi di altre directory, si può vedere come le directory possono essere organizzate in una gerarchia che differenzia insieme di file associati che possono essere raggruppati in directory differenti. La stringa che identifica un file o una directory è chiamata path. Il simbolo / separa i componenti del path, ciascuno dei quali rappresenta una directory.

Se pensassimo ad una directory come un albero, la radice dell’albero verrà chiamata root directory. I name path come /bin/ls che iniziano con / vengono definiti path assoluti i quali sono interpretati a partire dalla root directory. I path come Work/Class/OS che non iniziano con / sono definiti path relativi e sono interpretati a partire dalla directory corrente in cui il processo è in esecuzione.

Quando fai il log in, la shell inizialmente è settata alla home directory. I processori possono cambiare la directory corrente tramite la system call chdir(path). Così, per esempio, se tu stessi lavorando ad un progetto, potresti trovare conveniente far apparire il progetto in entrambe le directory “todo” e “OS” come nella figura sottostante.

Il mapping tra un nome e il file sottostante è chiamato hard link.

Se il sistema permette più hard link per lo stesso file, allora la gerarchia per le directory non può essere più un albero. La maggior parte dei file system che permettono hard link multipli per un file restringono tali link per evitare cicli, assicurando che venga creato un grafo aciclico (DAG). Evitare cicli può semplificare la gestione, per esempio, assicurandosi che gli attraversamenti ricorsivi di una directory terminano o usando il contatore delle reference per poter permettere al garbage collector di intervenire su di un file quando l’ultimo riferimento ad esso viene cancellato.

In aggiunta agli hard link, molti sistemi forniscono altre vie per usare nomi multipli per lo stesso file. Basta guardare la sidebar per un confronto di hard link, soft link, shortcut, ed alias.

Volume. Ogni istanza di un file system gestisce i file e le directory per un determinato volume. Un volume è una collezione di risorse di memorizzazione fisiche che formano un dispositivo di memorizzazione logico.

Un volume è un’astrazione che corrisponde al disco logico. Nel più semplice dei casi, un volume corrisponde ad un singolo disco fisico. Alternativamente, un singolo disco fisico può essere partizionato in volumi multipli o parecchi dischi fisici possono essere combinanti in un singolo volume disco fisico estendendosi in più dischi fisici.

Un computer singolo può usare file system multipli memorizzati su più dischi montando volumi multipli in una gerarchia logica singola. Montare un volume su un file system esistente crea un mapping di qualche path nel file system esistente alla root directory del file system del volume montato e lascia le mappature di controllo del file system montate per tutte le estensioni di tale path.

Per esempio, supponiamo che una chiavetta USB contiene un file system le cui cartelle sono /Movies e / Backup. Se Alice inserisse tale chiavette all’interno del laptop, il sistema operativo dovrebbe montare il file system del volume dell’USB con il path /Volumes/usb1. Se Alice facesse una open(/Volume/usb1/Movies/ vacation.mov), aprirà il file /Movies/vacation.mov dal file system del volume dell’USB. Allo stesso modo Bob aprirebbe media/disk1 per accedere al file system del volume montato attualmente e attraverso il path / Movies/vacation.mov aprirà il suo file.

11.2 API

Creare e cancellare file. I processi creano e distruggono i file con create() e unlink(). Create() fa due cose: crea un nuovo file e inizializza i suo metadati, e crea un nome per tale file nella directory.

link() crea un hard link – un nuovo path name per un file esistente. Dopo che la chiamata a link() termina correttamente, ci sono path name multipli che riferiscono lo stesso file sottostante.

unlink() rimuove un nome per un file dalla sua directory. Se un file ha nomi o link multipli, unlink() rimuove il nome specifico, lasciando che tale file sia accessibile da altri nomi. Se il nome specificato è l’unico link al file, allora l’unlink() cancellerebbe anche il file sottostante e le sue risorse.

Mkdir() e rmdir() creano e cancellano directory.

Linking ad un file vs linking ad una directory.

Sistemi come Linux supportano una system call link(), non consentono la creazione di nuovi hard link in una directory. Per esempio, existingPath non dovrebbe essere una directory. Perché Linux fa questo?

Per prevenire multipli hard link ad una directory prevenendo i cicli, assicurandosi che la struttura della directory sia sempre un grafico orientato aciclico (DAG).

In aggiunta, realizzare gli hard link per una directory confonderebbe la directory principale con la voce di una directory.

Aprire e chiudere. Per iniziare ad accedere un file, un processo chiama la open() per ottenere un file descriptor , tale riferimento può essere usato per riferire il file aperto. Il file descriptor è una terminologia Unix; in altri sistemi ed API gli oggetti svolgono regole simili chiamando tali file handles o file streams.

Il sistema operativo richiede ai processi di fare una open() esplicita ai file e di accedere a quest’ultimi tramite i file descriptor piuttosto che passare il path ogni qual volta si voglia fare una read() o write(). Per prima cosa, il path viene parsato e vengono controllati i diritti ogni qual volta viene aperto un file e questo non viene eseguito più ogni qual volta viene fatta una read() o write(). In secondo luogo, quando un processo apre un file, il sistema operativo crea una struttura dati che memorizza le informazioni sul processo che ha aperto il file come l’ID del file, se il processo può scrivere o solo leggere il file, e un puntatore alla posizione corrente del processo all'interno del file. Il file descriptor può anche essere pensato come una riferimento alla struttura dati che il sistema operativo usa per gestire gli accessi del processo al file per ogni file aperto nel sistema operativo.

Quando un’applicazione ha terminato di usare il file, chiama la close() , la quale rilascia il record del file aperto nel sistema operativo.

Accesso ai file. Quando un file è aperto, un’applicazione può accedere ai dati del file in due modi. Per prima cosa, può usare le normali procedure dell’interfaccia fornita, facendo delle chiamate di sistema come read() o write() su un file precedentemente aperto. Chiamare la read() e write() parte dalla posizione del file del processo corrente, e avanza di posizione in base ai byte che sono stati letti o scritti. Così, una sequenza di read() o write() si muove sequenzialmente all’interno di un file. Per supportare gli accessi random all’interno di un file, la chiamata di sistema seek() si posiziona in un punto preciso all’interno del file aperto.

Piuttosto che usare read() e write() per accedere ai dati del file, un’applicazione potrebbe usare mmap () per stabilire un mapping tra una regione della memoria virtuale del processo e qualche regione del file. Una volta che il file è stato mappato, ogni load o store per quella regione di memoria virtuale leggerà e scriverà i dati del file accedendo a pagine condivise nella cache del kernel, o segnalando un page fault in caso tale pagina non fosse presente in memoria. Quando un’applicazione ha finito con il file, può chiamare l’ munmap () per rimuovere tale mapping.

Infine, la chiamata fsync () è importante per la realizzazione dell’affidabilità. Quando un’applicazione aggiorna un file tramite write() o una memorizzazione in memoria per un file mappato, tali aggiornamenti sono memorizzati in un buffer e soltanto successivamente questi vengono effettivamente memorizzati. Le applicazioni usano questa funzione per due motivi. Per prima cosa, tale chiamata assicura che gli aggiornamenti sono duraturi e non saranno persi se il sistema andrebbe in crash o si staccasse al corrente. In secondo luogo, tale chiamata tra due aggiornamenti assicura che il primo aggiornamento verrà fatto sempre prima del secondo. Da notare che la chiamata ad fsync() non è sempre necessaria; il sistema