라이브러리 업그레이드 중에 응용 프로그램을 보호하는 메커니즘이 있습니까?


10

사용자가 동적으로 연결된 응용 프로그램에서 작업하고 시스템을 업그레이드하는 경우 응용 프로그램 손상을 방지하는 보호 메커니즘이 있습니까?

아니면 응용 프로그램에 달려 있습니까?


사용하는 방법에 대한 리눅스 책을 읽고 기억 ln -sf(가) 때문에, 라이브러리를 통해 교환 할 때를 -f허용 당신은 이제까지 "깨진"하지 않고 새 것으로 심볼릭 링크의 "덮어 쓰기"는 기존 대상, (에 당신이 않은 경우와는 달리 rm다음 ln -s). 따라서 명령 전에 library.so 는 예를 들어 이전 버전을 가리 켰습니다. library.so.4 ... 명령 후, 그것은 단순히 지적 library.so.5 대신 (또는 무엇이든) -도없이 하지 유효한 라이브러리를 가리키는.
Baard Kopperud

답변:


16

@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에서는) 실제로 손상된 동적 라이브러리에 대한 보호 장치가없는 것 같습니다.


install유틸리티는 일반적으로 이와 같은 것들에 사용됩니다. rm대상 파일 을 명시 적으로 지정할 필요는 없습니다 . 또한 기존 파일의 권한을 유지하고 백업을 만들고 새 모드를 설정할 수 있습니다. 사용법 예 :install /new/version/of/cat /bin/cat
Patrick

확실한. rm+는 cp예로서 의미했다. 새 파일을 원자 이름으로 제자리에 배치하는 것이 현명 할 수도 있습니다. 버전이없는 짧은 창을 피하십시오. (GNU install는 그렇게하지 않는 것처럼 보이지만, hmpf.)
ilkkachu

2
이 답변에있는 것을 분명히하고 싶습니다. 유닉스에서 파일이 열려 있고 제거 된 경우 ( rm) 아직 삭제되지 않았습니다. 디스크에 존재하며 열려있는 모든 프로세스에서 계속 읽을 수 있습니다. 하드 링크 수가 0에 도달하고 파일을 연 상태에서 세차 횟수가 0에 도달하면 삭제됩니다.
ctrl-alt-delor

@ 패트릭 : install유틸리티는 특히 안전하지 않습니다! 대상 파일을 원자 적으로 바꾸지 않고 대신 덮어 씁니다. mv(동일한 디렉토리에 source와 dest가 있으면 source는 일반적으로 temp 파일) 파일을 설치하는 유일한 안전한 방법입니다.
R .. GitHub 중지 도움 얼음

1
@Patrick까지 내과 같이 strace말한다, installGNU의로 coreutils에 복사합니다 다음 그 자리에 새로운 하나를 대상 파일 링크를 해제합니다. 이는 파일이 부분적인 동안 짧은 창이 있음을 의미합니다. 파일 이름을 원자 적으로 제자리에 설정하지 않습니다.
ilkkachu

3

파일이 여전히 열려있는 상태에서 연결이 해제되면 파일이 "제대로 삭제되지 않습니다". 이들이 닫히면 사용한 디스크 공간이 다시 "사용 가능한"것으로 간주됩니다. 이것은 현재 실행중인 응용 프로그램과 공유 라이브러리에도 적용됩니다.

내가 실패한 것으로 보이는 것은 프로그램이 필요할 때 dlopen()공유 라이브러리를로드하는 데 사용 되었거나 사전, 테마 파일 또는 갑자기 사라지는 다른 파일과 같은 다른 파일에 액세스해야하는 경우입니다.

설명 : 다른 쉘 세션에서 vim설치를 삭제하는 동안 한 쉘 세션에서 실행 해도 vim현재 실행중인 vim세션이 "손상"되거나 종료되지 않습니다 . 그러나 맞춤법 검사와 같은 일부 항목은 vim설치에서 파일을 열어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.