Ich schreibe einige Shell-Skripte, um einige Disk-Image-Inhalte zu verarbeiten, und ich muss Loop-Geräte verwenden, um auf einige Disk-Images zuzugreifen. Ich bin mir jedoch nicht sicher, wie ich ein Loop-Gerät richtig zuordnen soll, ohne mein Programm einer Race-Bedingung auszusetzen.
Ich weiß, dass ich losetup -f
das nächste nicht zugewiesene Schleifengerät abrufen und dieses Schleifengerät dann wie folgt zuweisen kann:
ld=$(losetup -f)
sudo losetup $ld myfile.img
dostuffwith $ld
Wenn ich jedoch mehrere Instanzen des Programms gleichzeitig ausführen möchte, ist dies fast ein Lehrbuchbeispiel für eine Rennbedingung, und das stört mich sehr. Wenn mehrere Instanzen dieses Programms ausgeführt würden oder andere Programme versuchen würden, auch ein Schleifengerät zu erhalten, könnte möglicherweise nicht jeder Prozess das Schleifengerät zuordnen, bevor der nächste Aufruf losetup -f
erfolgt. In diesem Fall würden beide Prozesse annehmen, dass dieselbe Schleife vorhanden ist Gerät ist verfügbar, aber nur einer kann es bekommen.
Ich könnte hierfür eine externe Synchronisation verwenden, möchte aber (wenn möglich) zusätzliche Komplexität vermeiden. Auch andere Programme, die Loop-Geräte verwenden, würden wahrscheinlich nicht die Synchronisation berücksichtigen, die ich mir einfallen lassen könnte.
Wie kann ich diese potenzielle Rennbedingung vermeiden? Idealerweise möchte ich das Schleifengerät atomar erkennen und binden können, beispielsweise mit einem Befehl wie:
ld=$(sudo losetup -f myfile.img)
dostuffwith $ld
Wenn ich das mache, wird es $ld
jedoch nicht dem Loop-Gerätepfad zugewiesen, und das Verschieben des sudo
Outs, wie in, sudo ld=$(losetup -f myfile.img)
gibt Berechtigungsfehler.
quelle
</dev/tty
?losetup --find --show
Rennen.for i in {1..100}; do losetup -f -s $i & done
gab mir nicht 100 Loop-Geräte. Loop-Geräte sind selten genug, damit sie normalerweise keine Rolle spielen. Wenn dies der Fall ist, können Sie nur Ihre eigenen Sperren erstellen und / oder überprüfen, ob das richtige Schleifengerät nachträglich erstellt wurde.losetup
möglicherweise fehl (z. B. weil Ihnen die Schleifeneinträge ausgegangen sind). Wenn jedoch ein Gerätename gemeldet wird, ist dies das Gerät, das erfolgreich zugewiesen wurde. Hatten frühere Versionen einen Fehler, der dazu führte, dass ein Gerätename geschrieben wurde, obwohl die Zuordnung fehlgeschlagen war? Ich sehe im Quellcode, dass die Schnittstelle für die Zuweisung im Kernel nur seit Kernel 3.1 existiert. Ist es möglicherweise ein Fehler mit der älteren Schnittstelle, für den daslosetup
Dienstprogramm die Suche durchführen muss?/dev/loop14
und so und das Gerät kann am Ende insgesamt fehlen. Vielleicht ist das/dev/loop-control
/proc/partitions
losetup
verwendet,/dev/loop-control
falls vorhanden, und das sieht nicht so aus, als ob es eine Race-Bedingung geben könnte: Die Zuweisung erfolgt im Kernel und das Drucken des Gerätepfads ist das Letzte, was das Dienstprogramm tut.Ich habe es herausgefunden. Obwohl ich nicht sicher bin, wie das Problem mit der Erlaubnis ist, kann ich stattdessen zuerst schießen und später so fragen:
quelle
Sie könnten verwenden
flock
:Die Idee hier ist, dass Sie versuchen,
flock
die Loop-Gerätedatei; Wenn eine andere Instanz desselben Skripts es zuerst abruft, wird es aufgerufenlosetup $ld myfile.img
undflock
gibt 0 zurück. Für das Skript, das die Rasse verliert,losetup
wird es nicht aufgerufen undflock
gibt 1 zurück, wodurch sich die Schleife wiederholt.Weitere Informationen finden Sie unter
man flock
.quelle
Wenn Sie das Image als Loopback-Gerät nur als Dateisystem bereitstellen und mit dem Inhalt arbeiten möchten, kann der
mount
Befehl dies automatisch erledigen .quelle