it-swarm-ko.tech

NFS를 통한 flock (2) 대 fcntl (2)

Perl 5.x 문서에는 flock (..) 구현이 다음 기본 호출 중 하나를 사용하며, 사용할 수없는 경우 1에서 시작하여 3을 향해 작동합니다.

  1. 무리 (2)
  2. fcntl (2)
  3. lockf (3)

괜찮아. 그러나 flock (2)을 NFS를 통해 사용해서는 안된다는 면책 조항을 알고 계실 것입니다. 이 문서는 -Ud_flock 플래그를 사용하여 Perl이 flock (2)을 사용하도록 할 것을 제안합니다. flock (2) (Redhat)의 man 페이지에는 NFS 문제에 대한 유사한 면책 조항이 나와 있습니다.

제 질문은 왜!?!? flock (2)이 NFS에서 안전하지 않은 이유에 대한 자세한 기사 나 설명을 찾을 수없는 것 같습니다.

Redhat (flock (2)이 사용되는 곳)과 Solaris (fcntl (2)가 사용되는 곳)에서 C와 Perl로 여러 테스트 스크립트를 작성했습니다. Perl이 실제로 flock (2) 및 fcntl (2)를 각각 사용하고 있는지 확인하기 위해 strace/truss를 실행했습니다. 잠금이 적용되지 않는 문제를 복제 할 수 없었습니다! 무엇을 제공합니까 ??

21
Jmoney38

Lennart Poettering은 최근에 리눅스 파일 시스템 잠금 동작을 파헤 쳤는데, 이는 NFS를 통한 잠금에 대해 특별히 장밋빛 그림을 그리지 않습니다 (특히 게시물 하단에 링크 된 후속 작업).

http://0pointer.net/blog/projects/locking.html

3
Ivatar

나는 당신이 레거시 문제를보고 있다고 확신합니다. Perl5 매뉴얼은 1994 년에 출시되었으며 1991 년부터 Perl4 매뉴얼의 편집본에 불과하다는 것을 상기하십시오. 그 당시에는 종종 이름이 붙여진 Nightmare File System에 대해 "곰이 춤을 잘 추는 것은 아닙니다. 놀랍지 만 전혀 춤을 추는 것입니다. ".

1991 년 Epoch의 NFS2는 서서히 Sun에서 다른 플랫폼으로 이동하고 있었고 상대적으로 조잡했습니다. 보안 모델은 본질적으로 존재하지 않았으며 (클라이언트 시스템의 루트는 NFS 마운트의 전체 내용을 읽을 수 있음) nfs.lockd를 통한 잠금은 실험적인 측면이었습니다. 상호 운용이 가능하다고 주장되는 두 개의 서로 다른 구현간에 무리 의미 체계가 제대로 작동 할 것이라고 기대하는 것은 어리석은 일이었습니다. Coax는 많은 네트워크 사용자가 사용하는 것에 불만이 없었던 당시 지배적 인 이더넷 PHY였습니다 (50 ???? 종단 저항을 켜는 것을 잊었다는 의미입니까?). 상태를 더 잘 파악할 수 있다면 인트라넷의.

Larry Wall과 승무원은 당시 NFS 잠금의 정확성에 대해 비관적 인 가정을 할 모든 이유를 가지고 있었으며, 이것은 결함이 없음을 증명하기가 너무 어렵 기 때문에 미래의 코드 자키가 제거하기를 싫어하는 일종의 방어 프로그래밍입니다. 들어 본 적도없는 레거시 시스템과의 상호 운용성에 다시 도입 된 오래된 코드를 제거합니다.

그 이후로 NFS는 상당히 개선되었으며 lockd는 Linux 2.6 커널의 기능으로 시간이지나면서 마이그레이션되었습니다. 2003+ 시스템 모음의 경우 NFS 파일 잠금을 신뢰할 수 있습니다. 특히 실행중인 여러 플랫폼에서 응용 프로그램 내에서 잘 테스트 된 경우 특히 그렇습니다.

