tagger tag puddletag para mp3tag kid3 easytag linux inotify fanotify

tag - ¿Cómo programo la nueva función de monitoreo del sistema de archivos `fanotify` de Linux?



ubuntu mp3 tag editor (3)

Acabo de enterarme de fanotificar y me parece muy bonito. Muy bonita interfaz!

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

No pude encontrar utilidades que lo usen, pero supongo que vendrán pronto.

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

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

Si está realmente interesado en esta nueva función, es posible que desee supervisar la Lista de correo del kernel de Linux e interactuar allí. También puede esperar hasta que se liberen las utilidades o desarrollar las suyas propias.

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

fanotify , construido sobre fsnotify , se supone que reemplaza a inotify que reemplazó a dnotify . ¿Hay algunos buenos ejemplos de programación o utilidades existentes que usan fanotify para observar los cambios en un sistema de archivos? ¿Cuántos detalles aporta fanotify ?


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

Aquí hay algunos ejemplos, siendo Fatrace el más elaborado.

Existen enlaces para Go y Python.


Este artículo LWN se cita a menudo como una fuente de documentación para fanotify. Pero la descripción allí parece estar desactualizada. fanotify ya no funciona utilizando una conexión de socket. En su lugar, 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 este artículo, estas llamadas al sistema aún se incluyen en la lista de páginas de manual que faltan . Sin embargo, hay un correo que contiene borradores para estas páginas de manual. Con una combinación de estas páginas de manual, una mirada a los encabezados en cuestión y un poco de prueba y error, debería poder hacer que esto funcione.

Parece que algunas de las funciones originalmente previstas para fanotify ya no se soportan de esa manera. Por ejemplo, el artículo FAN_GLOBAL_LISTENER describe un indicador 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, pero se puede lograr un resultado similar utilizando la siguiente marca:

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

Donde los eventos inotify proporcionan la ruta al objeto accedido como parte del evento, fanotify abre un descriptor de archivo para él. Para convertir este descriptor en un nombre de ruta, se puede usar la entrada correspondiente del sistema de archivos proc, como se describe here .

Aquí hay 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); } } }