UNIX/Linux에서 디렉토리 하드 링크가 허용되지 않는 이유는 무엇입니까?

UNIX/Linux에서 디렉토리 하드 링크가 허용되지 않는 이유는 무엇입니까?

나는 Unix/Linux가 디렉토리에 대한 하드 링크를 허용하지 않지만 소프트 링크를 허용한다는 것을 교과서에서 읽었습니다. 루프가 발생했을 때 하드 링크를 생성하고 일정 시간이 지난 후 원본 파일을 삭제하면 일부 쓰레기 값을 가리킬 것이기 때문입니까?

루프가 하드 링크가 허용되지 않는 유일한 이유라면 디렉토리에 대한 소프트 링크는 왜 허용됩니까?

답변1

하드 링크와 원래 이름을 구별할 방법이 없기 때문에 이것은 단지 나쁜 생각입니다.

디렉터리에 대한 하드 링크를 허용하면 파일 시스템의 방향성 비순환 그래프 구조가 손상되어 잠재적으로 디렉터리 루프가 생성되고 fsck다른 파일 트리 탐색자에게 오류가 발생하기 쉬운 디렉터리 하위 트리가 매달려 있게 됩니다.

먼저 이를 이해하기 위해 인덱스 노드에 대해 알아보겠습니다. 파일 시스템의 데이터는 디스크의 블록에 보관되며 inode에 의해 함께 수집됩니다. inode를 파일로 생각할 수 있습니다. 그러나 inode에 파일 이름이 없습니다. 여기가 링크가 작동하는 곳입니다.

링크는 단지 inode에 대한 포인터일 뿐입니다. 디렉토리는 링크를 보유하는 인덱스 노드입니다. 디렉토리의 각 파일 이름은 단지 inode에 대한 링크일 뿐입니다. Unix에서 파일을 열면 링크도 생성되지만 이는 다른 유형의 링크입니다(이름이 지정된 링크가 아님).

하드 링크는 해당 inode를 가리키는 추가 디렉토리 항목입니다. 링크 수를 지정할 때 ls -l권한 뒤의 숫자는 다음과 같습니다. 대부분의 일반 파일에는 링크가 있습니다. 새 파일 하드 링크를 생성하면 두 파일 이름이 모두 동일한 inode를 가리키게 됩니다. 노트:

% ls -l test
ls: test: No such file or directory
% touch test
% ls -l test
-rw-r--r--  1 danny  staff  0 Oct 13 17:58 test
% ln test test2
% ls -l test*
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
% touch test3
% ls -l test*
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
-rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
-rw-r--r--  1 danny  staff  0 Oct 13 17:59 test3
            ^
            ^ this is the link count

이제 하드링크 같은 것이 없다는 것을 확실히 알 수 있습니다. 하드링크는 일반 이름과 동일합니다. 위의 예 test또는 에서 test2원본 파일은 무엇이며 하드 링크는 무엇입니까? 결국 두 이름이 모두 동일한 것, 동일한 inode를 가리키기 때문에 (타임스탬프를 통해서도) 실제로 알 수는 없습니다.

% ls -li test*  
14445750 -rw-r--r--  2 danny  staff  0 Oct 13 17:58 test
14445750 -rw-r--r--  2 danny  staff  0 Oct 13 17:58 test2
14445892 -rw-r--r--  1 danny  staff  0 Oct 13 17:59 test3

-i플래그는 ls줄 시작 부분에 inode 번호를 표시합니다. 과 의 inode 번호 testtest2동일하지만 test3inode 번호가 다릅니다.

이제 디렉터리를 사용하여 이 작업을 수행할 수 있다면 파일 시스템의 서로 다른 지점에 있는 두 개의 서로 다른 디렉터리가 동일한 항목을 가리킬 수 있습니다. 실제로 하위 디렉터리는 상위 디렉터리를 가리키며 순환을 만들 수 있습니다.

이 주기에 주목할 가치가 있는 이유는 무엇입니까? 순회할 때 루핑 중임을 감지할 방법이 없기 때문입니다(순회하는 동안 아이노드 번호는 추적되지 않습니다). du디스크 사용량을 이해하기 위해 하위 디렉터리로의 재귀가 필요한 명령을 작성한다고 상상해 보십시오 . du루프에 언제 들어가는지 어떻게 알 수 있나요 ? du이 간단한 작업을 수행하려면 오류가 발생하기 쉽고 많은 장부가 필요합니다.

심볼릭 링크는 많은 파일 시스템 API가 자동으로 따르는 경향이 있는 특별한 유형의 "파일"이기 때문에 완전히 다른 짐승입니다. 심볼릭 링크는 inode를 직접 가리키는 것이 아니라 이름으로 가리키기 때문에 존재하지 않는 대상을 가리킬 수 있습니다. 이 개념은 하드 링크에는 적합하지 않습니다. 왜냐하면 "하드 링크"가 존재한다는 것은 파일이 존재한다는 것을 의미하기 때문입니다.

du그렇다면 심볼릭 링크는 처리하기가 더 쉽지만 하드 링크는 처리하기가 더 쉬운 이유는 무엇입니까 ? 위에서 보면 하드 링크가 일반 디렉토리 항목과 다르지 않다는 것을 알 수 있습니다. 그러나 심볼릭 링크는 특별하고 감지 가능하며 건너뛸 수 있습니다!  du심볼릭 링크는 심볼릭 링크이므로 완전히 건너뛰십시오!

% ls -l 
total 4
drwxr-xr-x  3 danny  staff  102 Oct 13 18:14 test1/
lrwxr-xr-x  1 danny  staff    5 Oct 13 18:13 test2@ -> test1
% du -ah
242M    ./test1/bigfile
242M    ./test1
4.0K    ./test2
242M    .

