it-swarm-es.tech

flock (2) versus fcntl (2) sobre un NFS

La documentación de Perl 5.x establece que su implementación de flock (..) utilizará una de las siguientes llamadas nativas, comenzando en 1 y trabajando hacia 3 si no está disponible:

  1. rebaño (2)
  2. fcntl (2)
  3. lockf (3)

Esta bien. Sin embargo, es posible que haya notado su descargo de responsabilidad de que flock (2) no debe usarse en un NFS. El documento sugiere usar una bandera -Ud_flock para forzar a Perl a usar flock (2). La página de manual de flock (2) (en Redhat) establece un descargo de responsabilidad similar sobre los problemas de NFS.

Mi pregunta es, ¿por qué?!? Parece que no puedo encontrar un artículo detallado o una explicación de POR QUÉ flock (2) no es seguro en un NFS.

He escrito varios scripts de prueba en C y Perl, tanto en Redhat (donde se usa flock (2)) como en Solaris (donde se usa fcntl (2)). Ejecuté strace/truss para asegurarme de que Perl estaba usando flock (2) y fcntl (2) respectivamente. ¡No pude replicar ningún problema en el que no se respetara un candado! ¿¿Lo que da??

21
Jmoney38

Lennart Poettering recientemente investigó un poco el comportamiento de bloqueo del sistema de archivos de Linux, lo que no pinta una imagen particularmente optimista para el bloqueo de NFS (especialmente el seguimiento al que se vincula al final de la publicación).

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

3
Ivatar

Estoy bastante seguro de que está analizando preocupaciones heredadas. Recuerde que el manual de Perl5 fue lanzado en 1994 y que era solo una edición del manual de Perl4 de 1991. En aquellos días, probablemente se podría decir sobre el frecuentemente llamado Nightmare File System que "no es lo bien que baila el oso lo que asombra, pero que baila nada ".

NFS2 en la Época de 1991 salía lentamente de Sun a otras plataformas y era relativamente tosco. El modelo de seguridad era esencialmente inexistente (la raíz en una máquina cliente podía leer el contenido completo de un montaje NFS) y el bloqueo, a través de nfs.lockd, era este lado de la experimentación. Habría sido una tontería esperar que la semántica de flock funcione correctamente entre dos implementaciones diferentes supuestamente interoperables. El cable coaxial era el PHY de Ethernet dominante en ese momento que muchos usuarios de la red nunca han tenido el disgusto de usar (¿qué quiere decir con que olvidó poner la resistencia de terminación 50 ????) si eso le da un mejor control del estado de intranets entonces.

Larry Wall y su equipo tenían todas las razones para hacer suposiciones pesimistas sobre la corrección de los bloqueos NFS en ese momento, y este es el tipo de programación defensiva que los futuros codificadores de código detestan eliminar porque es muy difícil probar la ausencia de un defecto mediante eliminando el código antiguo que se reintroduce en la interoperabilidad con un sistema heredado del que nunca había oído hablar.

Desde entonces, NFS ha mejorado considerablemente y lockd ha migrado a tiempo a una función del kernel de Linux 2.6. Para una colección de sistemas 2003+, es probable que se pueda confiar en el bloqueo de archivos NFS, especialmente si se prueba bien dentro de su aplicación en las muchas plataformas en las que se puede ejecutar.

Todo lo anterior se tomó de la memoria y probablemente podría corroborarse a través de la investigación (por ejemplo, http://nfs.sourceforge.net/ ) pero la prueba, como dicen, está en el candado, y si no lo probó, se presume que está roto.

16
msw

Otro, directamente de las preguntas frecuentes de Linux-NFS: nfs.sf.net

Estoy tratando de usar bloqueos flock ()/BSD para bloquear archivos usados ​​en varios clientes, pero los archivos se corrompen. ¿Cómo? A. Los bloqueos flock ()/BSD actúan solo localmente en clientes NFS de Linux antes de 2.6.12. Use bloqueos fcntl ()/POSIX para asegurarse de que los bloqueos de archivos sean visibles para otros clientes.

A continuación, se muestran algunas formas de serializar el acceso a un archivo NFS.

Utilice la API de bloqueo fcntl ()/POSIX. Este tipo de bloqueo proporciona bloqueo de rango de bytes en varios clientes a través del protocolo NLM o NFSv4. Use un archivo de bloqueo separado y cree enlaces físicos a él. Consulte la descripción en la sección O_EXCL de la página de manual de creat (2). Vale la pena señalar que hasta los primeros núcleos 2.6, las creaciones de O_EXCL no eran atómicas en los clientes NFS de Linux. No use O_EXCL crea y espere un comportamiento atómico entre varios clientes NFS a menos que esté ejecutando un kernel más reciente que 2.6.5.

Es un problema conocido que Perl usa el bloqueo flock ()/BSD de forma predeterminada. Esto puede romper programas portados desde otros sistemas operativos, como Solaris, que esperan que los bloqueos flock/BSD funcionen como los bloqueos POSIX.

En Linux, el uso de bloqueo de archivos en lugar de un vínculo físico tiene el beneficio adicional de marcar la caché del cliente con el servidor. Cuando se adquiere un bloqueo de archivo, el cliente vaciará la caché de la página de ese archivo para que las lecturas posteriores obtengan nuevos datos del servidor. Cuando se libera un bloqueo de archivo, los cambios realizados en el archivo de ese cliente se devuelven al servidor antes de que se libere el bloqueo para que otros clientes que esperan bloquear ese archivo puedan ver los cambios.

El cliente NFS en 2.6.12 proporciona soporte para bloqueos flock ()/BSD en archivos NFS al emular los bloqueos de estilo BSD en términos de bloqueos de rango de bytes POSIX. Otros clientes NFS que usan el mismo mecanismo de emulación, o que usan bloqueos fcntl ()/POSIX, verán los mismos bloqueos que ve el cliente NFS de Linux.

En los sistemas de archivos locales de Linux, los bloqueos POSIX y los bloqueos BSD son invisibles entre sí. Por lo tanto, debido a esta emulación, las aplicaciones que se ejecutan en un servidor NFS de Linux seguirán viendo los archivos bloqueados por los clientes NFS como si estuvieran bloqueados con un bloqueo fcntl ()/POSIX, ya sea que la aplicación en el cliente esté usando un estilo BSD o POSIX- bloqueo de estilo. Si la aplicación del servidor usa bloqueos BSD flock (), no verá los bloqueos que usan los clientes NFS.

3
Nikhil Mulley

Esto está desactualizado ahora. NFS4 admite el bloqueo dentro del protocolo (no se requiere un demonio lockd o un mecanismo de devolución de llamada RPC) y el método flock() de Perl funciona bien; lo estamos usando en producción.

Versiones muy antiguas del kernel implementaron flock (syscall) como una operación no operativa en NFS, y otras cosas como el bloqueo de rango de bytes no se admitían correctamente. De ahí viene la histeria.

3
rjh