Estou tentando descobrir uma maneira limpa e segura de usar dispositivos de loop dentro de um script de construção. Pelo que sei, são necessários dispositivos de loop se você deseja particionar (GPT) e (FAT32, EXT3) formatar um arquivo esparso 1 .
Por exemplo: digamos que eu tenha este script:
#!/bin/bash
set -ex
truncate --size 4G target.img
sfdisk target.img < partitions
loop_device=$(losetup -f --show target.img)
trap "losetup -d $loop_device" EXIT
partx -u $(loop_device)
mkfs.vfat ${loop_device}p1
mkfs.ext4 ${loop_device}p2
Na maioria dos caminhos felizes e infelizes, o dispositivo de loop será limpo por bash chamando losetup
. Mas existem alguns caminhos infelizes 2 que fazem com que o dispositivo de loop seja deixado para trás.
Se esta fosse uma questão sobre montagens, a solução simples seria executar em um namespace de montagem com unshare -m
. Isso resultaria na limpeza do ponto de montagem pelo kernel quando o processo fosse encerrado, sem que o processo executasse explicitamente a mesma ação.
Além disso, se o dispositivo de loop fosse criado com uma montagem em primeiro lugar, mount -o loop
o dispositivo de loop seria limpo quando o ponto de montagem fosse criado e, portanto, por proxy, um namespace de montagem também poderia ser usado para limpar o dispositivo de loop.
Mas como o que procuro é uma tabela de partição GPT em um arquivo com zeros, nenhum sistema de arquivos seria montado com êxito nele (AFAIK).
Então, existe alguma outra maneira de fazer com que o kernel limpe um dispositivo de loop quando um processo, grupo de processos, namespace, ... é limpo?
- 1 Estou ciente de que existem soluções, como formatar um arquivo separado e depois usá-lo
dd
para copiar com um deslocamento, mas isso resulta na gravação de vários GB de zeros no disco, em vez de permanecer como um arquivo esparso. Então aqui a palavra "esparso" é muito importante - 2 Uma coisa óbvia é o que acontece quando o bash é morto com
kill -9
losetup -d
desassocia um dispositivo de loop preguiçosamente, para que possa ser usado para remover um dispositivo de loop assim que ele não for mais usado. Em vez de capturar, abra um descritor de arquivo para o dispositivo de loop e desassocie-o imediatamente:Quando o script for encerrado, por qualquer motivo, exceto na pequena janela entre
losetup -f
elosetup -d
, o dispositivo de loop será limpo.