요약
- RFC 3010은 안정적인 클라이언트 이름과 특정 실행 상태(인카네이션)를 분리했다. 바뀌는 검증자(verifier), 협상된 clientid, 인증된 확인 절차를 통해 기억된 이름이 오래된 잠금을 조용히 물려받는 일을 막았다.
- 서버가 상태를 잃은 뒤에는 보통 임대 기간 하나만큼의 유예 기간 동안 재확인(reclaim)을 허용하면서 새로운 충돌 잠금과 보호된 입출력은 거부했고, 연속성은 영구적 권리 주장이 아니라 유한한 복구 절차가 되었다.
파일 서버는 소유권에 대한 기억보다 먼저 재부팅에서 돌아올 수 있다. 디스크는 그대로 있고, 이름은 여전히 풀리며, 네트워크는 요청을 받아들일 수 있지만, 어느 클라이언트가 어느 잠금을 쥐고 있었는지 말해주던 휘발성 테이블은 사라져 있다. 서버가 즉시 충돌하는 잠금을 허가하면, 여전히 자신의 이전 배타적 권한이 유효하다고 믿는 클라이언트를 배신하게 된다. 반대로 영원히 기다리면 죽은 클라이언트 하나가 살아 있는 시스템 전체를 마비시킬 수 있다.
RFC 3010, 즉 2000년 12월에 발표된 최초의 NFS 버전 4 프로토콜 사양은 이 간격을 관리자의 기분이 아니라 프로토콜 문제로 다루었다. NFSv4는 이전 버전이 서버 상태를 최소화하는 것으로 유명했던 설계에 잠금을 통합했다. 잠금, 열기(open), 위임(delegation)이 호출 사이에서 중요해지는 순간, 복구에는 그 자체의 증거와 시계와 순서가 필요해졌다.
첫 번째 구분은 클라이언트와 클라이언트 인카네이션 사이의 구분이었다. 클라이언트는 안정적으로 유지될 수 있는 불투명한 식별자와 함께, 클라이언트가 재시작되어 이전의 휘발성 상태를 잃을 때 바뀌리라 기대되는 검증자(verifier)를 제공했다. 호스트 이름이나 네트워크 주소는 "어느 기계인가?"에는 답할 수 있어도 "어느 부팅인가?"에는 답할 수 없었다. 검증자가 두 번째 질문을 보이게 만들었다.
이 구분은SETCLIENTID를 통해 협상되었다. 서버는 제안된 신원을 RPC 요청의 인증된 주체(principal)와 연결하고, 짧은 64비트 clientid를 돌려주며 확인용 검증자를 제공했다.SETCLIENTID_CONFIRM이 이 교환을 완료했다. 이후 clientid는 전역 신원도, 재산 권리도, 무기명 자격 증명도 아니라 이후 상태를 가리키는 효율적인 서버 로컬 참조로 기능했다.
이 핸드셰이크는 충돌도 드러냈다. 잘못된 구성, 복제된 고가용성 설정 또는 적대적 행동 때문에 두 대의 기계가 같은 불투명한 클라이언트 이름을 가질 수 있었다. RFC 3010은 서버에 이들을 병합하라고 말하지 않았다. 서버는NFS4ERR_CLID_INUSE를 반환하고 기존 점유자에게 연락 가능한 위치를 알려줄 수 있었다. 이름의 동일성은 해결해야 할 충돌의 증거였지, 공유된 주체의 증명이 아니었다.
동일한 인증된 클라이언트가 바뀐 검증자로 돌아오면, 서버는 새 인카네이션이 더 이상 기존 인메모리 잠금 상태를 보유하지 않는다고 추론할 수 있었다. 그러면 이전 clientid에 묶인 잠금을 해제할 수 있었다. 보안 한정자가 여기서 결정적이었다. 인증되지 않은 낯선 이가 남의 이름으로 재부팅을 주장해 유효한 잠금이 사라지게 해서는 안 되기 때문이다. 검증자가 시대(epoch)의 변경을 탐지하고, RPC 주체가 그 시대를 바꿀 수 있는 대상을 한정했다.
시간이 두 번째 경계를 제공했다. RFC 3010은 잠금 상태를 위한 서버가 선택한 임대(lease) 구간을 정의했다. 상태를 만들거나 사용하는 보통의 작업은 공통 클라이언트 마감 시한을 묵시적으로 갱신할 수 있고, 그 외에 한가한 클라이언트는RENEW를 보낼 수 있었다. 갱신은 클라이언트의 상태 집합에 적용되었으므로 천 개의 잠금이 천 개의 킵얼라이브를 요구하지 않았다.
임대는 충돌하는 허가에 대한 임시 보호이지 영구 소유가 아니었다. 클라이언트가 구간을 넘어 침묵하면 서버는 그 상태를 해제하고 다른 이들이 진행할 수 있게 했다. 긴 분할(partition) 이후 복귀한 클라이언트는 오래된 stateid를 사용하려 할 때NFS4ERR_EXPIRED를 받을 수 있었다. 올바른 대응은 옛 잠금이 여전히 서버를 지배한다고 가장하는 것이 아니었다. 응용 프로그램은 배타 권한이 상실되었음을 학습해야 했다.
서버 장애는 반대 방향의 비대칭을 만들었다. 재시작된 서버가 인식하지 못하는 stateid를 클라이언트들이 여전히 유효해 보이는 채로 기억하고 있을 수 있다. 그래서NFS4ERR_STALE_STATEID와NFS4ERR_STALE_CLIENTID는 시대(epoch)의 증거였다. 이들은 클라이언트에게 낡은 네임스페이스 아래에서 보통 작업을 단순히 다시 제출하지 말고 새 clientid를 확립해 복구에 들어가라고 말했다.
복구 메커니즘이 바로 유예 기간(grace period)이었다. 보통 임대 구간과 같은 기간 동안 복귀한 클라이언트는CLAIM_PREVIOUS를 포함한 재확인 형식의LOCK과OPEN요청을 보낼 수 있었다. 단순하고 안전한 서버 동작은 새 잠금, 새 열기, 읽기, 쓰기를NFS4ERR_GRACE로 거부하는 것이었다. 서버는 동작 중이었지만, 권한 표면의 한 부분이 의도적으로 닫혀 있었다.
이 임시 거부가 이 설계의 가장 중요한 행위다. 이는 아직 도착하지 않은 클라이언트들을 보호했다. 이전 점유자는 아직 재접속 중이거나, 재부팅을 인지하는 중이거나, 자신의 상태를 재구성하는 중일 수 있다. 새 충돌 허가를 먼저 허용하면 장애 이후의 도착 순서가 곧 소유권이 되어 버린다. 유예 기간은 새 청구자가 기다리는 동안 오래된 청구가 유한한 기회 안에서 재구성될 수 있게 만들었다.
이 일시 정지는 절대적이지 않았다. RFC 3010은 이후의 재확인이 충돌하지 않을 것이고 어떤 정당한 재확인도 새 작업 때문에 거부되지 않을 것임을 보장할 수 있을 때, 유예 기간 중 새 작업을 처리하는 것을 허용했다. 안정 저장소가 그런 증거를 제공할 수 있었다. 보존된 잠금 개수나 기록이 특정 파일에 회수해야 할 미결 청구가 없음을 보여줄 수 있는 것이다. 최적화는 증명 이후에만 허용되었고, 단지 서비스 압박이 대기를 불편하게 만든다는 이유로 허용되지 않았다.
또한 유예 기간은 끝없는 사면이 아니었다. 창이 닫힌 뒤에 제출된 재확인은 서버가 재시작 이후 충돌하는 잠금이나 입출력을 하나도 허가하지 않았음을 보장할 수 있는 경우에만 성공할 수 있었다. 새 사실이 상태 기계에 들어온 이후에는 기록되지 않은 오래된 청구가 그것들을 안전하게 밀어낼 수 없었다. 마감은 불확실성을 유한한 운영 비용으로 바꾸었다.
RFC 2624는 NFSv4 뒤에 있던 설계 압력을 기술했다. 더 강한 보안, 통합된 잠금, 인터넷 규모의 운영, 더 적은 왕복이 그것이었다. RFC 3010이 최초의 완전한 프로토콜을 제공했다. 이후RFC 3530이 이를 대체했고,RFC 7530이 그 다음 NFSv4.0 사양이 되었다. 어휘와 경계 사례는 진화했으므로, RFC 3010은 오늘의 구현 매뉴얼이 아니라 역사적 자료다.
NFSv4.1은 더 나아갔다.RFC 5661은EXCHANGE_ID, 세션, 더 명시적인 복구 아키텍처를 도입했다. 그것을 대체한RFC 8881은 오래 지속되는 트레이드오프를 설명한다. 서버가 곤란한 장애 이후 재확인을 더 관대하게 존중하고 싶을수록, 클라이언트와 상태에 대해 더 내구적인 증거를 보존해야 한다. 관용은 보관의 대가로 산다.
그 이후의 세부 사항이 원래의 통찰을 지우지는 않는다. 안정적인 이름은 안정적인 권한이 아니다. 클라이언트 이름은 그 프로세스, 기억, 의무가 모두 바뀌었음에도 같게 남을 수 있다. 서버 주소가 같게 남아 있어도 그 잠금 테이블은 새 시대에 속할 수 있다. 연속성은 그 단절을 가로지르는 영수증으로 입증되어야 한다.
Lu Heng의 Running-Code Primacy 관점에서 보면, 실질적인 권리는 재시작된 서버가 로컬에서 검증할 수 있는 권리다. 인증된 클라이언트 인카네이션, 인식된 복구 모드, 자격 있는 이전 상태, 만료되지 않은 복구 창, 이후 충돌의 부재. 최소 공통 규칙은 어떤 기관이 청구를 영원히 기억한다는 것이 아니라, 실행 가능한 복구 순서가 장애 덕분에 먼저 도착했다는 이유만으로 새 청구자가 이기지 못하게 만든다는 것이다.
안정성 환상(The Stability Fallacy)은 익숙한 이름이나 끊김 없는 파일시스템 뷰가 오래된 배타 권한이 여전히 존재한다는 증명으로 취급될 때 나타난다. RFC 3010은 더 어려운 일을 했다. 상태가 사라질 수 있음을 인정하고, 그 상실을 낡은 식별자로 드러내며, 새 충돌을 측정된 구간 동안 동결하고, 보통의 경쟁이 재개되기 전에 연속성이 재건되어야 한다고 요구했다.
잠금은 클라이언트가 기억했기 때문에 살아남은 것이 아니다. 클라이언트가 그것을 재구성할 기회를 받은 것은 프로토콜이 불확실성을 어떤 순서로 다루어야 하는지 기억하고 있었기 때문이다. 그것은 영속이라는 약속보다 작고, 훨씬 더 방어 가능한 약속이다.
출처
- RFC 3010, NFS version 4 Protocol
- RFC 3010 RFC 편집기 정보 페이지
- RFC 2624, NFS Version 4 Design Considerations
- RFC 3530, Network File System Version 4 Protocol
- RFC 5661, NFS Version 4 Minor Version 1 Protocol
- RFC 7530, Network File System Version 4 Protocol
- RFC 8881, NFS Version 4 Minor Version 1 Protocol
- Lu Heng, “Running-Code Primacy: The Patch Needed to Preserve the Internet’s Original Design”
- Lu Heng, “Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption for Internet Coordination Systems”
- Lu Heng, “The Stability Fallacy in the RIR Argument”
회원 브리핑
프로필 심층 컨텍스트
올바른 멤버십 등급으로 로그인하면 전체 브리핑과 출처 노트를 볼 수 있습니다.
Strategic Circle 전용
Strategic Circle
모든 독자에게 공개됩니다. 가입 후 로그인하면 프로필 브리핑를 열람할 수 있습니다.
Strategic Circle 가입하기Leadership Alliance 전용
Leadership Alliance
자격을 갖춘 IP 자산 소유자 및 운영진을 위한 콘텐츠입니다. 로그인하면 Leadership Alliance 브리핑을 열람할 수 있습니다.
Leadership Alliance 가입하기





