TP7 – Fichiers partagés (1/2)
Pour faire les exercices, vous avez besoin de connaître le langage bash. Vous pouvez vous référer à l'annexe shell. Vous pouvez aussi trouver une liste d'astuces ici. Tous les exercices sont obligatoires, sauf les exercices notés « défi » ou « optionnel » qui sont optionnels. En particulier, les exercices notés « hors présentiel » sont supposés fait d'une séance sur la suivante.
Vous aurez aussi besoin des scripts P.sh et V.sh.
Mise en évidence des incohérences provoquées par les commutations (∼0h30)
- Premier 2233
- Suivant 2234
Exécutez ce script jusqu'à ce que le contenu d'un des fichiers f1, f2 ou f3 ne contienne qu'une seule ligne au lieu de deux, c'est-à-dire, jusqu'à ce qu'une des écritures soit perdue. Expliquez le résultat obtenu.
Accès concurrents à un fichier (∼1h)
Soit le script ajout.sh suivant qui prend au moins deux paramètres. Le premier paramètre correspond à un fichier d'index (liste des fichiers créés), les autres sont les noms des fichiers à créer. Le script crée les fichiers dont le nom est passé en paramètre (s'ils n'existent pas) et met à jour le contenu du fichier d'index. Un message d'erreur est affiché si le nombre de paramètres n'est pas correct ou si le premier paramètre correspond à un nom de répertoire.
Le fichier index contient donc trois lignes :
Observez les contenus du répertoire et du fichier index après cette exécution et expliquez pourquoi fic1 apparaît deux fois dans index.
Soit le script essai2.sh suivant :
Est-il possible d'avoir l'exécution suivante ? Vous pouvez la faire apparaître en décommentant le sleep 2 de ajout.sh. Expliquez la suite d'événements menant à cette exécution.
Le processus enleve.sh prend alors la main et s'exécute jusqu'au bout sans être interrompu. Il teste donc que le fichier fic1 existe, il le supprime (la commande rm -f n'affiche aucun message si le fichier à supprimer n'existe pas), met à jour le fichier index (comme il ne contenait pas de ligne fic1, le contenu du fichier n'est pas modifié) et se termine.
Le processus ajout.sh reprend ensuite la main et poursuit son exécution en ajoutant fic1 au contenu du fichier index.- le fichier fic1 existe et il apparaît dans le fichier index (ce qui correspond à une exécution de enleve_verrou.sh avant ajoute_verrou.sh),
- le fichier fic1 n'existe pas et il n'apparaît pas dans le fichier index (ce qui correspond à une exécution de ajoute_verrou.sh avant enleve_verrou.sh).
Accès concurrents à plusieurs fichiers (∼1h)
- le fichier login.txt contient l'identifiant de connexion de chaque utilisateur connu du système à raison d'un identifiant par ligne,
- le fichier pass.txt contient le mot de passe de chaque utilisateur, à raison d'un mot de passe par ligne,
- le fichier nom.txt contient le nom de chaque utilisateur, à raison d'un nom par ligne.
Les informations sont associées en fonction de leur position dans les fichiers (les informations se trouvant à la iè ligne de chaque fichier concernent le même utilisateur).
Le script suivant est une première version du script de création d'un nouvel utilisateur :- deux utilisateurs ont pu être créés avec le même identifiant (deux lignes identiques dans le fichier login.txt),
- les informations concernant un utililisateur ne sont pas à la même ligne dans les trois fichiers.
Le premier cas peut se produire lors de l'exécution de :
Pour le second cas, on suppose donc qu'on exécute :
On peut alors avoir une commutation du premier script juste après la ligne echo "$1" >> login.txt. À ce moment, login.txt contient u1 et les autres fichiers sont vides. Le second script s'exécute entièrement et ajoute le triplet (l2, p2, u2) aux fichiers. Ensuite, le premier script reprend la main et ajoute p1 puis u1. Au résultat, les fichiers contiendront :
login.txt | pass.txt | nom.txt |
l1 | p2 | u2 |
l2 | p1 | u1 |
Non-atomicité des redirections (∼0h30 – défi)
- Le contenu du fichier est supprimé. On a alors un fichier vide.
- Le nouveau contenu est écrit dans le fichier.
- Le contenu du fichier est supprimé. On a alors un fichier vide.
- Le nouveau contenu est écrit dans le fichier.
- le processus 19371 écrit son PID dans le fichier, il y a une commutation de processus entre les deux étapes de l'écriture.
- le processus 19372, qui a repris la main après la suppression du contenu mais avant la nouvelle ériture, lit dans un fichier vide, la variable val est donc une chaîne vide.
- le test [ $val -ne 0 ] du processus 19372 est évalué à [ -ne 0]. Il manque donc un opérateur pour pouvoir effectuer la comparaison, d'où l'erreur signalée lors de l'exécution.