Я пишу несколько сценариев оболочки для обработки некоторых образов дисков, и мне нужно использовать петлевые устройства для доступа к некоторым образам дисков. Тем не менее, я не уверен, как правильно распределить петлевые устройства, не подвергая мою программу состоянию гонки.
Я знаю, что могу использовать losetup -f
для получения следующего нераспределенного устройства цикла, а затем выделить это устройство цикла следующим образом:
ld=$(losetup -f)
sudo losetup $ld myfile.img
dostuffwith $ld
Однако в случае, когда я хочу запустить несколько экземпляров программы одновременно, это почти учебный пример состояния гонки, и это очень беспокоит меня. Если бы у меня было несколько запущенных экземпляров этой программы или другие программы, пытающиеся также получить устройство цикла, то каждый процесс мог бы не иметь возможности выделить устройство цикла до вызова следующего losetup -f
, и в этом случае оба процесса думают, что один и тот же цикл устройство доступно, но получить его может только один.
Я мог бы использовать для этого внешнюю синхронизацию, но я бы хотел (если это возможно) избежать дополнительной сложности. Кроме того, другие программы, использующие петлевые устройства, вряд ли будут учитывать любую синхронизацию, с которой я могу столкнуться.
Как я могу избежать этого потенциального состояния гонки? В идеале я хотел бы иметь возможность обнаруживать и связывать устройство цикла атомарно, например, с помощью такой команды:
ld=$(sudo losetup -f myfile.img)
dostuffwith $ld
Тем не менее, когда я это делаю, $ld
не назначается путь устройства петли, и перемещение sudo
, как в, sudo ld=$(losetup -f myfile.img)
дает ошибки разрешения.
источник
</dev/tty
?losetup --find --show
гонки.for i in {1..100}; do losetup -f -s $i & done
не дал мне 100 устройств петли. Петлевые устройства достаточно редки, чтобы это не имело значения; если это так, единственный вариант - сделать свои собственные блокировки и / или проверить, что правильное устройство петли было создано как запоздалая мысль.losetup
может завершиться ошибкой (например, потому что у вас закончились циклические записи), но если он сообщает имя устройства, это устройство, которое он успешно выделил. Была ли в более ранних версиях ошибка, из-за которой она записывала имя устройства, даже если распределение не удалось? В исходном коде я вижу, что интерфейс для выделения в ядре существует только начиная с ядра 3.1. Может быть, это ошибка со старым интерфейсом, которая требует, чтобыlosetup
утилита выполняла поиск?/dev/loop14
и тому подобное, и устройство может в итоге вообще отсутствовать. Возможно исправление любезно предоставлено/dev/loop-control
, раньше оно просто смотрело на/proc/partitions
...losetup
использует,/dev/loop-control
если присутствует, и это не похоже на то, что это может иметь условие гонки: распределение происходит в ядре, и печать пути устройства - это последнее, что делает утилита.Я понял. Хотя я не уверен, какова проблема с разрешением, я могу вместо этого сначала выстрелить, а потом спросить так:
источник
Вы можете использовать
flock
:Идея в том, что вы пытаетесь и
flock
файл устройства цикла; если другой экземпляр того же скрипта получит его первым, он получит вызовlosetup $ld myfile.img
иflock
вернет 0. Для скрипта, который проиграл гонку,losetup
не будет вызван иflock
вернется 1, что приведет к повторению цикла.Для более см
man flock
.источник
Если все, что вы хотите сделать с образом в качестве петлевого устройства, это смонтировать его как файловую систему и работать с содержимым,
mount
команда может позаботиться об этом автоматически.источник