충돌없이 공유 라이브러리를 업그레이드하는 방법은 무엇입니까?


18

여기서는 실행 파일을 다시 쓸 수 있으며 프로세스가 정상적으로 실행된다는 것을 나타냅니다. 프로세스가 다시 시작되면 다시 읽습니다.

그러나 프로세스가 실행되는 동안 (dev에서 테스트 서버까지 scp를 사용하여) 바이너리 파일을 바꾸려고하면 'file busy'라고 표시됩니다. 그리고 공유 라이브러리 파일 (* .so)을 교체하면 해당 파일을 연결하는 모든 프로세스가 충돌합니다.

왜 그래? 뭔가 빠졌습니까? 프로세스를 중지 / 충돌하지 않고 바이너리 파일을 바꾸려면 어떻게해야합니까?


의존성을 점검하기 위해 .so파일 ldd filename.so을 점검 할 수 있습니다
Rahul Patil

나는 의존성을 안다. 실행중인 프로세스에 영향을 미치지 않고 해당 파일을 바꾸는 방법을 원합니다. 관련된 질문에서 알 수 있듯이
Sam

다운 타임이 필요합니다 .. 또는 원하는 작업을 수행 할 수 있습니다 stop app && create symlink of .so && start app
Rahul Patil

답변:


21

에서 언급 한 바와 같이 왜 실행 소프트웨어 패키지는 잘 그것은 업그레이드되는 않는 경우에도? 잠금은 파일 이름이 아닌 inode에 배치됩니다. 바이너리를로드하고 실행할 때 파일이 사용 중으로 표시되므로 파일을 쓰려고 할 때 ETXTBSY (파일 사용 중) 오류가 발생합니다.

이제 공유 라이브러리의 경우 약간 다릅니다. 라이브러리는를 사용하여 프로세스의 주소 공간에 메모리를 매핑합니다 mmap(). MAP_DENYWRITE지정할 수는 있지만 Linux에서 적어도 Glibc는 자동으로 무시합니다 (Man 페이지에 따라 소스를 확인하십시오)-이 스레드를 확인하십시오 . 따라서 실제로 파일을 쓸 수 있으며 메모리에 매핑되면 변경 사항이 거의 즉시 표시됩니다. 즉, 충분히 노력 하면 라이브러리를 덮어 써서 머신 을 브릭 할 수 있습니다 .

따라서 업데이트하는 올바른 방법은 다음과 같습니다.

  1. 파일 시스템에서 데이터에 대한 참조를 제거하는 파일을 제거하여 파일을 사용하려는 새로 생성 된 응용 프로그램에 액세스 할 수 없도록하고 파일을 이미 열거 나 매핑 한 모든 사람이 데이터에 액세스 할 수 있도록합니다. ;

  2. 업데이트 된 내용으로 새 파일을 만듭니다.

새로 작성된 프로세스는 업데이트 된 컨텐츠를 사용하고 실행중인 애플리케이션은 이전 버전에 액세스합니다. 제정신 패키지 관리 유틸리티가하는 일입니다. dlsym()라이브러리의 API가 자동으로 변경되면 코드를 동적으로로드하는 응용 프로그램 (예 : 친구들과 친구)이 아무런 위험이없는 것은 아닙니다 .

당신은 정말,에 있으려면 정말 , 안전을 시스템을 종료, 다른 운영 체제 인스턴스 업데이트에서 파일 시스템을 마운트하고 다시 업데이트 된 시스템을 가지고.


6

rpm 업그레이드는 충돌이없는 동안 바이너리와 라이브러리를 실행하는 것과 동일하게 수행됩니다.

차이점은 무엇입니까?

  1. 파일 연결 해제
  2. 같은 이름으로 새 파일을 작성하십시오

이것은 파일을 대체하지 않습니다. 사용중인 이진을 참조하는 inode는 파일을 열어 놓은 마지막 객체가 완료 될 때까지 여전히 "사용 중"입니다. 새로운 파일은 새로운 inode-number로 생성됩니다.

이제 scp또는 cp파일을 대체하려고 시도합니다. 그러면 inode가 참조하는 내용이 변경됩니다. 설명 된대로 작동하지 않습니다.

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