GNU/Linux >> Linux Esercitazione >  >> Linux

Considerazioni sul monitoraggio delle modifiche ai file con Linux sulla rete

Il monitoraggio di una directory per le modifiche con Linux è possibile tramite il noto meccanismo inotify. Con inotify è possibile impostare un orologio su una directory, configurarlo per guardare eventi sui contenuti e riceverai messaggi su un descrittore di file quando succede qualcosa. Funziona perfettamente quando la directory si trova su una memoria locale, come un disco rigido, SSD o un'unità USB, ma non è sufficiente quando la directory si trova su un filesystem di rete quando la memoria si trova su un altro computer. Un altro utente che lavora nella stessa directory, connesso tramite lo stesso o un altro filesystem, può rimuovere un file e l'orologio che hai impostato su di esso non riceverà alcuna notifica.

Perché questo?

In base alla progettazione, inotify ottiene il risultato di un'operazione (come mkdir o chmod) ma non si sa su quale tipo di filesystem si trova l'orologio (una scatola nera) da inotificare. Il filesystem non "sa" che un controllo è stato impostato, e quindi non può intraprendere l'azione giusta, come notificare all'host remoto qualcuno su cui vuole guardare una directory.

Finché sei l'unico utente, non ci sono problemi. Diventa un problema quando ci sono più utenti che lavorano nella directory che vuoi guardare.

È possibile confrontare questo comportamento con una libreria pubblica. Quando sei l'unico utente, sei in grado di sapere quali libri sono disponibili e quali no, poiché sai quali hai preso in prestito. Questo non è più possibile quando non sei l'unico utente, ci sono più utenti che prendono in prestito i libri.

In tal caso, qualcuno nella biblioteca dovrebbe amministrare ciò che viene preso in prestito da qualsiasi utente (che è il caso normale) e devi contattare questa persona per sapere se un libro è disponibile o meno. È come chiedere a qualcuno di informarti quando un libro, che al momento non è presente, sarà nuovamente disponibile.

Ora questo mettersi in contatto con la libreria per informarti non funziona con Linux, dove ovviamente la libreria è l'archiviazione remota e il server è "qualcuno" che sta lavorando nella libreria.

Per fare in modo che funzioni con Linux è fare in modo che il server remoto venga avvisato che è stato impostato un orologio.

In realtà, filesystem come CIFS e versioni recenti di NFS contengono il supporto per l'invio di un watch al server:per CIFS sulla riga 6438 di fs/cifs/cifssmb.c del kernel 4.1.2 il messaggio SMB per questo (NT_TRANSACT_NOTIFY_CHANGE) è commentato ma ancora presente. Il motivo per commentare questo è che ha funzionato con dnotify, che non è il sistema fsnotify predefinito per Linux da molto tempo ormai.


È possibile eseguire l'inoltro degli orologi su Linux con filesystem di rete e FUSE tramite lo spazio del kernel.

Recentemente ho provato a implementare questo "inoltro dell'orologio al server" con FUSE. Ho dovuto patchare:

Il sottosistema del kernel fsnotify, per notificare al modulo del kernel FUSE che un controllo è stato impostato o rimosso su un inode.

Il modulo del kernel FUSE per agire dopo essere stato informato da fsnotify. Ho introdotto un nuovo codice operativo
FUSE_FSNOTIFY che il modulo del kernel invia al demone userspace insieme all'inodenumber e alla maschera.

La libreria FUSE per ricevere ed elaborare la chiamata FUSE_FSNOTIFY richiamando la funzione corretta del filesystem userspace.

La libreria FUSE per ricevere ed elaborare gli eventi fs e segnalarli al VFS.

Dando un'occhiata più da vicino a come funzionano le cose, quando l'orologio è stato impostato correttamente dal filesystem dello spazio utente sul suo back-end (notare che è anche possibile che risponda a ENOSYS), il back-end può inviare un evento sull'orologio in qualsiasi momento, fino a quando l'orologio viene rimosso. Cosa fare con questo evento?

Un possibile scenario:

