I am writing some shell scripts to handle some disk image stuff, and I need to use loop devices to access some disk images. However, I am not sure how to properly allocate a loop device without exposing my program to a race condition.
I know that I can use
losetup -f to get the next unallocated loop device, and then allocate that loop device like this:
ld=$(losetup -f) sudo losetup $ld myfile.img dostuffwith $ld
However, in the case where I want to run multiple instances of the program at the same time, this is almost a textbook example of a race condition, and that bothers me quite a lot. If I had multiple instance of this program running, or other programs trying to also get a loop device, then each process might not be able to allocate the loop device before the next one calls
losetup -f, in which case both processes would think that the same loop device is available, but only one can get it.
I could use external synchronization for this, but I would like to (if possible) avoid additional complexity. Also, other programs that use loop devices wouldn't likely respect whatever synchronization I might come up with.
How can I avoid this potential race condition? Ideally, I'd like to be able to discover and bind the loop device atomically, for instance with a command like:
ld=$(sudo losetup -f myfile.img) dostuffwith $ld
However, when I do that,
$ld does not get assigned to the loop device path, and moving the
sudo out, as in
sudo ld=$(losetup -f myfile.img) gives permission errors.