NFS로 마운트 할 때 디렉토리에 이름이 같은 두 개의 파일을 어떻게 가질 수 있습니까?


8

NFS 마운트 디렉토리에 10,000 개의 파일을 작성하는 C ++ 응용 프로그램 테스트가 있지만, 한 디렉토리에 다른 10,000 개의 파일이 모두 같은 이름으로 두 개의 파일이 표시되어 최근에 한 번 테스트에 실패했습니다. 이는 디렉토리가 NFS 마운트 된 Linux Centos v4 또는 v5에서 볼 수 있지만 디스크가 상주하는 호스트 시스템에서는 볼 수 없습니다.

같은 디렉토리에 같은 이름을 가진 두 개의 파일을 어떻게 가질 수 있습니까?

[centos4x32 destination] ls -al ./testfile03373
-rwx------  1 user root 3373 Sep  3 03:23 ./testfile03373*
[centos4x32 destination] ls -al ./testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 ./testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 ./testfile03373*
[centos4x32 destination] ls -al *testfile03373
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
[centos4x32 destination] ls -alb test*file03373
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
-rwx------  1 user root 3373 Sep  3 03:23 testfile03373*

아래 답변 중 하나에서 제안 된 Perl 스크립트 실행 :

ls -la *03373* | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'

제공합니다 :

-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*
-rwx------\x20\x201\x20user\x20root\x203373\x20Sep\x20\x203\x2003:23\x20testfile03373*

inode (-i) 값으로 인쇄하면 두 복사본이 동일한 inode 항목을 갖습니다 (36733444).

[h3-centos4x32 destination] ls -alib te*stfile03373
36733444 -rwx------  1 user root 3373 Sep  3 03:23 testfile03373*
36733444 -rwx------  1 user root 3373 Sep  3 03:23 testfile03373*

디렉토리 항목이 어떻게 든 손상된 것 같습니다.

내 응용 프로그램에서 합법적으로이 상황을 만들었습니까? 아니면 운영 체제에서 버그입니까? 파일을 작성하는 프로그램에서이를 방지하기 위해 할 수있는 일이 있습니까?

NFS 탑재 소프트웨어에 어떤 종류의 버그가 있다고 생각합니다. 또한 문제가있는 NFS 드라이브의 'umount'와 'mount'로도 문제가 해결되지 않으면 다시 마운트 한 후에도 반복 된 항목이 남아 있습니다.


업데이트 1 : 이제 몇 시간 후에 두 번째 로이 문제가 발생했으며 실제로 이상한 파일은 동일한 파일 testfile03373에서 발생했지만 두 배의 파일에 대해서는 이번에는 다른 inode가 213352984입니다. 또한 디스크가 호스팅되는 Centos 5 시스템에서 파일이 생성되고 있으므로 로컬에서 생성되고 올바른 로컬로 표시되지만 NFS 마운트 된 다른 모든 시스템은 항목이 두 배로 표시됩니다.


업데이트 2 : Centos v6 시스템에 드라이브를 마운트 /var/log/messages하고 이중 항목을 확인한 후 다음을 발견 했습니다.

[root@c6x64 double3373file]# ls -laiB testfile03373* ; tail -3 /var/log/messages
36733444 -rwx------. 1 user root 3373 Sep  3 03:23 testfile03373
36733444 -rwx------. 1 user root 3373 Sep  3 03:23 testfile03373
...
Sep  4 14:59:46 c6x64 kernel: NFS: directory user/double3373file contains a readdir loop.Please contact your server vendor.  The file: testfile03373 has duplicate cookie 7675190874049154909
Sep  4 14:59:46 c6x64 kernel: NFS: directory user/double3373file contains a readdir loop.Please contact your server vendor.  The file: testfile03373 has duplicate cookie 7675190874049154909

또한 파일 이름을 바꾸면 이중 항목이 사라지지만 다시 이름을 바꾸면 이름이 두 배로 다시 나타나거나 이름이있는 새 파일을 만지면 testfile03373이중 항목이 나타납니다. 이 이중 항목이 표시된 두 개의 디렉토리


AFAIK, 모든 파일 시스템의 동일한 디렉토리에 동일한 이름과 확장자가 같은 두 개의 파일은 불가능합니다. 실패를 막기 위해 프로그램에서 일부 예외 메커니즘을 사용할 수 있습니다.
Doktoro Reichard

어떤 파일 시스템을 사용하고 있습니까?
Doktoro Reichard

그들은 정확히 동일합니까? 예를 들어 선행 또는 후행 공백이 없습니까? UTF-16 문자 없음, ...
Hennes

정확히 동일한 지 확인하기 위해 어떤 다른 테스트를 수행 할 수 있습니까?
WilliamKF

중요한 OS 온 전성 검사를 끝내는 방법을 배운 것처럼 들립니다.
Fiasco Labs

답변:


8

친구가이 문제를 추적하는 데 도움을 주었으며 여기에서 Linux 커널 용 Bugzilla 38572에 기록 된 버그를 발견했습니다 . 버그는 커널 3.0.0 버전에서 수정되었지만 최소한 2.6.38 버전에서는 나타납니다.

문제는 서버의 ReadDIR () RPC 호출이 잘못된 결과를 반환한다는 것입니다. 다음과 같은 이유로 발생합니다.

