Vous êtes sur la page 1sur 90

Universit Pierre et Marie Curie

Master dInformatique

M1 - Noyau
Unix Mcanismes Internes

Sept. 2013 Equipe pdagogique : ARANTES Luciana (Luciana.Arantes@lip6.fr) SENS Pierre (Pierre.Sens@lip6.fr) SOPENA Julien (Julien.Sopena@lip6.fr) THOMAS Gal (Gael.Thomas@lip6.fr)

Table des matires


TD 1 : Du saut la commutation . . . . . . . . . . . . . . . . . . . . . TD 2 : Introduction au noyau Unix . . . . . . . . . . . . . . . . . . . . TD 3 : La synchronisation des processus . . . . . . . . . . . . . . . . . Fichier slp.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 4 : Les signaux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fichier sig.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 5 : La gestion du temps et lordonnancement des processus . . . . Fichier clock2.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 6 : Commutation de processus . . . . . . . . . . . . . . . . . . . . Fichier swtch.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 7 : Cration et terminaison de processus . . . . . . . . . . . . . . . Fichier fork.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fichier exit.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 8 : Le buer cache . . . . . . . . . . . . . . . . . . . . . . . . . . . Fichier bio2.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 9 : Rpresantation Interne des Fichiers . . . . . . . . . . . . . . . Fichier iget.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fichier namei.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TD 10 : Structure des chiers Traduction dadresse / Gestion de lespace libre sur disque . . . . Fichier subr.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fichier alloc.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . TME 1 :Construction dun ordonnanceur dans lespace utilisateur . . . TME 2 :Implementation et utilisation de primitives de synchronisation TME 3 :Implementation du mcanisme de timeout . . . . . . . . . . . TME 4 :Implementation des fonctions du Buer Cache . . . . . . . . . Annexes : Fichier buf.h . Fichier callo.h . Fichier conf.h . Fichier fblk.h . Fichier lsys.h Fichier inode.h Fichier mount.h Fichier param.h Fichier proc.h . Fichier signal.h Fichier text.h . Fichier tty.h . . Fichier types.h Fichier user.h . Fichier var.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 5 7 9 11 13 16 17 21 23 25 26 29 30 31 38 40 43 47 49 52 55 59 65 67 69 70 72 73 74 75 76 77 78 79 81 82 83 84 85 87

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

. . . . . . . . . . . . . . .

TD 1

TD 1

TD 1 - Du saut la commutation

Vous allez tudier le code dun Unix version 6 7 pendant le module Noyau. Vous pouvez trouver les sources qui nont pas t reportes dans ce fascicule aux URL suivantes : La version 6 en pdf : v6.cuzuco.com/v6.pdf ; La version 6 interactive : http ://unix-tree.huihoo.org/V6/usr/sys/ken/index.html ; La version 7 interactive : http ://unix-tree.huihoo.org/V7/usr/sys/sys/index.html.

But
Ce TD a pour but de vous introduire la notion de commutation.

Prrequis
Vous devez tre familiaris avec la programmation en C.

Question 1
Que sont les segments de donnes, de code et de pile ? Comment le CPU y accde ? Dcrivez dans le petit programme suivant ltat de la mmoire au point indiqu. int x = 37; void f() { int i = 17; printf("Hello: %d\n", i); i = 45; // point dexcution } void main() { f(); }

Question 2
Les fonctions setjmp et longjmp sauvegardent leur environement dans une structure opaque jmp_buf. Lenvironment est constitu des registres. Setjmp sauvegarde lenvironnement et renvoie 0. Lors

TD 1

TD 1

du longjmp, lexcution reprend au point du setjmp avec un code de retour gal au second paramtre du longjmp.

int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val);

Que fait le code suivant ? A quel mcanisme ce code vous fait-il penser ?

jmp_buf buf; void f() { if(write(...) == -1) longjmp(buf, 1); } void g() { if(setjmp(buf) == 0) // on vient de sauvegarder lenvironment f(); else // retour = 1 => on vient du longjmp perror("Erreur"); }

Question 3
Que fait le programme suivant ? Droulez lexcution sur 5 secondes. Quest ce que ce programme va acher ?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

jmp_buf buff, bufg; void f() { int n = 0; while(1) { printf("Execute f: %d\n", n++); sleep(1); if(setjmp(buff) == 0) longjmp(bufg, 1); } } void g() { int m = 1000; while(1) { printf("Execute g: %d\n", m++); sleep(1); if(setjmp(bufg) == 0) longjmp(buff, 1); } } void main() { if(setjmp(bufg) == 0) f();

TD 1

TD 1

23 24 25

else g(); }

Question 4
Modier le programme pour prserver la pile chaque commutation.

Bref rappel sur les signaux

Question 5
Ecrivez un programme qui ache la chane de caractre "Bonjour" toutes les secondes. Pour raliser ce programme, vous utiliserez la fonction int alarm(int nb_sec) qui envoie un signal SIGALRM toutes les nb_sec secondes au processus. On vous rappel quun signal est un message envoy par un processus ou par le noyau un processus. Un processus enregistre des comportements associs au signal : le comportement ignorer le signal (SIG_IGN), le comportement excuter le comportement par dfaut (SIG_DFL) qui est bien souvent darreter le processus ou un comportement personnalis. Dans ce cas, il sagit dune fonction du processus. Un comportement personnalis est souvent appel gestionnaire ou handler en anglais. Pour associer un gestionnaire un signal, on peut utiliser la fonction C signal(int no, void (*handler)(int)). Elle associe la fonction handler au signal no. Vous verrez de faon beaucoup plus appronfondie les signaux dans le module POSIX et dans le suite de ce module.

TD 2

TD 2

TD 2 - Introduction au noyau Unix

But
Le but de ce TD est dintroduire les principaux concepts du code systme et son application dans les systmes Unix version 6 et version 7. Ceux-ci tournaient sur des machines appeles des PDP-11 qui taient parmi les premires machines fournir une visualisation de la mmoire. Ce TD prsente aussi les principales structures de donnes utilises par le noyau, structures que nous utiliserons au cours des TD ultrieurs.

Prrequis
Vous devez avoir une bonne pratique du systme Unix, tant du point de vue utilisation des commandes du shell que du point de vue programmation en langage C.

Question 1
Quelles sont les dirences entre excution en mode usager et en mode systme ? Pourquoi y-a-t-il ces dirences ? Comment le mode dexcution est-il gr par le PDP-11 ?

Question 2
Rappelez ce quest ce quun appel systme.

Question 3
Rappelez ce quest une interruption matriel.

Question 4
Justiez la prsence dune pile dexcution pour lusager et dune pile pour le systme.

Question 5
Etudiez la structure user et la structure proc. Expliquez pourquoi le descripteur de processus est dcompos en deux structures.

Question 6
Quest ce quest la zone U ?

TD 2

TD 2

Question 7
Expliquez la prsence dun numro didentit (pid) pour chaque processus. Comment est-il attribu ?

Question 8
Quest-ce que le BIOS ? Comment se passe linitialisation du systme au dmarrage de lordinateur ?

TD 3

TD 3

TD 3 - La synchronisation des processus

But
Le but de ce TD est de comprendre limplmentation des fonctions de synchronisation sleep et wakeup et des fonctions de masquage des interruptions spl et gpl.

Prrequis
Vous devez connatre la dirence entre mode utilisateur et mode systme et tre famillariss avec la table des processus.

Question 1
Rappelez le rle des fonctions sleep et wakeup.

Question 2
En utilisant les fonctions sleep et wakeup vues en cours, essayez de programmer une fonction flock qui verrouille un chier en lecture/criture (donc permet un accs exclusif au chier). Si le chier est dj verrouill, la fonction devra mettre le processus demandeur en attente. crire une fonction frelease qui libre le verrou, et rveille les ventuels processus qui attendraient de verrouiller ce chier. On utilisera le champ i_flag de linode correspondant au chier, en particulier les valeurs ILOCK et IWANT. On sendormira sur ladresse de linode, avec le paramtre PINOD. Dans frelease, on rveillera tous les processus endormis sur linode (i_flag aura alors le bit IWANT positionn 1). Que se passe-t-il si un processus ouvre le chier et y accde sans avoir pralablement appel flock ? Pensez-vous que ce soit un rel problme ?

Question 3
Quelle sont les oprations eectues par les fonctions spl et gpl ? Quel en est leet ? En quelles circonstances faut-il utiliser en plus spl ? Donnez des exemples.

TD 3

TD 3

Question 4
Lorsque vous appelez sleep, quand seectue la commutation de processus ? Mme question lorsque vous appelez wakeup. Dans quelles autres circonstances intervient la commutation de processus ? Quel est le rle de la variable runrun ?

Question 5
Quest-ce que le swapper ? Quel est le rle des variables runin et runout.

Question 6
Que signie largument pri de sleep ? Quand joue-t-il ?

Question 7
Dcrivez lalgorithme des fonctions sleep et wakeup.

TD 3

Fichier slp.c

Fichier slp.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

#include #include #include #include

"../ "../ "../ "../

s y s /param . h" s y s / t y p e s . h" s y s / u s e r . h" s y s / p r o c . h"

char

runin , runout , runrun ;

/ Give up t h e p r o c e s s o r t i l l a wakeup o c c u r s on chan , a t which time t h e p r o c e s s e n t e r s t h e s c h e d u l i n g queue a t p r i o r i t y p r i . The most i m p o r t a n t e f f e c t o f p r i i s t h a t when p r i <=PZERO a s i g n a l cannot d i s t u r b t h e s l e e p ; i f p r i >PZERO s i g n a l s w i l l be p r o c e s s e d . C a l l e r s o f t h i s r o u t i n e must be p r e p a r e d f o r premature r e t u r n , and c h e c k t h a t t h e r e a s o n f o r s l e e p i n g has gone away . /

s l e e p ( chan , p r i ) caddr_t chan ; { r e g i s t e r struct p r o c rp = u . u_procp ; r e g i s t e r s , op ;

i f ( p r i > PZERO) { if ( issig ()) goto p s i g ; s p l (CLINHB ) ; rp >p_wchan = chan ; rp >p_stat = SSLEEP ; rp >p_pri = p r i ; s p l (NORMAL) ; i f ( r u n i n != 0 ) { runin = 0; wakeup(& r u n i n ) ; } swtch ( ) ; if ( issig ()) goto p s i g ; } else { s p l (CLINHB ) ; rp >p_wchan = chan ; rp >p_stat = SSLEEP ; rp >p_pri = p r i ; s p l (NORMAL) ; swtch ( ) ; } return ;

Fichier slp.c

TD 3

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

/ I f p r i o r i t y was low (>PZERO) and t h e r e has been a s i g n a l , e x e c u t e non l o c a l g o t o t o the qsav l o c a t i o n . / psig : a r e t u ( u . u_qsav ) ; }

/ Wake up a l l p r o c e s s e s s l e e p i n g on chan . / wakeup ( chan ) r e g i s t e r caddr_t chan ; { r e g i s t e r struct p r o c p ; register c , i ;

c = chan ; p = &p r o c [ 0 ] ; i = NPROC; do { i f ( p>p_wchan == c ) { setrun (p ) ; } p++; } while ( i ) ; }

/ S e t t h e p r o c e s s running ; a r r a n g e f o r i t t o be swapped i n i f n e c e s s a r y . / setrun (p) r e g i s t e r struct p r o c p ; { p>p_wchan = 0 ; p>p_stat = SRUN; i f ( p>p_pri < u . u_procp>p_pri ) runrun++; i f ( runout != 0 && ( p>p_flag&SLOAD) == 0 ) { runout = 0 ; wakeup(& runout ) ; } }

TD 4

TD 4

TD 4 - Les signaux

But
Le but de ce TD est de comprendre limplmentation des signaux. Limplmentation tudie ne prend pas en compte la gestion des signaux suivant la norme POSIX, en particulier, les signaux ne peuvent pas tre masqus. De plus, la version tudie ne propose pas le signal SIGCHILD.

Prrequis
Vous devez avoir utilis les primitives systme kill et signal. Vous devez en outre avoir compris les mcanismes de synchronisation base de sleep et wakeup.

Question 1
Quelle est la dirence entre un signal ignor et un signal masqu ?

Question 2
Quels sont les rles des variables p->p_sig et u.u_signal ? Pourquoi quelle raison u.u_signal est dans la zone swappable ?

Question matrielles ? 3 Question 4

Quelles sont les dirences et similitudes entre les signaux sous Unix et les interruptions

Quels sont les rles des fonctions kill, psignal, issig, psig, fsig, sendsig et ssig ?

Question 5
Rappelez les oprations bit--bit en C. Que fait la fonction fsig (lignes 170-186) ?

Question 6
Expliquez comment se droule lmission dun signal avec psignal. Expliquez ce qui se passe lorsque le processus rcepteur est en attente dune ressource systme ?

TD 4

TD 4

Question 7
Expliquez quand et comment se droule la rception dun signal. Que se passe-t-il en cas de rception de plusieurs signaux ? Comment est ralis lappel de la fonction (handler) spcie par lutilisateur ?

Question 8
Expliquez le code de sendsig().

TD 4

Fichier sig.c

Fichier sig.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ s i g n a l system c a l l / ssig () { register a ; a = u . u_arg [ 0 ] ; i f ( a<=0 | | a>=NSIG | | a ==SIGKIL ) { u . u_error = EINVAL ; return ; } u . u_ar0 [ R0 ] = u . u _ s i g n a l [ a ] ; u . u _ s i g n a l [ a ] = u . u_arg [ 1 ] ; u . u_procp>p_sig &= ~(1<<(a 1 ) ) ; } / k i l l system c a l l / k i l l () { r e g i s t e r struct p r o c p , q ; register a ; int f ; f = 0; a = u . u_arg [ 1 ] ; q = u . u_procp ; f o r ( p = &p r o c [ 0 ] ; p < &p r o c [NPROC ] ; p++) { i f ( p>p_stat == NULL) continue ; i f ( a != 0 && p>p_pid != a ) continue ; i f ( a == 0 && ( p>p_ttyp != q>p_ttyp | | p <= &p r o c [ 1 ] ) ) continue ; i f ( u . u_uid != 0 && u . u_uid != p>p_uid ) continue ; f ++; p s i g n a l ( p , u . u_arg [ 0 ] ) ; } i f ( f == 0 ) u . u_error = ESRCH; } / Send t h e s p e c i f i e d s i g n a l t o the s p e c i f i e d process . / psignal (p , sig ) r e g i s t e r struct p r o c p ; register s i g ; {

Fichier sig.c

TD 4

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

i f ( ( unsigned ) s i g >= NSIG) return ; if ( sig ) p>p_sig |= 1<<( s i g 1); i f ( p>p_stat == SSLEEP && p>p_pri > PZERO) setrun (p ) ; } / Returns t r u e i f t h e c u r r e n t p r o c e s s has a s i g n a l t o p r o c e s s . This i s a s k e d a t l e a s t once each time a p r o c e s s e n t e r s t h e system . A s i g n a l d o e s not do a n y t h i n g d i r e c t l y to a process ; i t s e t s a f l a g that asks the process to do s o m e t h i n g t o i t s e l f . / i s s i g () { register n ; r e g i s t e r struct p r o c p ; p = u . u_procp ; while ( p>p_sig ) { n = f s i g (p ) ; i f ( ( u . u _ s i g n a l [ n ]&1) == 0 ) return ( n ) ; p>p_sig &= ~(1<<(n 1 ) ) ; } return ( 0 ) ; } / Perform t h e a c t i o n s p e c i f i e d by the current signal . The u s u a l s e q u e n c e i s : i f ( issig ()) psig (); / psig () { register n , p ; r e g i s t e r struct p r o c rp ; rp = u . u_procp ; n = f s i g ( rp ) ; i f ( n==0) return ; rp >p_sig &= ~(1<<(n 1 ) ) ; i f ( ( p=u . u _ s i g n a l [ n ] ) != 0 ) { u . u_error = 0 ; u . u_signal [ n ] = 0 ; sendsig (p , n ) ; return ; } switch ( n ) {

TD 4

Fichier sig.c

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155

case case case case case case case case case

SIGQUIT : SIGINS : SIGTRC : SIGIOT : SIGEMT : SIGFPT : SIGBUS : SIGSEG : SIGSYS : i f ( core ()) n += 0 2 0 0 ;

} exit (n ) ; } / f i n d t h e s i g n a l i n b i t p o s i t i o n r e p r e s e n t a t i o n i n p_sig . / f s i g (p) struct p r o c p ; { register n , i ; n = p>p_sig ; f o r ( i =1; i <NSIG ; i ++) { i f (n & 1) return ( i ) ; n >>= 1 ; } return ( 0 ) ; } / a d a p t e d from t h e v e r s i o n 6 / s e n d s i g ( void h a n d l e r , int num) { sp = u . u_ar0 [ SP ] 2 ; grow ( n ) ; u . u_ar0 [ SP ] = sp ; suword ( sp , u . u_ar0 [PC ] ) ; / sp [ 0 ] = PC u . u_ar0 [PC] = h a n d l e r ; }

TD 5

TD 5

TD 5 - La gestion du temps et lordonnancement des processus

Le but de ce TD est de comprendre limplmentation des fonctions de gestion du temps dans un systme comme Unixet dtudier un exemple de routine de traitement dinterruptions.

Prrequis
Vous devez avoir manipul les primitives de gestion de lhorloge et dordonnancement des processus.

Question 1
Rcapitulez les direntes notions du temps prsentes dans le systme.

Question 2
Que sont les timeouts ? A quoi servent-ils ? Quelle est la structure de donnes utilise pour implmenter ces timeouts ?

Question 3
Dcrivez lalgorithme de la routine timeout. Expliquez brivement comment fonctionne delay.

Question 4
Expliquez la structure de la routine dinterruption horloge et lenchanement des diverses fonctions. Dcrivez lalgorithme de la fonction clock et le fonction realtime.

Question 5
Programmez la fonction restart. Elle doit appeler les fonctions dont les timeouts sont arrivs expiration. Aprs cela, elle doit dcaler les entres corrrespondantes au timeouts en cours vers le dbut du vecteur de callout.

Question 6
Expliquez lalgorithme de la fontion setpri. Quand est-ce que cette fonction est appele ?

TD 5

Fichier clock2.c

Fichier clock2.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

#include #include #include #include #include

"../ "../ "../ "../ "../

s y s /param . h" s y s / c o n f . h" s y s / p r o c . h" s y s / u s e r . h" s y s / var . h"

/ c l o c k i s c a l l e d s t r a i g h t from r e a l time c l o c k i n t e r r u p t . Functions : implement c a l l o u t s maintain u s e r / system t i m e s p r o f i l e u s e r pro c s and k e r n e l l i g h t n i n g b o l t wakeup . /

clock () { extern int i a f l a g s , i d l e f l a g ; r e g i s t e r struct c a l l o p1 ; r e g i s t e r int pc ; i f ( v . v e _ c a l l o u t [ 0 ] . c_func != 0 ) { p1 = &v . v e _ c a l l o u t [ 0 ] ; while ( p1>c_time<=0 && p1>c_func !=0) p1++; p1>c_time ; } if (! idleflag ) { i f ( u . u_procp>p_cpu < 8 0 ) u . u_procp>p_cpu++; }

i f ( user_mode ( ) ) { u . u_utime++; } else { if (! idleflag ) u . u_stime++; }

i f ( ( v . v e _ c a l l o u t [ 0 ] . c_func !=0 && v . v e _ c a l l o u t [ 0 ] . c_time<=0) ) i a f l a g s |= CALOUT; i f (++ l b o l t >= HZ) i a f l a g s |= WAKEUP; }

realtime () { r e g i s t e r struct p r o c pp ;

Fichier clock2.c

TD 5

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

l b o l t = HZ ; time++;

/ f o r c e a s w i t c h e v e r y second / runrun++; wakeup(& l b o l t ) ; f o r ( pp = &v . ve_proc [ 0 ] ; pp < proc_end ; pp++) i f ( pp>p_stat ) { i f ( pp>p_time <= 1 2 7 ) pp>p_time++;

i f ( pp>p_clktim ) i f (pp>p_clktim == 0 ) p s i g n a l ( pp , SIGCLK ) ; / Update CPU Usage i n f o : / pp>p_cpu >>= 1 ; i f ( pp>p_pri >= (PUSER NZERO) ) s e t p r i ( pp ) ;

} i f ( r u n i n != 0 ) { runin = 0; wakeup ( ( caddr_t)& r u n i n ) ; } }

/ timeout i s c a l l e d to arrange t h a t fun ( a r g ) i s c a l l e d i n tim /HZ s e c o n d s . An e n t r y i s s o r t e d i n t o t h e v . v e _ c a l l o u t s t r u c t u r e . The time i n each s t r u c t u r e e n t r y i s t h e number o f HZ s more than t h e p r e v i o u s e n t r y . i n t h i s way , d e c r e m e n t i n g t h e f i r s t e n t r y has t h e e f f e c t o f updating a l l e n t r i e s . / t i m e o u t ( fun , arg , tim ) int ( fun ) ( ) ; caddr_t a r g ; int tim ; { r e g i s t e r struct c a l l o p1 , p2 ; int ps ; r e g i s t e r int t ;

t = tim ;

TD 5

Fichier clock2.c

114 p1 = &v . v e _ c a l l o u t [ 0 ] ; 115 ps = g p l ( ) ; 116 s p l (CLINHB ) ; 117 while ( p1>c_func != 0 && p1>c_time <= t ) { 118 t = p1>c_time ; 119 p1++; 120 } 121 p1>c_time = t ; 122 p2 = p1 ; 123 while ( p2>c_func != 0 ) 124 p2++; 125 i f ( p2 == &v . v e _ c a l l o u t [ v . v _ c a l l o u t 2]) { 126 s p l ( ps ) ; 127 p a n i c ( "no c a l l o u t s p a c e " ) ; 128 } 129 while ( p2 >= p1 ) { 130 ( p2+1)>c_time = p2>c_time ; 131 ( p2+1)>c_func = p2>c_func ; 132 ( p2+1)>c_arg = p2>c_arg ; 133 p2 ; 134 } 135 p1>c_time = t ; 136 p1>c_func = fun ; 137 p1>c_arg = a r g ; 138 s p l ( ps ) ; 139 } 140 141 142 r e s t a r t ( ) 143 { 144 struct c a l l o p1 ; 145 struct c a l l o p2 ; 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 } 164 165 166 #define PDELAY (PZERO 1) 167 d e l a y ( t i c k s ) 168 { 169 extern wakeup ( ) ; 170 171 172 i f ( t i c k s <=0)

Fichier clock2.c

TD 5

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196

return ; t i m e o u t ( wakeup , ( caddr_t ) u . u_procp +1, t i c k s ) ; s l e e p ( ( caddr_t ) u . u_procp +1, PDELAY) ; } / Set user p r i o r i t y . The r e s c h e d u l i n g f l a g ( runrun ) is set i f the p r i o r i t y i s higher than t h e c u r r e n t l y running p r o c e s s . / s e t p r i ( up ) { r e g i s t e r pp , p ; pp = up ; p = ( pp>p_cpu & 0 3 7 7 ) / 1 6 ; p =+ PUSER + pp>p_nice ; i f (p > 127) p = 127; i f ( p > u . u_procp>p_pri ) runrun++; pp>p_pri = p ; }

