J'écris des scripts shell pour gérer certains trucs d'image disque, et j'ai besoin d'utiliser des périphériques de boucle pour accéder à certaines images disque. Cependant, je ne sais pas comment allouer correctement un périphérique de boucle sans exposer mon programme à une condition de concurrence critique.
Je sais que je peux utiliser losetup -f
pour obtenir le prochain périphérique de boucle non alloué, puis allouer ce périphérique de boucle comme ceci:
ld=$(losetup -f)
sudo losetup $ld myfile.img
dostuffwith $ld
Cependant, dans le cas où je veux exécuter plusieurs instances du programme en même temps, c'est presque un exemple classique d'une condition de concurrence critique, et cela me dérange beaucoup. Si plusieurs instances de ce programme étaient en cours d'exécution ou que d'autres programmes essayaient également d'obtenir un périphérique de boucle, chaque processus pourrait ne pas être en mesure d'allouer le périphérique de boucle avant le prochain appel losetup -f
, auquel cas les deux processus penseraient que la même boucle est disponible, mais un seul peut l'obtenir.
Je pourrais utiliser la synchronisation externe pour cela, mais je voudrais (si possible) éviter une complexité supplémentaire. De plus, d'autres programmes qui utilisent des périphériques de boucle ne respecteraient probablement pas la synchronisation que je pourrais proposer.
Comment puis-je éviter cette condition de course potentielle? Idéalement, j'aimerais pouvoir découvrir et lier atomiquement le périphérique de boucle, par exemple avec une commande comme:
ld=$(sudo losetup -f myfile.img)
dostuffwith $ld
Cependant, lorsque je fais cela, il $ld
n'est pas attribué au chemin du périphérique de boucle, et le déplacement sudo
, comme dans, sudo ld=$(losetup -f myfile.img)
donne des erreurs d'autorisation.
la source
</dev/tty
sert?losetup --find --show
courses.for i in {1..100}; do losetup -f -s $i & done
ne m'a pas donné 100 appareils en boucle. Les périphériques en boucle sont assez rares pour que cela n'ait pas d'importance normalement; si c'est le cas, votre seule option est de créer vos propres verrous et / ou de vérifier que le bon périphérique de boucle a été créé après coup.losetup
peut échouer (par exemple parce que vous n'avez plus d'entrées de boucle), mais s'il signale un nom de périphérique, c'est le périphérique qu'il a correctement alloué. Les versions antérieures comportaient-elles un bogue qui provoquait l'écriture d'un nom de périphérique même si l'allocation avait échoué? Je vois dans le code source que l'interface pour l'allocation dans le noyau n'existe que depuis le noyau 3.1, est-ce peut-être un bogue avec l'ancienne interface qui nécessite l'losetup
utilitaire pour faire la recherche?/dev/loop14
et ainsi et le périphérique peut être complètement absent à la fin. Peut-être que le correctif est une courtoisie de/dev/loop-control
, il regardait juste/proc/partitions
...losetup
utilise/dev/loop-control
s'il est présent, et cela ne semble pas avoir une condition de concurrence critique : l'allocation se fait dans le noyau et l'impression du chemin du périphérique est la dernière chose que l'utilitaire fait.Je l'ai compris. Bien que je ne sois pas sûr de la nature du problème avec l'autorisation, je peux plutôt tirer en premier et demander plus tard comme ceci:
la source
Vous pouvez utiliser
flock
:L'idée ici est d'essayer
flock
le fichier de périphérique de boucle; si une autre instance du même script l'acquiert en premier, elle va appelerlosetup $ld myfile.img
etflock
retournera 0. Pour le script qui perd la course,losetup
ne sera pas appelé etflock
renverra 1, provoquant la répétition de la boucle.Pour plus voir
man flock
.la source
Si tout ce que vous voulez faire avec l'image en tant que périphérique de bouclage est de la monter en tant que système de fichiers et de travailler avec le contenu, la
mount
commande peut s'en occuper automatiquement.la source