일부 디스크 이미지 작업을 처리하기 위해 일부 쉘 스크립트를 작성 중이며 일부 디스크 이미지에 액세스하려면 루프 장치를 사용해야 합니다. 그러나 내 프로그램을 경쟁 조건에 노출시키지 않고 루프 장치를 올바르게 할당하는 방법을 잘 모르겠습니다.
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)
답변1
이는 동시성의 전형적인 문제입니다. 리소스를 할당할 때 리소스가 사용 가능한지 자동으로 확인하고 예약해야 합니다. 그렇지 않으면 리소스가 사용 가능한지 확인하는 시점과 예약하는 시점 사이에 다른 프로세스가 리소스를 예약할 수 있습니다. 그것.
losetup
자동 할당 모드( -f
) 를 사용 하고 --show
옵션을 전달하여 루프 장치 경로를 인쇄하십시오.
ld=$(sudo losetup --show -f /tmp/1m)
이 옵션은 버전 2.13(원래 다음과 같이 추가되었습니다.-s
이지만 출시된 모든 버전에서 지원되며 최신 버전에서는 옵션 이름이 --show
제거되었습니다 . -s
불행히도 BusyBox 버전에는 이 기능이 없습니다.
리눅스 커널 버전 3.1소개하다새 장치를 통해 커널에서 직접 라운드 로빈 장치 할당 작업을 수행하는 방법입니다 /dev/loop-control
. 이 방법은 util-linux 2.21부터만 지원됩니다. kernel <3.1 또는 util-linux <2.21인 경우 프로그램은 losetup
루프 장치 항목을 열거하여 하나를 예약합니다. 그러나 코드에는 경쟁 조건이 표시되지 않습니다. 안전해야 하지만 그렇지 않은 경우에도 모든 장치가 할당되었다고 잘못 보고하는 작은 창이 있을 수 있습니다.
답변2
나는 그것에 대해 생각했다. 권한 문제가 어떻게 발생하는지 잘 모르겠지만 먼저 촬영하고 나중에 다음과 같이 물어볼 수 있습니다.
sudo losetup -f myfile.img
ld=$(losetup -j myfile.img | grep -o "/dev/loop[0-9]*")
dostuffwith $ld
답변3
당신이 사용할 수있는 flock
:
tryagain=1
while [[ $tryagain -ne 0 ]]; do
ld=`losetup -f`
flock -n $ld -c "losetup $ld myfile.img"
tryagain=$?
done
여기서의 아이디어는 flock
장치 파일을 반복하려고 시도한다는 것입니다. 동일한 스크립트의 다른 인스턴스가 해당 파일을 먼저 가져오면 해당 파일이 호출되어 losetup $ld myfile.img
0 flock
을 반환합니다. 일치를 잃은 스크립트의 경우 losetup
호출되지 않고 flock
1을 반환하므로 루프가 반복됩니다.
자세한 내용을 확인하세요 man flock
.
답변4
루프백 장치로서 이미지를 사용하여 수행하려는 작업이 이미지를 파일 시스템으로 마운트하고 콘텐츠를 사용하는 것이라면 이 mount
명령이 이를 자동으로 처리할 수 있습니다.
mount -o loop myfile.img /tmp/mountpoint