Estou escrevendo alguns scripts de shell para lidar com algumas coisas de imagem de disco e preciso usar dispositivos de loop para acessar algumas imagens de disco. No entanto, não tenho certeza de como alocar corretamente um dispositivo de loop sem expor meu programa a uma condição de corrida.
Eu sei que posso usar losetup -f
para obter o próximo dispositivo de loop não alocado e alocar esse dispositivo de loop da seguinte maneira:
ld=$(losetup -f)
sudo losetup $ld myfile.img
dostuffwith $ld
No entanto, no caso em que desejo executar várias instâncias do programa ao mesmo tempo, esse é quase um exemplo de condição de corrida e isso me incomoda bastante. Se eu tivesse várias instâncias desse programa em execução ou outros programas tentando também obter um dispositivo de loop, cada processo poderá não ser capaz de alocar o dispositivo de loop antes da próxima chamada losetup -f
, caso em que ambos os processos pensariam que o mesmo loop dispositivo está disponível, mas apenas um pode obtê-lo.
Eu poderia usar a sincronização externa para isso, mas gostaria de (se possível) evitar complexidade adicional. Além disso, outros programas que usam dispositivos de loop provavelmente não respeitariam a sincronização que eu possa criar.
Como posso evitar essa possível condição de corrida? Idealmente, eu gostaria de poder descobrir e vincular o dispositivo de loop atomicamente, por exemplo, com um comando como:
ld=$(sudo losetup -f myfile.img)
dostuffwith $ld
No entanto, quando faço isso, $ld
não é atribuído ao caminho do dispositivo de loop e a sudo
saída, como em, sudo ld=$(losetup -f myfile.img)
dá erros de permissão.
fonte
</dev/tty
?losetup --find --show
corridas.for i in {1..100}; do losetup -f -s $i & done
não me deu 100 dispositivos de loop. Os dispositivos de loop são incomuns o suficiente para que não importem normalmente; se isso acontecer, sua única opção é fazer seus próprios bloqueios e / ou verificar se o dispositivo de loop correto foi criado como uma reflexão tardia.losetup
pode falhar (por exemplo, porque você ficou sem entradas de loop), mas se ele relatar um nome de dispositivo, esse será o dispositivo que ele alocou com sucesso. As versões anteriores tiveram um bug que causou a gravação de um nome de dispositivo, mesmo que a alocação tenha falhado? Vejo no código fonte que a interface para alocação no kernel existe apenas desde o kernel 3.1. Talvez seja um bug na interface mais antiga que requer que olosetup
utilitário faça a pesquisa?/dev/loop14
e tal, e o dispositivo pode estar ausente no final. Talvez a correção é cortesia de/dev/loop-control
, costumava basta olhar para/proc/partitions
...losetup
usa/dev/loop-control
se estiver presente, e isso não parece ter uma condição de corrida: a alocação ocorre no kernel e imprimir o caminho do dispositivo é a última coisa que o utilitário faz.Eu descobri. Embora eu não tenha certeza de como é o problema da permissão, eu posso filmar primeiro e depois perguntar assim:
fonte
Você poderia usar
flock
:A idéia aqui é que você tente e
flock
o arquivo do dispositivo de loop; se outra instância do mesmo script o adquirir primeiro, ele chamarálosetup $ld myfile.img
eflock
retornará 0. Para o script que perde a corrida,losetup
não será chamado eflock
retornará 1, fazendo com que o loop se repita.Para mais veja
man flock
.fonte
Se tudo o que você deseja fazer com a imagem como dispositivo de loopback é montá-la como um sistema de arquivos e trabalhar com o conteúdo, o
mount
comando pode cuidar disso automaticamente.fonte