Dlaczego zdarzenia niedotyczące są uruchamiane więcej niż raz?

13

To pytanie powstaje z innego pytania, które postawiłem na Stackoverflow . Używam Watcher - te same problemy dotyczą Incron - monitorować folder i jego foldery podrzędne dla zmian i cicho wiewiórki wyjazdowych tych zmian do Dropbox.

W tym celu monitoruję write_closezdarzenie - IN_CLOSE_WRITE- w tym celu. Początkowo oglądałem to modifywydarzenie, tj. IN_MODIFY. Podczas gdy to zadziałało, odkryłem, że podczas pisania dużych plików uruchomi się więcej niż raz. Brzmiało to uczciwie, więc przestawiłem się, IN_CLOSE_WRITEponieważ uznałem, że uzasadnione jest założenie, że dla danego pliku wystąpi to tylko raz.

Tak jednak nie jest. Nawet w przypadku bardzo małego pliku tekstowego - tylko jednego znaku - utworzonego w Nano zdarzenie występuje dwa razy. W najlepszym wypadku może to powodować niepotrzebny ruch, gdy ten sam plik zostanie zsynchronizowany dwukrotnie z Dropbox. W moim przypadku prowadzi to do katastrofy, ponieważ przy pierwszym zdarzeniu przeprowadzam synchronizację, a następnie usuwam plik po stronie serwera. Rezultat - przy drugim zdarzeniu plik boczny Dropbox staje się plikiem 0-bajtowym.

Zajmuję się tym na razie, zmuszając mój skrypt synchronizacji do uśpienia na 10 sekund, zanim zrobię cokolwiek innego, a następnie sprawdzam, czy dany plik nadal istnieje przed podjęciem próby synchronizacji Dropbox. Działa to, ponieważ podczas drugiej iteracji brakuje pliku, a skrypt właśnie się kończy.

To w najlepszym razie brzmi hackersko. Być może niezły hack, ale wolałbym zrozumieć - dlaczego nawet IN_CLOSE_WRITEzdarzenie zdarza się więcej niż jeden raz?


Niektóre dodatkowe informacje

  • Sprawdź, czy nie ma wielu uruchomionych obserwatorów.

Wyjście z 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

System plików to ext4. Powinienem wspomnieć, że napotkałem dokładnie ten sam problem z Incron. Uruchamiam demona Watchera ze skryptu wsadowego wykonanego za pośrednictwem /etc/rc2.d. Incron OTH uruchamia się bez bałaganu przeze mnie poprzez domyślną apt-get install incroninstalację.


Esencję mojego watcher.inipliku pokazano poniżej.

