2009-12-02 17 views
16

fanotify, construido en la parte superior de fsnotify, se supone que debe reemplazar inotify que reemplazó dnotify. ¿Hay algunos buenos ejemplos de programación o utilidades existentes que usan fanotify para observar los cambios en un sistema de archivos? ¿Cuánto detalle ofrece fanotify?¿Cómo programo la nueva función de supervisión del sistema de archivos `fanotify` de Linux?

+0

Solo para su información: Fanotify tiene un error. http://stackoverflow.com/questions/7566755/multi-thread-opening-file-hangs-when-fanotify-is-on aquí hay un parche. http://marc.info/?l=linux-kernel&m=131822913806350&w=2 – user377808

Respuesta

6

Acabo de enterarme de fanotify y me parece muy agradable. Muy buena interfaz!

Aún no está en el árbol de Linus, pero supongo que llegará allí para Linux 2.6.33 y antes para probarlo (hoy noté algunos parches en LKML). En el parche original anuncian un árbol GIT por lo que es posible que puedas construir un kernel de prueba desde allí. También puede encontrar pruebas de git trees.

No pude encontrar las utilidades que lo usan pero supongo que vendrán pronto.

Hay un ejemplo aquí, al final del correo electrónico:

http://lwn.net/Articles/339253/

Si usted está realmente interesado en esta nueva característica es posible que desee controlar la lista de correo del kernel de Linux e interactuar allí. También puede esperar hasta que se liberen los servicios o desarrolle los suyos propios.

Sobre el detalle, parece que el fanotify proporciona menos eventos que inotify. Supongo que esto podría cambiar en el futuro, pero dado que esta es una característica nueva en el desarrollo, no hay mucho que pueda decir al respecto ahora.

+1

Al final, el fanotify entró en 2.6.36 –

16

This LWN article a menudo se cita como una fuente de documentación para fanotify. Pero la descripción allí parece estar desactualizada. el fanotify ya no funciona con una conexión de socket. En cambio, hay dos nuevas funciones libc que envuelven syscalls, declaradas en sys/fanotify.h. Uno se llama fanotify_init, el otro es fanotify_mark. En el momento de escribir estas líneas, estas llamadas a los sistemas todavía se incluyen en el list of missing manual pages. Sin embargo, hay un mail containing drafts para estas páginas de manual. Con una combinación de estas páginas man, un vistazo a los encabezados en cuestión, y un poco de prueba y error, debería ser capaz de poner esto en marcha.

Parece que algunas de las funciones previstas originalmente para fanotify ya no se suipportan de esa manera. Por ejemplo, el artículo LWN describe una bandera FAN_GLOBAL_LISTENER que marcará implícitamente todo el árbol del sistema de archivos a menos que las partes estén explícitamente sin marcar. La interfaz actual no tiene tal disposición, sino un resultado similar se puede conseguir utilizando la siguiente marca:

fanotify_mark(fan, 
       FAN_MARK_ADD | FAN_MARK_MOUNT, 
       FAN_OPEN | FAN_EVENT_ON_CHILD, 
       AT_FDCWD, "/") 

Dónde eventos inotify proporcionan la ruta de acceso al objeto visitada como parte del evento, fanotify abre un descriptor para su . Para convertir este descriptor en un nombre de ruta, se puede usar la entrada correspondiente del sistema de archivos proc, como se describe en here.

Aquí está un ejemplo simple que simplemente imprime el nombre de cada archivo abierto:

#include <fcntl.h> 
#include <limits.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/fanotify.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#define CHK(expr, errcode) if((expr)==errcode) perror(#expr), exit(EXIT_FAILURE) 
int main(int argc, char** argv) { 
    int fan; 
    char buf[4096]; 
    char fdpath[32]; 
    char path[PATH_MAX + 1]; 
    ssize_t buflen, linklen; 
    struct fanotify_event_metadata *metadata; 
    CHK(fan = fanotify_init(FAN_CLASS_NOTIF, O_RDONLY), -1); 
    CHK(fanotify_mark(fan, FAN_MARK_ADD | FAN_MARK_MOUNT, 
        FAN_OPEN | FAN_EVENT_ON_CHILD, AT_FDCWD, "/"), -1); 
    for (;;) { 
    CHK(buflen = read(fan, buf, sizeof(buf)), -1); 
    metadata = (struct fanotify_event_metadata*)&buf; 
    while(FAN_EVENT_OK(metadata, buflen)) { 
     if (metadata->mask & FAN_Q_OVERFLOW) { 
     printf("Queue overflow!\n"); 
     continue; 
     } 
     sprintf(fdpath, "/proc/self/fd/%d", metadata->fd); 
     CHK(linklen = readlink(fdpath, path, sizeof(path) - 1), -1); 
     path[linklen] = '\0'; 
     printf("%s opened by process %d.\n", path, (int)metadata->pid); 
     close(metadata->fd); 
     metadata = FAN_EVENT_NEXT(metadata, buflen); 
    } 
    } 
} 
11

La documentación de la API fanotify está disponible en las páginas de manual de Linux:


He aquí algunos ejemplos, siendo fatrace el más elaborado.

enlaces existen para Go y Python.

Cuestiones relacionadas