답변2

마운트 지점 외에도 모든 디렉토리에는 하나의 상위 디렉토리만 있습니다: ...

한 가지 방법은 pwddevice:inode에 "." 및 '..'이 있는지 확인하는 것입니다. 동일하다면 파일 시스템의 루트에 도달한 것입니다. 그렇지 않으면 상위 디렉터리에서 현재 디렉터리의 이름을 찾아 스택에 푸시하고 "../."를 먼저 "../.."와 비교한 다음 "../../."를 비교하기 시작합니다. 기다리다. 루트가 발견되면 스택을 꺼내고 이름을 인쇄하기 시작합니다. 이 알고리즘은 모든 디렉터리에 상위 디렉터리가 하나만 있다는 사실에 의존합니다.

디렉토리에 대한 하드 링크가 허용되면 여러 상위 디렉토리 중 어느 디렉토리가 ..하나를 가리켜야 합니까? 이것이 디렉토리 하드 링크를 허용하지 않는 강력한 이유입니다.

디렉터리에 대한 기호 링크는 문제를 일으키지 않습니다. 프로그램이 원하는 경우 lstat()경로 이름의 각 부분에 대해 작업을 수행하고 기호 링크가 발견되는 시기를 감지할 수 있습니다. 이 pwd알고리즘은 대상 디렉토리의 실제 절대 경로 이름을 반환합니다. 대상 디렉토리를 가리키는 텍스트(기호 링크)가 어딘가에 있다는 사실은 거의 관련이 없습니다. 이 심볼릭 링크의 존재는 그래프에 순환을 생성하지 않습니다.

답변3

이 문제에 대해 몇 가지 사항을 추가하고 싶습니다. 디렉토리에 대한 하드 링크는 Linux에서 허용되지만 제한된 방식으로 허용됩니다.

이를 테스트하는 한 가지 방법은 디렉토리의 내용을 나열할 때 두 개의 특수 디렉토리 "."를 찾는 것입니다. 그리고"..". 우리가 아는 한 "."은 동일한 디렉터리를 가리키고 ".."는 상위 디렉터리를 가리킵니다.

따라서 "a"가 상위 디렉터리이고 디렉터리 "b"가 하위 디렉터리인 디렉터리 트리를 만들어 보겠습니다.

 a
 `-- b

디렉터리 "a"의 인덱스 노드를 확인하세요. "a" 디렉터리에서 작업을 수행하면 ls -la"."을 볼 수 있습니다. 디렉토리도 동일한 inode를 가리킵니다.

797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a

여기에서 "a" 디렉토리에는 세 개의 하드 링크가 있음을 알 수 있습니다. 이는 inode 797358에 "."라는 이름의 하드 링크가 3개 있기 때문입니다. "a" 디렉터리에서 이름은 ".."입니다. "b" 디렉터리에서 이름은 "a"입니다.

$ ls -ali a/
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 .

$ ls -ali a/b/
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 ..

따라서 여기서 우리는 하드 링크가 디렉토리를 상위 디렉토리 및 하위 디렉토리에 연결하는 데만 사용된다는 것을 이해할 수 있습니다. 따라서 하위 디렉터리가 없는 디렉터리에는 2개의 하드 링크만 있으므로 "b" 디렉터리에는 2개의 하드 링크만 있습니다.

무료 디렉토리 하드 링크를 방지하는 이유 중 하나는 파일 시스템을 순회하는 프로그램을 혼란스럽게 할 수 있는 무한 참조 순환을 방지하는 것입니다.

파일 시스템은 트리로 구성되어 있으며 트리는 순환 참조를 가질 수 없으므로 이는 피해야 합니다.

답변4

디렉터리에 대한 하드 링크 생성은 복구할 수 없습니다. 다음과 같은 결과가 있다고 가정합니다.

/dir1
├──this.txt
├──directory
│  └──subfiles
└──etc

에 하드링크했습니다 /dir2.

이제 /dir2이러한 파일과 디렉터리도 모두 포함됩니다.

마음이 바뀌면 어떻게 되나요? 난 그럴 수 없어 rmdir /dir2(비어있지 않으니까)

재귀적으로 삭제하면 /dir2... 그것도 삭제됩니다 /dir1!

IMHO, 이것이 이것을 피하는 좋은 이유입니다!

편집하다:

의견에서는 디렉토리에 대한 작업을 수행하여 디렉토리를 삭제할 것을 제안합니다 rm. 그러나 rm비어 있지 않은 디렉토리에서는 실패하며 디렉토리가 하드 링크되었는지 여부에 관계없이 이 동작을 유지해야 합니다. 따라서 연결을 끊을 수는 없습니다 rm. 새 매개변수를 사용 rm하고 "inode의 참조 개수가 1보다 큰 경우에만 디렉터리 연결을 해제하세요"라고 말합니다.

이것은 결국 또 다른 가장 놀라운 원칙을 깨뜨립니다. 즉, 방금 생성한 디렉터리 하드 링크를 삭제하는 것은 일반 파일 하드 링크를 삭제하는 것과 동일하지 않다는 의미입니다.

내 문장을 다시 표현하겠습니다. 추가 개발이 없으면 하드 링크 생성을 되돌릴 수 없습니다. (현재 명령은 현재 동작과 일치하지 않고 삭제를 처리할 수 없기 때문입니다.)

더 많은 개발자가 이 사건을 처리하도록 허용하면 트랩의 수와데이터 손실 위험시스템 작동 방식에 대해 충분히 알지 못한다면 이와 같은 개발은 IMHO, 이것이 디렉토리 하드 링크를 제한하는 좋은 이유라는 것을 의미합니다.

관련 정보