File system: system call e
strutture dati a run-time
Indice
1. Accesso ai file: system call e strutture dati di base
2. Redirezione dell’input/output
3. Pipelines
4. Altre strutture dati
1. Accesso ai file: system call e strutture dati di
base
Gestione dei file: filosofia
• opencarica in memoria l’i-node del file
• read / writeaccedono al file tramite il suo i-node
• closerilascia le strutture dati di memoria del file
Gestione dei file: strutture dati del kernel
Ø
1
2
NON RESIDENTE (U-AREA)
RESIDENTE
File descriptor Table File Table I-node Table
(Processo 1)
Ø
1
2
File descriptor Table
(Processo 2)
. . .
n
(Globale)
1 m read
1 p write
2 n write
(Globale)
2
1
Una entry per ogni file aperto da ogni processo Una entry per ogni
modalità di apertura di ogni file aperto
Una entry per ogni file aperto
ref count
offset di ultimo byte letto/scritto
modalità di apertura
. . .
. . .
. . .
. . .
. . .
. . .
. . .
• i-number • logical device number • flag di modificato
in-core i-node (copia dell'i-node statico)
ref count
in-core i-node table
La system call open
fd=open(pathname, mode)
1. tramite il pathname del file cerca il suo i-node nella i-list su disco2. se il file non esiste o non è accessibile nella modalità richiesta
restituisce un codice di errore3. altrimenti: copia il suo i-node nella in-core i-node table e la completa4. crea una entry nella File Table, e inizializza modalità di apertura,
reference count e offset5. crea una entry nella File Descriptor Table del processo utilizzando la
prima entry libera6. restituisce al chiamante l’indice di tale entry (fd)7. (se l’i-node esiste già nella in-core i-node table, inizia da 4)
File Descriptor
Table
File table
in-core i-node table
5
Ricerca nel file system tramite pathname
23
4a 567
b 458
c 234
a
b
c
56
7
45
8
i-list data blockssuperblock
/a/b/c
Esempioint fd;…fd=open (pathname, …);if (fd=-1) /* gestione errore */….read (fd, …);….close(fd);
NB: Un file può essere aperto più volte, e quindi avere più file descriptor associati contemporaneamente
La system call close
i=close(fd);
• dealloca la entry nella File Descriptor Table• se il reference count nella File Table è >1, lo decrementa e conclude • altrimenti
– dealloca la File Table entry– se il reference count nell’in-core i-node è >1 lo decrementa e conclude– altrimenti: dealloca l’in-core i-node
• restituisce l’esito dell’operazione (0 o 1)
File Descriptor
Table
File table in-core i-node table
5
Esempio
012
User File descriptor Table File Table I-node Table
(Processo A)
(Processo B)
345
012345
count 1
Read
count 1
Rd-Wrt
count 1
Read
count 1
Write
count 1
Read
count 3
(/etc/passwd)
count 1
(local)
count 1
(private)
Processo A
fd1=open("/etc/passwd",O_RDONLY);
fd2=open("local",O_RDWR);
fd3=open("/etc/passwd",O_WRONLY);
Processo B
fd1=open("/etc/passwd",O_RDONLY);
fd2=open("private",O_RDONLY);
La system call read
n=read(fd, buffer, nbytes)• accede alla File Table entry a partire da fd e controlla la
modalità di apertura• accede all’in-core i-node; lock l’in-core i-node• trasforma l’offset nella File Table entry in un indirizzo fisico
(indirizzo blocco + offset all’interno del blocco), attraverso la tabella di indirizzamento nell’in-core i-node
• legge il blocco/i richiesto/i nella buffer cache e copia gli nbytes richiesti in *buffer
• aggiorna l’i-node; unlock i-node• aggiorna l’offset in File Table entry• restituisce al chiamante il numero di byte letti
File Descriptor Table
File table
in-core i-node table
La buffer cache: lettura
kernel processo disco
buffer cachebuffer
read(fd, buffer, n)
La system call writesize=write(fd, buffer, nbytes)
• accede alla File Table entry a partire da fd e controlla la modalità di apertura
• accede all’in-core i-node; lock l’in-core i-node• trasforma l’offset nella File Table entry in un indirizzo fisico
(indirizzo blocco + offset all’interno del blocco), attraverso la tabella di indirizzamento nell’in-core i-node
• scrive gli nbytes di buffer nella buffer cache• aggiorna l’i-node; unlock i-node• aggiorna l’offset in File Table entry• restituisce al chiamante il numero di byte scritti
File Descriptor Table
File table
in-core i-node table
La buffer cache: scrittura
kernel processo disco
buffer cachebuffer
write(fd, buffer, n)
La system call lseek
currpos=lseek (fd, offset, dadove)
• sposta la posizione corrente del file fd di offset bytes a partire dalla posizione specificata nel terzo parametro
• restituisce la posizione corrente dopo la operazione, o –1 se errore
NB: Non effettua alcuna operazione di I/O
File Descriptor Table
File table
in-core i-node table
Altre system call• creat (pathname, permissions)
crea un file vuoto e lo apre in scrittura• link (pathname1, pathname2)
creazione di un (hard) link a un file• unlink (pathname)
distrugge il link indicato (se è l’ultimo, rimuove il file)• rename (oldname, newname)
cambia nome a un file• chmod (pathname, mode)
cambia i permessi di un file• chown (pathname, uid, gid)
cambia l’owner di un file• stat (pathname, buffer)
fornisce informazioni di stato sul file• ecc.
Directories: system call• mkdir (pathname, mode)
creazione di una directory• rmdir (pathname)
distruzione di una directory• chdir (pathname)
cambia la working directory• opendir (pathname)
apre una directory• readdir (dp)
legge da una directory entry• closedir (dp)
chiude una directory• ecc.
Introduzione al linguaggio Java 6
...
Processo 2
Testo
Dati
Stack
Processo n
Testo
Dati
Stack
U-Area
Processo 1
Testo
Dati
Stack
U-Area
Ready queue
Ker
nel
Buffer pool
File table i-node table
SwitcherSwitcher
System calls Interrupt Handlers I/O drivers
Process Table
Visione d’insieme
File descriptor table
2. Redirezione dell’input/output
La system call dup
i= dup (fd);
• duplica il file descriptor fd nella prima posizione libera della File Descriptor Table
• restituisce il nuovo file descriptor o –1 se errore
File Descriptor Table
File table
in-core i-node table
dup: esempio
0
1
2
3
4
5
6
File descriptor table
0
1
2
3
4
5
6
File table
0
1
2
3
4
5
6
in-core i-node table
dup (5)
dup: esempio
0
1
2
3
4
5
6
File descriptor table
0
1
2
3
4
5
6
File table
0
1
2
3
4
5
6
in-core i-node table
dup (5)
Standard files
0
1
2
3
4
5
6
File Descriptor Table
0
1
2
3
4
5
6
File Table
0
1
2
3
4
5
6
in-core i-node table
stdin
stdout
stderrstan
dar
d f
iles
Redirezione dell’input
0
1
2
3
4
5
6
File descriptor table
0
1
2
3
4
5
6
File table
0
1
2
3
4
5
6
in-core i-node table
close (0)
Redirezione dell’input
0
1
2
3
4
5
6
File descriptor table
0
1
2
3
4
5
6
File table
0
1
2
3
4
5
6
in-core i-node table
dup (5)close (0)
Redirezione dell’input
0
1
2
3
4
5
6
File descriptor table
0
1
2
3
4
5
6
File table
0
1
2
3
4
5
6
in-core i-node table
dup (5)close (0) close (5)
Redirezione dell’input
0
1
2
3
4
5
6
File descriptor table
0
1
2
3
4
5
6
File table
0
1
2
3
4
5
6
in-core i-node table
dup (5)close (0) close (5)
Struttura generale della shell
write (1, PROMPT);while ((n=read(0,buffer,80)=!0) {
riconosci nome file e args;If ( (pid=fork()) ==0) { /* I/O redirection */
if (exec(file, args)==-1) exit (1) }
procid=wait(status);If (status !=0) write (2, error);write(1,PROMPT)
}
FIGLIO
PADRE
Se il comando è eseguito in background, non viene eseguita la wait
$file args<><output>$
Shell: redirezione dell’input
If ((pid=fork())==0 {/* processo figlio */if (input redirection) {
fd=open(“f1”, …);close (0);dup (fd);close (fd);
}exec (…);
}
$cmd < f1
Shell: redirezione dell’output
If ((pid=fork())==0 {/* processo figlio */if (output redirection) {
fd=creat(“f1”, …);close (1);dup (fd);close (fd);
}exec (…);
}
$cmd > f1
3. Pipelines
Pipelines
L’operatore di pipe richiede alla shell di connettere fra loro due (o più) comandi:
comando1 comando2 …redirigendo lo standard output del primo nello standard input del successivo, e così via
Pipeline: come funzionanoPer eseguire AB la shell:
• crea un file temporaneo di tipo speciale, chiamato pipe (invisibile all’utente)
• redirige lo stdout di A sulla pipe, e crea un processo che esegue A (produttore)
• redirige lo stdin di B sulla pipe, e crea un processo che esegue B (consumatore)
• Il produttore A e il consumatore B si sincronizzano automaticamente
• quando A e B terminano, la pipe viene distrutta
A
"pipe"
B
Pipe
Una pipe è un file di dimensione limitata gestita come una coda FIFO:– un processo produttore deposita dati (e resta in
attesa se la pipe è piena)– un processo consumatore legge dati (e resta in
attesa se la pipe è vuota)
Produttore Consumatore
Tipi di pipe
• Pipe con nomecreate da mknod (devono essere aperte con open)
• Pipe senza nomecreate e aperte da pipe su un “pipe device” definito al momento della configurazione
Creazione di una pipe senza nome: pipe
i = pipe ( fd[2] )
• crea una “pipe” senza nome, e la apre in lettura e scrittura
• restituisce l’esito dell’operazione (0 o –1)
• assegna a fd[0] il file descriptor del lato aperto in lettura, e a fd[1] quello del lato aperto in scrittura
Pipe e file ordinari
Creazione e uso di un file ordinario:int fd;If ((fd=creat(filename,…) <0 ) err();write(fd,…);…Creazione e uso di una pipe (senza nome):int fd[2];If ( pipe(fd) < 0 ) err();write(fd[1],…);read(fd[0],…);…
File descriptor table
2
1
0
.....
n
.....
.....
m
read e write offset (stanno qui e non nella file table, perché devono essere visti da entrambi i processi)
1
1
2read
write
File table I-node table
fd_pipe n m
10pipe ( )
Pipe: uso tipico
figlio
pipe (fd);
close (fd[0]); write (fd[1],...);
fork ( );
close (fd[1]); read (fd[0],...);
padre
....
0
1
2
3
4u
-are
a
fd 3 4
0 1dat
i/sta
ckstrutture dati
che rappresentano
la pipe....
0
1
2
3
4
fd 3 4
0 1
Realizzazione di una pipelineshell
fork ( )(wait or proceed)
pipe (fd); fork ( );
close (1); dup (fd[1]); close (fd[0]); close (fd[1]);
exec (cmd1,...);
close (0); dup (fd[0]); close (fd[0]); close (fd[1]);
exec (cmd2,...);
produttore
consumatore
$cmd1 cmd2
Realizzazione di una pipeline (segue)• if ((pid=fork()) == 0) {• /* processo figlio */• if (pipeline) {• pipe (fd_pipe);• if (fork()==0) { /* produttore */• close(1);• dup(fd_pipe[1]);• close(fd_pipe[0]);• close(fd_pipe[1]);• exec (cmd1, ...);• } /* consumatore */• close (0);• dup (fd_pipe[0]);• close (fd_pipe[0]);• close(fd_pipe[1]);• exec (cmd2, ...);• }• ...• }
4. Altre strutture dati
Mount table
Tabella sempre residente, aggiornata da mount e umount, che contiene, per ogni file system montato:– major e minor number del device– puntatore al superblocco del file system– puntatore alla root del file system a cui è
montato– puntatore alla directory su cui è montato
Introduzione al linguaggio Java 6
...
Processo 2
Testo
Dati
Stack
Processo n
Testo
Dati
Stack
U-Area
Processo 1
Testo
Dati
Stack
U-Area
Ready queue
Ker
nel
Buffer pool
File table i-node tableMount Table
SwitcherSwitcher
System calls Interrupt Handlers I/O drivers
Process Table
Visione d’insieme
Top Related