UNIX 파일 권한을 모든 프로세스에 동시에 적용할 수 있습니까?

UNIX 파일 권한을 모든 프로세스에 동시에 적용할 수 있습니까?

파일에 대한 권한 변경을 사용하면 chmod기존 파일 설명자는 이전 권한으로 파일에 계속 액세스할 수 있습니다.

권한 변경으로 인해 기존 파일 설명자가 즉시 닫히거나 실패하거나 사용할 수 없게 될 수 있습니까?

답변1

커널은 파일 설명에 대한 권한을 확인하지 않습니다. 원본 파일에 액세스한 적이 없는 다른 프로세스에 복사할 수도 있습니다.FD 전송.

수동으로 시도할 수 있는 유일한 방법이라고 생각합니다.프로세스를 알아보세요파일 설명자를 연 다음 까다로운 방법을 사용하여 닫습니다 1 . 이러한 "교활한 트릭"의 예는 디버거( gdb)를 연결하고 이를 사용하여 fd를 닫는 것입니다.

이것은 매우 극단적인 일이다.FD가 갑자기 종료되면 프로세스가 어떻게 작동할지 알 수 있는 방법이 없습니다. 경우에 따라 프로세스에 메모리에 매핑된 파일이 있을 수 있으므로 해당 파일을 닫고 메모리 매핑을 삭제하면 프로세스에서 분할 오류로 인해 충돌이 발생할 것으로 예상됩니다.

훨씬 낫다파일을 사용하고 있는 프로세스를 찾아 수동으로 종료하면 됩니다. 최소한 이 방법으로 다른 데이터를 손상시키지 않고 잘 종료하도록 요청할 수 있습니다.


1 주석에서 언급했듯이 이 작업을 수행하는 가장 좋은 방법은 원본 파일 대신 fd를 가리키도록 변경하는 dup2대신 호출하는 것입니다. 이는 코드가 닫힐 것으로 예상하지 않고 fd(number)가 재활용될 때 매우 이상하고 안전하지 않은 작업을 수행할 수 있기 때문입니다.close/dev/null

답변2

Philip Couling이 언급한 "부적절한 트릭"을 통하지 않고는 기존 파일 설명자를 무효화할 수 없습니다. 그러나 (합리적으로) 이식 가능한 방식으로 비슷한 효과를 얻을 수 있습니다.

foo이미 열려 있는 프로세스가 계속해서 작성하는 것을 방지하려는 경우 foo다음을 수행할 수 있습니다 cp foo foo2; chmod -w foo2; mv foo2 foo. 이제 이전 파일을 여는 모든 프로세스는 foo더 이상 호출되지 않는 파일에 계속해서 기록합니다 foo(이전보다 하드 링크가 하나 적음). 이러한 프로세스 foo는 쓰기 위해 열 수 없기 때문에 새로운 프로세스에 영향을 미치지 않습니다.

비슷한 전략은 독서를 방지하려는 경우입니다 cp foo foo2; chmod -r foo2; truncate foo; mv foo2 foo. 여기서는 이전 항목이 foo잘렸습니다(즉,삭제되지 않고 크기가 0으로 줄어듭니다. 따라서 이미 열려 있는 프로세스는 foo다음에 읽으려고 할 때 아무것도 볼 수 없으며 새 프로세스를 열 수 없습니다 foo. 그러나 이것이 작동한다는 보장은 없습니다. 모든 프로세스에 mmaped 가 있는 foo경우 잘림이 실제로 이러한 매핑에 영향을 미치는지 여부를 지정할 수 있는 방법이 없습니다.

답변3

이것은 매우 재미있는 질문이며 이를 해결하는 것은 실제로 Netflix를 시청하는 것보다 일요일을 더 재미있게 만듭니다 :-)

  • 다른 답변에 따르면 posix가 아닌
  • 더러운 트릭: YMMV, 파일 매핑을 해제하여 디버거 트릭을 확장해야 한다고 확신합니다. (이런, 그건 사악합니다. 시스템 호출 사이에 파일 설명자가 유효하지 않게 되는 것은 좋지 않습니다. 하지만 처리하는 것은 불가능합니다. 데이터 구조의 일부가 사라짐).
  • Linux에서: 다음을 보면https://upload.wikimedia.org/wikipedia/commons/f/fb/The_Linux_Storage_Stack_Diagram.svg실제로, 일반적으로 제안 사항을 구현하려면 inode의 페이지 캐시 위치를 조회하고 알 수 없는 방법을 통해 직접 찾아야 합니다(그렇지 않으면 이미 매핑된 메모리가 여전히 존재하므로 시스템 호출이 필요하지 않습니다.). (참고: 페이지 캐시에 대한 액세스를 잠그거나 프로세스 포크를 방지하지 않으면 사용자 공간에서 안정적으로 수행되지 않을 수 있습니다.)
  • (리눅스) 강제 잠금 마운트 옵션 +flock을 사용해 볼 수 있지만 잠금을 "훔칠" 수 있는지 잘 모르겠습니다.

이는 다음을 의미합니다.

  • 우리는 메모리 매핑을 좋아하지 않습니다
  • 우리는 FS 계층 아래의 작업을 방해하는 것을 좋아하지 않습니다.

사용 사례에 따라 다른 가능성도 있습니다.

  • 오버레이 파일 시스템을 구현합니다. 이렇게 하면 매핑이 방지되고 호출을 필터링할 수 있습니다. 실제로는 복잡하지 않습니다.
  • 네트워크 파일 시스템을 사용하여 유사한 작업 수행
  • 가장 중요한 것은 서버 프로세스를 통해 파일에 대한 액세스를 구성하는 것입니다(본질적으로 "오버레이 파일 시스템 구현과 동일하지만 이식 가능" :-)).

관련 정보