TD 6

TD 6

TD 6 - Commutation de processus

But
Le but de ce TD est de comprendre comment le noyau gre la commutation de processus, les appels systmes et les interruptions.

Prrequis
Vous devez connatre la dirence entre mode utilisateur et mode systme, tre familiariss avec la table des processus et connatre le rle des variables runrun, runin et runout.

Commutation

Question 1
En sachant que le PDP-11 gre une mmoire segmente et en vous aidant des gures 1 et gures 2, expliquez comment le PDP-11 gre la mmoire.

Question 2
Quels sont les segments dun processus ? Quels sont les segments du noyau ? Comment est organise physiquement la mmoire associe ?

Question 3
Comment le noyau commute ?

Question 4
Expliquez lalgorithme de la fonction swtch de commutation dans le noyau.

Entre et sortie du systme

TD 6

TD 6

15

13

Processor Status Word

Mode
Mode S 256k 64k Mode U

64k

0k

Espace dadressage virtuel noyau

Table des segments noyau

0k

Mmoire Physique

Table des segments user

Espace dadressage virtuel user

0k

Figure 1 Tables des segmentation. Les zones grises ne sont pas mappes ou alloues.
Adresse virtuelle No. Seg.
15 13 12

No de bloc
6

Dplacement
5 0

28

Registre de segment Dbut (en bloc de 64 octets)

16

Taille (en bloc de 64 octets)


14 17 8

6 5

Dbut + No de bloc Adresse Physique

Dplacement

Figure 2 Rsolution dune adresse virtuelle.

Question 5
Que sont une trap, une exception et une interruption ? Dcrivez la table des interruptions.

Question 6
Expliquez les actions eectues lors dun appel systme.

Question 7
Expliquez les actions eectues lors dune interruption.

TD 6

Fichier swtch.c

Fichier swtch.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ This r o u t i n e i s c a l l e d t o r e s c h e d u l e t h e CPU. i f t h e c a l l i n g p r o c e s s i s not i n RUN s t a t e , arrangements f o r i t t o r e s t a r t must have been made e l s e w h e r e , u s u a l l y by c a l l i n g v i a s l e e p . / swtch ( ) { s t a t i c struct p r o c p ; register i , n ; r e g i s t e r struct p r o c rp ; i f ( p == NULL) p = &p r o c [ 0 ] ; / Remember s t a c k o f c a l l e r / savu ( u . u_rsav ) ; / Switch to scheduler s stack / r e t u ( p r o c [ 0 ] . p_addr ) ; loop : runrun = 0 ; rp = p ; p = NULL; n = 128; / Search f o r h i g h e s t p r i o r i t y r u n n a b l e p r o c e s s / i = NPROC; do { rp++; i f ( rp >= &p r o c [NPROC] ) rp = &p r o c [ 0 ] ; i f ( rp >p_stat==SRUN && ( rp >p_flag&SLOAD) ! = 0 ) { i f ( rp >p_pri < n ) { p = rp ; n = rp >p_pri ; } } } while ( i ) ; / I f no p r o c e s s i s r u n n a b l e , i d l e . / i f ( p == NULL) { p = rp ; idle (); goto l o o p ; } rp = p ; / S w i t c h t o s t a c k o f t h e new p r o c e s s and s e t up

Fichier swtch.c

TD 6

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78

his segmentation r e g i s t e r s . / r e t u ( rp >p_addr ) ; sureg ( ) ; / I f t h e new p r o c e s s paused b e c a u s e i t was swapped out , s e t t h e s t a c k l e v e l t o t h e l a s t c a l l t o savu ( u_ssav ) . This means t h a t t h e r e t u r n which i s e x e c u t e d i m m e d i a t e l y a f t e r t h e c a l l t o a r e t u a c t u a l l y r e t u r n s from t h e l a s t r o u t i n e which d i d t h e savu . You a r e not e x p e c t e d t o u n d e r s t a n d t h i s . / i f ( rp >p_flag&SSWAP) { rp >p_flag =& ~SSWAP; a r e t u ( u . u_ssav ) ; } / The v a l u e r e t u r n e d h e r e has many s u b t l e i m p l i c a t i o n s . See t h e newproc comments . / return ( 1 ) ; }

TD 7

TD 7

TD 7 - Cration et terminaison de processus

Cration de processus - fork


Lappel systme fork appele la fonction newproc pour crer un process ls.

Question 1
En analysant le code de newproc : Quelles sont les resources (structures) qui seront partages par le pre et le ls ? Quels compteurs de rfrence seront alors modis ? Comment le manque de mmoire est-il gr ?

Question 2
Donnez lalgorithme de fork et newproc.

Terminaison de processus - exit

Question 3
Quest ce quun processus zombi ? Quand un processus nest plus zombi ?

Question 4
Donnez lalgorithme du code d exit. Quelle est la signication (lutilit) du wakeup de la lignes 35 ?

Question 5
Les primitives exit et wait sont trs lies. Donnez le code interne de la primitive wait() (sans prendre en compte les statistiques dutilisation) en vous inspirant du code de exit.

Fichier fork.c

TD 7

Fichier fork.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

fork () { r e g i s t e r p r o c p1 ; p2 ; p1 = u . u_procp ; f o r ( p2 = &p r o c [ 0 ] ; p2 < &p r o c [NPROC} ; p2++) i f ( p2>p_stat == NULL) goto found ; u_u_error = EAGAIN; goto out ; found : i f ( newproc ( ) ) { u . u_ar0 [ R0 ] = 0 ; u . u_cstime [ 0 ] = u . u_cstime [ 1 ] = u . u_stime = 0 ; u . u_cutime [ 0 ] = u . u_cutime [ 1 ] = u . u_utime = 0 ; return ; }

0; 0; 0; 0;

u . u_aro [ R0 ] = p2>p_pid ; out : u . u_ar0 [ R7 ] = +2; }

