Perché gli eventi inotify si attivano più di una volta


13

Questa domanda sorge da un'altra che avevo posto su Stackoverflow . Sto usando Watcher - gli stessi problemi si applicano a Incron - per monitorare una cartella e le sue cartelle secondarie alla ricerca di modifiche e silenziare silenziosamente quelle modifiche a Dropbox.

Controllo l' write_closeevento - IN_CLOSE_WRITE- allo scopo. Inizialmente stavo guardando l' modifyevento, cioè IN_MODIFY. Mentre questo ha funzionato, ho scoperto che quando si scrivevano file di grandi dimensioni si attiva più di una volta. Sembrava giusto, quindi sono passato IN_CLOSE_WRITEdal momento che ho ritenuto che fosse ragionevolmente ragionevole supporre che per un dato file sarebbe successo solo una volta.

Tuttavia, non è così. Anche per un file di testo molto piccolo - solo un carattere - creato in Nano, l'evento si verifica due volte. Nella migliore delle ipotesi, ciò può comportare un traffico non necessario quando lo stesso file viene sincronizzato su Dropbox due volte. Nel mio caso porta al disastro poiché al primo evento eseguo la sincronizzazione e quindi elimino il file sul lato server. Il risultato: al secondo evento il file laterale Dropbox diventa un file a 0 byte.

Ho a che fare con questo per ora facendo dormire lo script di sincronizzazione per 10 secondi prima di fare qualsiasi altra cosa e quindi controllo che il file in questione esista ancora prima di tentare la sincronizzazione di Dropbox. Questo funziona perché nella seconda iterazione manca il file e lo script termina.

Questo suona al massimo hacker. Forse non è un brutto trucco, ma preferirei capire - solo perché l' IN_CLOSE_WRITEevento si verifica più di una volta?


Alcune informazioni aggiuntive

  • Verifica che non vi siano più istanze di watcher in esecuzione.

Uscita da ps ax|grep watcher.py

23880 ?        Sl     0:01 python /usr/local/bin/watcher.py restart
24977 pts/0    S+     0:00 grep --color=auto watcher.py

Il file system è ext4. Devo dire che ho riscontrato esattamente lo stesso problema con Incron. Avvio il demone Watcher da uno script batch eseguito tramite /etc/rc2.d. Incron OTH si avvia senza alcun problema da parte mia tramite la sua apt-get install incroninstallazione predefinita .


L'essenza del mio watcher.inifile è mostrata di seguito.

[DEFAULT]
logfile=/var/log/watcher.log
pidfile=/var/run/watcher.pid

[job1]
watch=/path/to/watch

events=write_close
excluded=
recursive=true
autoadd=true

command=/home/datastore.php $filename

Ho ridotto lo datastore.phpscript agli elementi essenziali per verificare che sia stato attivato due volte senza nessuno dei miei disordinati upload Dropbox + codice di eliminazione del codice sorgente.

#! /usr/bin/php
<?php
file_put_contents('/tmp/watcher',$argv[1],FILE_APPEND);

?>

Ho quindi creato un piccolo file nel percorso in questione e poi esaminato /tmp/watcher. Il problema persiste ancora: il file ha ancora due voci successive per $argv[1].


1
Ho provato molte varianti, ma non riesco a duplicare il tuo problema con più scatti IN_CLOSE_WRITE. Tutto ciò che ho fatto provoca un singolo output inotify. Continuerò a provare cose. Ma finora, solo domande. Quale file system? Ext4? Altro?
Lornix,

@lornix - vedi le modifiche alla mia domanda. Il file system è ext4e sono ragionevolmente sicuro di non avere due istanze di Watcher in esecuzione. Ho riscontrato lo stesso problema con Incron.
DroidOS,

Hai detto "Eseguo la sincronizzazione e quindi elimino il file sul lato server". Questa eliminazione attiva il secondo evento? Puoi disabilitare la deleteroutine e riprovare?
Germar,

@Germar - vedi la modifica alla mia domanda. Anche con lo script di sincronizzazione che non esegue alcuna sincronizzazione vera e propria e unlinkil problema persiste
DroidOS

Siamo spiacenti, piuttosto per idee, non riesco a riprodurre il problema su nessuna delle mie macchine. Ricevo un evento, non di più. Qualcos'altro è coinvolto, qualcosa di non menzionato. Hai installato un antivirus? niente del genere?
Lornix,

Risposte:


1

Non ne sono sicuro, ma molto probabilmente il primo write_close scrive gli attributi dei file al suo interno, come i tempi di creazione, e solo dopo scrive i dati effettivi. In effetti rsync crea un file temporaneo e quando tutto è fatto, sposta il file temporaneo nel file effettivo nella stessa cartella, quindi è facile da monitorare, quando si usa rsync, è stato normalmente creato il monitoraggio e lo spostamento è un'operazione atomica. D'altra parte c'è qualcosa di calle in un colpo in inotify, probabilmente che usando questo possiamo innescare qualcosa sul primo messaggio di modifica, e come hai suggerito di dormire per un ragionevole lasso di tempo prima di iniziare l'operazione. Sto scavando questo ora e aggiornerò quando trovo qualcosa di nuovo. /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify


Potresti aver messo il dito su qualcosa di abbastanza valido qui. Richiederà qualche indagine. Grazie per il consiglio. Riporterò post nel caso in cui trovo che questo sia in qualche modo un problema.
DroidOS,

Non credo che ATTRIB aggiunga nulla al file stesso, mi sbagliavo.
Edik Mkoyan,

0

Non ho abbastanza rappresentante per pubblicare questo come commento, ma sei sicuro che i file temporanei, eventualmente nascosti, non vengano creati? Ho avuto un problema simile con l' inotifywaitattivazione più volte, ma mi sono reso conto che era perché Vim avrebbe creato un file .swp durante la modifica, che avrebbe generato un evento alla chiusura. Raccoglierebbe anche l'evento di chiusura dal file originale.

Sembra che tu stia notando l'evento che ha sparato più file sullo stesso file, il che non è qualcosa che sono stato in grado di riprodurre - questo accadrebbe solo una volta per il file temporaneo e una volta per l'originale.

Ho provato un test rapido con nano e non credo che crei affatto un file temporaneo (almeno per il caso di pochi caratteri), ma c'è qualcos'altro nella tua configurazione che potrebbe fare affidamento su un comportamento simile?


Grazie per i vostri suggerimenti. Ho riscontrato il problema con inotify multiple anche quando creo un file di 1 byte molto banale con Nano - o anche semplicemente reindirizzando un singolo carattere dalla console in un file. La "soluzione" che ho delineato nella mia domanda originale mi sta facendo andare avanti per ora. Tuttavia, a lungo termine l'unica soluzione che devo ricostruire il mio server partendo da zero per identificare proprio quando inizia l'errore: la mia configurazione con Incron, Watcher (tra l'altro è successo quando avevo appena Incron), MariaDB, Nginx, Redis, Memcached ... non è esattamente "semplice".
DroidOS,

Per ogni evenienza, ricontrolla se non stai monitorando due volte la stessa cartella. In caso contrario, ad esempio, quando copio il file nella condivisione samba tramite il client os x samba, ciò accade creare, close_write, eliminare, creare, close_write Quando lo faccio con un client Windows, sembra più ragionevole creare, write_close e niente di più. Quindi risolvo il mio problema monitorando la prima modifica del file con questa directory IN_MODIFY, IN_ONESHOT /. sleep someTime comandi oneshot fa la cosa.
Edik Mkoyan,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.