빌드 스크립트 내에서 루프 장치를 사용하는 깨끗하고 안전한 방법을 찾으려고 노력 중입니다. 내가 아는 한, 파일을 (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
마운트 지점이 존재할 때 루프 장치가 정리되므로 프록시를 통해 마운트 네임스페이스를 사용하여 루프 장치를 정리할 수도 있습니다.
그러나 내가 원하는 것은 모두 0인 파일의 GPT 파티션 테이블이기 때문에 (내가 아는 한) 어떤 파일 시스템도 성공적으로 마운트될 수 없습니다.
그렇다면 프로세스, 프로세스 그룹, 네임스페이스 등이 정리될 때 커널이 루프 장치를 정리할 수 있는 다른 방법이 있습니까?
- 1 별도의 파일을 포맷한 다음
dd
오프셋을 사용하여 복사하는 것과 같은 솔루션이 존재한다는 것을 알고 있지만 이로 인해 스파스 파일로 남아 있는 대신 디스크에 여러 기가바이트의 0이 기록됩니다. 따라서 여기서 "희소"라는 단어는 매우 중요합니다. - 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
루프 장치가 정리됩니다.