Sistemi Operativi L’interfaccia del file system Per la maggior parte degli utenti, il file system è l’aspetto più visibile di un sistema operativo. Il file system fornisce il supporto per la memorizzazione dei dati e dei programmi, ed è composto da due parti: un insieme di file , in ciascuno dei quali sono memorizzati dati e programmi, e una struttura della directory , che organizza l’accesso ai file di tutto il sistema e fornisce informazioni su di essi. In alcuni file system viene fornita un’ulteriore caratteristica : le partizioni, usate per separare fisicamente o logicamente grandi insiemi di directory. Il concetto di file I computer possono memorizzare le informazioni su veri supporti, quali i dischi magnetici, i nastri magnetici, i dischi ottici e altro. Per un utilizzo più semplice del computer, il sistema operativo fornisce una visione logica e uniforme della memorizzazione delle informazioni, astraendo dalle proprietà fisiche dei dispositivi per definire un’unità logica di memorizzazione, il file. Un file è un insieme di informazioni identificato in modo univoco da un nome ed è conservato in un dispositivo di memoria secondaria. Dal punto di vista dell’utente, un file è la più piccola porzione di informazione logica che può essere memorizzata; in altre parole, i dati non possono essere scritti in una memoria secondaria se non vengono inclusi in un file. Comunemente i file contengono programmi ( in forma sorgente o in forma eseguibile) e dati. I file di dati possono essere alfanumerici o binari . I file possono avere un formato libero ( quali i file di testo) o essere formattati rigidamente. Il generale un file è una sequenza di bit, byte, righe o record, il cui significato è definito dal creatore del file. Attributi del file Un file ha certi attributi, che variano da un sistema operativo all’altro, ma tipicamente consistono in: nome: il nome simbolico del file visibile agli utenti identificatore : etichetta unica che identifica il file all’interno del file system tipo: per sistemi che supportano diferenti tipi locazione: puntatore al dispositivo e alla locazione fisica del file nel dispositivo dimensione: dimensione corrente del file in byte protezione: determina il controllo dell’accesso, cioè chi può leggere, scrivere,eseguire tempo, data e identificativo utente Le informazioni su tutti i file sono mantenute nella directory, che risiede come il file in un’unità di memoria secondaria. Tipicamente, un valore nella directory consiste nel nome del file e in un identificatore univoco che, a sua volta, individua gli altri attributi del file. Può essere necessario più di un Kilobyte per registrare queste informazioni per ogni file. Operazioni sui file Creazione di un file: Sono necessari due passi per creare un file; si deve anzitutto trovare spazio nel file system, poi si deve creare un descrittore nella directory che registra il nome del file, la relativa locazione nel file system ed eventualmente altre informazioni. Scrittura del file: Dato il nome del file il sistema cerca nella directory la posizione fisica del file. Il sistema deve mantenere un puntatore di scrittura alla locazione nel file dove avverrà la scrittura successiva. Lettura del file: Per leggere da un file, si usa una chiamata di sistema che specifica il nome del file e dove, in memoria centrale, dovrebbe essere posto il record successivo del file. Il sistema cerca quindi nella directory il descrittore associato; il sistema ha bisogno di L’interfaccia del file system 1 di 8 Sistemi Operativi mantenere un puntatore di lettura alla locazione del file da cui avrà luogo la lettura successiva. Riposizionamento all’interno di un file: Si cerca nella directory il descrittore appropriato e il puntatore alla posizione corrente nel file viene impostato ad un dato valore. L’operazione è detta anche ricerca (seek) nel file. Cancellazione di un file: Si cerca nella directory il file avente tale nome. Attraverso il descrittore si rilascia tutto lo spazio del file e si canella il descrittore della directory. Troncamento di un file . Per cancellare il contenuto mantenendo gli attributi Accodamento Rinomina La maggior parte delle operazioni menzionate coinvolgono la ricerca, entro la directory cui appartiene il file, del descrittore associato al file avente un dato nome. Per evitare questa continua ricerca, molti sistemi operativi richiedono che sia effettuata una chiamata di sistema open() prima di usare un file. Il sistema operativo mantiene una piccola tabella, chiamata tabella dei file aperti contenente informazioni su tutti i file aperti. Quando viene richiesta una operazione su un file non è necessaria una ricerca in memoria secondaria per trovare il descrittore. L’operazione open() prende il nome del file e cerca nella directory, copiando il descrittore del file da questa alla tabella dei file aperti. Alcuni sistemi operativi offrono la possibilità di bloccare un file aperto ( o parti di un file) permettendo ad un processo di impedire ad altri di accedervi. Il blocco (lock) è utile per file che sono condivisi tra vari processi. Tipi di file Se un sistema operativo riconosce un tipo di file, può allora operare sul file in modo mirato. Ad esempio un errore comune si presenta quando un utente cerca di stampare l’oggetto binario di un programma: questo tentativo porta ad una stampa non intelligibile. Una tecnica comune per implementare i tipi di file consiste nell’includere il tipo come parte del nome del file. Il nome è diviso in due parti: il nome vero e proprio e una estensione usualmente separati da un punto. In questo modo, l’utente e il sistema operativo possono riconoscere il tipo di file semplicemente dal nome. Ad esempio in MS-DOS un nome può avere fino a otto caratteri seguiti da un punto e una estensione finale al massimo di tre caratteri. Il sistema operativo usa l’estensione per indicare il tipo di file e quindi il tipo di operazioni che si possono eseguire su quel file. Ad esempio solo i file .com .exe o .bat possono essere eseguiti. I file di tipo .com e .exe sono due forme di file binari eseguibili, mentre un file .bat è un file batch (file di comandi), che contiene in formato ASCII , dei comandi per il sistema operativo. Anche i programmi applicativi usano le estensioni per indicare i tipi di file cui sono interessati. Ad esempio gli assemblatori si aspettano che i file sorgente abbiano una estensione .asm Il sistema UNIX non fornisce una tale caratteristica. L’interfaccia del file system 2 di 8 Sistemi Operativi I file in C E’ consentito operare su file, intesi come sequenze lineari di byte, mediante funzioni per la creazione, rimozione di file, lettura e scrittura di byte da/su file. La prima operazione da eseguire per poter scrivere o leggere da file è l’apertura: #include <stdio.h> main() { FILE *fp; fp= fopen(“ordini”, “r”); … Il programmatore deve includere stdio.h dove è contenuta la definizione del tipo derivato FILE prima di poter utlizzare le funzioni di accesso ai file. La funzione fopen apre il file di nome ordini ; l’operazione di apertura serve ad associare la variabile puntatore fp, nota con il nome di file pointer, al file di nome ordini. Dopo che il file è stato aperto, il programmatore dovrà usare il file pointer fp per poter scrivere e leggere le informazioni al suo interno. Nel caso si verifichi un errore, per esempio perché il file ordini non esiste, la funzione fopen ritorna un file pointer NULL. Dopo aver terminato le operazioni di lettura e/o scrittura è necessario eseguire l’operazione di chiusura del file: fclose(fp); La chiusura del file garantisce che tutti i dati scritti nel file ordini siano salvati su disco; infatti molto spesso il sistema operativo, per ottimizzare le prestazioni del programma, ritarda le scritture sulla memoria di massa mantenendo le informazioni temporaneamente in memoria centrale. Al momento dell’apertura è sempre necessario specificare, oltre al nome del file, anche il tipo di operazione che si intende eseguire. In generale le possibili modalità di apertura sono le seguenti: “r” sola lettura “w” solo scrittura; se il file non esiste sarà automaticamente creato “r+” lettura e scrittura ; se il file non esiste la fopen ritorna NULL “w+” scrittura e lettura; se il file non esiste viene automaticamente creato “a” append, scrittura a fine file. Se non esiste viene creato Esempio di lettura int elementi, dimensione; char buf[100] FILE *fp; int n; ... elementi = 100; dimensione =1; n=fread(buf, dimensione, elementi, fp); la funzione fread legge 100 caratteri dal file fp e li trasferisce nel vettore buf. I parametri della funzione fread sono: buf è il vettore dove vengono trasferite le informazioni lette L’interfaccia del file system 3 di 8 Sistemi Operativi dimensione elementi fp è la dimensione in byte di un elemento indica il numero di elementi è il file da leggere il valore di ritorno della fread indica al programmatore il numero di elementi letti dal file; tale numero può non coincidere con il numero di elementi del vettore buf come nel caso il file sia vuoto o contenga un numero di elementi inferiore a quello di buf. Se il valore di ritorno è negativo vuol dire che c’è stato qualche errore. Le operazioni di lettura accedono al file in maniera sequenziale e mantengono traccia del punto in cui si è arrivati con la lettura; a ogni chiamata a fread il puntatore si sposta in avanti di un numero di byte pari a quelli che sono stati letti. Quando tutto il contenuto del file è stato letto la funzione fread ritorna il valore 0 per indicare che il puntatore è ormai posizionato a fine file. /* Determina il numero di caratteri di un file esistente */ #include <stdio.h> main() { char buf[100]; /* Buffer per la lettura */ FILE *fp; /* File pointer */ long nc; /* Contatore caratteri */ int n ; /* Numero caratteri letti con fread() */ int fine_file=0 /* Indica la fine della lettura del file */ fp = fopen(“clienti”, “r”); /* Apertura del file clienti */ if (fp== NULL ) printf(“ Errore : il file non esiste \n”); else nc= 0L /* inizializza il contatore */ do { /* Legge 100 caratteri dal file ordini */ n = fread(buf,1,100,fp); if (n == 0) fine_file=1; nc = nc + n; /* incremento del contatore */ } while (fine_file==0); fclose (fp); printf(“Il file clienti contiene %ld caratteri\n”, nc); } } Posizionamento del puntatore In C è possibile sui file di byte non solo in modo strettamente sequenziale ma anche in modalità random. La funzione fseek consente infatti di muovere il puntatore di lettura e/o scrittura in una qualunque posizione all’interno del file L’interfaccia del file system 4 di 8 Sistemi Operativi err= fseek(fp, n, mode); I parametri della funzione fseek hanno il seguente significato: fp è il file pointer n indica di quanti byte il file pointer deve essere spostato; se n è negativo il file pointer deve essere spostato indietro mode indica da quale posizione il file pointer deve essere spostato; se mode =0 è a partire dall’inizio, se vale 1 dalla posizione corrente, e se infine vale 2 dalla fine del file. Altre funzioni fprintf fscanf fgetc fputc scrive sul file in modo formattato legge dal file in modo formattato legge un singolo carattere scrive un singolo carattere Struttura interna di un file Internamente l’individuazione di uno piazzamento entro un file può essere complicata per il sistema operativo. I dischi hanno tipicamente una dimensione ben definita del blocco fisico che può essere memorizzato, determinata da quella di un settore. Tutte le operazioni di I/O relative ai dischi avvengono in termini di un blocco fisico. E’ improbabile che la dimensione del blocco fisico eguagli esattamente la lunghezza del record logico desiderato e definito dal programmatore. Ad esempio, il sistema operativo UNIX definisce tutti i file come sequenze di byte. Struttura della directory I file system possono essere vasti; alcuni sistemi memorizzano milioni di file, su dischi da qualche Terabyte; per gestire tutti questi dati, bisogna organizzarli, e l’organizzazione viene di solito effettuata in due parti. Innanzitutto, i dischi sono organizzati in una o più partizioni( o volumi in ambito PC o Macintosh) . Tipicamente, ogni disco in un sistema contiene almeno una partizione, che è una struttura a basso livello in cui risiedono i file e le directory. In alcuni sistemi, le partizioni possono essere usate per fornire aree separate all’interno di un disco, ognuna vista come un dispositivo di memorizzazione separato, mentre in altri sistemi è possibile che le partizioni siano più grandi di un disco in modo da poter raggruppare i dischi in un’unica struttura logica. Le partizioni possono essere pensate come dischi virtuali. Esse, fra l’altro, possono memorizzare sistemi operativi diversi, permettendo a un computer di caricare e far funzionare più di un sistema operativo. In secondo luogo, ogni partizione contiene informazioni sui file presenti in essa. Queste informazioni sono conservate nella directory del dispositivo, nota anche come indice del volume. La directory del dispositivo registra le informazioni – quale nome, posizione, dimensione e tipo – per tutti i file in quella partizione. L’interfaccia del file system 5 di 8 Sistemi Operativi directory directory file partizione A disco 2 disco 1 file directory partizione C partizione B file disco 3 Directory a singolo livello Tutti i file sono contenuti nella stessa directory. E’ una struttura semplice che presenta delle limitazioni significative quando il numero dei file aumenta o quando il sistema ha più di un utente. Cat bo a test data mail cont hex records directory file Directory a due livelli user 1 cat bo a L’interfaccia del file system test user 2 a user 3 user 4 data a directory principale test data directory dei file utente 6 di 8 Sistemi Operativi Ogni utente ha una propria directory dei file utente. Quando ha inizio un processo dell’utente o l’utente si connette viene fatta una ricerca nella directory principale che è indicizzata per nome utente e ogni descrittore punta alla directory dei file utente (UFD User File Dirctory). Utenti differenti possono avere file con lo stesso nome. Directory strutturata ad albero Questa generalizzazione permette agli utenti di creare delle proprie sottodirectory. radice stat mail bob spell bin dist first nuovi uno program p primo sec uno due terzo due La struttura diventa un albero di altezza arbitraria. Ad esempio il sistema MS-DOS è strutturato come un albero. L’albero ha una directory radice, e ogni file nel sistema ha un percorso univoco che va dalla radice, attraverso tutte le sue sottodirectory, sino al file specificato. Una directory o sottodirectory contiene un insieme di file o sottodirectory. Una directory è semplicemente un altro file ma viene trattata in modo speciale. Nell’uso normale ogni utente ha una directory corrente. Montaggio del file system Così come un file deve essere aperto prima di essere usato, un file system deve essere montato prima di essere disponibile nel sistema. La procedura di montaggio è diretta: al sistema operativo viene fornito il nome del dispositivo e il punto di montaggio, ossia la locazione entro il file system esistente alla quale il file system da montare deve agganciarsi. Tipicamente un punto di montaggio è una directory vuota. Ad esempio, nel sistema UNIX un file system che contiene la directory dell’utente jane potrebbe essere montato come /users. Quindi si accederà alla struttura della directory con il percorso /users/jane. Il sistema operativo verifica che il dispositivo da montare contenga un file system valido. Per illustrare il montaggio del file system si consideri il file system rappresentato in figura L’interfaccia del file system 7 di 8 Sistemi Operativi File system esistente / partizione non montata users bill sue jane fred prog doc aiuto La figura successiva mostra gli effetti del montaggio della partizione che risiede in /device/dsk sopra /users / users sue jane prog doc Nel sistema operativo MacOS, ogni volta che il sistema incontra per la prima volta un disco (i dischi rigidi vengono trovati al momento dell’avvio, i dischi floppy vengono visti al momento dell’inserimento nel lettore), il sistema operativo cerca un file system nel dispositivo: se ne trova uno monta automaticamente il file system a livello di radice aggiungendo sullo schermo un’icona di cartella etichettata con il nome del file system come è memorizzato nella directory del dispositivo. I sistemi operativi della famiglia Microsoft Windows (95,98,NT,2000,XP) mantengono la struttura della directory a due livelli estesa con lettere assegnate a dispositivi e partizioni. Le partizioni hanno una struttura della directory a grafo generale, associata alla lettera del drive. Un grafo generale si ottiene quando si aggiungono dei collegamenti link a file, a partire da una directory ad albero. Il percorso verso un file specifico prende la forma lettera del drive: \percorso\verso\il\file. Questi sistemi operativi riconoscono automaticamente tutti i dispositivi e montano tutti i file system localizzati al momento dell’avvio. In alcuni sistemi come UNIX i comandi di montaggio sono espliciti. L’interfaccia del file system 8 di 8