/ C r e a te a new p r o c e s s ( t h e i n t e r n a l v e r s i o n o f f o r k ) The new p r o c e s s r e t u r n s 1 i n t h e new p r o c e s s . The e s s e n t i a l f a c t i s t h a t t h e new p r o c e s s i s c r e a t e d i n such a way t h a t i t a p p e a r s t o have s t a r t e d e x e c u t i n g i n t h e same c a l l t o newproc as t h e p a r e n t , b u t i n f a c t t h e code runs i s t h a t o f s w i t c h . The s u b t l e i m p l i c a t i o n o f t h e r e t u r n e d v a l u e o f s w i t c h i s t h a t t h i s i s t h e v a l u e t h a t newproc s c a l l e r i n t h e new p r o c e s s s e e s . / newproc ( ) int a1 , a2 ; struct p r o c p , up ; r e g i s t e r struct p r o c rpp ; register rip , n ; { p = NULL; / F i r s t , j u s t l o c a t e a s l o t f o r a p r o c e s s and copy t h e u s e f u l i n f o from t h i s p r o c e s s i n t i t . The p a n i c cannot happen b e c a u s e f o r k has a l r e a d y c h e c k e d f o r t h e e x i s t a n c e o f a s l o t . / retry : mpid++; i f ( mpid < 0 ) {

TD 7

Fichier fork.c

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

mpid =0; goto r e t r y ; } f o r ( rpp = &p r o c [ 0 ] ; rpp < &p r o c [NPROC ] ; rpp++) { i f ( rpp >p_stat == NULL && p== NULL) p = rpp ; i f ( rpp>p_pid == mpid ) goto r e t r y ; } i f ( ( rpp = p)== NULL ) p a n i c ( "no p r o c s " ) ; / make proc e n t r y f o r new pr oc / r i p = u . u_proc ; up =r i p ; rpp>p_stat = SRUN; rpp>p_flag = SLOAD; rpp>p_uid = r i p >p_uid ; rpp>p_ttyp = r i p >p_ttyp ; rpp>p_nice= r i p >p_nice ; rpp>p_textp = r i p >p_textp ; rpp>p_pid = mpid ; rpp>p_ppid = r i p >p_pid ; rpp >p_time = 0 ; / make d u p l i c a t e e n t r i e s where needed / f o r ( r i p = &u . u _ o f i l e [ 0 ] ; r i p < i f ( ( rpp = r i p ++) !=NULL) rpp>f_count ++; &u . u _ o f i l e [ NOFILE ] ; )

i f ( ( rpp = up>p_textp ) != NULL) { rpp >x_count++; rpp >x_ccount ++; } u . u_cdir >i_count++; / P a r t i a l l y s i m u l a t e t h e environment o f t h e new p r o c e s s so t h a t when i t i s a c t a u l l y c r e a t e d ( by c o p y i n g ) i t w i l l l o o k r i g h t / savu ( u . u_rsav ) ; rpp =p ; u . u_procp = rpp ; r i p = up ; n = r i p > p _ s i z e ; a1 = r i p >p_addr ; rpp > p _ s i z e =n ; a2 =m a l l o c ( coremap , n ) ; / i f t h e r e i s not enough memory f o r t h e new p r o c e s s , swap ou t h e c u r r e n t p r o c e s s t o g e n e r a t e t h e copy / i f ( a2 == NULL) { r i p >p_stat = SIDL ; rpp > p_addr = a1 ;

Fichier fork.c

TD 7

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

savu ( u . u_ssav ) ; xswap ( rpp , 0 , 0 ) ; rpp > p_flag = SSWAP; r i p > p_stat = SRUN; } else { / t h e r e i s memory , so j u s t copy / rpp > p_addr = a2 ; while ( n) c o p y s e g ( a1++, a2 ++); } u . u_procp = r i p ; return ( 0 ) ; }

TD 7

Fichier exit.c

Fichier exit.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

exit () { r e g i s t e r int a , b ; r e g i s t e r struct p r o c p ; u . u_procp>p _ f l a g s &= ~STRC; f o r ( a = &u . u _ s i g n a l [ 0 ] ; a < &u . u _ s i g n a l [ NSIG ] ; ) a++ = 1 ; f o r ( a = &u . u _ o f i l e [ 0 ] ; a < &u . u _ o f i l e [ NOFILE ] ; a++) i f (b = a ) { a = NULL; c l o s e f (b ) ; }

i p u t ( u . u_cdir ) ;

b = m a l l o c ( swapmap , 1 ) ; i f ( b == NULL) p a n i c ( " out o f swap" ) ; p = g e t b l k ( swapdev , b ) ; bcopy(&u , p>b_addr , 2 5 6 ) ; bwrite (p ) ;

a = u . u_procp ; mfree ( coremap , a>p s i z e , a>p_addr ) ; a>p_stat = SZOMB; loop : f o r ( p = &p r o c [ 0 ] ; p < &p r o c [NPROC ] ; p++) i f ( a>p_ppid == p>p_pid ) { wakeup ( p ) ; f o r ( p = &p r o c [ 0 ] ; p < &p r o c [NPROC ] ; p++) i f ( a>p_pid == p>p_ppid ) { p>p_ppid = 1 ; i f ( p>p_stat == SSTOP) setrun (p ) ; } swtch ( ) ; / no r e t u r n / }

a>p_ppid = 1 ; goto l o o p ; }

TD 8

TD 8

TD 8 - Le buffer cache

But
Le but de ce TD est ltude du fonctionnement du buer cache et loptimisation de laccs aux blocs.

Prrequis
Vous devez avoir compris le rle de la fonction bmap et sa place dans le noyau. Vous devez en outre connatre les dirences entre drivers en mode bloc et en mode caractre.

Question 1
Quelles sont les dirences entre les caches dentres / sorties sous Unix et les caches des processeurs ?

Question 2
Quel est le rle du buer cache ? Rappelez lorganisation du buer cache. Comment les descripteurs sont-ils chans entre eux ?

Question 3
Quest-ce quun device number ? Quelle est la fonction qui traite lentre / sortie physique ?

Question 4
Que reprsentent les tats B_BUSY et B_DELWRI ? Expliquez pourquoi et quand un buer ne se trouve plus dans la liste des buers libres. Expliquez comment il y est remis. Commentez lintrt de lopration.

Question 5
Expliquez ce qui se passe lorsquun processus demande une lecture et que :

TD 8

Fichier bio2.c

1. le bloc est dj dans un buer, 2. le bloc nest pas dans un buer, et la free-list commence par un buer non modi, et 3. le bloc nest pas dans un buer, et la free-list commence par un buer modi. Expliquez les avantages et inconvnients de lutilisation du buer cache.

Question 6
Quel est le rle du ag B_WANTED ? Expliquez ce qui se passe lorsquun processus essaye de lire des donnes dans un chier alors quune entre / sortie est dj en cours sur ce mme bloc du mme chier ? Commentez lutilisation des deux routines sleep et wakeup.

Question 7 Question 8
Que signie ltat B_DONE ? Expliquez comment est eectu le contrle de la n de lentre / sortie. Dcrivez le fonctionnement de la fonction iodone().

Question 9
Dcrivez lalgorithme de getblk.

Question 10
Compltez le corps de la fonction brelse, qui libre un tampon quand le noyau a ni de lutiliser. La fonction doit rveiller les processus qui se sont endormis parce que le tampon tait occup et ceux qui se sont endormis parce quaucun tampon ne restait dans la liste de tampons libres. La fonction doit alors placer le tampon la n de la liste de tampons libres, moins quune erreur dentre-sortie ne se soit produite. Noubliez pas que la liste de blocs libres est une ressource critique et doit tre accde de faon exclusive (masquage/dmasquage dinterruption).

Question 11
Compltez le corps de la fonction bread qui eectue la lecture dun bloc disque. Cette fonction doit utiliser la fonction getblk pour rechercher le block dans le buer cache. Sil y est, le systme le lui retourne immdiatement sans le lire physiquement du disque. Sinon, bread doit appeler la fonction du priphrique disque qui lance la lecture dun bloc. Dans ce cas, la fonction devra endormir le processus qui la appele, qui sera rveill par linterruption disque. Expliquez maintenant le code de la fonction breada, qui lit deux blocs, dont le deuxime de faon asynchrone. Quel est le but dorir une telle fonction ?

Question 12
Compltez le corps de la fonction bwrite qui eectue lcriture dun bloc disque. La fonction indique au priphrique du disque quil y a un tampon dont le contenu doit tre enregistr sur le disque. Si lcriture est synchrone, le processus appelant sendort en attendant la n de lcriture. Puis il libre le bloc quand il est rveill. Si lcriture est asynchrone, la fonction lance lcriture mais nattend pas sa n. Expliquez le code de la fonction bdwrite et bawrite.

Fichier bio2.c

TD 8

Fichier bio2.c

1 #include " . . / s y s / buf . h" 2 #include " . . / s y s /param . h" 3 #include " . . / s y s / t y p e s . h" 4 5 6 / 7 The f o l l o w i n g s e v e r a l r o u t i n e s a l l o c a t e and f r e e 8 b u f f e r s w i t h v a r i o u s s i d e e f f e c t s . In g e n e r a l t h e 9 arguments t o an a l l o c a t e r o u t i n e a r e a d e v i c e and 10 a b l o c k number , and t h e v a l u e i s a p o i n t e r t o 11 t o t h e b u f f e r h e a d e r ; t h e b u f f e r i s marked " b u s y " 12 so t h a t no one e l s e can t o u c h i t . I f t h e b l o c k was 13 a l r e a d y i n core , no I /O need be done ; i f i t i s 14 a l r e a d y busy , t h e p r o c e s s w a i t s u n t i l i t becomes f r e e . 15 The f o l l o w i n g r o u t i n e s a l l o c a t e a b u f f e r : 16 getblk 17 bread 18 breada 19 E v e n t u a l l y t h e b u f f e r must be r e l e a s e d , p o s s i b l y w i t h t h e 20 s i d e e f f e c t o f w r i t i n g i t out , by u s i n g one o f 21 bwrite 22 bdwrite 23 bawrite 24 brelse 25 / 26 27 28 / 29 U n l i n k a b u f f e r from t h e a v a i l a b l e l i s t and mark i t b u s y . 30 ( internal interface ) 31 / 32 n o t a v a i l ( bp ) 33 { 34 register s ; 35 36 37 s = gpl ( ) ; 38 s p l (BDINHB ) ; 39 bp>av_back>av_forw = bp>av_forw ; 40 bp>av_forw>av_back = bp>av_back ; 41 bp>b _ f l a g s |= B_BUSY; 42 b f r e e l i s t . b_bcount ; 43 spl ( s ); 44 } 45 46 47 / 48 Read i n ( i f n e c e s s a r y ) t h e b l o c k and r e t u r n a b u f f e r p o i n t e r . 49 / 50 struct buf 51 bread ( dev , blkno ) 52 dev_t dev ; 53 daddr_t blkno ; 54 {

TD 8

Fichier bio2.c

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

r e g i s t e r struct buf bp ;

/ Read i n t h e b l o c k , l i k e bread , b u t a l s o s t a r t I /O on t h e read ahead b l o c k ( which i s not a l l o c a t e d t o t h e c a l l e r ) / struct buf breada ( dev , blkno , r a b l k n o ) dev_t dev ; daddr_t blkno , r a b l k n o ; { r e g i s t e r struct buf bp , rabp ;

bp = NULL; i f ( ! i n c o r e ( dev , blkno ) ) { bp = g e t b l k ( dev , blkno ) ; i f ( ( bp>b _ f l a g s& B_DONE) == 0 ) { bp>b _ f l a g s |= B_READ; bp>b_bcount = BSIZE ; ( bdevsw [ bmajor ( dev ) ] . d _ s t r a t e g y ) ( bp ) ; } } i f ( r a b l k n o && b f r e e l i s t . b_bcount>1 && ! i n c o r e ( dev , r a b l k n o ) ) { rabp = g e t b l k ( dev , r a b l k n o ) ; i f ( rabp >b _ f l a g s & B_DONE) b r e l s e ( rabp ) ; else { rabp >b _ f l a g s |= B_READ|B_ASYNC; rabp >b_bcount = BSIZE ; ( bdevsw [ bmajor ( dev ) ] . d _ s t r a t e g y ) ( rabp ) ; } } i f ( bp == NULL) return ( bread ( dev , blkno ) ) ; i o w a i t ( bp ) ; return ( bp ) ; }

