사용자가 동적으로 연결된 애플리케이션을 사용하고 시스템이 업그레이드되는 경우 애플리케이션이 손상되는 것을 방지하는 보호 메커니즘이 있습니까?
아니면 신청상태에 따라 달라지나요?
답변1
@Kusalananda가 언급했듯이 일반적으로 업그레이드는 이전 파일을 삭제하고 동일한 이름의 새 파일을 생성하여 수행됩니다. 이렇게 하면 새 inode가 포함된 새 파일이 효과적으로 생성되며, 이전 파일이 열려 있는 동안 시스템은 이를 자유롭게 사용할 수 있습니다.
단순화된 예를 들면 다음과 같습니다.
rm /bin/cat
cp /new/version/of/cat /bin/cat
논리적인 새 파일이 생성되고 cat
실행 중이더라도 작동합니다. 도서관도 마찬가지다. (위의 내용은 예시이며 실제 환경에서 파일을 업그레이드하는 신뢰할 수 있는 방법은 아닙니다.)
누군가가 동일한 이름을 가진 새 바이너리를 생성하는 대신 바이너리를 변경해 볼 수 있습니까? 이 경우 적어도 Linux는 실제로 사용 중인 실행 파일의 변경을 차단합니다.
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
그러나 동적으로 로드된 라이브러리에서는 작동하지 않는 것 같습니다...
테스트용 복사본을 만들고 libc.so.6
다음을 사용할 때 0으로 채웠습니다.
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(다른 창에서 동시에, foo
segfault 이후, 이전)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
실제로 온라인에서 코드를 편집했기 때문에 프로그램 자체에서는 이에 대해 아무 것도 할 수 없습니다.
(이것은 시스템에 따라 다를 수 있습니다. 저는 Debian Jessie 8.5, Linux 3.16.7-ckt25-2+deb8u3에서 테스트했습니다. 특히 IIRC Windows 시스템은 사용 중인 파일이 수정되는 것을 방지하는 데 더 적극적입니다.)
그래서 내 생각에 업그레이드는 일반적으로 파일 시스템 내부 덕분에 문제를 피하는 방식으로 수행된다는 것이 답인 것 같습니다. 그러나 (Linux에서는) 동적 라이브러리의 실제 손상을 방지하기 위해 수행된 작업이 없는 것 같습니다.
답변2
파일이 열려 있는 동안 연결이 해제되면 파일이 "제대로 삭제"되지 않습니다. 종료되면 사용한 디스크 공간은 다시 "무료"로 간주됩니다. 이는 현재 실행 중인 애플리케이션과 해당 공유 라이브러리에도 적용됩니다.
이 오류가 발생하는 유일한 경우는 프로그램이 dlopen()
요청 시 공유 라이브러리를 로드하는 데 사용되거나 프로그램이 요청 시 사전, 테마 파일 또는 갑자기 사라지는 기타 파일과 같은 다른 파일에 액세스해야 하는 경우입니다.
설명하자면, vim
하나의 셸 세션에서 실행 중일 때 다른 셸 세션에서 설치를 삭제해도 vim
현재 실행 중인 세션이 "손상"되거나 종료되지 않습니다 vim
. 그러나 vim
설치 시 파일을 열어야 하는 맞춤법 검사와 같은 일부 작업은 실패하기 시작합니다 .