![디렉토리의 원자적 제거](https://rvso.com/image/36018/%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%EC%9D%98%20%EC%9B%90%EC%9E%90%EC%A0%81%20%EC%A0%9C%EA%B1%B0.png)
rename(2)
에 의해 호출되기 때문에 mv
다음이 원자적이라고 가정하는 것이 안전합니까?
$ mv /home/me/someDir /tmp/toBeDeleted
$ rm -rf /tmp/toBeDeleted
답변1
그만큼mv
명령전화하다rename
시스템 호출, 이는 원자성이 보장됩니다. 그러나 두 가지 예외가 있습니다.
- 소스와 대상이 서로 다른 파일 시스템에 있는 경우(대체로 일반적임) 실패
/home
하고 소스 트리를 대상에 복사한 다음 소스 트리를 제거하여 작동합니다. 이것은 분명히 원자적이지 않습니다./tmp
rename
mv
rename
NFS의 특정 구현과 같이 원자적이지 않은 파일 시스템이 있습니다 . "일반적인" 로컬 파일 시스템에서는rename
원자적입니다.
답변2
디렉터리가 단일 파일 시스템으로 마운트된 동일한 하드웨어 파티션에 있는 경우, 그런 다음 무언가를 이동하는 것은 실제로 이름을 다른 경로로 바꾸는 것입니다. 그러나 그렇지 않은 경우 내부의 각 파일을 읽고 복사해야 할 수 있으므로 이동의 어떤 부분도 원자적이지 않습니다. Gilles가 지적했듯이 POSIX는 이것이 개별 파일 시스템의 경우라고 규정합니다.
strace
이를 제외하고 확인을 통한 빠른 확인에는 시스템 호출이 mv
사용됩니다 ( 명령줄 유틸리티인 rename()
와 혼동하지 마십시오 ). 그러면 사용자 공간 관점에서 디렉토리가 원자화 rename
됩니다 . 다음과 같은 경우 mv
시스템 rename()
호출에서 EBUSY 오류가 발생합니다.
oldpath 또는 newpath는 일부 프로세스에서 사용 중이거나(현재 작업 디렉토리, 루트 디렉토리 또는 읽기 위해 열려 있기 때문에) 시스템에서 사용 중인 디렉토리(예: 마운트 지점)입니다. 시스템에서는 이를 오류로 간주합니다. (이러한 경우에는 EBUSY를 반환할 필요가 없습니다. 어쨌든 이름을 바꾸는 데 아무런 문제가 없습니다. 하지만 시스템이 그러한 상황을 처리할 수 없는 경우 EBUSY를 반환하는 것이 허용됩니다.)
에서 man 2 rename
. 여기서 "원자성"에 대한 연결은 디렉터리에서 작업하는 다른 프로세스를 중단할 수 없고 다른 프로세스가 이를 중단할 수 없다는 것입니다. 이를 초과하면 잘못된 경로/찾을 수 없음 유형 오류가 발생하게 됩니다. 추격.
답변3
두 답변 모두 본질적으로 동일한 내용을 말하지만 제거의 한 측면에만 중점을 둡니다.
이름이 변경되거나 이동된 디렉토리 트리 내에 작업 디렉토리가 있는 쉘이 있는 경우 계속해서보다그리고사용해당 파일은 실제로 제거될 때까지 삭제됩니다. 이로 인해 쉘은 다양한 삭제 상태의 파일을 볼 수 있으며 결과적으로 이름 바꾸기/이동(동안 5월BE"원자"그 자체)는~ 아니다파일의 모든 사용자의 관점에서 볼 때 원자 형태의 삭제입니다. 처음부터 쉘이 디렉토리 트리 외부에 있는 사용자에게만 영향을 미칩니다.
쉘은 자신이 속한 디렉토리에 관한 자체 정보를 유지합니다. 이는 일부 구성에서 실제 경로를 결정하는 데 필요한 디렉토리 정보 체인을 읽을 권한이 없는 디렉토리로 현재 디렉토리를 변경할 수 있기 때문입니다. 예를 들어 다음과 같습니다. 보호된 디렉토리에 대한 심볼릭 링크.
POSIX는 동작 이유에 대해 모호하지만 다음에 대한 동작을 지적합니다.pwd
(쉘 내장) 및cd
(쉘 내장).