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

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

여기실행 파일을 다시 작성할 수 있으며 프로세스가 제대로 실행될 것이라고 말합니다. 프로세스가 다시 시작되면 다시 읽혀질 것입니다.

그러나 프로세스가 실행되는 동안(개발 서버에서 테스트 서버로 scp를 사용하여) 바이너리를 교체하려고 하면 "파일 사용 중"이라고 표시됩니다. 공유 라이브러리 파일(*.so)을 교체하면 이를 연결하는 모든 프로세스가 중단됩니다.

왜 이런거야? 내가 뭐 놓친 거 없니? 프로세스를 중지/충돌시키지 않고 바이너리를 교체하려면 어떻게 해야 합니까?

답변1

에서 언급했듯이업그레이드 후에도 소프트웨어 패키지가 여전히 정상적으로 실행되는 이유는 무엇입니까?, 파일 이름 대신 inode에 잠금이 설정됩니다. 바이너리 파일을 로드하고 실행하면 파일이 사용 중으로 표시됩니다. 따라서 파일에 쓰려고 할 때 ETXTBSY(파일 사용 중) 오류가 발생합니다.

이제 공유 라이브러리의 경우 상황이 약간 다릅니다. 라이브러리는 메모리를 프로세스의 주소 공간에 매핑합니다 mmap(). 지정될 수 있지만 MAP_DENYWRITE적어도 Linux의 Glibc는 이를 자동으로 무시합니다(맨 페이지에 따르면 자유롭게 소스를 확인하십시오). 이것을 확인하십시오.철사. 따라서 실제로 파일에 쓸 수 있고 메모리가 매핑되어 있으므로 모든 변경 사항이 거의 즉시 표시됩니다. 즉, 열심히 노력하면 관리할 수 있습니다. 벽돌라이브러리를 컴퓨터에 덮어씁니다.

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

  1. 파일을 삭제하면 파일 시스템에서 데이터에 대한 참조가 제거되어 해당 파일을 사용하려는 새로 생성된 응용 프로그램에서 액세스할 수 없도록 하는 동시에 파일을 열거나 매핑한 모든 사람이 데이터에 액세스할 수 있도록 유지합니다.

  2. 업데이트된 콘텐츠로 새 파일을 만듭니다.

새로 생성된 프로세스는 최신 콘텐츠를 사용하고 실행 중인 애플리케이션은 이전 버전에 액세스합니다. 이것이 정상적인 패키지 관리 유틸리티가 수행하는 작업입니다. 이것이 위험이 전혀 없는 것은 아니라는 점에 유의하십시오. 예를 들어 dlsym()코드를 동적으로 로드하는 애플리케이션(사용 및 친구)은 라이브러리의 API가 자동으로 변경되면 문제가 발생합니다.

진짜 사람이 되고 싶다면,진짜안전을 유지하려면 시스템을 종료하고, 다른 OS 인스턴스에서 파일 시스템을 마운트하고, 업데이트된 시스템을 다시 업데이트하고 시작하십시오.

답변2

rpm 업그레이드의 효과는 동일합니다. 즉, 충돌 없이 바이너리와 라이브러리를 실행합니다.

그렇다면 차이점은 무엇입니까?

  1. 파일 연결 해제
  2. 같은 이름으로 새 파일 작성

이는 파일을 제자리에 대체하지 않습니다. 사용 중인 바이너리 파일을 참조하는 inode는 해당 파일을 열어 둔 마지막 개체가 완료될 때까지 "사용 중" 상태로 유지됩니다. 새 파일은 새 inode 번호로 생성됩니다.

이제 scp또는 cp제자리에 있는 파일을 교체하려고 시도합니다. 이렇게 하면 inode가 참조하는 내용이 변경됩니다. 설명하신대로 작동하지 않습니다.

관련 정보