Neden inotify olayları birden fazla ateş ediyor


13

Bu soru, Stackoverflow üzerinde sormuş olduğum başka bir sorudan kaynaklanıyor . Ben kullanıyorum Watcher - Aynı konular için geçerli Incron - Bir klasörü ve uzak değişiklikler ve sessizce sincap Dropbox'a bu değişiklikler için çocuk klasörleri izlemek için.

Ben izlemek write_closeolay - IN_CLOSE_WRITE- amaç için. Başlangıçta modifyolayı izliyordum , yani IN_MODIFY. Bu çalışırken, büyük dosyalar yazarken birden fazla kez ateş olacağını buldum. Bu kulağa adil geldi, IN_CLOSE_WRITEbu yüzden belirli bir dosya için sadece bir kez olacağını varsaymanın makul olduğunu düşündüğümden beri geçtim.

Ancak durum böyle değil. Nano'da oluşturulan çok küçük bir metin dosyası için (yalnızca bir karakter) bile olay iki kez gerçekleşir. En iyi ihtimalle, aynı dosya Dropbox'ta iki kez senkronize edildiğinde gereksiz trafik ortaya çıkabilir. İlk olayda senkronizasyonu gerçekleştirdiğimden sonra sunucu tarafı dosyasını sildiğim için kendi durumumda felakete yol açıyor. Sonuç - ikinci olayda Dropbox yan dosyası 0 bayt dosyası olur.

Ben başka bir şey yapmadan önce benim senkronizasyon komut dosyası 10 saniye uyku yaparak bu konuda ilgileniyorum ve daha sonra söz konusu dosyanın hala Dropbox senkronizasyon denemeden önce var olup olmadığını kontrol edin. Bu, ikinci yinelemede dosya eksik olduğu ve komut dosyasının sonlandığı için çalışır.

Bu en iyi ihtimalle kulağa hoş geliyor. Belki de kötü bir hack değil ama anlamayı tercih ederim - neden IN_CLOSE_WRITEolay bile birden fazla kez gerçekleşiyor?


Bazı ek bilgiler

  • Çalışan birden fazla izleyici örneği olmadığından emin olun.

Çıktı 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

Dosya sistemi ext4. Incron ile tam olarak aynı sorunla karşılaştığımı belirtmeliyim. Watcher arka plan programını, üzerinden yürütülen bir toplu komut dosyasından başlatırım /etc/rc2.d. Incron OTH, varsayılan apt-get install incronkurulumu aracılığıyla benim tarafımdan herhangi bir karışıklık yaşamadan başlar .


Dosyamın özü watcher.iniaşağıda gösterilmiştir.

