GNU/Linux >> Tutoriales Linux >  >> Linux

Reflexiones sobre la supervisión de cambios de archivos con Linux a través de la red

Es posible monitorear un directorio en busca de cambios con Linux a través del conocido mecanismo inotify. Con inotify es posible establecer una vigilancia en un directorio, configurarlo para ver eventos en los contenidos y recibirá mensajes en un descriptor de archivo cuando algo suceda. Esto funciona perfectamente cuando el directorio está en un almacenamiento local, como un disco duro, SSD o una unidad USB, pero no es suficiente cuando el directorio está en un sistema de archivos de red cuando el almacenamiento está en otra computadora. Otro usuario que trabaje en el mismo directorio, conectado a través del mismo u otro sistema de archivos, puede eliminar un archivo y el reloj que ha configurado no recibirá una notificación.

¿Por qué es esto?

Por diseño, inotify obtiene el resultado de una operación (como mkdir o chmod) pero se desconoce en qué tipo de sistema de archivos se encuentra el reloj (una caja negra) para inotify. El sistema de archivos no "sabe" que se ha configurado una vigilancia y, por lo tanto, no puede tomar la acción correcta, como notificar al host remoto en el que alguien quiere vigilar un directorio.

Mientras seas el único usuario, no hay problema. Se convierte en un problema cuando hay más usuarios trabajando en el directorio que desea ver.

Puede comparar este comportamiento con una biblioteca pública. Cuando eres el único usuario, puedes saber qué libros están disponibles y cuáles no, ya que sabes cuáles tienes prestados. Esto ya no es posible cuando no eres el único usuario, hay más usuarios que toman prestados los libros.

En ese caso, alguien de la biblioteca debe administrar lo prestado por cualquier usuario (que es lo habitual), y hay que contactar con esa persona para saber si un libro está disponible o no. Eso es como pedirle a alguien que le informe cuando un libro, que actualmente no está presente, vuelve a estar disponible.

Ahora, ponerse en contacto con la biblioteca para informarle que no funciona con Linux, donde, por supuesto, la biblioteca es el almacenamiento remoto y el servidor es "alguien" que está trabajando en la biblioteca.

Para que esto funcione con Linux es hacer que el servidor remoto reciba una notificación de que se ha configurado una vigilancia.

En realidad, los sistemas de archivos como CIFS y las versiones recientes de NFS admiten el envío de un reloj al servidor:para CIFS en la línea 6438 de fs/cifs/cifssmb.c del kernel 4.1.2, el mensaje SMB para esto (NT_TRANSACT_NOTIFY_CHANGE) está comentado pero sigue presente. La razón para comentar esto es que funcionó con dnotify, que no es el sistema fsnotify predeterminado para Linux desde hace mucho tiempo.


Hacer que el reenvío de relojes funcione en Linux con sistemas de archivos de red y FUSE es posible a través del espacio del kernel.

Recientemente intenté implementar este "reenvío del reloj al servidor" con FUSE. Tuve que parchear:

El subsistema del kernel fsnotify, para notificar al módulo del kernel FUSE que se ha configurado o eliminado una vigilancia en un inodo.

El módulo del núcleo FUSE para tomar medidas después de ser informado por fsnotify. Introduje un nuevo código de operación
FUSE_FSNOTIFY que el módulo kernel envía al demonio del espacio de usuario junto con el número de inodo y la máscara.

La biblioteca FUSE para recibir y procesar la llamada FUSE_FSNOTIFY llamando a la función correcta del sistema de archivos del espacio de usuario.

La biblioteca FUSE para recibir y procesar los eventos fs y reportarlos al VFS.

Echando un vistazo más de cerca a cómo funcionan las cosas, cuando el reloj ha sido configurado con éxito por el sistema de archivos del espacio de usuario en su backend (tenga en cuenta que también es posible que responda ENOSYS), el backend puede enviar un evento en el reloj en cualquier momento, hasta el se quita el reloj. ¿Qué hacer con este evento?

Un escenario posible:

