Résumé

  • La RFC 3010 distingua le nom durable d’un client de son incarnation en cours : un verifier renouvelé au redémarrage, un clientid négocié et une confirmation authentifiée empêchaient un même nom d’hériter silencieusement des anciens verrous.
  • Après la perte d’état du serveur, une période de grâce d’environ un bail donnait priorité aux reclaims et retenait les nouveaux verrous et E/S conflictuels. La continuité devenait une procédure limitée, non un droit perpétuel.

Le disque se souvenait du fichier. Le client se souvenait du verrou. Seul le serveur, fraîchement redémarré, avait oublié la relation entre les deux. Cette asymétrie est plus dangereuse qu’une panne franche : chaque côté possède une histoire plausible, mais elles ne décrivent plus le même état.

Publiée en décembre 2000, la RFC 3010 fut la première spécification complète de NFS version 4. En intégrant le verrouillage à un protocole auparavant associé à la réduction de l’état serveur, NFSv4 devait décider comment un droit temporaire survivait — ou ne survivait pas — aux redémarrages et aux partitions.

Le premier outil séparait le client de son incarnation. Le client présentait un identifiant opaque susceptible de rester stable et un verifier appelé à changer à chaque initialisation. Un nom d’hôte pouvait désigner la machine sans distinguer la mémoire de verrouillage d’avant et d’après l’amorçage. Le verifier donnait un contour à cette rupture.

SETCLIENTID liait le couple proposé au principal authentifié dans la requête RPC. Le serveur renvoyait un clientid court et un verifier de confirmation ; SETCLIENTID_CONFIRM fermait l’échange. Le clientid accélérait ensuite les références à l’état. Il n’était ni une identité universelle, ni un titre de propriété, ni une autorisation transportable.

Deux machines pouvaient pourtant présenter le même identifiant opaque, par erreur de configuration, duplication d’un dispositif de haute disponibilité ou action hostile. NFS4ERR_CLID_INUSE rendait la collision visible. L’égalité du nom ne fusionnait pas les acteurs ; elle imposait de résoudre le conflit avant de distribuer l’autorité.

Si le même principal authentifié revenait avec un nouveau verifier, le serveur pouvait conclure que l’incarnation avait changé et que l’ancien état volatil n’existait plus côté client. Il pouvait libérer les verrous liés à l’ancien clientid. Sans l’authentification, ce mécanisme aurait été une arme : un intrus aurait pu simuler le redémarrage d’autrui pour faire disparaître ses exclusions.

Le deuxième outil était le temps. Le serveur fixait une durée de bail commune à l’état d’un client. Les opérations ordinaires renouvelaient implicitement cette échéance, et RENEW servait au client silencieux. Un seul renouvellement couvrait l’ensemble ; le nombre de verrous ne multipliait pas les battements de vie.

Le bail protégeait sans éterniser. Après son expiration, le serveur pouvait récupérer l’état d’un client absent et accorder un conflit. Au retour d’une partition trop longue, un ancien stateid pouvait recevoir NFS4ERR_EXPIRED. Cette erreur obligeait le client à reconnaître auprès de l’application que son exclusion avait cessé. Sa mémoire locale ne constituait pas une injonction durable au serveur.

Lors d’un redémarrage serveur, l’incertitude s’inversait. Les clients conservaient des clientid et stateid d’apparence valable, mais le serveur avait changé d’époque. NFS4ERR_STALE_CLIENTID et NFS4ERR_STALE_STATEID matérialisaient cette frontière. Le client devait négocier un nouvel identifiant puis passer par la reprise, au lieu de réutiliser l’ancien espace d’état.

La période de grâce donnait son ordre à cette reprise. Pendant environ un bail, les anciens clients pouvaient envoyer des LOCK et OPEN en mode reclaim, notamment CLAIM_PREVIOUS. La règle sûre la plus simple consistait à répondre NFS4ERR_GRACE aux nouveaux verrous, ouvertures, lectures et écritures. Le service répondait, mais son pouvoir de créer un conflit restait suspendu.

Ce refus temporaire protégeait les absents. Un détenteur antérieur pouvait encore détecter la panne, se reconnecter ou reconstituer sa liste. Si une demande neuve gagnait uniquement parce qu’elle arrivait plus vite après le redémarrage, la latence deviendrait une règle de propriété. La grâce offrait une chance bornée à l’histoire sans donner un veto infini aux clients morts.

La RFC autorisait une reprise plus sélective lorsque le serveur possédait des preuves durables. Il pouvait servir une opération nouvelle s’il garantissait qu’aucun reclaim ultérieur ne serait en conflit ni rejeté à cause d’elle. Des enregistrements stables ou des comptes de verrous réduisaient ainsi la surface gelée. L’optimisation reposait sur une preuve d’absence de conflit, non sur le seul désir de retrouver du débit.

Après la fenêtre, un reclaim tardif ne reprenait pas automatiquement le dessus. Il ne pouvait réussir que si le serveur garantissait qu’aucun verrou ou accès contradictoire n’avait été accordé depuis le redémarrage. Les nouveaux faits déjà créés avaient leur propre poids. Le délai bornait donc le prix de l’incertitude et fixait le moment où la concurrence ordinaire reprenait.

La RFC 2624 avait exposé les contraintes de conception ; la RFC 3010 livra le premier protocole complet. La RFC 3530 la remplaça, puis la RFC 7530 devint la référence ultérieure de NFSv4.0. Il s’agit donc ici d’histoire architecturale, pas d’un guide d’exploitation contemporain.

Avec NFSv4.1, la RFC 5661 ajouta EXCHANGE_ID, les sessions et une reprise plus détaillée. Sa remplaçante, la RFC 8881, rend explicite le coût de la tolérance : plus un serveur veut honorer de reclaims dans les cas difficiles, plus il doit conserver durablement d’éléments sur les clients et leur état.

Sous la grille de Running-Code Primacy de Lu Heng, le droit opératoire est celui que le serveur redémarré peut vérifier localement : principal, incarnation, bail, mode reclaim, fenêtre et absence de conflit postérieur. Le minimum commun n’est pas la mémoire institutionnelle éternelle. C’est une règle exécutable empêchant qu’un nouveau venu gagne seulement parce que la panne l’a fait arriver le premier.

La Stability Fallacy consisterait à prendre un nom stable ou un système de fichiers accessible pour une autorité inchangée. La RFC 3010 exposa au contraire la rupture par les erreurs stale, suspendit les conflits et reconstruisit la continuité par des reçus. Le verrou ne survécut pas parce que le client s’en souvenait ; il reçut une chance de renaître parce que le protocole avait conservé l’ordre de l’incertitude.

Sources