[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

Ben datastore.phpherhangi bir dağınık Dropbox yükleme + kaynak silme kodu olmadan iki kez ateşlendiğini doğrulamak için betiği çıplak temellere indirgedim .

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

?>

Daha sonra söz konusu yolda küçük bir dosya oluşturdum ve sonra inceledim /tmp/watcher. Sorun hala devam ediyor - dosyanın hala iki ardışık girişi var $argv[1].


1
Birçok varyasyonu denedim, ancak sorununuzu birden fazla IN_CLOSE_WRITE ateşleme ile çoğaltamıyorum. Yaptığım her şey tek bir inotify çıktısına neden oluyor. Bir şeyler denemeye devam edeceğim. Ama şimdiye kadar sadece sorular. Hangi dosya sistemi? Ext4? Diğer?
lornix

@lornix - lütfen sorumun düzenlemelerine bakın. Dosya sistemi ext4ve ben çalışan iki Watcher örneği olmadığından eminim. Incron ile aynı sorunu yaşadım.
DroidOS

'Senkronizasyonu gerçekleştiriyorum ve sonra sunucu tarafı dosyasını siliyorum' dediniz. Bu silme ikinci olayı tetikliyor mu? Rutini devre dışı deletebırakıp tekrar deneyebilir misiniz?
Germar

@Germar - sorumun düzenlemesine bakın. Senkronizasyon betiği bile gerçek senkronizasyon yapmıyorsa unlinkve sorun
çözülmediyse bile

Üzgünüm, fikirlerden ziyade, sorunu hiçbir makinemde yeniden üretemiyorum. Bir olay daha olsun. Başka bir şey söz konusudur, bahsedilmeyen bir şey. Yüklü bir virüsten koruma yazılımınız var mı? böyle bir şey?
lornix

Yanıtlar:


1

Emin değilim, ama büyük olasılıkla ilk write_close dosya öznitelikleri, oluşturma zamanı gibi içine yazar ve sadece bundan sonra gerçek verileri yazar. Aslında rsync bir geçici dosya oluşturur ve her şey tamamlandığında geçici dosyayı aynı klasördeki gerçek dosyaya taşır, bu nedenle rsync kullandığınızda normalde izlenmesi kolaydır ve hareket atomik bir işlemdir. Öte yandan inotify'da bir atış calle, muhtemelen bunu kullanarak ilk değişiklik mesajında ​​bir şey tetikleyebileceğimiz ve operasyona başlamadan önce makul bir süre uyumanızı önerdiğimiz bir şey var. Bunu şimdi kazıyorum ve yeni bir şey bulduğumda güncellenecek. /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify


Parmağınızı burada oldukça geçerli bir şeye koymuş olabilirsiniz. Biraz araştırma gerektirecek. Bahşiş için teşekkürler. Bunun bir şekilde bir sorun olduğunu fark ettiğimde geri göndereceğim.
DroidOS

ATTRIB dosyasının kendisine bir şey eklediğini sanmıyorum, yanılmışım.
Edik Mkoyan

0

Bunu yorum olarak göndermek için yeterli temsilcim yok, ancak geçici, muhtemelen gizli dosyaların oluşturulmadığından emin misiniz? inotifywaitBirden çok kez ateşlemede benzer bir sorunum vardı , ancak bunun vim'in düzenleme sırasında bir .swp dosyası oluşturacağı ve bunun kapanırken bir olayı tetikleyeceği için olduğunu fark ettim. Ayrıca orijinal dosyadan close olayını alır.

Yine de aynı dosyada birden çok dosyayı tetikleyen etkinliğin farkına varmışsınız gibi görünüyor, bu da üretebildiğim bir şey değil - bu sadece geçici dosya için ve orijinal için bir kez olur.

Nano ile hızlı bir test denedim ve hiç geçici bir dosya oluşturduğunu sanmıyorum (en azından birkaç karakter durumda), ancak kurulumunuzda benzer davranışlara güvenebilecek başka bir şey var mı?


önerileriniz için teşekkür ederim. İçine çalıştırdığınız Inotify ya da sadece bir dosya içine konsolundan bir tek karakter yönlendirerek - Ben çok önemsiz 1 bayt Nano ile dosya oluştururken hatta birden sorunu. Orijinal sorumda ana hatlarıyla anlattığım "çözüm" beni şimdilik sürdürüyor. Ancak, daha uzun vadede, sunucunun sıfırdan başlayarak, hatanın ne zaman başladığını belirlemek için yeniden oluşturmam gereken tek çözüm - Incron, Watcher (btw sadece Incron'um olduğunda oldu), MariaDB, Nginx, Redis, Memcached ... tam olarak "basit" değil.
DroidOS

Her ihtimale karşı, aynı klasörü iki kez izleyip izlemediğinizi iki kez kontrol edin. Değilse, örneğin dosyayı samba paylaşımına os x samba istemcisi aracılığıyla kopyaladığımda bu oluşur, kapat_yazar, sil, oluştur, kapat_yazar Bunu bir Windows istemcisi ile yaptığımda, daha makul bir şekilde oluştur, yazma_Kapat ve başka bir şey görünmez. Bu yüzden bu IN_MODIFY, IN_ONESHOT / dizini ile dosyanın ilk değişikliğini izleyerek sorunumu çözdüm. uyku someTime komutları oneshot şeyi yapar.
Edik Mkoyan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.