Fanotify

Beispiel für das Sperren von Dateien, jedoch kümmert sich fanotify überhaupt nicht um das Löschen einer Datei im zu überwachenden Ordner.
Alles funktioniert nur in SUSE 13.1 auf Anhieb. Wheezy kennt fanotify anscheinend nicht (Fehler 3 Process not found).
Um Debian Wheezy für Fanotify einzurichten muss erst der Kernel neu gebaut werden, siehe hier Fanotify for Wheezy ....
Für das Beispiel werden zwei Konsolen als root gebraucht.
Solange das Programm in der einen Konsole läuft, kann keine Datei in /install in der anderen Konsole erstellt oder gelesen (geschweige denn geschrieben) werden.

fanotify-wait.c
// stolen from here http://www.xypron.de/projects/fanotify-manpages/man7/fanotify.7.html 
// changed from me richard 
// compile with: gcc -o fanotify-waiting fanotify-waiting -lpthread 
//
#define _GNU_SOURCE // for O_LARGEFILE 
#include <fcntl.h> 
#include <limits.h> 
#include <pthread.h> 
#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h>
#include <string.h> 
#include <sys/fanotify.h>
 
char* verzeichnis = "/install";
 
//---------------------------------------------------------------- 
static void *run(void *data) {
    char buf[4096], *p;
    int fd,ret;
    const struct fanotify_event_metadata *metadata;
    int len;
    char path[PATH_MAX];
    int path_len;
    struct fanotify_response response;
    if (-1 == (fd = fanotify_init(FAN_CLOEXEC | FAN_CLASS_CONTENT, O_RDONLY | O_LARGEFILE))) {
        perror("Cannot init");
        return NULL;
    }
    if (-1 == (fanotify_mark(fd, FAN_MARK_ADD  , FAN_OPEN | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD , FAN_NOFD, verzeichnis))) {
        perror("Cannot mark");
        close(fd);
        return NULL;
    }
    while (-1 != (len = read(fd, (void *) &buf, sizeof (buf)))) {
        metadata = (struct fanotify_event_metadata *) buf;
        while (FAN_EVENT_OK(metadata, len)) {
            if (metadata->fd != FAN_NOFD) {
                if (metadata->fd >= 0) {
                    if (metadata->mask & FAN_OPEN) 
			{
                        response.fd = metadata->fd;
                        }
                    sprintf(path, "/proc/self/fd/%d", metadata->fd);
                    path_len = readlink(path, path, sizeof (path) - 1);
                    if (path_len > 0) {
                        path[path_len] = 0x00;
 
			if (strcmp(path,verzeichnis))
			{
			response.response = FAN_DENY;
                        write(fd, &response, sizeof (struct fanotify_response));
			printf("DENY path: %s\t", path);
			}
                    }
                    close(metadata->fd);
                }
                printf("\n");
            }
            metadata = FAN_EVENT_NEXT(metadata, len);
        }
    }
    close(fd);
    return NULL;
}
//---------------------------------------------------------------- 
int main(int argc, char *argv[]) {
    pthread_attr_t attr;
    pthread_t thread;
    void *result;
    if (pthread_attr_init(&attr)) {
        return EXIT_FAILURE;
    }
    if (pthread_create(&thread, &attr, run, NULL)) {
        return EXIT_FAILURE;
    }
    printf("Press any key to terminate\n");
    getchar();
    if (0 != pthread_kill(thread, SIGUSR1)) {
        return EXIT_FAILURE;
    }
    pthread_join(thread, &result);
    return EXIT_SUCCESS;
}
 
//----------------------------------------------------------------
 
 
/www/htdocs/w00d1d2b/wiki/JS_data/pages/linux/fanotify.txt · Zuletzt geändert: 2014/08/26 18:40 von richard