ビルドスクリプト内でループデバイスを使用するためのクリーンで安全な方法を見つけようとしています。私が知る限り、ファイルを(GPT)分割して(FAT32、EXT3)フォーマットするにはループデバイスが必要です。足りないファイル1。
たとえば、次のスクリプトがあるとします。
#!/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
ほとんどの幸せなパスと不幸なパスでは、ループデバイスはbash呼び出しを介してクリーンアップされますlosetup
。しかし、屋根ふき装置が残るいくつかの不快な経路があります。
これがマウントに関する問題の場合、簡単な解決策はマウントネームスペースで実行することですunshare -m
。これにより、プロセスが明示的に同じ操作を実行せずにプロセスが終了したときにカーネルがマウントポイントをクリーンアップします。
ループデバイスがマウントによって最初に作成された場合、マウントポイントがmount -o loop
存在するときにループデバイスがクリーンアップされるため、プロキシを介してマウントネームスペースを使用してループデバイスをクリーンアップすることもできます。
しかし、私が望むものはすべてゼロのファイルのGPTパーティションテーブルなので、私が知っている限り、どのファイルシステムも正常にマウントできません。
それでは、プロセス、プロセスグループ、名前空間などがクリーンアップされたときにカーネルがループデバイスをクリーンアップする他の方法はありますか?
- 1 別々のファイルをフォーマットしてから
dd
オフセットを使用してコピーするなどの解決策があることを知っていますが、これはスパースファイルのままではなく、ディスクに複数のギガバイトのゼロが書き込まれます。したがって、ここで「希少」という言葉は非常に重要です。 - 2 明らかな例は、bashが死んだときに起こるものです。
kill -9
答え1
losetup -d
使用されなくなったらすぐに取り外しできるように、ループデバイスをゆっくりと切断します。キャプチャする代わりに、ループデバイスのファイルディスクリプタを開き、すぐに切断します。
#!/bin/bash
set -ex
truncate --size 4G target.img
sfdisk target.img < partitions
loop_device=$(losetup -f --show target.img)
exec 5< "$loop_device"
losetup -d "$loop_device"
partx -u "$loop_device"
mkfs.vfat "${loop_device}p1"
mkfs.ext4 "${loop_device}p2"
losetup -f
スクリプトが終了すると、間の短いウィンドウを除いて何らかの理由でlosetup -d
ループデバイスがクリーンアップされます。