flock (2) contre fcntl (2) sur un NFS

19

La documentation Perl 5.x indique que son implémentation de flock (..) utilisera l'un des appels natifs suivants, commençant à 1 et progressant vers 3 s'il n'est pas disponible:

  1. troupeau (2)
  2. fcntl (2)
  3. lockf (3)

C'est très bien. Cependant, vous avez peut-être remarqué leur exclusion de responsabilité selon laquelle flock (2) ne doit pas être utilisé sur un NFS. Le doc suggère d'utiliser un drapeau -Ud_flock pour forcer Perl à utiliser flock (2). La page de manuel de flock (2) (sur Redhat) indique une clause de non-responsabilité similaire concernant les problèmes NFS.

Ma question est, pourquoi!?!? Je n'arrive pas à trouver un article approfondi ou une explication de POURQUOI flock (2) n'est pas sûr sur un NFS.

J'ai écrit plusieurs scripts de test en C et Perl, sur Redhat (où flock (2) est utilisé) et sur Solaris (où fcntl (2) est utilisé). J'ai exécuté strace / truss pour m'assurer que Perl utilisait bien flock (2) et fcntl (2) respectivement. Je n'ai pu reproduire aucun problème où un verrou n'était pas respecté! Ce qui donne??

Jmoney38
la source

Réponses:

3

Lennart Poettering a récemment fait des recherches sur le comportement de verrouillage du système de fichiers Linux, ce qui ne donne pas une image particulièrement optimiste du verrouillage sur NFS (en particulier le suivi auquel il renvoie au bas de l'article).

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

Ivatar
la source
1
C'est exactement le type d'informations que je recherchais. Je vous remercie! Après plusieurs semaines d'enquête, c'est une résolution très similaire à laquelle je suis parvenu, mais c'est génial de lire un article qui confirme mes soupçons (et en suggère d'autres). Le lien des commentaires de cette page était également une bonne référence, et un bon article sur POSIX et son histoire): samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
Jmoney38
15

Je suis à peu près sûr que vous examinez les préoccupations héritées. Rappelons que le manuel Perl5 a été publié en 1994 et qu'il ne s'agissait que d'une édition du manuel Perl4 de 1991. À l'époque, on pouvait probablement dire à propos du souvent appelé Nightmare File System que "ce n'est pas à quel point l'ours danse qui étonne, mais qu'il danse du tout ".

NFS2 à l'époque de 1991 rampait lentement hors de Sun vers d'autres plates-formes et était relativement grossier. Le modèle de sécurité était essentiellement inexistant (la racine sur une machine cliente pouvait lire l'intégralité du contenu d'un montage NFS) et le verrouillage - via nfs.lockd - était de ce côté expérimental. Vous auriez été stupide de vous attendre à ce que la sémantique de troupeau fonctionne correctement si elle existait entre deux implémentations prétendument interopérables différentes. Le coaxial était le PHY Ethernet dominant à l'époque que de nombreux utilisateurs du réseau n'ont jamais eu le déplaisir d'utiliser (que voulez-vous dire que vous avez oublié de mettre la résistance de terminaison 50𝛀?) Si cela vous donne une meilleure maîtrise de l'état des intranets.

Larry Wall et son équipe avaient toutes les raisons de faire des hypothèses pessimistes sur l'exactitude des verrous NFS à l'époque, et c'est le genre de programmation défensive que les futurs jockeys de code détestent supprimer car il est si difficile de prouver l'absence de défaut par supprimer l'ancien code qui est réintroduit dans l'interopérabilité avec un système hérité dont vous n'avez même jamais entendu parler.

Depuis lors, NFS s'est considérablement amélioré et lockd a migré dans le temps vers une fonctionnalité du noyau Linux 2.6. Pour une collection de systèmes 2003+, le verrouillage de fichiers NFS peut probablement être approuvé, surtout s'il est bien testé dans votre application sur les nombreuses plates-formes sur lesquelles elle s'exécute.

