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].


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


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?


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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.