Introdurre un codice operativo FUSE aggiuntivo FUSE_FSNOTIFY_EVENT, tradurre la maschera nell'evento ricevuto dal protocollo di backend in qualcosa che fsnotify capisca e rispedirla al modulo FUSE utilizzando il nuovo codice operativo, l'inode dell'orologio, il nome della voce e la maschera tradotta. Il modulo FUSE a sua volta lo invia al sottosistema fsnotify, che informa i listener (inotify eo fanotify), dove viene fornita l'informazione che l'evento è sul backend. (è richiesto un flag di evento aggiuntivo, ad esempio per inotificare la maschera dell'evento IN_REMOTE, per fannotify FAN_REMOTE). Sta all'ascoltatore cosa fare con queste informazioni. Il VFS locale potrebbe o meno essere già aggiornato.

Note:

Tradurre una maschera da un back-end in qualcosa che fsnotify comprende può essere molto facile e non così facile, a seconda dell'evento. Gli eventi di base come la creazione (o la rimozione) di una voce nella directory controllata sono semplici (FS_CREATE e FS_DELETE risp.), anche il cambio del proprietario non è così difficile (FS_ATTRIB), ma qualcosa come un attributo esteso (SMB utilizza quelli molto) possono essere tradotti solo in qualcosa di generico come FS_ATTRIB.

Il modulo FUSE dovrebbe controllare che l'orologio e/o l'inode siano ancora validi e se la maschera dell'orologio si applica all'evento.

Sono richiesti bit di maschera aggiuntivi IN_REMOTE (per inotify) e FAN_REMOTE (per fannotify).

La doppia informazione è da evitare. Questo è difficile. Ad esempio, la creazione di un file nella directory controllata sullo stesso host dell'orologio è attiva. Quando questa operazione ha esito positivo, verrà generato un evento fsnotify FS_CREATE e verrà creato anche un FS_CREATE | Evento FS_REMOTE, poiché l'operazione è stata eseguita correttamente sul backend, risultando in questo messaggio (da backend→libreria fuse→modulo kernel FUSE→sottosistema fsnotify→inotify e/o fanotify).

Un modo per affrontare questo problema è chiedere al back-end di inviare solo eventi avviati da altri. Per il backend, è piuttosto semplice confrontare l'iniziatore (host) di un evento FS con l'host che effettua la connessione.

Un'altra soluzione consiste nel confrontare l'evento segnalato con la cache locale nella libreria dei fusibili e nel modulo FUSE. Con l'esempio che crea un file, la libreria (e il modulo FUSE) dovrebbero verificare che la voce esista già nella directory controllata. In caso contrario, non viene avviato da questo host. Per un'eliminazione, questo è simile.

Per altri eventi, come la scrittura di un file o la modifica del proprietario, questo metodo non è sufficiente, ulteriori informazioni su ciò che è cambiato in remoto (come nuova dimensione, nuovo proprietario) devono essere nel messaggio inviato dall'host remoto.

Se tali informazioni non sono fornite dal back-end, un'altra soluzione consiste nel rendere il demone responsabile della visione degli eventi FS per conto dei client, mantenendo una cache degli eventi locali recenti. Se viene segnalato un evento remoto e nella cache non viene trovato un equivalente locale, viene avviato da un altro host. Questo può diventare complicato perché gli eventi vengono segnalati utilizzando una connessione per un determinato utente, altri utenti possono o meno essere autorizzati a ricevere eventi. E quanto sarà grande questa cache?

Ho usato FUSE sopra, penso che sia simile per altri filesystem come CIFS e NFS.

Oh e sì, c'è ancora un'altra opzione:sondaggi ogni 5 secondi circa.

Stef Bon


Linux
  1. Controlla i comandi e le attività con il comando watch di Linux

  2. Trova file e directory su Linux con il comando find

  3. Controlla lo stato del file su Linux con il comando stat

  4. Iniziare con il comando tac di Linux

  5. Monitoraggio del livello del microfono con uno strumento a riga di comando in Linux

Linux:come condividere file su una rete locale con woof

Comando Linux watch con esempi

Comando Linux WC con esempi

Monitoraggio della larghezza di banda su Linux con Nethogs

Network Manager su Linux con esempi

Proteggi Linux con il file Sudoers