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
1Quote 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
2FILE: RAPPRESENTAZIONE E ACCESSO
3Definizioni 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.
4Il 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.
5File 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
diskRecupero 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.
7Recupero 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.
8Tipi 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. 9Estensione
(.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).
11Supporto 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. 12Supporto 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
14L'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.
15Il 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.
16Il 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.
17FILE: ORGANIZZAZIONE INTERNA
18Organizzazione 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. 19Impacchettamento 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. 20Organizzazione 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”.
21Organizzazione 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.
22Organizzazione 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.
23Organizzazione 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). 24L'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 26Metodi di accesso ai file
(Sequenziale, diretto, con indice)
Un file può essere acceduto in tre modi distinti.
Accesso sequenziale.
Accesso diretto.
Accesso per indice.
27Accesso 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.
28Accesso 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.
29Accesso 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).
30Relazione 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! 31Fine 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. 32La 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.
33I/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.
34Buffering 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). 35Buffering 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
36Esempio: 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
37Impostazione 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.
38Flushing 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.
39I/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().
40I/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
42Accesso 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.
44Accesso 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 numeroAccesso 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
48La 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. 50I 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”. 51Directory 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. 52Directory 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
53Un 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. 55Directory 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 → gawkUn 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. 58Soft 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.
59Gestione 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 60Cancellazione 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.
61Alcune 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.
62Gestione 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.
63Implementazione 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). 64Implementazione 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.
65Implementazione 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.
66Accesso 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.
67Elementi 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.
68Operazioni 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.
69Gestione 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); 70Creazione 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.
71MONTAGGIO E SMONTAGGIO
72Aggancio 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).
73La 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
74Sgancio 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. 76Aggancio 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
77Aggancio 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
78Opzioni 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.
79Montaggio 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.
80Puoi anche leggere