라이브러리 업그레이드 중에 애플리케이션을 보호하는 메커니즘이 있습니까?

라이브러리 업그레이드 중에 애플리케이션을 보호하는 메커니즘이 있습니까?

사용자가 동적으로 연결된 애플리케이션을 사용하고 시스템이 업그레이드되는 경우 애플리케이션이 손상되는 것을 방지하는 보호 메커니즘이 있습니까?

아니면 신청상태에 따라 달라지나요?

답변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

(다른 창에서 동시에, foosegfault 이후, 이전)

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설치 시 파일을 열어야 하는 맞춤법 검사와 같은 일부 작업은 실패하기 시작합니다 .

관련 정보