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
• open
carica in memoria l’i-node del file
• read / write
accedono al file tramite il suo i-node
• close
rilascia le strutture dati di memoria del
file
Gestione dei file: strutture dati del kernel
NON RESIDENTE
(U-AREA)
RESIDENTE
File descriptor Table
File Table
in-core i-node table
I-node Table
Ø
1
...
2
...
...
m
1
(Processo 1)
read
...
1
p
2
write
File descriptor Table
...
...
Ø
1
1
n
2
2
write
...
n
...
(Processo 2)
Una entry per ogni
file aperto da ogni
processo
ref
count
modalità di
apertura
offset di
ultimo byte
letto/scritto
ref
count
in-core
i-node (copia
dell'i-node statico)
• i-number
• logical device
number
• flag di modificato
(Globale)
(Globale)
Una entry per ogni
modalità di apertura
di ogni file aperto
Una entry per ogni
file aperto
La system call open
fd=open(pathname, mode)
5
File
Descriptor
Table
1.
2.
3.
4.
5.
6.
7.
File
table
tramite il pathname del file cerca il suo i-node nella i-list su
disco
se il file non esiste o non è accessibile nella modalità richiesta
restituisce un codice di errore
altrimenti: copia il suo i-node nella in-core i-node table e la
completa
crea una entry nella File Table, e inizializza modalità di
apertura, reference count e offset
crea una entry nella File Descriptor Table del processo
utilizzando la prima entry libera
restituisce al chiamante l’indice di tale entry (fd)
(se l’i-node esiste già nella in-core i-node table, inizia da 4)
in-core
i-node
table
Ricerca nel file system tramite pathname
a 567
a
b 458
b
/a/b/c
c 234
c
superblock
i-list
data blocks
Esempio
int 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);
5
File
Descriptor
Table
File table
in-core
i-node
table
• 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)
Esempio
Processo A
fd1=open("/etc/passwd",O_RD
ONLY);
fd2=open("local",O_RDWR);
fd3=open("/etc/passwd",O_WR
ONLY);
Processo B
fd1=open("/etc/passwd",O_RD
ONLY);
fd2=open("private",O_RDONLY
);
La system call read
n=read(fd, buffer, nbytes)
File
Descript
or Table
File
table
• 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 inode
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
in-core
i-node
table
La buffer cache: lettura
buffer
buffer cache
read(fd, buffer, n)
processo
kernel
disco
La system call write
File
Descript
or Table
File
table
size=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
in-core
i-node
table
La buffer cache: scrittura
buffer
buffer cache
write(fd, buffer, n)
processo
kernel
disco
La system call lseek
File
Descript
or Table
File
table
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
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.
Visione d’insieme
Kernel
Switcher
Ready queue
System calls
Interrupt Handlers
i-node table
File table
Process Table
I/O drivers
Buffer pool
U-Area
Stack
U-Area
File descriptor table
Stack
Stack
...
Dati
Dati
Dati
Testo
Testo
Testo
Processo 1
Processo 2
Processo n
Introduzione al linguaggio Java 6
2. Redirezione dell’input/output
La system call dup
File
Descript
or Table
File
table
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
in-core
i-node
table
dup: esempio
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
File descriptor
table
dup (5)
File table
in-core i-node
table
dup: esempio
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
File descriptor
table
dup (5)
File table
in-core i-node
table
Standard files
0
stdin
stdout
stderr
0
0
1
1
2
2
3
3
3
4
4
4
5
5
5
6
6
6
1
2
File Descriptor
Table
File Table
in-core i-node
table
Redirezione dell’input
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
File descriptor
table
close (0)
File table
in-core i-node
table
Redirezione dell’input
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
File descriptor
table
close (0)
File table
dup (5)
in-core i-node
table
Redirezione dell’input
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
File descriptor
table
close (0)
File table
dup (5)
in-core i-node
table
close (5)
Redirezione dell’input
0
0
0
1
1
1
2
2
2
3
3
3
4
4
4
5
5
5
6
6
6
File descriptor
table
close (0)
File table
dup (5)
in-core i-node
table
close (5)
Struttura generale della shell
$file args<>
<output>
$
write (1, PROMPT);
while ((n=read(0,buffer,80)=!0) {
riconosci nome file e args;
FIGLIO
If ( (pid=fork()) ==0) { /* I/O redirection */
if (exec(file, args)==-1) exit (1) }
procid=wait(status);
PADRE
If (status !=0) write (2, error);
write(1,PROMPT)
}
Se il comando è eseguito in background, non viene
eseguita la wait
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 funzionano
Per eseguire AB 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
B
"pipe"
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 nome
create da mknod (devono essere aperte
con open)
• Pipe senza nome
create 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
File table
I-node table
0
1
2
.....
n
.....
1
read
1
write
2
m
.....
fd_pipe
pipe
(
n
m
0
1
)
read e write offset
(stanno qui e non
nella file table, perché
devono essere visti da
entrambi i processi)
Pipe: uso tipico
padre
pipe (fd);
fork ( );
figlio
eredita i file aperti,
e quindi anche le pipe
pipe
write (fd[1],...);
read (fd[0],...);
pipe
read (fd[0],...);
write (fd[1],...);
in alternativa
u-area
padre
0
0
1
1
2
2
3
4
....
dati/stack
figlio
strutture dati
che
rappresentano
la pipe
3
4
....
fd 3 4
fd 3 4
0 1
0 1
pipe (fd);
fork ( );
close (fd[0]);
write (fd[1],...);
close (fd[1]);
read (fd[0],...);
Realizzazione di una pipeline
shell
produttore
$cmd1  cmd2
fork ( )
(wait or proceed)
pipe (fd);
fork ( );
consumatore
close (1);
dup (fd[1]);
close (fd[0]);
close (fd[1]);
close (0);
dup (fd[0]);
close (fd[0]);
close (fd[1]);
exec (cmd1,...);
exec (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
Visione d’insieme
Kernel
Switcher
Ready queue
Process Table
System calls
Mount
Table
Interrupt Handlers
I/O drivers
i-node table
File table
Buffer pool
U-Area
Stack
U-Area
Stack
Stack
...
Dati
Dati
Dati
Testo
Testo
Testo
Processo 1
Processo 2
Processo n
Introduzione al linguaggio Java 6
Scarica

PPT 302 Kb