여기서는 실행 파일을 다시 쓸 수 있으며 프로세스가 정상적으로 실행된다는 것을 나타냅니다. 프로세스가 다시 시작되면 다시 읽습니다.
그러나 프로세스가 실행되는 동안 (dev에서 테스트 서버까지 scp를 사용하여) 바이너리 파일을 바꾸려고하면 ‘file busy’라고 표시됩니다. 그리고 공유 라이브러리 파일 (* .so)을 교체하면 해당 파일을 연결하는 모든 프로세스가 충돌합니다.
왜 그래? 뭔가 빠졌습니까? 프로세스를 중지 / 충돌하지 않고 바이너리 파일을 바꾸려면 어떻게해야합니까?
답변
에서 언급 한 바와 같이 왜 실행 소프트웨어 패키지는 잘 그것은 업그레이드되는 않는 경우에도? 잠금은 파일 이름이 아닌 inode에 배치됩니다. 바이너리를로드하고 실행할 때 파일이 사용 중으로 표시되므로 파일을 쓰려고 할 때 ETXTBSY (파일 사용 중) 오류가 발생합니다.
이제 공유 라이브러리의 경우 약간 다릅니다. 라이브러리는를 사용하여 프로세스의 주소 공간에 메모리를 매핑합니다 mmap()
. MAP_DENYWRITE
지정할 수는 있지만 Linux에서 적어도 Glibc는 자동으로 무시합니다 (Man 페이지에 따라 소스를 확인하십시오)-이 스레드를 확인하십시오 . 따라서 실제로 파일을 쓸 수 있으며 메모리에 매핑되면 변경 사항이 거의 즉시 표시됩니다. 즉, 충분히 노력 하면 라이브러리를 덮어 써서 머신 을 브릭 할 수 있습니다 .
따라서 업데이트하는 올바른 방법은 다음과 같습니다.
-
파일 시스템에서 데이터에 대한 참조를 제거하는 파일을 제거하여 파일을 사용하려는 새로 생성 된 응용 프로그램에 액세스 할 수 없도록하고 파일을 이미 열거 나 매핑 한 모든 사람이 데이터에 액세스 할 수 있도록합니다. ;
-
업데이트 된 내용으로 새 파일을 만듭니다.
새로 작성된 프로세스는 업데이트 된 컨텐츠를 사용하고 실행중인 애플리케이션은 이전 버전에 액세스합니다. 제정신 패키지 관리 유틸리티가하는 일입니다. dlsym()
라이브러리의 API가 자동으로 변경되면 코드를 동적으로로드하는 응용 프로그램 (예 : 친구들과 친구)이 아무런 위험이없는 것은 아닙니다 .
당신은 정말,에 있으려면 정말 , 안전을 시스템을 종료, 다른 운영 체제 인스턴스 업데이트에서 파일 시스템을 마운트하고 다시 업데이트 된 시스템을 가지고.
답변
rpm 업그레이드는 충돌이없는 동안 바이너리와 라이브러리를 실행하는 것과 동일하게 수행됩니다.
차이점은 무엇입니까?
- 파일 연결 해제
- 같은 이름으로 새 파일을 작성하십시오
이것은 파일을 대체하지 않습니다. 사용중인 이진을 참조하는 inode는 파일을 열어 놓은 마지막 객체가 완료 될 때까지 여전히 “사용 중”입니다. 새로운 파일은 새로운 inode-number로 생성됩니다.
이제 scp
또는 cp
파일을 대체하려고 시도합니다. 그러면 inode가 참조하는 내용이 변경됩니다. 설명 된대로 작동하지 않습니다.