Introduzca un código de operación FUSE adicional FUSE_FSNOTIFY_EVENT, traduzca la máscara en el evento recibido del protocolo backend en algo que fsnotify entienda y envíelo de regreso al módulo FUSE usando el nuevo código de operación, el inodo del reloj, el nombre de la entrada y la máscara traducida. El módulo FUSE a su vez lo envía al subsistema fsnotify, el cual informa a los listners (inotify y/o fanotify), donde se brinda la información de que el evento está en el backend. (Se requiere un indicador de evento adicional, por ejemplo, para notificar la máscara de evento IN_REMOTE, para fanotify FAN_REMOTE). Depende del oyente qué hacer con esta información. El VFS local puede o no estar actualizado.

Notas:

Traducir una máscara de un backend a algo que fsnotify comprenda puede ser muy fácil o no tan fácil, según el evento. Los eventos básicos como la creación (o eliminación) de una entrada en el directorio supervisado son simples (FS_CREATE y FS_DELETE respectivamente), el cambio del propietario tampoco es tan difícil (FS_ATTRIB), pero algo así como un atributo extendido (SMB usa esos muchos) solo se puede traducir a algo genérico como FS_ATTRIB.

El módulo FUSE debe verificar que el reloj y/o el inodo aún sean válidos, y si la máscara del reloj se aplica a la máscara del evento.

Se requieren bits de máscara adicionales IN_REMOTE (para inotify) y FAN_REMOTE (para fanotify).

Debe evitarse la doble información. Esto es complicado. Por ejemplo, la creación de un archivo en el directorio supervisado en el mismo host en el que se encuentra la supervisión. Cuando esta operación es exitosa, esto generará un evento fsnotify FS_CREATE, y también creará un FS_CREATE | Evento FS_REMOTE, ya que la operación se realizó con éxito en el backend, lo que genera este mensaje (del backend→biblioteca fuse→módulo kernel FUSE→subsistema fsnotify→inotify y/o fanotify).

Una forma de abordar esto es pedirle al servidor que solo envíe eventos iniciados por otros. Para el backend, es bastante simple comparar el iniciador (host) de un evento FS con el host que realiza la conexión.

Otra solución es comparar el evento informado con el caché local en la biblioteca de fusibles y el módulo FUSE. Con el ejemplo de creación de un archivo, la biblioteca (y el módulo FUSE) deben verificar que la entrada ya existe en el directorio observado. Si no, no lo inicia este host. Para una eliminación, esto es similar.

Para otros eventos, como se escribe un archivo o se cambia el propietario, este método no es suficiente, la información adicional sobre lo que ha cambiado el control remoto (como el nuevo tamaño, el nuevo propietario) debe estar en el mensaje enviado por el host remoto.

Si el backend no proporciona esa información, otra solución es hacer que el daemon sea responsable de la vigilancia de los eventos de FS en nombre de los clientes que mantienen un caché de eventos locales recientes. Si se informa un evento remoto, y en el caché no se encuentra un equivalente local, lo inicia otro host. Esto puede volverse complicado porque los eventos se informan mediante una conexión para un determinado usuario, otros usuarios pueden o no estar autorizados para recibir eventos. ¿Y qué tan grande será este caché?

He usado FUSE arriba, creo que es similar para otros sistemas de archivos como CIFS y NFS.

Ah, y sí, todavía hay otra opción:simplemente sondear cada 5 segundos más o menos.

Stef Bon


Linux
  1. Ver comandos y tareas con el comando watch de Linux

  2. Encuentra archivos y directorios en Linux con el comando de búsqueda

  3. Primeros pasos con el comando tac de Linux

  4. Forzar cambios de contraseña del sistema Linux con el comando chage

  5. monitorear cambios de archivos c ++ linux

Linux:Cómo compartir archivos en una red local con guau

Comando de vigilancia de Linux con ejemplos

Comando WC de Linux con ejemplos

Monitoreo del ancho de banda en Linux con Nethogs

Network Manager en Linux con ejemplos

Asegure Linux con el archivo Sudoers