클라이언트는 디렉토리를 읽을 때 최대 버퍼 크기를 지정하고 쿠키를 0으로 만듭니다. 디렉토리가 너무 큰 경우 회신은 회신이 부분적인 것임을 나타내며 쿠키를 업데이트합니다. 그런 다음 클라이언트는 업데이트 된 쿠키로 RPC를 다시 실행하여 다음 데이터 청크를 얻을 수 있습니다. (데이터는 파일 핸들과 이름의 집합입니다. ReadDirPlus ()의 경우 stat / inode / vnode 데이터도 있습니다.) 설명서에는 이것이 ReadDirPlus ()의 버그임을 나타내지는 않지만 아마도있을 수 있습니다. 게다가.

실제 문제는 각 청크의 마지막 파일 (이름, 핸들 튜플)이 때때로 다음 청크의 첫 번째 파일로 반환 된다는 것 입니다.

기본 파일 시스템과의 상호 작용이 잘못되었습니다. Ext4는 이것을 보여 주지만 XFS는 그렇지 않습니다.

그렇기 때문에 일부 상황에서는 문제가 발생하지만 다른 상황에서는 발생하지 않으며 작은 디렉토리에서는 거의 발생하지 않습니다. 질문 설명에서 볼 수 있듯이 파일은 동일한 inode 번호를 표시하고 이름은 동일합니다 (손상되지 않음). Linux 커널은 open () 등과 같은 기본 작업에 대해 vnode 작업을 호출하므로 파일 시스템의 기본 루틴은 어떤 일이 발생하는지 결정합니다. 이 경우, 필요한 정보가 속성 캐시에없는 경우 NFS3 클라이언트는 단지 vnode 작업을 RPC로 변환합니다. 클라이언트가 서버가이 작업을 수행 할 수 없다고 판단하기 때문에 혼란스러워집니다.


커널 3.18.17-13.el6.x86_64 (CentOS 6)에서도 나에게 일어나고 있습니다. 디렉토리가 마운트 된 QNAP TS-212 NAS의 기본 NFS 시스템의 버그라고 확신합니다. 누구 확인?
godzillante

6

디스크는 NFS 마운트 디스크입니다. 드라이브를 게시하는 호스트 컴퓨터로 이동하면 파일이 한 번만 나열됩니다.

NFS의 버그, 문제 또는 경쟁 조건 일 수 있습니다.

16 진 편집기를 사용하여 파일 시스템 구조를 직접 편집하면 동일한 이름의 파일 두 개를 가질 수 있습니다. 그러나 파일을 삭제하거나 열려고하면 어떻게 될지 잘 모르겠습니다. inode 번호 (복제 할 수 없음)로 파일에 액세스하기 위해 Linux에 어떤 도구가 있는지 확실하지 않지만 작동 할 수 있습니다.

파일 이름이 중복 fsck되면 문제가 발생하여 해결하려고 할 수 있습니다.

그러나 파일 뒤에 후미 공백이 다른 파일이 없는지 확인하십시오.


필자는 파일 시스템에 쓰는 양이 궁극적으로 무언가를 깨뜨 렸고 두 개의 동일한 파일이 존재할 수 있다고 제안하려고했습니다.
Doktoro Reichard

실행 중 fsck문제가 없습니다. 호스트와 클라이언트 시스템을 모두 재부팅했는데 여전히 문제가 표시됩니다.
WilliamKF

좀 더 명확 했어야합니다. fsck아마도 NFS 마운트 시스템이 아닌 로컬 파일 시스템에서만 작동 할 것입니다. 아마도 nfs 패키지와 커널을 업그레이드 / 패치해야합니다. @somequixotic에서 언급했듯이 CentOS는 오래되었으며 향후 업데이트에서 발생하는 문제가 해결되었을 수 있습니다.
LawrenceC

4

파일 이름 중 하나에 인쇄 할 수없는 숨겨진 문자 나 공백이있을 수 있습니다. 다음과 같은 -b옵션을 제공하여 확인할 수 있습니다 ls.

user@server:~/test$ ls -lab
total 8
drwxr-xr-x 2 user user 4096 Sep  3 12:20 .
drwx------ 8 user user 4096 Sep  3 12:20 ..
-rw-r--r-- 1 user user    0 Sep  3 12:19 hello
-rw-r--r-- 1 user user    0 Sep  3 12:19 hello\

메모 \명시를 그런 파일 이름의 끝에있는 공간.

   -b, --escape
          print C-style escapes for nongraphic characters

대안으로 (위가 작동해야하지만)이 perl 스크립트를 통해 출력을 파이프하여 인쇄 가능한 ASCII 문자가 아닌 것을 16 진수 코드로 바꿀 수 있습니다. 예를 들어, 공백이됩니다 \x20.

while (<>) {
    chomp();
    while (/(.)/g) {
        $c = $1;
        if ($c=~/[!-~]/) {
            print("$c");
        } else {
            printf("\\x%.2x", ord($c));
        }
    }
    print("\n");
}

용법:

ls -la | perl -e 'while(<>){chomp();while(/(.)/g){$c=$1;if($c=~/[!-~]/){print("$c");}else{printf("\\x%.2x",ord($c));}}print("\n");}'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.