/ Write t h e b u f f e r , w a i t i n g f o r c o m p l e t i o n . Then r e l e a s e t h e b u f f e r . / b w r i t e ( bp ) r e g i s t e r struct buf bp ; {

Fichier bio2.c

TD 8

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

register f l a g ;

/ R e l e a s e t h e b u f f e r , marking i t so t h a t i f i t i s g r a b b e d f o r a n o t h e r p u r p o s e i t w i l l be w r i t t e n o u t b e f o r e b e i n g g i v e n up ( e . g . when w r i t i n g a p a r t i a l b l o c k where i t i s assumed t h a t a n o t h e r w r i t e f o r t h e same b l o c k w i l l soon f o l l o w ) . This can t be done f o r magtape , s i n c e w r i t e s must be done i n t h e same o r d e r as r e q u e s t e d . / b d w r i t e ( bp ) r e g i s t e r struct buf bp ; { bp>b _ f l a g s |= B_DELWRI | B_DONE; bp>b _ r e s i d = 0 ; b r e l s e ( bp ) ; }

/ R e l e a s e t h e b u f f e r , s t a r t I /O on i t , b u t don t w a i t f o r c o m p l e t i o n . / b a w r i t e ( bp ) r e g i s t e r struct buf bp ; { bp>b _ f l a g s |= B_ASYNC; b w r i t e ( bp ) ; }

/ r e l e a s e t h e b u f f e r , w i t h no I /O i m p l i e d . / b r e l s e ( bp ) r e g i s t e r struct buf bp ; {

TD 8

Fichier bio2.c

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231

/ See i f t h e b l o c k ( mainly t o a v o i d / i n c o r e ( dev , blkno ) r e g i s t e r dev_t dev ; daddr_t blkno ; { r e g i s t e r struct r e g i s t e r struct

i s a s s o c i a t e d w i t h some b u f f e r g e t t i n g hung up on a w a i t i n b r e a d a )

buf bp ; buf dp ;

dp = bhash ( dev , blkno ) ; f o r ( bp=dp>b_forw ; bp != dp ; bp = bp>b_forw ) i f ( bp>b_blkno==blkno && bp>b_dev==dev ) return ( 1 ) ; return ( 0 ) ; }

/ Assign a b u f f e r f o r the given b l o c k . I f the appropriate block i s already associated , return i t ; otherwise search f o r t h e o l d e s t nonb u s y b u f f e r and r e a s s i g n i t . / struct buf g e t b l k ( dev , blkno ) r e g i s t e r dev_t dev ; daddr_t blkno ; { r e g i s t e r struct buf bp ; r e g i s t e r struct buf dp ;

loop : s p l (NORMAL) ; dp = bhash ( dev , blkno ) ; i f ( dp == NULL)

Fichier bio2.c

TD 8

232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290

p a n i c ( " devtab " ) ; f o r ( bp=dp>b_forw ; bp != dp ; bp = bp>b_forw ) { i f ( bp>b_blkno != blkno | | bp>b_dev!= dev ) continue ; s p l (BDINHB ) ; i f ( bp>b _ f l a g s&B_BUSY) { bp>b _ f l a g s |= B_WANTED; s l e e p ( ( caddr_t ) bp , PRIBIO+1); goto l o o p ; } s p l (NORMAL) ; n o t a v a i l ( bp ) ; return ( bp ) ; } s p l (BDINHB ) ; i f ( b f r e e l i s t . av_forw == & b f r e e l i s t ) { b f r e e l i s t . b _ f l a g s |= B_WANTED; s l e e p ( ( caddr_t)& b f r e e l i s t , PRIBIO+1); goto l o o p ; } s p l (NORMAL) ; bp = b f r e e l i s t . av_forw ; n o t a v a i l ( bp ) ; i f ( bp>b _ f l a g s & B_DELWRI) { bp>b _ f l a g s |= B_ASYNC; b w r i t e ( bp ) ; goto l o o p ; } bp>b _ f l a g s = B_BUSY; bp>b_back>b_forw = bp>b_forw ; bp>b_forw>b_back = bp>b_back ; bp>b_forw = dp>b_forw ; bp>b_back = dp ; dp>b_forw>b_back = bp ; dp>b_forw = bp ; bp>b_dev = dev ; bp>b_blkno = blkno ; return ( bp ) ; }

/ Wait f o r I /O c o m p l e t i o n on t h e b u f f e r ; r e t u r n e r r o r s to the user . / i o w a i t ( bp ) r e g i s t e r struct buf bp ; {

s p l (BDINHB ) ; while ( ( bp>b _ f l a g s& B_DONE)==0) s l e e p ( ( caddr_t ) bp , PRIBIO ) ; s p l (NORMAL) ; g e t e r r o r ( bp ) ; }

i o d o n e ( bp )

TD 8

Fichier bio2.c

291 292 293 294 295 296 297 298

r e g i s t e r buf bp { bp>b _ f l a g s |= B_DONE; i f ( ( bp>b _ f l a g s&B_ASYNC) ! = 0 ) b r e l s e ( bp ) ; else wakeup ( ( caddr_t ) bp ) ; }

TD 9

TD 9

TD 9 - Rpresantation Interne des Fichiers

But
Le but de ce TD est dtudier comment les chiers et rpertoires sont rpresents et acds dans le systme UNIX.

Question 1
Comment la rpresantation interne dun chier est faite dans le systme Unix ? Et celle dun rpertoire ?

Question 2
Pourquoi y-a-t-il une table des inode en mmoire ?

Question 3
Etudiez les chanages entre la table des i_node et la table des chiers. Etudiez aussi le chanage entre ces deux tables et la table de descripteurs de chier utilisateur. Expliquer le rle des champs i_count et f_count. Deux processus peuvent-ils ouvrir un mme chier ? Un mme chier peut-il avoir deux ou plusieurs noms ?

Question 4
Quelles sont les informationts quune strucutre i_node contient ?

Question 5
Dcrivez lalgorithme de la fonction iget, qui rend la rfrence un i_node dont le numro est connu.

Question 6
Dcrivez lalgorithme de la fonction iput, utilise pour librer un i_node.

TD 9

TD 9

Question 7
Comment le noyau aecte un i_node disque un chier nouvellement cr ? Comment le noyau gre les inodes libres dans le superbloc ?

Question 8
A quoi sert la fonction namei ? Donnez son pseudocode.

Fichier iget.c

TD 9

Fichier iget.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ Look up an i n o d e by d e v i c e , inumber . A pointer to a locked inode s t r u c t u r e i s returned I t d o e s not i n c l u d e t h e mounting o f volumes /

i g e t ( dev , i n o ) { r e g i s t e r struct i n o d e p ; register ip2 ; int i p 1 ;

loop : i p = NULL; f o r ( p = &i n o d e [ 0 ] ; p < &i n o d e [NINODE ] ; p++){ i f ( dev == p>i_dev && i n o == p>i_number ) { i f ( ( p>i _ f l a g & ILOCK) !=0) { p>i _ f l a g =| IWANT; s l e e p ( p , PINOD ) ; goto l o o p ; }

p>i_count++; p>i _ f l a g |= ILOCK ; return ( p ) ; } i f ( i p== NULL && p>i_count i p =p ; } i f ( ( p = i p ) == NULL) { p r i n t f ( " i n o d e t a b l e o v e r f l o w \n" ) ; u . u_error = ENFILE ; return (NULL ) ; } ==0)

p>i_dev = dev ; p>i_number = i n o ; p>i _ f l a g = ILOCK ; p>i_count ++; p>i _ l a s t r =1; i p = bread ( dev , l d i v ( i n o +31 ,16) ) ;

/ c h e c k I /O e r r o r s / i f ( ip >b _ f l a g s & B_ERROR) { brelse ( ip ) ; iput (p ) ; return (NULL ) ; }

TD 9

Fichier iget.c

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

i p 1 = ip >b_addr + 32 lrem ( i n o +31 ,16) ; i p 2 = &p>i_mode ; while ( i p 2 < &p>i_addr [ 8 ] ) i p 2++ = i p 1 ++; blrese ( ip ) ; return ( p ) ; }

/ Decrement r e f e r e n c e co un t o f an i n o d e s t r u c t u r e . On t h e l a s t r e f e r e n c e , w r i t e t h e i n o d e o u t and i f n e c e s s a r y , t r u n c a t e and d e a l l o c a t e t h e f i l e / iput (p) struct i n o d e p { r e g i s t e r rp ; rp =p ;

i f ( rp >i_count == 1 ) { rp >i _ f l a g |= ILOCK ; i f ( rp >i _ n l i n k == 0 ) { i t r u n c ( rp ) ; rp >i_mode =0; i f r e e ( rp >i_dev , rp >i_number ) ;

} i u p d a t e ( rp , time ) ; p r e l e ( rp ) ;

} rp >i_count ; }

i f r e e ( dev , i n o ) / f r e e t h e s p e c i f i e d i n o d e on t h e s p e c i f i e d d e v i c e /

i u p d a t e ( p , tm) int p , int tm ; {

/ c h e c k a c c e s s e d and u p d a t e f l a g s on an i n o d e s t r u c t u r e . I f e i t h e r i s on , u p d a t e t h e i n o d e w i t h t h e c o r r e s p o n d i n g d a t e s s e t t o t h e argument tm / }

Fichier iget.c

TD 9

114 115 116 117 118 119 120 121 122 123 124

itrunc ( ip ) int i p ; { / f r e e a l l d i s k b l o c k s a s s o c i a t e d w i t h t h e s p e c i f i e d i n o d e s t r u c t u r e . The b l o c k s o f t h e f i l e a r e removed in reverse order . / }

Pour l a f o n c t i o n p r e l e ( i p ) , v o i r l e f i c h i e r p i p e . c /

TD 9

Fichier namei.c

Fichier namei.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ c o n v e r t a pathname i n t o a p o i n t e r t o an i n o d e . Note t h a t t h e i n o d e i s l o c k e d f u n c = f u n c t i o n c a l l e d t o g e t n e x t ch ar o f name &uchar i f name i s i n u s e r s p a c e s c h a r i s name i s i n system s p a c e f l a g = 0 , i f name i s s o u g h t 1 i f name i s t o be c r e a t e d 2 i f name i s t o be d e l e t e d /

namei ( func , f l a g ) int ( f u n c ) ( ) ; { r e g i s t e r struct i n o d e dp ; register c ; r e g i s t e r char cp ; int eo , bp ;

/ i f name s t a r t s w i t h / , s t a r t from r o o t ; o t h e r w i s e s t a r t from c u r r e n t d i r ; /

dp = u . u_cdir ; i f ( ( c= ( f u n c ( ) ) == / ) dp = r o o t d i r ; i g e t ( dp>i_dev , dp>i_number ) ; while ( c == / ) c = ( func ) ( ) ; i f ( c == \0 && f l a g !=0) { u . u_error = ENOENT; goto out ; }

cloop : / Here dp c o n t a i n s p o i n t e r t o l a s t component matched /

i f ( u . u_error ) goto out ;

i f ( c == \0 ) return ( dp ) ;

/ i f t h e r e i s a n o t h e r component , dp must be a

Fichier namei.c

TD 9

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

d i r e c t o r y and must have x p e r m i s s i o n /

i f ( ( dp >i_mode & IFMT) != IFDIR ) { u . u_error = ENOTDIR; goto out ; }

i f ( a c c e s s ( dp , IEXEC ) ) goto out ;

/ g a t h e r up name i n t o u s e r s d i r b u f f e r /

cp = &u . u_dbuf [ 0 ] ; while ( c != / && c != \0 && u . u_error == 0 ) i f ( cp < &u . u_dbuf [ DIRSIZ ] ) cp++ =c ; c= ( f u n c ) ( ) ; {

while ( cp < &u . u_dbuf [ DIRSIZ ] ) cp++ = \0 ;

while ( c == / ) c= ( f u n c ) ( ) ;

i f ( u . u_error ) goto out ;

/ s e t up t o s e a r c h a d i r e c t o r y / u . u_offset [ 1 ] = 0; u . u_offset [ 0 ] = 0 ; u . u _ s e g f l g =1; eo = 0 ; u . u_count = l d i v ( dp>i _ s i z e , DIRSIZ +2 ) ; bp= NULL;

eloop : / i f a t t h e end o f t h e d i r e c t o r y , t h e s e a r c h f a i l e d . Report what i s a p p r o p r i a t e as p e r f l a g / i f ( u . u_count == 0 ) { i f ( bp != NULL) b r e l s e ( bp ) ; i f ( f l a g == 1 && c == /0 ) { i f ( a c c e s s ( dp , IWRITE) goto out ;

TD 9

Fichier namei.c

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172

u_u_pdir = dp ; i f ( eo ) u . u _ o f f s e t [ 1 ] = eo DIRSIZE 2; else dp >i _ f l a g =| IUPD ; return (NULL ) ; } u . u_error = ENOENT; goto out ; }

/ i f o f f s e t i s on a b l o c k boundary , read t h e n e x t d i r e c t o r y b l o c k . R e l e a s e p r e v i o u s i f i t e x s t s /

i f ( ( u . u _ o f f s e t [ 1 ] & 0777 == 0 ) { i f ( bp != NULL ) b r e l s e ( bp ) ; bp = bread ( dp> i_dev , bmap ( dp , l d i v ( u . u _ o f f s e t [ 1 ] , 512 ) ) ) ; }

/ Note f i r s t empty d i r e c t o r y s l o t i n eo f o r p o s s i b l e c r e a t . S t r i n g compare t h e d i r e c t o r y e n t r y and t h e c u r r e n t component . I f t h e y do not match , go b a c k t o s l o o p /

bcopy ( bp>b_addr + ( u . u _ o f f s e t [ 1 ] & 0 7 7 7 ) , &u . u_dent , ( DIRSIZE +2)/2 ) ;

u . u _ o f f s e t [ 1 ] =+ DIRSIZ +2;

u . u_count ;

f ( u . u_dent . u_ino == 0 ) { i f ( eo == 0 ) eo = u . u _ o f f s e t [ 1 ] ; goto e l o o p ; }

f o r ( cp = &u . u_dbuf [ 0 ] ; cp < &u . u_dbuf [ DIRSIZ ] ; cp++) i f ( cp != cp [ u . u_dent . u_name u . u_dbuf ] ) goto e l o o p ;

/ h e r e a component matched i n a d i r e c t o r y . i f t h e r e i s more pathname , go b a c k t o e l o o p , o t h e r w i s e r e t u r n /

i f ( bp != NULL) b r e l s e ( bp ) ; i f ( f l a g == 2 && c == \0 ) { i f ( a c c e s s ( dp , IWRITE) )

Fichier namei.c

TD 9

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191

goto out ; return ( dp ) ; }

bp = dp > i_dev ; i p u t ( dp ) ; dp = i g e t ( bp , u . u_dent . u_ino ) ;

i f ( dp == NULL) return (NULL ) ; goto c l o o p ;

out : i p u t ( dp ) ; return (NULL ) ; }

TD 10

TD 10

TD 10 - Structure des fichiers Traduction dadresse / Gestion de lespace libre sur disque

But
Le but de ce TD est ltude de la structure physique des chiers sur disque : traduction dadresse ncessaire entre ladresse logique dun bloc fourni par lutilisateur et ladresse physique sur disque et gestion de lespace libre (allocation et libration de blocs).

Prrequis
Vous devez avoir utilis et compris le fonctionnement des appels systme read, write et lseek. Vous devez avoir assimil le fonctionnement des entres/sorties sur Unix et le rle des inodes. Vous devez connatre la structure gnrale des disques et des volumes dans le systme Unix, ainsi que la mthode daccs aux donnes via le buer cache.

Question 1
Rappelez limplmentation physique des chiers sous Unix.

Question 2
Quelle est la taille maximum dun chier ? Combien le noyau doit-il faire dentres / sorties au minimum et au maximum pour lire dans le chier ?

Question 3
Quel est le rle de la fonction bmap ? Expliquer son intrt. O se situe-t-elle dans le noyau par rapport lappel systme ?

Question 4
Expliquez lenchanement des actions lorsquun utilisateur utilise les primitives lseek et read.

Question 5
Expliquez la gestion de lespace libre.

TD 10

TD 10

Question 6
Quel est le rle des fonctions alloc et free ? A quels moments sont-elles appeles ? Donnez lalgorithme des fonctions alloc et free.

Question 7
Expliquez la provenance du champ s_flock du super-block.

TD 10

Fichier subr.c

Fichier subr.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

#include " . . / s y s / i n o d e . h" #include " . . / s y s / buf . h" #include " . . / s y s / t y p e s . h"

/ Bmap d e f i n e s t h e s t r u c t u r e o f f i l e system s t o r a g e by r e t u r n i n g t h e p h y s i c a l b l o c k number on a d e v i c e g i v e n t h e i n o d e and t h e l o g i c a l b l o c k number i n a f i l e . When c o n v e n i e n t , i t a l s o l e a v e s t h e p h y s i c a l b l o c k number o f t h e n e x t b l o c k o f t h e f i l e i n r a b l o c k f o r use i n read ahead . /

daddr_t bmap( ip , bn , r w f l g ) struct i n o d e i p ; daddr_t bn ; int r w f l g ; { register i ; struct buf bp , nbp ; int j , sh ; daddr_t nb , bap ; dev_t dev ;

i f ( bn < 0 ) { u . u_error = EFBIG ; return ( ( daddr_t ) 0 ) ; } dev = ip >i_dev ; rablock = 0; / b l o c k s 0 . .NADDR 4 a r e d i r e c t b l o c k s / i f ( bn < NADDR 3) { i = bn ; nb = ip >i_addr [ i ] ; i f ( nb == 0 ) { i f ( r w f l g== B_READ | | ( bp = a l l o c ( dev))==NULL) return ( ( daddr_t ) 1); nb = bp>b_blkno ; b d w r i t e ( bp ) ; ip >i_addr [ i ] = nb ; ip >i _ f l a g |= IUPD | ICHG ; } i f ( i < NADDR 4) r a b l o c k = ip >i_addr [ i + 1 ] ; return ( nb ) ; } / a d d r e s s e s NADDR 3, NADDR 2, and NADDR 1

Fichier subr.c

TD 10

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

have s i n g l e , d o u b l e , t r i p l e i n d i r e c t b l o c k s . the f i r s t s te p i s to determine how many l e v e l s o f i n d i r e c t i o n . / sh = 0 ; nb = 1 ; bn = NADDR 3; f o r ( j =3; j >0; j ) { sh += NSHIFT ; nb <<= NSHIFT ; i f ( bn < nb ) break ; bn = nb ; } i f ( j == 0 ) { u . u_error = EFBIG ; return ( ( daddr_t ) 0 ) ; } / f e t c h t h e a d d r e s s from t h e i n o d e / nb = ip >i_addr [NADDR j ] ; i f ( nb == 0 ) { i f ( r w f l g== B_READ | | ( bp = a l l o c ( dev))==NULL) return ( ( daddr_t ) 1); nb = bp>b_blkno ; b d w r i t e ( bp ) ; ip >i_addr [NADDR j ] = nb ; ip >i _ f l a g |= IUPD | ICHG ; } / f e t c h through the i n d i r e c t b l o c k s / f o r ( ; j <=3; j ++) { bp = bread ( dev , nb ) ; i f ( bp>b _ f l a g s & B_ERROR) { b r e l s e ( bp ) ; return ( ( daddr_t ) 0 ) ; } bap = bp>b_daddr ; sh = NSHIFT ; i = ( bn>>sh ) & NMASK; nb = bap [ i ] ; i f ( nb == 0 ) { i f ( r w f l g== B_READ | | ( nbp = a l l o c ( dev))==NULL) { b r e l s e ( bp ) ; return ( ( daddr_t ) 1); } nb = nbp>b_blkno ; b d w r i t e ( nbp ) ; bap [ i ] = nb ; b d w r i t e ( bp ) ; } else b r e l s e ( bp ) ; } / c a l c u l a t e read ahead . / i f ( i < NINDIR 1)

TD 10

Fichier subr.c

114 115 116

r a b l o c k = bap [ i + 1 ] ; return ( nb ) ; }

Fichier alloc.c

TD 10

Fichier alloc.c

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

#include #include #include #include

"../ "../ "../ "../

s y s / f i l s y s . h" s y s / f b l k . h" s y s / buf . h" s y s / i n o d e . h"

typedef struct f b l k FBLKP;

/ a l l o c w i l l obtain the next a v a i l a b l e f r e e d i s k b l o c k from t h e f r e e l i s t o f the s p e c i f i e d device . The s u p e r b l o c k has up t o NICFREE remembered f r e e b l o c k s ; t h e l a s t o f t h e s e i s r ead t o o b t a i n NICFREE more . . . / struct buf a l l o c ( dev ) dev_t dev ; { daddr_t bno ; r e g i s t e r struct f i l s y s f p ; r e g i s t e r struct buf bp ;

f p = g e t f s ( dev ) ; while ( fp >s _ f l o c k ) s l e e p ( ( caddr_t)&fp >s _ f l o c k , PINOD ) ; do { i f ( fp >s _ n f r e e <= 0 ) goto n o s p a c e ; i f ( fp >s _ n f r e e > NICFREE) { prdev ( "Bad f r e e count " , dev ) ; goto n o s p a c e ; } bno = fp >s _ f r e e [ fp >s _ n f r e e ] ; i f ( bno == 0 ) goto n o s p a c e ; } while ( badblock ( fp , bno , dev ) ) ; i f ( fp >s _ n f r e e <= 0 ) { fp >s _ f l o c k ++; bp = bread ( dev , bno ) ; i f ( ( bp>b _ f l a g s& B_ERROR) == 0 ) { fp >s _ n f r e e = ( (FBLKP) ( bp>b_addr))> d f _ n f r e e ; bcopy ( ( caddr_t ) ( (FBLKP) ( bp>b_addr))> d f _ f r e e , ( caddr_t ) fp >s _ f r e e , s i z e o f ( fp >s _ f r e e ) ) ; } b r e l s e ( bp ) ; fp >s _ f l o c k = 0 ; wakeup ( ( caddr_t)&fp >s _ f l o c k ) ; i f ( fp >s _ n f r e e <=0) goto n o s p a c e ; }

TD 10

Fichier alloc.c

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

i f ( fp >s _ n f r e e <= 0 | | fp >s _ n f r e e > NICFREE) { prdev ( "Bad f r e e count " , dev ) ; goto n o s p a c e ; }

bp = g e t b l k ( dev , bno ) ; c l r b u f ( bp ) ; i f ( fp >s _ t f r e e ) fp >s _ t f r e e ; fp >s_fmod = 1 ; return ( bp ) ;

nospace : fp >s _ n f r e e = 0 ; fp >s _ t f r e e = 0 ; prdev ( "no s p a c e " , dev ) ; u . u_error = ENOSPC; return (NULL ) ; }

/ place the s p e c i f i e d disk block b a c k on t h e f r e e l i s t o f t h e specified device . /

f r e e ( dev , bno ) dev_t dev ; daddr_t bno ; { r e g i s t e r struct f i l s y s f p ; r e g i s t e r struct buf bp ;

f p = g e t f s ( dev ) ; while ( fp >s _ f l o c k ) s l e e p ( ( caddr_t)&fp >s _ f l o c k , PINOD ) ; i f ( badblock ( fp , bno , dev ) ) return ; i f ( fp >s _ n f r e e <= 0 ) { fp >s _ n f r e e = 1 ; fp >s _ f r e e [ 0 ] = 0 ; } i f ( fp >s _ n f r e e >= NICFREE) { fp >s _ f l o c k ++; bp = g e t b l k ( dev , bno ) ; ( (FBLKP) ( bp>b_addr))> d f _ n f r e e = fp >s _ n f r e e ; bcopy ( ( caddr_t ) fp >s _ f r e e , ( caddr_t ) ( (FBLKP) ( bp>b_addr))> d f _ f r e e , s i z e o f ( fp >s _ f r e e ) ) ; fp >s _ n f r e e = 0 ; b w r i t e ( bp ) ; fp >s _ f l o c k = 0 ; wakeup ( ( caddr_t)&fp >s _ f l o c k ) ; } fp >s _ f r e e [ fp >s _ n f r e e ++] = bno ;

Fichier alloc.c

TD 10

114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142

fp >s _ t f r e e ++; fp >s_fmod = 1 ; }

/ Check t h a t a b l o c k number i s i n t h e range b e t w e e n t h e I l i s t and t h e s i z e of the device . This i s used mainly t o c h e c k t h a t a g a r b a g e f i l e system has not been mounted . bad b l o c k on dev x / y not i n range /

badblock ( fp , bn , dev ) r e g i s t e r struct f i l s y s f p ; daddr_t bn ; dev_t dev ; {

i f ( bn < fp >s _ i s i z e | | bn >= fp >s _ f s i z e ) { prdev ( "bad b l o c k " , dev ) ; return ( 1 ) ; } return ( 0 ) ; }

TME 1

TME 1

TME 1 - Construction dun ordonnanceur dans lespace utilisateur

But
Le but de ce TP et de programmer une bibliothque dordonnancement dans lespace utilisateur.

Prrequis Sujet
Dans ce TP, vous allez construire une bibliothque dordonnancement, cest dire une bibliothque capable dexcuter plusieurs processus en temps partag. Cette bibliothque doit orir les fonctions suivantes : void init_sched() : Initialise la bibliothque. void new_proc(void (*f)(int), int arg) : enregistre un nouveau processus excuter. Ce processus devra tre dmarr en excutant f(arg). void start_sched() : cette fonction doit dbuter lordonnancement.

Question 1
La premire tape de ce TP est de dnir la table des processus. Chaque entre dans le table est dnie par une structure Tproc. Quels sont les champs ncessaires dans cette structure. Une variable globale elu indiquera en permanence quel est lindex du processus actuellement lu dans cette table.

Indication
Quand vous allez commuter un processus, vous aurez besoin de sauvegarder ses registres (son environnement) et sa pile. Noubliez pas quune case de la table ne contient pas forcment un processus.

Question 2
La fonction init_sched doit calculer le haut de la pile dexcution pour pouvoir la sauvegarder lors dune commutation. Proposez une mthode pour calculer le haut de la pile. Pour quelle raison la fonction init_sched doit tre dnie comme une macro C ? Cette macro placera dans une variable global appele char *top_stack cette adresse. crivez et testez cette macro.

TME 1

TME 1

Question 3
Les fonctions setjmp et longjmp ne sont pas susantes pour faire de lordonnancement. En eet, ces fonctions ne sauvegardant pas la pile, les processus partageraient la pile, ce qui conduirait des erreurs. On vous demande donc dcrire deux fonctions mysetjmp et mylongjmp qui, en plus de sauvegarder/restaurer le contexte, sauvegardent/restaurent la pile dexcution de lappelant jusquau main. La fonction int mysetjmp(int idx) prend en paramtre un index dans la table des processus. Elle sauvegarde le contexte du processus appelant cet index, cest--dire quelle sauvegarde la pile du processus appelant et utilise setjmp pour sauvegarder les registres. Si le retour du setjmp est zro, cest que le processus vient dtre sauvegard. Dans ce cas, la fonction setjmp renvoie zro. Si le retour du setjmp est dirent de zro, cest que le processus vient dtre restaur suite un longjmp. Dans ce cas, la fonction mysetjmp restaure la pile du processus nouvellement lu (indiqu par la variable globale elu) et renvoie la valeur 1. La fonction void mylongjmp(int idx) prend en paramtre un index dans la table des processus. Elle positionne le nouveau processus lu idx et restaure les registres de celui-ci. La restauration de la pile aura lieu dans mysetjmp.

Indication
La fonction mysetjmp doit eectuer, dans lordre : Le calcul de la taille de la pile. Pour faire ce calcul, vous utiliserez la variable top_stack. Attention, la pile des pentiums se dplace vers le bas... Lallocation dans la variable stack de la structure Tproc du processus idx de la place ncessaire pour sauvegarder la pile. Cette partie peut tre vite en dnissant la variable stack comme un tableau de 64536 octets 1 . La Copie de la pile courante dans la structure Tproc. La sauvegarde du contexte dans la sous structure jmp_buf de la structure Tproc. La restauration du processus entrant dans le cas o le setjmp renvoie vrai. La fonction mylongjmp doit eectuer, dans lordre : Laection de la variable elu La restauration des registres du processus. Attention, dans la fonction mysetjmp, avant la restauration de la pile du processus entrant, toutes les variables locales et tous les paramtres de la fonction deviennent invalides puisquils sont placs dans la pile.

Question 4
Testez vos fonctions mysetjmp et mylongjmp. avec les exemples vus en TD.

Question 5
Dnissez deux fonctions f et g qui vous serviront tester votre ordonnanceur.

Indication
Ces fonctions doivent se terminer et durer susamment longtemps pour pouvoir observer lexcution. Il vous est est donc conseill de faire des boucles susamment longues et de faire des achages rguliers.
1. En eet, dans le TP, votre pile fera entre 100 et 2000 octets. Dans le cas gnral, cette solution risque de vous faire des dbordements de pile.

TME 1

TME 1

Question 6
Programmez la fonction new_proc. Enregistrer vos fonctions f et g avec new_proc.

Indication
Cette fonction doit trouver une entre libre dans la table des processus, noter cette entre comme utilise et sauvegarder le contexte. Si le retour de mysetjmp est gal 0, cest quon vient denregistrer le contexte, il faut donc sortir de la fonction. Sinon, cest que le processus vient dtre mis sur le processeur pour la premire fois, il faut donc appeler f(arg).

Question 7
crivez une fonction int election() qui choisit un processus lire.

Indication
Le but de ce TP nest pas encore dtudier dirents algorithmes dlection. Vous pouvez donc choisir un algorithme simple. Vous choisirez comme nouveau processus le suivant de elu dans la table des processus. Noubliez pas de faire un parcourt circulaire. Pensez aussi que les entres de la table de contiennent pas toutes des processus valides.

Question 8
Dnissez une fonction void commut(int no) qui fait juste un achage et commencez crire la fonction start_sched(). Cette fonction devra mettre en place un gestionnaire pour le signal SIGALRM et amorcer lalarme. Avant de passer la suite, assurez vous que votre alarme est appele rgulirement, i.e. que la fonction commut fait rgulirement un achage.

Question 9
Finissez la fonction void start_sched(). Elle devra choisir un processus prt et restaurer son contexte. Pour le moment, la fonction commut() ne fait rien, donc le processus choisi sexcutera de bout en bout. Il ne vous est pas encore demand de grer la terminaison de votre application.

Question 10
crivez la fonction commut.

Indication
La fonction commut doit choisir un nouveau processus mettre sur le processeur, sauvegarder celui qui sy trouve et placer le nouveau dessus.

Question 11
Tester votre programme avec plusieurs instances de f et g.

Question 12
Dans cette question, on vous demande de vous occuper de la terminaison de la bibliothque et des processus. Lorsquun processus est termin, vous devez noter sa case comme vide, et lorsquil ny a plus de processus lire, vous devez revenir au main et quitter proprement votre application.

TME 1

TME 1

Indication
Demandez votre charg de TP...

Question 13
Que se passe-t-il si vous appelez new_proc pendant que vous recevez un signal SIGALRM ? Proposez une solution.

TME 2

TME 2

TME 2 - Implementation et utilisation de primitives de synchronisation

But
Le but de ce TP est dimplmenter les primitives sleep et wakeup dans la libsched. Le mode demploi de la libsched est donn en annexe.

Sujet
On souhaite ajouter dans la libsched les deux fonctions suivantes : - int tsleep(int pri, void *obs) : fonction qui endort le thread appelant sur lobstacle obs avec la priorit pri. - int twakeup(void *obs) : fonction qui rveille tous les threads endormi sur lobstable obs. Observation : Contrairement au code de wakeup, si une thread plus prioritaire est reveille, il faudra explicitement appeler lordonnanceur (fonction commut ()) la n de la fonction twakeup. Pour rliser ce TME, vous devez copier le chier TME_sleep_wakeup.tgz du rpertoir : /V rac/noyau/ et crer lenvironment de test avec la commande :

$tar -xzvf

TME_sleep_wakeup.tgz

Les rpertoires crs sont : - src : chiers source de la libsched - include : chiers include de la libsched - obj : chiers objet de la libsched - lib : bibliothques - demo : chiers de tests et chier makele correspondants Le seul chier source de la libsched disponible pour ce TME est le src/synch.c o se trouvent les squelettes de la fonction tsleep et de la fonction twakeup. Le chier Makele dans la racine cre la libsched tandis que les chiers demo/make_sleep_wakeup et demo/make_mesg doivent tre utiliss pour crer les excutables de test test_sleep_wakeup et test_mesg respectivement. Exercice 1

TME 2

TME 2

- Compltez les fonctions tsleep et twakeup qui se trouvent dans le chier src/synch.c. Pour crer une nouvelle bibliothque libsched.a, utilisez le chier Makle de la racine. - Testez les fonctions tsleep et twakeup en utilisant le programme test_sleep_wakeup.c qui se trouve dans le repertoire demo. Utilisez pour cela le chier make_sleep_wakeup qui se trouve sous le mme rpertoire. Pour gnrer lexcutable :

$make -f make_sleep_wakeup Exercice 2 Maintenant on veut utiliser les fonctions tsleep et twakeup pour raliser une synchronisation de type Producteur / Consommateur. Pour cela on va implanter un gestion de le de messages dont la structure est la suivante (dnie demo/mesg.h) :

/* Un message */ typedef struct t_msg { int exp; void *data; } t_msg; /* Une file de message */ #define MAXMSG 8 /* Nombre maximum de messages dans une file */ typedef struct t_fmsg { t_msg file[MAXMSG]; /* Les messages */ int nb_msg; /* Nombre de messages */ unsigned int deposer; /* indice pour dposer */ unsigned int retirer; /* indice pour retirer */ void *file_pleine; /* Condition dattente file pleine */ void *file_vide; /* Condition dattente file vide */ } t_fmsg;

Ecrivez le corps des fonctions DeposerFile et RetirerFile qui se trouvent dans le chier mesg.c. Pour gnrer lexcutable utiliser le chier make_mesg.

$ make -f make_mesg $ ./mesg

Libsched : Mode demploi


La bibliothque dordonnancement libsched permet de tester des algorirthmes dordonnancement de fonctions utilisateur. Lutilisateur a lillusion que ses fonctions sexcutent en parallle.

TME 2

TME 2

Grce libsched, on peut dnir et paramtrer de nouveaux algorithmes dordonnancement. Deux chiers sont fournis par la bibliothque libsched.a et le chier dinclusion sched.h

Fonctions de la librairie
#include <sched.h> int CreateProc(function_t func, void *arg, int duration);

Cette fonction permet de crer une nouvelle fonction (que lon appelle processus lger) qui pourra sexcuter en parallle. Le paramtre func est le nom de la fonction, arg est un pointeur vers les arguments de la fonction et duration est la dure estime de la fonction. Par dfaut le paramtre duration nest pas utilis mais il peut tre utile pour des algorithmes dordonnnancement du type SJF (Shortest Job First). CreateProc retoune lidentifant du processus lger cr (pid).

void SchedParam(int type, int quantum, int (*felect)(void));

Cette fonction permet de rgler les paramtres de lordonnanceur. type indique le type dordonnancement. 3 types sont possibles (dnis dans sched.h) : BACTH indique un ordonnancement sans temps partag de type FIFO. Dans ce cas, les paramtres quantum et felect sont ignors. PREMPT indique un ordonnancement premptif de type tourniquet. Cest lordonnancement par dfaut. Dans ce cas, le paramtre quantum xe en seconde la valeur du quantum de temps. NEW indique une nouvelle stratgie dordonnancement (dnie par lutilisateur). Dans ce cas, le paramtre quantum xe en seconde la valeur du quantum de temps. Si quantum est gal 0, lordonnancement devient non premptif (sans temps partag). Le paramtre felect est le nom de la fonction dlection qui sera appele automatiquement par la librairie avec une priode de "quantum" secondes (si quantum est dirent de 0). La fonction dlection felect doit avoir la forme suivant :

int Mon_election(void) { /* Choix du nouveau processus lu */ return elu; } La fonction dlection choisit le nouveau processus lu ( ltat RUN) en fonction des informations regroupes dans la table Tproc dnie dans sched.h :

// Types dordonnancement #define NEW #define PREMPT #define BATCH #define MAXPROC 1 2 3 15 // Nouvelle strategie definie par lutilisateur // Ordonnancement preemptif // Ordonnancement de type Batch // Nombre maximum de processus

TME 2

TME 2

#define MINPRIO 0 #define MAXUSERPRIO 50 // Priorit maximum dun thread utilisateur #define MAXPRIO 100 // Priorit maximum

// Etat #define #define #define #define

dun thread RUN 1 IDLE 2 ZOMB 3 SLEEP 4

typedef void (*function_t)(); /* Table des descripteurs de processus */

struct proc { int p_flag; // Etat de la tache int p_pri; // Priorit int p_usrpri; // Priorit en mode utilisateur int p_pid; // Pid sigjmp_buf p_env; // Contexte matriel (registres) function_t p_func; // Le code void *p_arg; // Les arguments unsigned long p_stack_size; // La taille de la pile dexcution char *p_stack_svg; // La pile struct timeval p_end_time; // date de fin struct timeval p_start_time; // date de cration struct timeval p_realstart_time; // date de lancement double p_ncpu; // "cpu" consomms double p_duration; // temps estim de la tche void *p_ptr; // Pointeur pour donnes additionnelles }; struct proc Tproc[MAXPROC];

Une fois le processus choisi, felect doit retourner lindice dans Tproc du processus lu.

int GetElecProc(void);

Fonction qui retourne lindice dans Tproc du processus lu.

void sched(int printmode);

Cette fonction lance lordonnanceur. Lordonnancement eective des processus ne commence qu partir de lappel cette fonction. Par dfaut lordonnanceur excute un algorithme similaire Unix base de priorit dynamique. Le paramtre printmode permet de lancer lordonnanceur en mode " verbeux ". Si printmode est dirent de 0, lordonnanceur achera chaque commutation la liste des tches prtes. Cette fonction se termine lorsquil nexiste plus de tche ltat prt (RUN).

void commut(int s);

TME 2

TME 2

Cette fonction ralise une commutation de tche. Elle appelle la fonction dlection pour choisir la tche prte de plus haute priorit et change le contexte pour excuter la tche lue. Le paramtre s peut prendre une valeur quelconque (cela na pas dinuence sur la commutation).

void PrintStat(void);

Cette fonction ache les statistiques sur les tches excutes (temps rel dexcution, temps processeur consomm, temps dattente).

Exemple Lexemple suivant illustre lutilisation des primitives


#include #include #include #include #include <stdio.h> <stdlib.h> <unistd.h> <malloc.h> <sched.h>

// Fonction utilisateur void MonProc(int *pid) { long i; for (i=0;i<8E7;i++) if (i%(long)4E6 == 0) printf("%d - %ld\n",*pid, i); printf("############ FIN PROC %d\n\n", *pid ); } // // // // // // Exemple de primitive delection definie par lutilisateur Remarques : les primitives delection sont appeles directement depuis la librairie. Elles ne sont appeles que si au moins un processus est letat pret (RUN) Ces primitives manipulent la table globale des processus dfinie dans sched.

// Election alatoire int RandomElect(void) { int i; printf("RANDOM Election !\n"); do { i = (int) ((float)MAXPROC*rand()/(RAND_MAX+1.0)); } while (Tproc[i].p_flag != RUN); return i; }

int main (int argc, char *argv[]) { int i;

TME 2

TME 2

int *j; // Crer 3 processus for (i = 0; i < 3; i++) { j = (int *) malloc(sizeof(int)); *j= i; CreateProc((function_t)MonProc,(void *)j, 0); } // Exemples de changement de paramtres // Dfinir une nouvelle primitive delection avec un quantum de 2 secondes SchedParam(NEW, 2, RandomElect); // Redfinir le quantum par defaut SchedParam(PREMPT, 2, NULL); // Passer en mode batch SchedParam(BATCH, 0, NULL); // Lancer lordonnanceur en mode non "verbeux" sched(0); // Imprimer les statistiques PrintStat(); return EXIT_SUCCESS; }

TME 3

TME 3

TME 3 - Implementation du mcanisme de timeout

But
Le but de ce TME est dimplanter le mcanisme de timeout comme nous avons vu en TD (Gestion de Temps).

Sujet
Nous souhaitons ajouter la libsched la fonction timeout qui permet de spcier que la fonction fun doit tre excute aprs tim ticks dhorloge avec largument arg : timeout (void (*fun) ( ), void *arg, int tim). Comme nous avons vu en TD, la fonction qui traite linterruption horloge contrle le vecteur de fonctions (vecteur callout) en excutant chaque fonction au bon moment (voir fonctions clock et restart du TD). Vous devez rcuprer le chier TME_callout.tgz dans /Vrac/noyau/ et crer lenvironment de test avec la commande :

$tar -xzvf

TME_callout.tgz

Les rpertoires crs sont les mmes que ceux du TME prcdent (tsleep/twakeup). Cependant cette fois-ci, le seul chier source de la libsched disponible pour le TME est src/callout.c o se trouvent les squelettes de la fonction timeout et de la fonction restart. La structure struct callo est dni dans le chier include/callo.h et la variable v o se trouve le vecteur de callout est dclare dans le chier include/var.h

Exercice 1
Vous devez programmer les fonctions timeout et restart an dorir un mcanisme de timeout aux programmeurs. Pour cela, vous allez complter le corps des fonctions timeout et restart que se trouvent dans le chier src/callout.c. Pour gnrer la bibliothque libsched, vous devez utilisez le chier Makele que se trouve sous la racine. Le chier demo/test1_callo.c permet de tester le mcanisme de timeout. Utilisez le chier makecallo pour gnrer lexcutable :

$make -f makecallo test1_callo

TME 3

TME 3

Lexcutable test1_callo doit gnrer la sortie suivante :

8 TICKS: func1 appele par main 12 TICKS: func3 appele par main 14 TICKS: func2 appele par main 17 TICKS: func3 appele par func2 18 TICKS: func4 appele par func1

Observations : Si ncessaire, vous pouvez utiliser les macros MASK_ALRM et UNMASK_ALRM pour simuler le masquage/dmasquage dinterruption (voir chier include/callo.h).

Exercice 2
Maintenant nous voulons que la fonction timeout renvoie une valeur entire (id), qui identiera lappel du timeout en question : id = timeout (void (*fun) ( ), void *arg, int tim). Pour cela, le champ int c_cid a t ajout la struct callo an sauvegarder lidentiant du timeout (voir chier include/callo.h). En vous inspirant de lalgorithme utilis par timeout, programmez la fonction untimeout(ident), qui enlve de la table de callout lentre correspondante au timeout dont lidentiant est ident. La fonction renvoie -1, si elle na pas trouv lidentiant. Sinon elle renvoie 0. Vous devez utilisez les chier it demo/test2_callo.c pour tester la fonction untimeout. Utilisez le chier makecallo pour gnrer lexcutable :

$make -f makecallo test2_callo

Lexcutable test2_callo doit gnrer la sortie suivante :

8 TICKS: func1 appele par main 12 TICKS: func3 appele par main 18 TICKS: func4 appele par func1

TME 4

TME 4

TME 4 - Implementation des fonctions du Buffer Cache

But
Le but de ce TME est dimplanter des fonctions du buer cache.

Sujet
Nous souhaitons ajouter la libsched un mcanisme de buer cache. Vous devez rcuprer le chier TME_buer_cache.tgz dans /Vrac/noyau et crer lenvironment de test avec la commande : > tar -xzvf TME_buer_cache.tgz Les rpertoires crs sont les mmes que ceux des TMEs prcdents (tme_sleeep_wakeup et tme_callout). Cependant cette fois-ci, le seul chier source de la libsched disponible pour le TME est src/bio.c o se trouve les fonctions du buer cache completer. La structure struct buf est dnie dans le chier include/buf.h ainsi que les ags utiliss par le buer cache.

Exercice 1
Vous devez programmer les fonctions getblk et brelse du buer cache. Pour gnrer la bibliothque libsched, vous devez utilisez le chier Makele qui se trouve sous la racine. Lapplication demo/test1_bu1.c permet de tester les deux fonctions. Utilisez le chier makebu pour gnrer lexcutable : > make -f makebu test1_bu Lapplication test1_bu1 cre les threads UTIL1 et UTIL2. Les deux threads appellent la fonction getblk pour le bloc 0 du device 0. Cependant, comme la thread UTIL2 fait une attente active au dbut de son code, la thread UTIL1 appelera la fonction buf=getblk (0,0) en premier. Lorsque UTIL2 appelera la mme fonction, elle sera bloque. Elle ne sera rveille lorsque la thread UTIL1 librera le bloc (fonction brelse(buf ) ). Lexcutable test1_bu doit gnrer la sortie suivante :

UTIL1 UTIL1 UTIL1 UTIL2

: : : :

Demande de [0, 0] ([dev, blkno])... [0, 0] obtenu Debut du traitement... Demande de [0, 0] ([dev, blkno])...

TME 4

TME 4

SLEEP UTIL1 : Appel brelse... WAKEUP ####################### fin UTIL1 UTIL2 : [0, 0] obtenu UTIL2 : Debut du traitement... UTIL2 : Fin du traitement... UTIL2 : Appel brelse... ####################### fin UTIL2 - Pour endormir Observations : ou rveiller une thread, utilisez les fonctions tsleep et twakeup respectivement. - Si ncessaire, vous pouvez utiliser les fonctions int splbio() et spl(int s) pour simuler le masquage/dmasquage dinterruption de linterrruptio, disque. Les constantes NORMAL et BDINHB ont t dnies.

Exercice 2
Maintenant vous devez complter le corps des fonctions bread et bwrite. Pour tester ces fonctions, vous devez utiliser lapplication demo/test2_bu.c. en utilisant le chier makebu pour gnrer lexcutable :

$make -f makebuff test2_buff

Dans cette application, aprs avoir obtenu le bloc 0 du device 0 (buf=getblk(0,0)), la thread UTIL1 crit le message ***UTIL1 MSG***" dans ce buer en utilisant la fonction bwrite (buf ). Lorsque la thread UTIL2 essaie de lire ce mme bloc (buf=bread (0,0)), elle se bloquera parce que le bloc se trouve dans ltat B_BUSY, pris par la thread UTIL1. A la n de lcriture du bloc, la thread UTIL1, endormie en attente de la n E/S, sera rveille par la fonction iodone et librera le bloc en appellant la fonction brelse(buf )). Cette fonction rveillera alors la thread UTIL2. A la n, la thread UTIL2 libre elle aussi le bloc en appelant brelse (buf ). Observations : Les entres-sorties sur disque de la libsched sont simules. Dans cette exemple, lcriture dure 50 ticks horloges. Lexcutable test2_bu doit gnrer la sortie suivante :

UTIL1 : Demande de [0, 0] ([dev, blkno])... UTIL1 : [0, 0] obtenu UTIL1 : Debut du traitement... UTIL2 : Demande de [0, 0] ([dev, blkno])... SLEEP UTIL1 : Fin du traitement... UTIL1 : Appel bwrite !B_ASYNC... Strategy : accs au device 0 Strategy : Fin e/s dans 50 ticks... SLEEP WAKEUP ####################### fin UTIL1 UTIL2: [0, 0] obtenu. Contenu: ***UTIL1 MSG*** UTIL2 : Debut du traitement... UTIL2 : Fin du traitement... UTIL2 : Appel brelse... ####################### fin UTIL2

Annexes des Travaux Dirigs UNIX

Dfinition des types et structures de donnes du noyau

Fichier buf.h

TME 4

Fichier buf.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ Each b u f f e r i n t h e p o o l i s u s u a l l y d o u b l y l i n k e d i n t o 2 l i s t s : t h e d e v i c e w i t h which i t i s c u r r e n t l y a s s o c i a t e d ( a l w a y s ) and a l s o on a l i s t o f b l o c k s a v a i l a b l e f o r a l l o c a t i o n f o r o t h e r use ( u s u a l l y ) . The l a t t e r l i s t i s k e p t i n l a s t used order , and t h e two l i s t s a r e d o u b l y l i n k e d t o make i t e a s y t o remove a b u f f e r from one l i s t when i t was found by l o o k i n g t h r o u g h t h e o t h e r . A b u f f e r i s on t h e a v a i l a b l e l i s t , and i s l i a b l e t o be r e a s s i g n e d t o a n o t h e r d i s k b l o c k , i f and o n l y i f i t i s not marked BUSY. When a b u f f e r i s busy , t h e a v a i l a b l e l i s t p o i n t e r s can be used f o r o t h e r p u r p o s e s . Most d r i v e r s use t h e f o r w a r d p t r as a l i n k i n t h e i r I /O a c t i v e queue . A b u f f e r h e a d e r c o n t a i n s a l l t h e i n f o r m a t i o n r e q u i r e d t o perform I /O. / struct buf { int b_flags ; / b u f f e r f l a g s / struct buf b_forw ; / p r e v i o u s b u f on b _ l i s t / struct buf b_back ; / n e x t b u f on b _ l i s t / struct buf av_forw ; / p r e v i o u s b u f on a v _ l i s t / struct buf av_back ; / n e x t b u f on a v _ l i s t / int b_dev ; / major+minor d e v i c e name / int b_count ; / t r a n s f e r co u nt / union { caddr_t b_un_addr ; / low o r d e r c o r e a d d r e s s / struct f i l s y s b _ u n _ f i l s y s ; / s u p e r b l o c k s / struct d i n o d e b_un_dino ; / i l i s t / daddr_t b_un_daddr ; / i n d i r e c t b l o c k / } b_un ; int b_xmem ; / t r a n s f e r memory a d d r e s s / int b_base ; / page number f o r p h y s i c a l i /o / int b_size ; / number o f p a g e s f o r p h y s i c a l i /o / daddr_t b_blkno ; / b l o c k number on d e v i c e / char b_error ; / r e t u r n e d a f t e r I /O / int b_resid ; / b y t e s not t r a n s f e r e d / int b_pri ; / P r i o r i t y / }; #define b_addr b_un . b_un_addr #define b _ f i l s y s b_un . b _ u n _ f i l s y s #define b_dino b_un . b_un_dino #define b_daddr b_un . b_un_daddr

/ These f l a g s a r e k e p t / #define B_WRITE 0 x0000 #define B_READ 0 x0001 #define B_DONE 0 x0002 #define B_ERROR 0 x0004 #define B_BUSY 0 x0008 #define B_WANTED 0 x0010 #define B_ASYNC 0 x0020

in b_flags . / / / / / / / nonrea d pseudo f l a g / rea d when I /O o c c u r s / t r a n s a c t i o n f i n i s h e d / t r a n s a c t i o n a b o r t e d / not on av_forw / b a c k l i s t / i s s u e wakeup when BUSY g o e s o f f / don t w a i t f o r I /O c o m p l e t i o n /

TME 4

Fichier buf.h

55 #define B_PHYS 0 x0040 / w a i t I /O c o m p l e t i o n : p h y s i c a l I /O / 56 #define B_DELWRI 0 x0080 / don t w r i t e t i l l b l o c k l e a v e s a v a i l l i s t / 57 58 59 extern struct buf buf [ ] ; / The b u f f e r p o o l i t s e l f / 60 extern struct buf b f r e e l i s t ; / head o f a v a i l a b l e l i s t / 61 extern char b u f f e r s [ ] [ BSIZE ] ; 62 63 64 / 65 Fast a c c e s s t o b u f f e r s i n ca ch e by h a s h i n g . 66 / 67 68 69 #define bhash ( d , b ) ( ( struct buf )& hbuf [ ( ( int ) d+( int ) b)&v . v_hmask ] ) 70 71 72 struct hbuf 73 { 74 int b_flags ; 75 struct buf b_forw ; 76 struct buf b_back ; 77 } ; 78 79 80 extern struct hbuf hbuf [ ] ;

Fichier callo.h

TME 4

Fichier callo.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14

/ The c a l l o u t s t r u c t u r e i s f o r a r o u t i n e a r r a n g i n g t o be c a l l e d by t h e c l o c k i n t e r r u p t ( c l o c k . c ) w i t h a s p e c i f i e d argument , i n a s p e c i f i e d amount o f time . /

struct c a l l o { int c_time ; caddr_t c_arg ; int ( c_func ) ( ) ; };

/ i n c r e m e n t a l time / / argument t o r o u t i n e / / r o u t i n e /

TME 4

Fichier conf.h

Fichier conf.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42

/ Used t o d i s s e c t i n t e g e r d e v i c e code i n t o major ( d r i v e r d e s i g n a t i o n ) and minor ( d r i v e r parameter ) p a r t s . / struct { char d_major ; char d_minor ; };

/ Declaration of device s w i t c h . Each e n t r y ( row ) i s the only l i n k between the main u n i x code and t h e d r i v e r . The i n i t i a l i z a t i o n o f t h e device switches i s in the f i l e config . c . Character device switch . / struct cdevsw { int ( d_open ) ( ) ; int ( d_close ) ( ) ; int ( d_read ) ( ) ; int ( d_write ) ( ) ; int ( d_xint ) ( ) ; int ( d_ioctl ) ( ) ; } cdevsw [ ] ;

/ Block d e v i c e switch . / struct bdevsw { int ( d_open ) ( ) ; int ( d_close ) ( ) ; int ( d_strategy ) ( ) ; } bdevsw [ ] ;

Fichier fblk.h

TME 4

Fichier fblk.h

1 2 3 4 5

struct f b l k { int df_nfree ; daddr_t d f _ f r e e [ NICFREE ] ; };

TME 4

Fichier lsys.h

Fichier filsys.h

1 / 2 S t r u c t u r e o f t h e super b l o c k 3 / 4 struct f i l s y s 5 { 6 unsigned short s _ i s i z e ; / s i z e i n b l o c k s o f i l i s t / 7 daddr_t s _ f s i z e ; / s i z e i n b l o c k s o f e n t i r e volume / 8 short s_nfree ; / number o f a d d r e s s e s i n s _ f r e e / 9 daddr_t s _ f r e e [ NICFREE ] ; / f r e e b l o c k l i s t / 10 short s_ninode ; / number o f i nodes i n s_inode / 11 ino_t s_inode [ NICINOD ] ; / f r e e i node l i s t / 12 char s_flock ; / l o c k d u r i n g f r e e l i s t m a n i p u l a t i o n / 13 char s_ilock ; / l o c k d u r i n g i l i s t m a n i p u l a t i o n / 14 char s_fmod ; / s u p e r b l o c k m o d i f i e d f l a g / 15 char s_ronly ; / mounted read o n l y f l a g / 16 time_t s_time ; / l a s t s u p e r b l o c k u p d a t e / 17 daddr_t s _ t f r e e ; / t o t a l f r e e b l o c k s / 18 ino_t s_tinode ; / t o t a l f r e e i n o d e s / 19 short s_m ; / i n t e r l e a v e f a c t o r / 20 short s_n ; / " " / 21 char s_fname [ 6 ] ; / f i l e system name / 22 char s_fpack [ 6 ] ; / f i l e system pack name / 23 24 25 / s t u f f f o r i n o d e h a s h i n g / 26 ino_t s_lasti ; / s t a r t p l a c e f o r c i r c u l a r s e a r c h / 27 ino_t s_nbehind ; / e s t # f r e e i n o d e s b e f o r e s _ l a s t / 28 } ; 29 30 31 #define NICFREE 50 32 #define NICINOD 100

Fichier inode.h

TME 4

Fichier inode.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

#define NADDR 13 struct i n o d e { char char dev_t ino_t unsigned short short short short off_t struct { daddr_t daddr_t }; };

i_flag ; i_count ; i_dev ; i_number ; i_mode ; i_nlink ; i_uid ; i_gid ; i_size ;

/ r e f e r e n c e c ou nt / / d e v i c e where i n o d e r e s i d e s / / i number , 1 to 1 w i t h d e v i c e a d d r e s s / / / / / d i r e c t o r y e n t r i e s / owner / group o f owner / s i z e o f f i l e /

i_addr [NADDR] ; / i f normal f i l e / d i r e c t o r y / i_lastr ; / l a s t l o g i c a l b l o c k rea d ( f o r read ahead ) /

extern struct i n o d e i n o d e [ ] ; / The i n o d e t a b l e i t s e l f / / f l a g s / #define ILOCK #define IUPD #define IACC #define IMOUNT #define IWANT #define ITEXT #define ICHG0 / modes / #define IFMT #define IFDIR #define IFCHR #define IFBLK #define IFREG #define IFMPC #define IFMPB #define ISUID #define ISGID #define ISVTX #define IREAD #define IWRITE #define IEXEC

01 02 04 010 020 040 100

/ / / / / / /

i n o d e i s l o c k e d / f i l e has been m o d i f i e d / i n o d e a c c e s s time t o be u p d a t e d / i n o d e i s mounted on / some p r o c e s s w a i t i n g on l o c k / i n o d e i s pure t e x t p r o t o t y p e / i n o d e has been changed /

0170000 0040000 0020000 0060000 0100000 0030000 0070000 04000 02000 01000 0400 0200 0100

/ / / / / / / / / / /

t y p e o f f i l e / d i r e c t o r y / c h a r a c t e r s p e c i a l / b l o c k s p e c i a l / r e g u l a r / m u l t i p l e x e d c har s p e c i a l / m u l t i p l e x e d b l o c k s p e c i a l / s e t u s e r i d on e x e c u t i o n / s e t group i d on e x e c u t i o n / s a v e swapped t e x t even a f t e r use / read , w r i t e , e x e c u t e p e r m i s s i o n s /

TME 4

Fichier mount.h

Fichier mount.h

1 / 2 Mount s t r u c t u r e . 3 One a l l o c a t e d on e v e r y mount . 4 / 5 struct mount 6 { 7 int m_flags ; / s t a t u s / 8 dev_t m_dev ; / d e v i c e mounted / 9 struct i n o d e m_inodp ; / p o i n t e r t o mounted on i n o d e / 10 struct buf m_bufp ; / b u f f e r f o r s u p e r b l o c k / 11 struct i n o d e m_mount ; / p o i n t e r t o mount r o o t i n o d e / 12 } mount [NMOUNT] ; 13 14 15 #define MFREE 0 16 #define MINUSE 1 17 #define MINTER 2

Fichier param.h

TME 4

Fichier param.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22

/ fundamental constants cannot be changed /

#define CBSIZE #define CROUND #define SROUND

12 15 7

/ number o f i n f o char i n a c l i s t b l o c k / / s i z e o f ( i n t ) + CBSIZE 1 / / CBSIZE>>1 /

/ processor p r i o r i t y / #define CLINHB 7 #define BDINHB 6 #define CDINHB 5 #define CALOUT 4 #define CDINTR 3 #define WAKEUP 2 #define SWITCH 1 #define NORMAL 0

levels / / / / / / / / c l o c k i n h i b i t l e v e l / b l o c k d e v i c e i n h i b i t l e v e l / c h a r a c t e r d e v i c e i n h i b i t l e v e l / c l o c k c a l l o u t p r o c e s s i n g l e v e l / c h a r a c t e r d e v i c e i n t e r r u p t l e v e l / c l o c k wakeup p r o c e s s i n g l e v e l / s w i t c h p r o c e s s i n g l e v e l / normal p r o c e s s i n g l e v e l /

TME 4

Fichier proc.h

Fichier proc.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ One s t r u c t u r e a l l o c a t e d p e r a c t i v e p r o c e s s . I t c o n t a i n s a l l d a t a needed about the process while the p r o c e s s may be swapped o u t . Other p e r p r o c e s s d a t a ( u s e r . h ) i s swapped w i t h t h e p r o c e s s . /

struct p r o c { short p_addr ; / short p_size ; / int p_flag ; / char p_stat ; / char p_pri ; / char p_nice ; / long p_sig ; / short p_uid ; / short p_suid ; / short p_time ; / int p_cpu ; / short p_ttyp ; / short p_pid ; / short p_ppid ; / caddr_t p_wchan ; / struct t e x t p_textp ; short p_tsize ; / short p_ssize ; / short p_clktim ; / } p r o c [NPROC ] ;

a d d r e s s o f s w a p p a b l e image / s i z e o f s w a p p a b l e image ( i n b l o c k s ) / p r o c e s s f l a g s / p r o c e s s s t a t e / p r i o r i t y , n e g a t i v e i s h i g h / n i c e f o r s c h e d u l i n g / s i g n a l number s e n t t o t h i s p r o c e s s / r e a l u s e r id , used t o d i r e c t t t y s i g n a l s / s e t ( e f f e c t i v e ) u s e r i d / r e s i d e n t time f o r s c h e d u l i n g / cpu u s a g e f o r s c h e d u l i n g / c o n t r o l l i n g t t y / u n i q u e p r o c e s s i d / p r o c e s s i d o f p a r e n t / e v e n t p r o c e s s i s a w a i t i n g / / p o i n t e r t o t e x t s t r u c t u r e / s i z e o f t e x t / s i z e o f s t a c k / time t o alarm c l o c k s i g n a l /

/ s t a t #define #define #define #define #define #define #define #define #define

c o d e s / SSLEEP 1 SWAIT 2 SRUN 3 SIDL 4 SZOMB 5 SSTOP 6 SXBRK 7 SXSTK 8 SXTXT 9

/ / / / / / / / /

a w a i t i n g an e v e n t / ( abandoned s t a t e ) / running / i n t e r m e d i a t e s t a t e i n p r o c e s s c r e a t i o n / i n t e r m e d i a t e s t a t e i n p r o c e s s t e r m i n a t i o n / p r o c e s s b e i n g t r a c e d / p r o c e s s b e i n g xswapped / p r o c e s s b e i n g xswapped / p r o c e s s b e i n g xswapped /

/ f l a g #define #define #define #define #define #define #define

c o d e s / SLOAD 0 x0001 SSYS 0 x0002 SLOCK 0 x0004 SSWAP 0 x0008 STRC 0 x0010 SWTED 0 x0020 SMOVE 0 x0040

/ / / / / / /

p r o c e s s i n memory / s c h e d u l i n g p r o c e s s / p r o c e s s l o c k e d i n memory / p r o c e s s i s b e i n g swapped o u t / p r o c e s s i s b e i n g t r a c e d / a n o t h e r t r a c i n g f l a g / p r o c e s s moved /

Fichier proc.h

TME 4

55 #define SULOCK 56 #define STEXT 57 #define SSPART

0 x0080 0 x0100 0 x0200

/ u s e r s e t t a b l e l o c k i n c o r e / / t e x t p o i n t e r i s v a l i d / / p r o c e s s i s p a r t i a l l y swapped o u t /

TME 4

Fichier signal.h

Fichier signal.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

#define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define

SIGHUP SIGINT SIGQUIT SIGILL SIGTRAP SIGIOT SIGEMT SIGFPE SIGKILL SIGBUS SIGSEGV SIGSYS SIGPIPE SIGALRM SIGTERM SIGUSR1 SIGUSR2 SIGCLD SIGPWR

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

/ / / / / / / / / / / / / / / / / / /

hangup / i n t e r r u p t ( r u b o u t ) / q u i t ( ASCII FS) / i l l e g a l i n s t r u c t i o n ( not r e s e t when c a u g h t ) / t r a c e t r a p ( not r e s e t when c a u g h t ) / IOT i n s t r u c t i o n / EMT i n s t r u c t i o n / f l o a t i n g p o i n t e x c e p t i o n / k i l l ( cannot be c a u g h t or i g n o r e d ) / bus e r r o r / s e g m e n t a t i o n v i o l a t i o n / bad argument t o system c a l l / w r i t e on a p i p e w i t h no one t o read i t / alarm c l o c k / s o f t w a r e t e r m i n a t i o n s i g n a l from k i l l / u s e r d e f i n e d s i g n a l 1 / u s e r d e f i n e d s i g n a l 2 / d e a t h o f a c h i l d / power f a i l r e s t a r t /

#define NSIG

19

#define SIG_DFL ( int ( ) ( ) ) 0 #define SIG_IGN ( int ( ) ( ) ) 1

Fichier text.h

TME 4

Fichier text.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

/ Text s t r u c t u r e . One a l l o c a t e d p e r pure p r o c e d u r e on swap d e v i c e . M a n i p u l a t e d by t e x t . c / struct t e x t { daddr_t x_daddr ; caddr_t x_caddr ; long x_size ; struct i n o d e x_iptr ; char x_count ; char x_ccount ; } t e x t [NTEXT ] ;

/ / / / / /

d i s k a d d r e s s o f segment / c o r e a d d r e s s , i f l o a d e d / s i z e ( 6 4 ) / i n o d e o f p r o t o t y p e / r e f e r e n c e c ou n t / number o f l o a d e d r e f e r e n c e s /

TME 4

Fichier tty.h

Fichier tty.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48

/ A c l i s t s t r u c t u r e i s t h e head o f a l i n k e d l i s t queue o f c h a r a c t e r s . The c h a r a c t e r s a r e s t o r e d i n 4 word b l o c k s c o n t a i n i n g a l i n k and 6 c h a r a c t e r s . The r o u t i n e s g e t c and p u t c ( prim . c ) manipulate these s t r u c t u r e s . / struct c l i s t { int c_cc ; / c h a r a c t e r c ou n t / char c_cf ; / p o i n t e r t o f i r s t c h a r a c t e r / char c_cl ; / p o i n t e r t o l a s t c h a r a c t e r / };

struct c b l o c k { struct c b l o c k c_next ; char c _ i n f o [ CBSIZE ] ; };

struct

cblock

cfreelis ;

#define CBSIZE #define CROUND #define SROUND

12 15 7

/ nombre de c a r a c t e r e s par b l o c s / ( s i z e o f ( int )+CBSIZE 1) ( CBSIZE>>1)

/ I n t e r n a l s t a t e b i t s / #define CARR_ON 0 x0001 #define WOPEN 0 x0002 #define ISOPEN 0 x0004 #define OPEN 0X0004 #define READING 0 x0010 #define WRITING 0 x0020 #define TTSTOP 0 x0040 #define TTSTART 0 x0080 #define TIMEOUT 0 x0100 #define ASLEEP 0 x0200 #define XCLUDE 0 x0400 #define HUPCLS 0 x0800 #define ATTENT 0 x1000 #define TBLOCK 0 x2000 #define CNTLQ 0 x8000

/ S o f t w a r e copy o f c a r r i e r p r e s e n t / / Waiting f o r open t o c o m p l e t e / / D ev i c e i s open / / / / / / / / / / / / I n p u t i n p r o g r e s s / Output i n p r o g r e s s / <^s><^q> p r o c e s s i n g / <^s><^q> p r o c e s s i n g / Delay t i m e o u t i n p r o g r e s s / Wakeup when o u t p u t done / e x c l u s i v e use f l a g , a g a i n s t open / Hangup a f t e r l a s t c l o s e / A t t e n t i o n c h a r a c t e r r e c e i v e d / Tandem queue b l o c k e d / i n t e r p r e t t_un as c l i s t /

Fichier types.h

TME 4

Fichier types.h

1 2 3 4

typedef typedef typedef typedef

long char int unsigned short

daddr_t caddr_t dev_t ino_t

/ / / /

disk address core address d e v i c e code i n o d e number

/ / / /

TME 4

Fichier user.h

Fichier user.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ The u s e r s t r u c t u r e . One a l l o c a t e d p e r p r o c e s s . Contains a l l p e r p r o c e s s d a t a t h a t doesn t need t o be r e f e r e n c e d w h i l e t h e p r o c e s s i s swapped . The u s e r b l o c k i s USIZE b l o c s long ; resides at v i r t u a l kernel l o c a t i o n 0 xc000 ; c o n t a i n s t h e system s t a c k per user ; i s cross r e f e r e n c e d w i t h t h e proc s t r u c t u r e f o r t h e same p r o c e s s . / struct u s e r { int u_rsav [ 2 ] ; / s a v e d env . f o r p r o c e s s s w i t c h i n g / int u_ssav [ 2 ] ; / s a v e d env . f o r swapping / int u_qsav [ 2 ] ; / s a v e d env . f o r s i g n a l i n g / struct p r o c u_procp ; char char int int int u_error ; u_intflg ; u_ar0 ; u_arg [ 2 0 ] ; u_ap ; / p o i n t e r t o p roc s t r u c t u r e / / / / / / r e t u r n e r r o r code / c a t c h i n t r from s y s / a d d r e s s o f u s e r s s a v e d R0 / arguments t o c u r r e n t system c a l l / p o i n t e r t o a r g l i s t /

struct f i l e u _ o f i l e [ NOFILE ] ; / p o i n t e r s t o open f i l e / int int int int int int int int int int int long long long long u _ s i g n a l [ NSIG ] ; u_uid ; u_gid ; u_ruid ; u_rgid ; u_uisa [ 1 6 ] ; u_uisd [ 1 6 ] ; u_tsize ; u_dsize ; u_ssize ; u_csize ; u_utime ; u_stime ; u_cutime ; u_cstime ; / / / / / d i s p o s i t i o n o f s i g n a l s / e f f e c t i v e u s e r i d / e f f e c t i v e group i d / r e a l u s e r i d / r e a l group i d /

/ p r o t o t y p e o f s e g m e n t a t i o n a d d r e s s e s / / p r o t o t y p e o f s e g m e n t a t i o n d e s c r i p t o r s / / / / / / / / / / / / / / t e x t s i z e ( i n b l o c s ) / d a t a s i z e ( i n b l o c s ) / s t a c k s i z e ( i n b l o c s ) / amount o f s t a c k i n use ( i n b l o c s ) / t h i s p r o c e s s u s e r time / t h i s p r o c e s s system time / sum o f c h i l d s u t i m e s / sum o f c h i l d s s t i m e s / f l a g f o r i /o u s e r or k e r n e l / b a s e a d d r e s s f o r IO / b y t e s rema ining f o r IO / o f f s e t i n f i l e f o r IO / p o i n t e r t o i n o d e o f c u r r e n t d i r /

int u_segflg ; char u_base ; int u_count ; long u_offset ; struct i n o d e u_cdir ;

Fichier user.h

TME 4

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104

char u_dbuf [ DIRSIZ ] ; / char u_dirp ; / struct { / int u_ino ; char u_name [ DIRSIZ ] ; } u_dent ; struct i n o d e u_pdir ; /

c u r r e n t pathname component / c u r r e n t p o i n t e r t o i n o d e / c u r r e n t d i r e c t o r y e n t r y /

i n o d e o f p a r e n t d i r e c t o r y o f d i r p / s t r u c t u r e s o f open f i l e s /

int

u_stack [ 1 ]

/ k e r n e l s t a c k p e r u s e r e x t e n d s from u + USIZE backward not t o r e a c h h e r e /

} u;

/ u_error c o d e s / #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define EPERM ENOENT ESRCH EINTR EIO ENXIO E2BIG ENOEXEC EBADF ECHILD EAGAIN ENOMEM EACCES EFAULT ENOTBLK EBUSY EEXIST EXDEV ENODEV ENOTDIR EISDIR EINVAL ENFILE EMFILE ENOTTY ETXTBSY EFBIG ENOSPC ESPIPE EROFS EMLINK EPIPE 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / Not super u s e r No such f i l e or d i r e c t o r y No such p r o c e s s i n t e r r u p t e d system c a l l I /O e r r o r No such d e v i c e or a d d r e s s Arg l i s t t o o l o n g Exec f o r ma t e r r o r Bad f i l e number No c h i l d r e n No more p r o c e s s e s Not enough c o r e Permission denied Bad a d d r e s s Block d e v i c e r e q u i r e d Mount d e v i c e b u s y File exists Cross d e v i c e l i n k No such d e v i c e Not a d i r e c t o r y Is a directory I n v a l i d argument File table overflow Too many open f i l e s Not a t y p e w r i t e r Text f i l e b u s y F i l e too l a r g e No s p a c e l e f t on d e v i c e I l l e g a l seek Read o n l y f i l e system Too many l i n k s Broken p i p e / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / /

TME 4

Fichier var.h

Fichier var.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

/ The f o l l o w i n g i s used by machdep . c / struct var { int v_uprocs ; / max # o f u s e r s p r o c e s s / int v_timezone ; / t i m e z o n e / int v_cargs ; / max # o f b y t e s g i v e n t o e x e c / int v_cspeed ; / d e f a u l t a s y n c h r o n o u s l i n e s p e e d / long v_fill [20]; / r f u / int v_proc ; / pro c t a b l e / struct p r o c ve_proc ; int vs_proc ; int v_clist ; / c b l o c k l i s t / struct c b l o c k v e _ c l i s t ; int vs_clist ; int v_mount ; / mount t a b l e / struct mount ve_mount ; int vs_mount ; int v_inode ; / i n o d e t a b l e / struct i n o d e ve_inode ; int vs_inode ; int v_file ; / f i l e t a b l e / struct f i l e v e _ f i l e ; int vs_file ; int v_cmap ; / c o r e map / struct map ve_cmap ; int vs_cmap ; int v_smap ; / swap map / struct map ve_smap ; int vs_smap ; int v_callout ; / c a l l o u t t a b l e / struct c a l l o v e _ c a l l o u t ; int vs_callout ; int v_text ; / t e x t segment t a b l e / struct t e x t ve_text ; int vs_text ; int v_buf ; / d a t a b u f f e r s / struct buf ve_buf ; int vs_buf ; / b e g i n n i n g o f i n t e r n a l b u f f e r s / int v_Buf ; / d a t a b u f f e r s / struct Buffer_Data ve_Buf ; int vs_Buf ; int v_io ; / s p a c e f o r i o _ i n f o b u f / long ve_io ; int vs_io ; int v_hbuf ; / s t r u c t u r e s f o r d a t a b u f f e r s h a s h i n g / struct hbuf ve_hbuf ; int vs_hbuf ; int v_hino ; / s t r u c t u r e s f o r i n o d e h a s h i n g / struct i n o d e ve_hino ; int vs_hino ; int v_hproc ; / hash pr oc l i s t s / struct p r o c ve_hproc ;

Fichier var.h

TME 4

55 56 57 58 59 60 61 62 63

int int int int } v;

vs_hproc ; v_zero ; ve_zero ; vs_zero ;

struct p r o c proc_end ; long b u f b a s e ;

/ l a s t l o g i c a l pr oc o f pro c t a b l e /