Resumo

  • A RFC 3010 separou o nome durável do cliente de sua encarnação em execução: verifier renovado no boot, clientid negociado e confirmação autenticada impediram que o mesmo nome herdasse sozinho bloqueios antigos.
  • Quando o servidor perdia estado, um grace period de aproximadamente um lease priorizava reclaims e segurava locks e E/S novos que pudessem conflitar. Continuidade era procedimento temporário, não posse eterna.

O arquivo continuava no disco, mas o servidor já não lembrava quem podia impedir os outros de tocá-lo. O cliente guardava um stateid e sua memória do bloqueio; o processo recém-iniciado não guardava a tabela correspondente. Esse desencontro podia transformar o primeiro pedido após a falha em vencedor de uma disputa que começara antes dela.

Publicada em dezembro de 2000, a RFC 3010 apresentou a primeira especificação completa de NFSv4. Integrar locks ao protocolo trouxe uma obrigação nova: explicar como estado temporário atravessaria reinicializações, partições e memórias divergentes.

O cliente possuía duas faces. Um identificador opaco podia ficar estável; um verifier deveria mudar a cada inicialização. Nome de host dizia qual máquina, mas não qual boot. O estado volátil pertencia à encarnação, e não ao rótulo abstrato.

SETCLIENTID ligava id e verifier ao principal autenticado da chamada RPC. O servidor devolvia um clientid curto e um verifier de confirmação; SETCLIENTID_CONFIRM fechava a negociação. Depois, o clientid servia de referência local eficiente. Não era identidade global, título de propriedade ou autorização portátil.

Nomes iguais podiam revelar erro. Configurações clonadas ou clientes indevidos podiam apresentar o mesmo id. NFS4ERR_CLID_INUSE impedia uma fusão silenciosa. A coincidência exigia separar os demandantes antes de associar estado.

Se o principal correto voltasse com verifier novo, o servidor podia reconhecer uma nova encarnação sem a memória anterior e liberar locks do clientid antigo. A autenticação era indispensável: sem ela, um terceiro poderia fabricar o reinício alheio e apagar bloqueios válidos. O verifier marcava época; o principal dizia quem podia marcá-la.

O lease estabelecia a fronteira temporal. O servidor definia um período comum para todo o estado do cliente. Operações usuais renovavam o prazo implicitamente e RENEW atendia clientes ociosos. Uma renovação cobria o conjunto, sem criar uma mensagem para cada lock.

Quando o prazo acabava, o servidor podia recuperar estado e conceder conflitos. Após uma partição longa, o stateid antigo podia gerar NFS4ERR_EXPIRED. A aplicação precisava saber que sua exclusão havia acabado; a lembrança no cliente não mantinha o servidor preso para sempre.

No reboot do servidor, a assimetria se invertia. Os clientes ainda possuíam ids, enquanto a nova época do servidor não os reconhecia. NFS4ERR_STALE_CLIENTID e NFS4ERR_STALE_STATEID tornavam a ruptura explícita. O caminho correto era obter clientid novo e recuperar, não continuar operações normais com referências mortas.

O grace period organizava a fila. Durante cerca de um lease, clientes anteriores podiam enviar LOCK e OPEN em forma de reclaim, inclusive CLAIM_PREVIOUS. A política simples e segura era responder NFS4ERR_GRACE a locks, opens, reads e writes novos. O servidor estava online, mas suspendia por pouco tempo seu poder de criar conflito.

Essa recusa defendia quem ainda não voltara. Detectar a falha e reconstruir estado toma tempo. Se o pedido novo entrasse antes, velocidade de reconexão substituiria legitimidade. A janela dava chance limitada aos antigos e, por ter fim, não entregava veto indefinido aos mortos.

Evidência persistente permitia uma pausa menor. O servidor podia processar trabalho novo se garantisse que nenhum reclaim futuro colidiria ou seria negado por causa dele. Registros estáveis de locks delimitavam o risco. A melhora de disponibilidade dependia do que sobreviveu, não de confiança vazia.

Depois da janela, reclaim tardio só podia vencer se nenhum lock ou I/O conflitante tivesse sido concedido desde o reboot. Fatos novos já consumados também precisavam ser protegidos. O tempo convertia incerteza sem limite em custo previsível.

A RFC 2624 descreveu as tensões de projeto; a RFC 3010 foi substituída pela RFC 3530, e a RFC 7530 é uma formulação posterior de NFSv4.0. Trata-se de história do mecanismo, não de instrução operacional atual.

No NFSv4.1, a RFC 5661 acrescentou EXCHANGE_ID, sessões e recuperação detalhada. Sua substituta, RFC 8881, esclarece a troca: quanto mais tolerante o servidor quiser ser com reclaims após falhas difíceis, mais prova sobre clientes e estado terá de guardar de forma durável.

Pela lente de Running-Code Primacy de Lu Heng, direito efetivo é o que o servidor reiniciado consegue verificar: principal, encarnação, lease, forma de reclaim, janela e inexistência de conflito posterior. A regra mínima comum evita que o recém-chegado ganhe apenas porque chegou primeiro depois do desastre.

A Stability Fallacy seria confundir nome ou filesystem estável com autoridade contínua. A RFC 3010 expôs a perda como stale, conteve conflitos e pediu reconstrução. O lock não persistiu porque o cliente o lembrava. Recebeu oportunidade porque o protocolo lembrava a ordem certa para lidar com o esquecimento.

Sources