5 - Les verrous

5.1 - Introduction : Les accès concurrents

Dans un système d’exploitation multitâches, les différents processus sont concurrents et par conséquent sont susceptibles d’accéder à un fichier régulier en « même temps ». La nécessité de régler ce type de conflit est particulièrement fondamentale dans le développement d’applications de gestion.

5.2 - Les verrous externes

5.2.1 - Le principe

Un verrou externe est tout simplement un fichier régulier dont la seule présence constitue le verrouillage de la ressource à protéger.

5.2.2 - Création d’un fichier verrou

On utilise la primitive open habituelle avec deux drapeaux particuliers O_CREAT (création de fichier) et O_EXCL (en mode exclusif) .

Si le fichier verrou n’existe pas, la primitive s’exécutera normalement et renverra un descripteur associé à ce fichier verrou.

Si le fichier verrou existe déjà, la primitive échouera et renverra -1 avec errno=EEXIST .

5.2.3 - Suppression d’un fichier verrou

On utilise la primitive unlink habituelle.

5.2.4 - Première utilisation :assurer l’unicité d’un processus

On veut se garder ici de lancer plusieurs fois la même commande (typiquement un processus démon assurant un service) : le verrouillage externe est parfaitement adapté à ce type de fonctionnalité.

 

#include <fcntl.h>

#include <sys/errno.h>

#include <stdio.h>

 

extern int errno;

int main(void)

{ int desc;

  if((desc=open(“cad“,O_CREAT|O_EXCL,0))==-1 && errno== EEXIST)

    exit(1) ;

  else

  {

    close(desc);

    /* Action du processus */

    unlink(“cad“);

    exit(0);

  }

}

5.2.5 - Seconde utilisation : accès exclusif à un fichier

On veut s’assurer ici que le processus accède seul à une ressource pendant une partie de son existence. Avant de rentrer dans cette section « critique », le processus essaie de créer un fichier verrou externe et se met en attente si nécessaire.

 

#include <fcntl.h>

#include <sys/errno.h>

 

extern int errno;

 

int main(void)

{

  int descV;

  while((descV=open(“cad“,O_CREAT|O_EXCL,0))==-1&&errno==EEXIST)

    sleep(10);

  /* Section critique */

  unlink(“cad “);

  /* Suite programme*/

  exit(0);

}

5.2.6 - Critique du mécanisme

5.3 - Les verrous internes

5.3.1 - Introduction

Les verrous internes sont davantage associés aux fichiers à protéger en ce sens que leur présence va être détectée dans les tables gérées par le système. Les mécanismes mis en place dans System V (repris par POSIX) et BSD diffèrent aussi bien au niveau des fonctionnalités qu’au niveau de l’implémentation d’où problèmes de portabilité des applications.

5.3.2 - Caractéristiques générales

verrous partagés pour la lecture

verrous exclusifs pour l’écriture

5.3.3 - L’implémentation System V

Le noyau gère une table de verrous dont chaque entrée a une structure flock qui peut être consultée ou modifiée avec la primitive fcntl.

5.3.3.1 - Champs de la structure flock

l_type type du verrou

F_RDLCK partagé (en lecture)

F_WRLCK exclusif (en écriture)

F_UNLCK absence de verrou

l_whence type de repérage dans le fichier à verrouiller

0 par rapport au début

1 par rapport à la position courante

2 par rapport à la fin

l_start position du début de la zone à verrouiller relativement à l_whence

l_len longueur de la zone à verrouiller (longueur nulle = tout le fichier)

l_pid PID du processus propriétaire (fournie au retour dans certains cas)

5.3.3.2 - Manipulation des verrous avec la primitive fcntl

#include  <fcntl.h>

int  fcntl(int desc,int oper,struct flock *buf_adr) ;

 

Le paramètre desc est le descripteur du fichier à verrouiller qui aura été ouvert auparavant.

Le paramètre oper désigne l’opération à réaliser sur le verrou :

F_SETLK pose non bloquante : en cas d’échec, c.a.d. si un verrou incompatible existe déjà, la primitive revient en erreur

F_SETLKW pose bloquante (attend de pouvoir mettre le verrou)

F_GETLCK test d’existence et information sur le verrou

Le dernier paramètre est l’adresse d’un objet de structure flock qui servira à décrire le verrou à mettre en place (F_SETLK ou F_SETLKW) ou à récupérer la description d’un verrou existant (F_GETLCK).

5.3.3.3 - Mode opératoire

Par défaut, les verrous System V sont consultatifs : rien n’empêche un processus ne jouant pas le jeu d’éditer un fichier verrouillé ! ! !

 

Certaines implémentations autorisent les verrous impératifs : d’abord on positionne le set-gid bit sur le fichier à protéger, sans que le bit d’exécution soit levé pour le groupe, puis on pose le verrou interne sur le fichier. Le fichier sera déverrouillé par le système si le processus propriétaire du verrou est tué ou meurt avant d’avoir levé le verrou.