위의 모든 내용은 기억에서 비롯되었으며 연구를 통해 입증 될 수 있지만 (예 : http://nfs.sourceforge.net/ ) 증거는 잠금에 있습니다. 테스트하지 않으면 손상된 것으로 간주됩니다.

16
msw

Linux-NFS FAQ : nfs.sf.net의 또 다른

여러 클라이언트에서 사용되는 파일을 잠그기 위해 flock ()/BSD 잠금을 사용하려고하는데 파일이 손상되었습니다. 어째서? A. flock ()/BSD 잠금은 2.6.12 이전의 Linux NFS 클라이언트에서만 로컬로 작동합니다. fcntl ()/POSIX 잠금을 사용하여 파일 잠금이 다른 클라이언트에 표시되는지 확인하십시오.

다음은 NFS 파일에 대한 액세스를 직렬화하는 몇 가지 방법입니다.

Fcntl ()/POSIX 잠금 API를 사용하십시오. 이러한 유형의 잠금은 NLM 프로토콜 또는 NFSv4를 통해 여러 클라이언트에 대해 바이트 범위 잠금을 제공합니다. 별도의 잠금 파일을 사용하고 이에 대한 하드 링크를 만듭니다. creat (2) 매뉴얼 페이지의 O_EXCL 섹션에있는 설명을 참조하십시오. 2.6 초기 커널까지 O_EXCL 생성은 Linux NFS 클라이언트에서 원 자성이 아니었다는 점에 주목할 가치가 있습니다. 2.6.5보다 새로운 커널을 실행하지 않는 한 O_EXCL 생성을 사용하지 말고 여러 NFS 클라이언트간에 원자 적 동작을 기대하십시오.

Perl이 기본적으로 flock ()/BSD 잠금을 사용하는 것은 알려진 문제입니다. 이것은 플록/BSD 잠금이 POSIX 잠금처럼 작동 할 것으로 예상하는 Solaris와 같은 다른 운영 체제에서 포팅 된 프로그램을 손상시킬 수 있습니다.

Linux에서 하드 링크 대신 파일 잠금을 사용하면 클라이언트의 캐시를 서버와 검사하는 추가 이점이 있습니다. 파일 잠금이 획득되면 클라이언트는 해당 파일에 대한 페이지 캐시를 플러시하여 후속 읽기가 서버에서 새 데이터를 가져 오도록합니다. 파일 잠금이 해제되면 해당 파일을 잠그기를 기다리는 다른 클라이언트가 변경 사항을 볼 수 있도록 해당 클라이언트의 파일에 대한 변경 사항이 잠금이 해제되기 전에 서버로 다시 플러시됩니다.

2.6.12의 NFS 클라이언트는 POSIX 바이트 범위 잠금 측면에서 BSD 스타일 잠금을 에뮬레이트하여 NFS 파일에 대한 flock ()/BSD 잠금을 지원합니다. 동일한 에뮬레이션 메커니즘을 사용하거나 fcntl ()/POSIX 잠금을 사용하는 다른 NFS 클라이언트는 Linux NFS 클라이언트가 보는 것과 동일한 잠금을 보게됩니다.

로컬 Linux 파일 시스템에서 POSIX 잠금과 BSD 잠금은 서로에게 보이지 않습니다. 따라서이 에뮬레이션으로 인해 Linux NFS 서버에서 실행되는 응용 프로그램은 클라이언트의 응용 프로그램이 BSD 스타일을 사용하든 POSIX- 스타일 잠금. 서버 응용 프로그램이 flock () BSD 잠금을 사용하는 경우 NFS 클라이언트가 사용하는 잠금을 볼 수 없습니다.

3
Nikhil Mulley

이것은 현재 구식입니다. NFS4는 잠금 프로토콜 내부 (잠긴 데몬 또는 RPC 콜백 메커니즘이 필요하지 않음)을 지원하며 Perl의 flock() 메서드는 정상적으로 작동합니다. 우리는 프로덕션에서 사용하고 있습니다.

매우 오래된 커널 버전은 NFS에서 no-op으로 flock (syscall)을 구현했으며 바이트 범위 잠금과 같은 다른 기능은 제대로 지원되지 않았습니다. 이것이 히스테리가 시작되는 곳입니다.

3
rjh