Lezione 20 File system Linux - WEB Lab
←
→
Trascrizione del contenuto della pagina
Se il tuo browser non visualizza correttamente la pagina, ti preghiamo di leggere il contenuto della pagina quaggiù
Lezione 20 File system Linux Sistemi Operativi (9 CFU), CdL Informatica, A. A. 2020/2021 Dipartimento di Scienze Fisiche, Informatiche e Matematiche Università di Modena e Reggio Emilia http://weblab.ing.unimo.it/people/andreolini/didattica/sistemi-operativi 1
Quote of the day (Meditate, gente, meditate...) “I think the major good idea in Unix was its clean and simple interface: open, close, read, and write. Ken Thompson (1943-) Programmatore Il padre dei SO UNIX e Plan 9 Ideatore dei linguaggi B e Go 2
FILE: RAPPRESENTAZIONE E ACCESSO 3
Definizioni preliminari (File, directory, file system) Nei SO moderni (non solo UNIX), le informazioni possono essere memorizzate in maniera strutturata e permanente su supporto secondario. Paradigma d'uso: memorizzazione gerarchica tramite cartelle (directory) e fascicoli (file). Un file system è una gerarchia di directory e file, ospitata su un dispositivo di memorizzazione secondaria. 4
Il file (Not so easy as you might think) Un file è una sequenza di byte memorizzata su supporto secondario. È identificabile univocamente tramite un nome. È un contenitore di dati arbitrari. Un file è composto da due parti. Una struttura di controllo che memorizza le proprietà durevoli (meritevoli di sopravvivere al riavvio). Un insieme di blocchi di dati. 5
File Control Block (La struttura di controllo) FCB Il File Control Block è la struttura che memorizza le proprietà durevoli di un file. Proprietario. Date notevoli (creazione, ultimo accesso, modifica). Dimensione. Permessi di accesso. Puntatori a blocchi di dati (il primo o tutti). Il FCB è memorizzato su disco. Hard 6 disk
Recupero dei metadati (API GNU/Linux) int stat(const char *path, Riempie la struttura dati buf struct stat &buf); con i metadati del file puntato da path. 7
Recupero dei metadati (API) In GNU/Linux, la chiamata di sistema stat() ritorna una struttura dati contenente i metadati di un file. I parametri passati in ingresso sono due: il nome del file. il puntatore ad una struttura dati che sarà riempito con i metadati. 8
Tipi di file (File di testo, documenti, eseguibili, script di shell) I file possono essere classificati in tipi, in modo tale da assegnare ad essi una applicazione di default che li possa gestire. Esempi: Codice sorgente → editor del programmatore. File multimediale → riproduttore audio/video. Come fa il SO a riconoscere il tipo di file? Associazione di una estensione. Analisi del contenuto del file. 9
Estensione (.txt, .doc, .exe, .sh) Si aggiunge al nome del file una estensione secondo lo schema: Esempi: command.com, autoexec.bat, report.doc In tale schema: nome_file è un nome assegnato dall'utente. estensione è una stringa rappresentante univocamente il tipo di dato in questione. separatore è un carattere che delinea il nome 10 dall'estensione (solitamente, un punto).
Supporto per le estensioni: associazione diretta (Il SO decide l'applicazione di default) Il meccanismo più semplice di riconoscimento del tipo del file è la associazione diretta. Il SO legge l'estensione del file e gli associa automaticamente una applicazione tipo. Il nome dell'applicazione tipo: è cablato nel SO (MS-DOS, UNIX linea di comando con filtro lesspipe). è scritto come metadato del file (Mac OS). 11
Supporto per le estensioni: lista di estensioni 1/2 (L'applicazione dichiara la sua lista di estensioni) Ciascuna applicazione gestisce una lista di estensioni gradite. Ad esempio, Libreoffice → .doc, .odt, .docx Diverse applicazioni possono leggere lo stesso tipo di file. Abiword, Openoffice, Libreoffice → .doc Una sola applicazione può essere impostata come il default per un dato tipo di file. 12
Supporto per le estensioni: lista di estensioni 2/2 (L'applicazione dichiara la sua lista di estensioni) Quando un utente clicca due volte sull'icona di un file in un ambiente desktop, il SO carica l'applicazione di default. Quando un utente clicca col tasto destro sull'icona del file e seleziona “Apri con...”, viene mostrata la lista delle applicazioni in grado di gestire il tipo di file. Approccio usato nei SO: Windows 13 UNIX (desktop grafico)
Analisi del contenuto (Approccio “signature-based”, simile al modus operandi di un antivirus) Ciascun file è riconoscibile da una o più sequenze di byte (dette magic number) in offset strategici. Ad esempio, un eseguibile in formato ELF contiene i caratteri 'E', 'L', 'F' nel secondo, terzo e quarto byte. Si digiti less /bin/ls per verificare. Il sistema operativo contiene tutti i magic number in un database locale su file, detto magic file. /usr/share/file/misc/magic 14
L'interfaccia ai magic file (Approccio “signature-based”; molto più potente delle estensioni) Il comando file (UNIX, linea di comando) scandisce un file alla ricerca dei magic number, fino a quando non ne trova uno corretto. file file.txt file.txt: ASCII text, with very long lines. 15
Il tipo di dato “file eseguibile” (AKA Come far partire i programmi eseguibili digitando il loro nome) In GNU/Linux, un file eseguibile (riconosciuto dalla signature del formato ELF) è associato ad un programma detto caricatore (loader). /lib/ld-linux.so.2 Il caricatore: carica in memoria le librerie necessarie all'esecuzione. carica il programma. 16
Il tipo di dato “file eseguibile” (AKA Come far partire gli script digitando il loro nome) Il caricatore controlla se il file inizia con una riga simile (detta she-bang): #!/bin/bash Tale linea specifica l'interprete dello script. In tal caso, il caricatore: carica l'interprete (con relative librerie) esegue l'interprete con argomento pari al nome dello script. 17
FILE: ORGANIZZAZIONE INTERNA 18
Organizzazione logica e fisica (Come viene visto il file dall'utente e dal SO) L'organizzazione del Struttura logica contenuto di un file è (una riga del file, una informazione) suddivisa in due aspetti. Struttura fisica Logica: il file è acceduto per (le righe del file sono impacchettate in 4 unità logiche (singoli byte, blocchi del disco) righe o record, indici). Fisica: impacchettamento delle unità logiche nei blocchi fisici del disco. 19
Impacchettamento del file su disco (Unità logiche → blocchi su disco) L'unità logica del file è mappata sulla rappresentazione fisica del disco (settore). Nel caso degli hard disk, un settore è spesso lungo 512 byte. In un file, l'unità logica è quasi sempre di dimensione diversa rispetto al settore. Tipicamente, il record logico è più piccolo →Il gestore del file system cerca di impacchettare più record logici nei settori. 20
Organizzazione logica (Byte, linea, indice) Un file può essere organizzato logicamente in tre modi distinti. Organizzazione “per flusso di byte”. Organizzazione “per record logici”. Organizzazione “per indice”. 21
Organizzazione per flussi di byte (The true UNIX way; keep it simple and stupid) 1 record logico Un file è visto come una sequenza di record logici di lunghezza pari ad 1 (sequenza di byte). Non esiste una strutturazione; l'applicazione legge flussi di byte. È compito della applicazione dare un significato al flusso di byte. 22
Organizzazione per record logici (L'unità è la riga di testo o la struttura dati binaria) 1 record logico Un file è visto come una sequenza di record logici di lunghezza maggiore di 1. L'applicazione legge e scrive un certo numero di record logici. Linee (I/O formattato). Strutture dati. 23
Organizzazione per indice (Usata nelle basi di dati) 1 record Indice: 1 Un file contiene una sequenza di logico Dati record logici di lunghezza fissa. Indice: 2 Ciascun record contiene un campo Dati indice in una posizione fissa. Indice: 3 L'albero è ordinato in base Dati all'indice. Indice: 4 Con una ricerca binaria sull'indice, Dati si trova l'elemento i-mo in O(log n) passi (n=numero di record logici). 24
L'indice doppio (Fondamentale in caso di accesso frequente alla base di dati) In caso di cancellazioni ed inserimenti frequenti dei record File indice File dati logici, diventa molto costoso Mario Rossi 30 mantenere ordinato il file. Si usano due file: Un file indice contenente coppie . Rossi Un file dati contenente i record logici. Cancellazioni e inserimenti non comportano il riordino fisico del 25 file dati.
L'indice gerarchico (Fondamentale in caso di basi di dati di grandi dimensioni) File indice File indice primario secondario Se il file indice cresce a dismisura, i si adotta un indice multilivello. → Schema gerarchico. ... Un file indice primario punta ad un file indice secondario. Il file indice secondario punta al Rossi i record. Tecnica utilizzata nei DBMS (IBM Mario Rossi 30 ISAM). File dati 26
Metodi di accesso ai file (Sequenziale, diretto, con indice) Un file può essere acceduto in tre modi distinti. Accesso sequenziale. Accesso diretto. Accesso per indice. 27
Accesso sequenziale (Le unità logiche sono accessibili soltanto dalla prima all'ultima) L'informazione contenuta nel file viene acceduta sequenzialmente, ossia un record dopo l'altro. Il modello considerato è quello di un nastro. Applicazioni: copie di file, caricamento di un programma. 28
Accesso diretto (Le unità logiche sono accessibili anche direttamente) L'informazione contenuta nel file viene acceduta per singoli blocchi fisici, direttamente (casualmente). Modello di un disco. Applicazioni: deframmentazione di un disco. 29
Accesso per indice (Le unità logiche sono accessibili velocemente tramite indice) L'informazione contenuta nel file viene acceduta per indice, casualmente. Modello di una base di dati. Applicazioni: Database Management System (DBMS). 30
Relazione struttura interna ↔ accesso (La norma) Solitamente: Accesso sequenziale → organizzazione per flussi di byte. Accesso diretto → organizzazione per record logici. Accesso tramite indice → organizzazione per indice. Tuttavia, ciò non è sempre vero. La copia efficiente di un file contenente un DBMS (rappresentazione ad indice) avviene tramite letture e scritture a blocchi. → In realtà, è il tipo di applicazione che determina il tipo di accesso! 31
Fine del file (Il kernel deve comunicarlo all'utente in qualche modo) Nei metodi di accesso sequenziale e diretto, può capitare di leggere oltre la fine del file (End Of File, EOF). Il SO deve rilevare questa condizione e segnalarla all'utente. Due strategie: Si fa ritornare un valore opportuno alla operazione di lettura. Si usa una operazione apposita per il controllo sul raggiungimento della fine del file. 32
La tabella dei file aperti (Il kernel deve sapere quali file ha aperto un processo) Ciascun PCB di processo contiene un puntatore ad una tabella dei file aperti. Tale tabella contiene strutture dati descriventi, all'intenro del kernel, i file attualmente aperti dal processo. In Linux, la task_struct ha un campo struct files_struct *files. 33
I/O low-level e bufferizzato (Si interagisce direttamente col kernel oppure si usa un buffer della GLIBC) I/O diretto (basso livello, low-level): le operazioni sono inviate direttamente al kernel, una per una. I/O bufferizzato: le operazioni di I/O sono gestite da un buffer intermedio. Letture e scritture sono “ritardate” fino al riempirsi del buffer. 34
Buffering in GNU/Linux (Due buffer; uno applicativo, uno del kernel) Buffer applicativo. Usato dalle funzioni di libreria del C. Le operazioni di I/O lavorano con un buffer più grande di un carattere. Una chiamata di sistema → Un minimo di lavoro per il kernel. Buffer del kernel. Usato per “ricordarsi” delle letture fatte (le richieste successive sono servite da RAM). Usato per “raggruppare” le scritture (essendo più lente delle letture, sono fatte tutte insieme). 35
Buffering in GNU/Linux (Un'immagine vale 1000 parole) Applicazione Libreria del C Funzioni di I/O Buffer (Bufferizzato o no) applicativo User Chiamate di sistema Kernel Esecutore Buffer I/O kernel Hardware 36
Esempio: read bufferizzata (Un'immagine vale 1000 parole) Applicazione Libreria del C 9 Funzioni di I/O Buffer (Bufferizzato o no) applicativo 1 8 2 7 User Chiamate di sistema Kernel 3 6 Esecutore Buffer I/O kernel Hardware 4 5 37
Impostazione del buffer applicativo (Tre modalità distinte) Nessun buffer: il buffer ha dimensione nulla (non viene utilizzato). Singola riga: il buffer è considerato riempito quando raggiunge la sua massima dimensione o quando si incontra un carattere newline. Buffering completo: il buffer è considerato riempito quando raggiunge la sua massima dimensione. 38
Flushing dei buffer (Applicativi e kernel) È possibile forzare in ogni istante il contenuto dei buffer applicativo e/o kernel sul disco. Un concetto, due nomi distinti. Flush: svuotamento del buffer applicativo. Sync: svuotamento del buffer del kernel. 39
I/O diretto e file descriptor (Il legame tra descrittore di file e tabella dei file aperti) In caso di I/O diretto, un file aperto è identificato da un intero detto descrittore di file (file descriptor). Il descrittore di file è un indice all'elemento relativo della tabella dei file aperti. Il descrittore di file è ottenuto come valore di ritorno della chiamata di sistema open(). 40
I/O bufferizzato e FILE * (Il legame tra FILE * e tabella dei file aperti) In caso di I/O bufferizzato, un file aperto è chiamato stream ed è identificato da un puntatore ad una struct _IO_FILE (FILE * nella libreria del C). Tale struttura contiene: il descrittore del file con cui identificare l'elemento della tabella dei file aperti. un puntatore al buffer applicativo di default. informazioni di controllo dello stream (posizione della testina, lunghezza del buffer, ...). Il FILE * è ottenuto come valore di ritorno della 41 funzione di libreria fopen().
Descrittore di file e FILE * (Un'immagine vale 1000 parole) FILE * I/O Applicazione bufferizzato Descrittore del file I/O non Descrittore bufferizzato del file Descrittore User del file Kernel Tabella dei file aperti Hardware 42
Accesso non bufferizzato 1/2 (API GNU/Linux) int open(const char Apre un file di nome pathname nella *pathname, int modalità indicata da flags e con i flags, mode_t mode); permessi indicati da mode. Si ottiene un descrittore al file. ssize_t read(int fd, Legge count byte dal file identificato void *buf, size_t da fd nel buffer puntato da buf. count); Ritorna il numero di byte letti, 0 se fine file,
Accesso non bufferizzato 2/2 (API GNU/Linux) off_t lseek(int fd, Sposta la testina di lettura del file off_t offset, int indicato da fd alla posizione offset, whence); partendo da whence. int close(fd); Chiude il file indicato da fd. 44
Accesso bufferizzato 1/3 (API GNU/Linux) FILE *fopen(const Apre uno stream di nome pathname char *pathname, nella modalità e con i permessi indicati const char *mode); da mode. Si ottiene un puntatore al file (descrittore e puntatori agli stream). ssize_t fread(void Legge nmemb strutture dati di *ptr, size_t size, dimensione size dallo stream size_t nmemb, FILE * indicato da stream e le memorizza stream); nel buffer puntato da ptr. Ritorna il numero di strutture lette, 0 se fine file o errore. ssize_t fwrite(void Scrive nmemb strutture dati di *ptr, size_t size, dimensione size (contenute nel size_t nmemb, FILE * buffer puntato da ptr) nello stream 45 stream); indicato da stream. Ritorna il numero
Accesso bufferizzato 2/3 (API GNU/Linux) int feof(FILE Ritorna 1 se è stata raggiunta la fine *stream); dello stream puntato da stream. int ferror(FILE Ritorna 1 se è stato rilevato un errore *stream); nelle operazioni sullo stream puntato da stream. int clearerr(FILE Pulisce gli indicatori di errore e di *stream); EOF per lo stream puntato da stream. int fseek(FILE Sposta la testina di lettura dello *stream, long stream indicato da stream alla offset, int whence) posizione offset, partendo da whence. int fclose(FILE Chiude lo stream indicato da 46 *fp); stream.
Accesso bufferizzato 3/3 (API GNU/Linux) int fileno(FILE Ritorna il descrittore di file associato *stream); allo stream puntato da stream. void setvbuf(FILE Imposta il tipo di buffering dello stream *stream, char *buf, puntato da stream nella modalità int mode, size_t specificata da mode. Il buffer puntato size); da buf può essere nullo o di dimensione massima pari a size. int fflush(FILE Svuota il buffer applicativo associato *stream); allo stream puntato da stream. int fsync(int fd); Svuota il contenuto del buffer del kernel relativo allo stream associato al descrittore di file fd. 47 void sync(void); Svuota l'intero buffer del kernel.
DIRECTORY: RAPPRESENTAZIONE 48
La directory (Easier than I thought) Una directory è un file nome FCB contenente coppie del tipo nome FCB (nome, puntatore). nome FCB nome FCB Nome: Nome ad alto livello di un contenitore di informazioni (file, directory). Puntatore: punta ad una struttura dati contenente i metadati di un file o di un'altra 49 directory.
Strutture di directory (Oggi si usa il modello a grafo) 1. 2. Una directory può essere rappresentata mediante diversi modelli (e relative strutture dati). 3. 4. 1.A singolo livello. 2.A due livelli. 3.Ad albero. 4.A grafo. 50
I difetti dei primi schemi (AKA “Perché oggi si usa lo schema a grafo”) Schema a singolo livello (console anni '80): estremamente scomodo nei sistemi multiutente (che succede se due utenti nominano allo stesso modo un file?). Schema a doppio livello (VMS): esiste un completo isolamento fra utenti. Schema ad albero (MSDOS): è scomodo condi- videre file fra utenti senza copiarli; è impossibile creare “collegamenti a file”. 51
Directory a grafo aciclico (Aciclico → niente cicli infiniti di directory) Il file system è modellato con un grafo aciclico. Vertici: directory o file. Archi: relazioni fra directory e file contenuti. Vertice radice: rappresenta la directory radice del file system (UNIX: /, Windows: C:\). In tale modello, il contenuto di un file può essere referenziato da due elementi di directory (hard link) distinti. Usato da: SO UNIX. 52
Directory a grafo aciclico (Aciclico → niente cicli infiniti di directory) / I due elementi di directory home bin puntano allo stesso FCB (dunque, allo stesso contenuto). Hard link amap amap6 Hard link 53
Un esempio di hard link (Debian) Nel SO Debian GNU/Linux, i due comandi eseguibili sudo e sudoedit (in /usr/bin) sono due hard link allo stesso contenuto. ls -l /usr/bin/sudo* Si osserva il contatore di hard link (secondo campo). Il contatore è posto a 2 (due elementi di directory puntano allo stesso contenuto). Rationale: il programma si comporta in maniera diversa a seconda del suo nome (ARGV[0]). Non c'è bisogno di installare due programmi quasi54 identici; se ne usa uno solo → risparmio di spazio.
Limitazioni del modello a grafo aciclico (Diverse, purtroppo) Non è possibile introdurre un ciclo nel grafo. → Niente link a directory superiori (si creerebbe un ciclo infinito). cd directory in una directory con ciclo → stallo. Non è possibile creare un hard link ad un file in un altro file system. File system diversi → implementazioni diverse delle directory. Ogni file system dovrebbe conoscere l'implementazione delle directory di ogni altro file system → impraticabile. 55
Directory a grafo ciclico (Ciclico → possibili cicli infiniti di directory) Il file system è modellato con un grafo ciclico. Vertici: directory o file. Archi: relazioni fra directory e file contenuti. Vertice radice: rappresenta la directory radice del file system (UNIX: /, Windows: C:\). In tale modello, è possibile creare link in grado di chiudere cicli (noti con il nome di soft link). Il contenuto è unico! I metadati del file sono unici! Usato da: SO UNIX (soft link), Windows 56 (collegamenti simbolici).
Directory a grafo ciclico (Ciclico → possibili cicli infiniti di directory) / I due elementi di directory puntano ad FCB diversi. Il contenuto puntato Il contenuto puntato da questo FCB è il da questo FCB è home bin percorso del file quello del file originale. collegato. Hard link gawk awk Hard link 57 Soft link awk → gawk
Un esempio di soft link (Debian) Nel SO Debian GNU/Linux, il comando eseguibile xzcat (in /usr/bin) è un link simbolico al file xz. ls -l /usr/bin/xz{cat,} Il tipo di file è il link simbolico (lettera 'l' iniziale). La dimensione del link simbolico è 2 (“xz”). Gli hard link sono posti ad 1 (due istanze uniche di contenuti; il contenuto originale ed il percorso ad esso). Rationale: gli stessi degli hard link. 58
Soft link vs. hard link (2:0) I soft link possono essere creati fra molteplici file system. Se il file destinazione non è presente (ad es. è su un CDROM non inserito), il link è colorato di rosso. I soft link possono essere creati verso directory superiori. 59
Gestione dei cicli infiniti (2:0) / Scenario: il comando find scandisce un sottoalbero di directory home bin con un soft link alla directory di partenza. → Ciclo infinito. studente andreoli La gestione dei cicli infiniti è delegata alle applicazioni. find /home/andreoli -name andreoli andreoli -follow 60
Cancellazione di file (“Si tagliano gli hard link con le forbici”) L'hard link di un file è un conteggio di riferimento. Il conteggio serve ad impedire la distruzione del contenuto di un file in presenza di utenti che ne usufruiscono. Quando si cancella un file, si decrementa di uno il conteggio degli hard link. Se il conteggio è zero, si stacca il contenuto del file dal suo FCB. 61
Alcune doverose osservazioni (Da ricordare) Il contenuto del file non è fisicamente cancellato, bensì staccato dal file system. È possibile recuperarlo con strumenti appositi. Un file aperto da una applicazione rimane ancora accessibile fino alla chiusura del descrittore. 62
Gestione dei link (API GNU/Linux) int link(const char Crea un nuovo link hard di nome *oldpath, const char newpath al file identificato dal nome *newpath); oldpath. int symlink(const Crea un nuovo link soft di nome char *oldpath, const newpath al file identificato dal nome char *newpath); oldpath. int unlink(const Decrementa di uno il contatore degli char *pathname); hard link. Se il contatore diventa zero, il file non è più accessibile con mezzi standard. 63
Implementazione delle directory (Una semplice lista?) L'implementazione più semplice di una directory è attraverso una lista semplice di strutture dati contenenti, ciascuna: un nome di file/directory. un puntatore al FCB. L'implementazione è semplice, l'efficienza può essere molto bassa (scansione lineare della lista → O(n) con il numero di file nella directory). Implementato in Linux (EXT2, EXT3). 64
Implementazione delle directory (Una tabella hash?) Un'altra implementazione della tabella delle directory fa uso di una tabella hash e di una lista semplice (Linux, EXT3, EXT4 prime versioni). Lista semplice: Contiene le coppie . Tabella hash: Chiave: un hash del nome del file. Valore: Un puntatore all'elemento della lista corrispondente. 65
Implementazione delle directory (Binary tree?) Un'altra implementazione della tabella delle directory fa uso di un albero binario (Linux, EXT4 versione attuale). L'albero binario contiene hash dei nomi di file ordinati alfanumericamente. I nodi foglia dell'albero contengono puntatori ai FCB. 66
Accesso alle directory (Molto simile all'accesso bufferizzato ai file) L'accesso alle directory avviene mediante un descrittore di directory simile al puntatore allo stream usato nell'I/O bufferizzato. Tale descrittore è rappresentato dalla struttura struct __dirstream rinominata in DIR nella libreria del C). Si ottiene un puntatore a tale descrittore mediante la funzione di libreria opendir() che, analogamente a fopen(), apre una directory. 67
Elementi di directory (Un elemento ↔ una struct dirent) Nei sistemi GNU/Linux, ogni elemento di directory è identificato da una struct dirent, definita nel file seguente: $LINUX/include/dirent.h. Nome dell'elemento. Tipo di file (regolare, directory, speciale, link, …). Puntatore al FCB associato al file. 68
Operazioni su una directory (Directory ↔ Stream) La directory viene gestita come uno stream di record logici di tipo struct dentry. Riposizionamento dello stream. Recupero posizione dello stream. Lettura della prossima struct dentry. 69
Gestione delle directory (API GNU/Linux) DIR *opendir(const Apre la directory di percorso name e char *name); ritorna un descrittore di directory. struct dirent * Ritorna il prossimo elemento della readdir(DIR *dirp); directory identificata da dirp. Ritorna NULL se la directory è stata scandita tutta. void rewinddir(DIR Reimposta il prossimo elemento da *dirp); scandire al primo file della directory. long telldir(DIR Ritorna la posizione dell'ultimo *dirp); elemento scandito nella directory. int closedir(DIR Chiude la directory identificata da dirp. *dirp); 70
Creazione e cancellazione di directory (API GNU/Linux) int mkdir(const char Crea la directory di nome pathname *pathname, mode_t con i permessi specificati da mode. mode); int rmdir(const char Rimuove la directory di nome *pathname); pathname. La directory deve essere vuota. 71
MONTAGGIO E SMONTAGGIO 72
Aggancio di un nuovo file system (File system mount) Un file system, prima di essere utilizzato deve essere associato ad un dispositivo di memorizzazione secondaria. deve essere agganciato ad un file system esistente, usando una directory come punto di attacco. Tali due operazioni prendono il nome di file system mount o, più brevemente, mount. La directory di aggancio prende il nome di mount point (punto di attacco). 73
La tabella di mount (Analogia con la tabella dei file aperti) Il kernel mantiene una tabella di mount. In tale tabella sono mantenute tutte le associazioni dispositivo ↔ mount point. In Linux, la tabella di mount è implementata tramite la struttura dati struct vfsmount. File $LINUX/include/mount.h 74
Sgancio del file system (File system umount) Il file system può essere staccato dal suo mount point tramite l'operazione di unmount (umount nel gergo UNIX), sostanzialmente l'inversa di mount. L'unmount è preceduto da un flush dei buffer del kernel. NOTA BENE: per motivi di efficienza, le scritture su di un file system sono eseguite in blocco, al momento più favorevole. → Estrarre fisicamente un dispositivo senza aver smontato il suo file system equivale a75 corromperne i dati!
Root file system (La radice di tutti i mali) Almeno un file system deve essere presente all'avvio del SO, affinché il mount degli altri file system sia sempre possibile. Tale file system prende il nome di root file system e contiene almeno il comando init (directory /sbin o /usr/bin) per avviare i servizi della macchina. Tipicamente, il root file system è associato ad un disco rigido installato permanentemente. 76
Aggancio file system: prima (Due alberi staccati) Tabella di mount Root file system su disco rigido / Disco rigido Root directory / File system su CD-ROM Mount point /media/cdrom 77
Aggancio file system: dopo (Due alberi uniti) Tabella di mount Root file system su disco rigido / Disco rigido Root directory /media/cdrom CDROM / File system su CD-ROM Mount point /media/cdrom 78
Opzioni di mount (Lettura e scrittura, esecuzione, sincrona, asincrona) read-only: il file system è montato in sola lettura. sync: le scritture sono sincrone (eseguite una dietro l'altra, in maniera bloccante). async: le scritture sono asincrone (eseguite in blocco, più avanti, nel momento più favorevole). exec: si permette l'esecuzione dei programmi. 79
Montaggio e smontaggio (API GNU/Linux) int mount(const char Monta il file system identificato dal *source, const char percorso source nel mountpoint *target, const char* identificato dal percorso target. È filesystemtype, possibile specificare direttamente il tipo di filesystem nella stringa di nome unsigned long filesystemtype. Le opzioni di mountflags, const montaggio sono impacchettate void *data); nell'intero lungo mountflags. Il puntatore data permette di passare informazioni specifiche di un filesystem. int umount (const Rimuove l'associazione fra dispositivo e char *target); mountpoint. 80
Puoi anche leggere