[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

Skróciłem datastore.phpskrypt do niezbędnego minimum, aby sprawdzić, czy został uruchomiony dwa razy bez żadnego bałaganu podczas przesyłania Dropbox + kodu źródłowego.

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

?>

Następnie utworzyłem mały plik przy danej ścieżce, a następnie zbadałem /tmp/watcher. Problem nadal występuje - plik nadal zawiera dwa kolejne wpisy $argv[1].

DroidOS
źródło
1
Próbowałem wielu odmian, ale nie jestem w stanie powielić problemu z wieloma uruchomieniami IN_CLOSE_WRITE. Wszystko, co zrobiłem, powoduje pojedyncze wyjście inotify. Będę próbować dalej. Ale jak dotąd tylko pytania. Który system plików Ext4? Inny?
lornix,
@lornix - zobacz zmiany mojego pytania. System plików jest ext4i jestem całkiem pewien, że nie mam uruchomionych dwóch instancji Watchera. Mam ten sam problem z Incron.
DroidOS,
Powiedziałeś „Wykonuję synchronizację, a następnie usuwam plik po stronie serwera”. Czy to usunięcie wyzwala drugie zdarzenie? Czy możesz wyłączyć deleterutynę i spróbować ponownie?
Germar
@Germar - zobacz edycję mojego pytania. Nawet przy skrypcie synchronizacji nie wykonującym prawdziwej synchronizacji i żaden unlinkproblem nie występuje
DroidOS
Niestety, raczej z pomysłów, nie mogę odtworzyć problemu na żadnym z moich komputerów. Dostaję jedno wydarzenie, nigdy więcej. W grę wchodzi coś jeszcze, coś nie wymienionego. Czy masz zainstalowany program antywirusowy? nic podobnego?
lornix,

Odpowiedzi:

1

Nie jestem pewien, ale najprawdopodobniej pierwszy write_close zapisuje w nim atrybuty pliku, takie jak czas utworzenia, a dopiero potem zapisuje rzeczywiste dane. W rzeczywistości rsync tworzy plik tymczasowy, a gdy wszystko jest zrobione, przenosi plik tymczasowy do rzeczywistego pliku w tym samym folderze, dzięki czemu można łatwo monitorować, że normalnie utworzono go podczas korzystania z programu rsync, a ruch jest operacją atomową. Z drugiej strony jest coś calle jeden strzał w inotify, prawdopodobnie za pomocą tego możemy wyzwolić coś przy pierwszej wiadomości modyfikującej i jak zasugerowałeś sen przez rozsądny czas przed rozpoczęciem operacji. Kopię to teraz i zaktualizuję, gdy znajdę coś nowego. /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify

Edik Mkoyan
źródło
Możliwe, że położyłeś palec na czymś całkiem ważnym. Będzie to wymagało trochę dochodzenia. Dzięki za wskazówkę. Wyślę z powrotem w przypadku, gdy stwierdzę, że jest to jakoś problem.
DroidOS
Nie sądzę, że ATTRIB dodaje coś do samego pliku, myliłem się.
Edik Mkoyan,
0

Nie mam wystarczającej liczby przedstawicieli, aby opublikować to jako komentarz, ale czy jesteś pewien, że tymczasowe, prawdopodobnie ukryte pliki nie są tworzone? Miałem podobny problem z inotifywaitwielokrotnym odpalaniem, ale zdałem sobie sprawę, że było tak, ponieważ vim utworzyłby plik .swp podczas edycji, co wywołałoby zdarzenie podczas zamykania. Odbierze również zdarzenie zamknięcia z oryginalnego pliku.

Wygląda na to, że zauważysz zdarzenie uruchamiające wiele plików w tym samym pliku, czego nie byłem w stanie odtworzyć - zdarzy się to tylko raz dla pliku tymczasowego i raz dla oryginału.

Próbowałem szybkiego testu z nano i nie wydaje mi się, aby w ogóle tworzył plik tymczasowy (przynajmniej w przypadku kilku znaków), ale czy jest jeszcze coś w twojej konfiguracji, co mogłoby polegać na podobnym zachowaniu?

neocpp
źródło
dziękuję za twoje sugestie. Mam biegać w inotify wielokrotnej emisji nawet gdy tworzę bardzo trywialne plik 1 bajt z Nano - lub nawet tylko przekierowanie pojedynczego char z konsoli do pliku. „Rozwiązanie”, które nakreśliłem w moim pierwotnym pytaniu, podtrzymuje mnie na razie. Jednak w dłuższej perspektywie jedynym rozwiązaniem jest konieczność odbudowania serwera od zera, aby zidentyfikować, kiedy zaczyna się błąd - moja konfiguracja z Incronem, Watcherem (przy okazji, gdy miałem właśnie Incrona), MariaDB, Nginx, Redis, Memcached ... nie jest do końca „prosty”.
DroidOS
Na wszelki wypadek sprawdź dwukrotnie, czy nie monitorujesz dwukrotnie tego samego folderu. Jeśli nie, to na przykład, kiedy kopiuję plik do udziału samby za pomocą klienta os x samba, dzieje się tak: twórz, zamykaj, pisz, usuwaj, twórz, zamykaj, pisząc Kiedy robię to z klientem Windows, bardziej rozsądnie wygląda tworzenie, pisanie i zamykanie i nic więcej. Rozwiązuję więc problem, monitorując pierwszą modyfikację pliku w tym katalogu IN_MODIFY, IN_ONESHOT /. sleep someTime polecenia oneshot robi to samo.
Edik Mkoyan,