Tout ce qui précède a été enregistré de mémoire, et pourrait probablement être corroboré par la recherche (par exemple, http://nfs.sourceforge.net/ ) mais la preuve - comme on dit - se trouve dans le verrouillage, et si vous ne l'avez pas testé , il est présumé cassé.

msw
la source
Voilà une excellente analyse. En fait, je suis arrivé à la même conclusion jusqu'à présent. J'ai relu la page nfs sourceforge après avoir posté ce lien, et j'ai enfin trouvé ce que je cherchais! Voici une analyse approfondie directement de la bouche du cheval!
Jmoney38
2
oups, j'ai appuyé sur Entrée ... allez sur nfs.sourceforge.net , la section D10 vers le bas traite de ce problème en détail.
Jmoney38
3

Un autre, directement à partir de la FAQ Linux-NFS: nfs.sf.net

J'essaie d'utiliser des verrous flock () / BSD pour verrouiller les fichiers utilisés sur plusieurs clients, mais les fichiers sont corrompus. Comment venir? A. Les verrous flock () / BSD n'agissent que localement sur les clients NFS Linux avant 2.6.12. Utilisez les verrous fcntl () / POSIX pour vous assurer que les verrous de fichiers sont visibles pour les autres clients.

Voici quelques façons de sérialiser l'accès à un fichier NFS.

Utilisez l'API de verrouillage fcntl () / POSIX. Ce type de verrouillage fournit un verrouillage de plage d'octets sur plusieurs clients via le protocole NLM ou via NFSv4. Utilisez un fichier de verrouillage distinct et créez des liens physiques vers celui-ci. Voir la description dans la section O_EXCL de la page de manuel creat (2). Il convient de noter que jusqu'au début des noyaux 2.6, les créations O_EXCL n'étaient pas atomiques sur les clients Linux NFS. N'utilisez pas O_EXCL crée et attendez un comportement atomique entre plusieurs clients NFS, sauf si vous exécutez un noyau plus récent que 2.6.5.

C'est un problème connu que Perl utilise le verrouillage flock () / BSD par défaut. Cela peut interrompre les programmes portés à partir d'autres systèmes d'exploitation, tels que Solaris, qui s'attendent à ce que les verrous flock / BSD fonctionnent comme les verrous POSIX.

Sous Linux, l'utilisation du verrouillage de fichier au lieu d'un lien dur présente l'avantage supplémentaire de contrôler le cache du client avec le serveur. Lorsqu'un verrou de fichier est acquis, le client vide le cache de pages de ce fichier afin que toutes les lectures ultérieures obtiennent de nouvelles données du serveur. Lorsqu'un verrou de fichier est libéré, toutes les modifications apportées au fichier sur ce client sont renvoyées au serveur avant que le verrou ne soit libéré afin que les autres clients en attente de verrouiller ce fichier puissent voir les modifications.

Le client NFS dans 2.6.12 prend en charge les verrous flock () / BSD sur les fichiers NFS en émulant les verrous de style BSD en termes de verrous de plage d'octets POSIX. Les autres clients NFS qui utilisent le même mécanisme d'émulation, ou qui utilisent des verrous fcntl () / POSIX, verront alors les mêmes verrous que le client NFS Linux voit.

Sur les systèmes de fichiers Linux locaux, les verrous POSIX et BSD sont invisibles les uns aux autres. Ainsi, en raison de cette émulation, les applications exécutées sur un serveur Linux NFS verront toujours les fichiers verrouillés par les clients NFS comme étant verrouillés avec un verrou fcntl () / POSIX, que l'application sur le client utilise un style BSD ou un POSIX- serrure de style. Si l'application serveur utilise des verrous flock () BSD, elle ne verra pas les verrous utilisés par les clients NFS.

Nikhil Mulley
la source
Alors, deux clients NFS exécutant le noyau 3.13. * Voient-ils les flock () s respectifs?
reinierpost
Si je comprends bien, la réponse est non. Sauf si j'ai raté quelque chose, flockn'a pas, ne fait pas, et ne se verrouille pas sur les montages nfs.
Daniel Farrell
C'est le cas, au moins sur NFS4.
rjh
3

C'est obsolète maintenant. NFS4 prend en charge le verrouillage à l'intérieur du protocole (aucun démon lockd ou mécanisme de rappel RPC n'est requis) et la flock()méthode de Perl fonctionne très bien - nous l'utilisons en production.

De très anciennes versions du noyau implémentées flock(le syscall) en tant que no-op sur NFS, et d'autres choses comme le verrouillage de plage d'octets n'étaient pas correctement prises en charge. C'est de là que vient l'hystérie.

rjh
la source
Merci beaucoup pour l'astuce. Le montage avec NFS4 a résolu mon problème. Suivi access.redhat.com/documentation/en-us/red_hat_enterprise_linux/... pour obtenir la configuration fstab droite.
maraspin