Tại sao các sự kiện inotify cháy nhiều lần


13

Câu hỏi này phát sinh từ một câu hỏi khác mà tôi đã đặt ra trên Stackoverflow . Tôi đang sử dụng Watcher - các vấn đề tương tự áp dụng cho Incron - để theo dõi một thư mục và các thư mục con của nó để thay đổi và âm thầm tìm kiếm những thay đổi đó cho Dropbox.

Tôi theo dõi write_closesự kiện - IN_CLOSE_WRITE- cho mục đích. Ban đầu tôi đang xem modifysự kiện, tức là IN_MODIFY. Trong khi điều này hoạt động tôi thấy rằng khi viết các tệp lớn, nó sẽ kích hoạt nhiều lần. Điều đó nghe có vẻ công bằng vì vậy tôi đã chuyển sang IN_CLOSE_WRITEvì tôi cảm thấy rằng thật hợp lý khi cho rằng đối với một tệp nhất định, nó sẽ chỉ xảy ra một lần.

Tuy nhiên, đó không phải là trường hợp. Ngay cả đối với một tệp văn bản rất nhỏ - chỉ một ký tự - được tạo trong Nano, sự kiện này xảy ra hai lần. Tốt nhất điều này có thể dẫn đến lưu lượng không cần thiết khi cùng một tệp được đồng bộ hóa trên Dropbox hai lần. Trong trường hợp của riêng tôi, nó dẫn đến thảm họa vì trong sự kiện đầu tiên tôi thực hiện đồng bộ hóa và sau đó xóa tệp phía máy chủ. Kết quả - trong sự kiện thứ hai, tệp bên Dropbox trở thành tệp 0 byte.

Bây giờ tôi đang xử lý vấn đề này bằng cách làm cho tập lệnh đồng bộ hóa của tôi ngủ trong 10 giây trước khi tôi làm bất cứ điều gì khác và sau đó tôi kiểm tra xem tệp đang nghi vấn có còn tồn tại trước khi thử đồng bộ hóa Dropbox không. Điều này hoạt động bởi vì ở lần lặp thứ hai, tệp bị thiếu và tập lệnh chỉ chấm dứt.

Điều này nghe có vẻ tốt nhất. Có lẽ không phải là một hack xấu nhưng tôi muốn hiểu - tại sao ngay cả IN_CLOSE_WRITEsự kiện này xảy ra nhiều hơn một lần?


Một số thông tin bổ sung

  • Kiểm tra để đảm bảo rằng không có nhiều phiên bản của trình theo dõi đang chạy.

Đầu ra từ 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

Hệ thống tập tin là ext4. Tôi nên đề cập rằng tôi đã gặp chính xác vấn đề tương tự với Incron. Tôi khởi động Trình theo dõi lên từ một tập lệnh thực thi thông qua /etc/rc2.d. Incron OTH khởi động mà không có bất kỳ sự lộn xộn nào của tôi thông qua apt-get install incroncài đặt mặc định của nó .


Bản chất của watcher.initập tin của tôi được hiển thị dưới đây.

[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

Tôi đã giảm datastore.phptập lệnh xuống mức tối thiểu để xác minh rằng nó được kích hoạt hai lần mà không có bất kỳ mã tải lên + mã xóa mã nguồn lộn xộn nào của tôi.

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

?>

Sau đó tôi đã tạo ra một tập tin nhỏ ở đường dẫn trong câu hỏi và sau đó kiểm tra /tmp/watcher. Vấn đề vẫn còn tồn tại - tệp vẫn có hai mục liên tiếp $argv[1].


1
Tôi đã thử nhiều biến thể, nhưng không thể sao chép vấn đề của bạn bằng nhiều cách sử dụng IN_CLOSE_WRITE. Bất cứ điều gì tôi đã làm gây ra một đầu ra inotify. Tôi sẽ tiếp tục thử mọi thứ. Nhưng cho đến nay, chỉ có câu hỏi. Hệ thống tập tin nào? Ext4? Khác?
lornix

@lornix - vui lòng xem các chỉnh sửa cho câu hỏi của tôi. Hệ thống tệp là ext4và tôi chắc chắn rằng tôi không có hai phiên bản Watcher đang chạy. Tôi đã gặp vấn đề tương tự với Incron.
DroidOS

Bạn nói 'Tôi thực hiện đồng bộ hóa và sau đó xóa tệp phía máy chủ'. Liệu xóa này kích hoạt sự kiện thứ hai? Bạn có thể vô hiệu hóa deletethói quen và thử lại không?
Germar

@Germar - xem chỉnh sửa câu hỏi của tôi. Ngay cả với tập lệnh đồng bộ hóa không thực hiện đồng bộ hóa thực sự và không có unlinkvấn đề gì vẫn tồn tại
DroidOS

Xin lỗi, thay vì hết ý tưởng, tôi không thể tái tạo vấn đề trên bất kỳ máy nào của mình. Tôi nhận được một sự kiện, không còn nữa. Một cái gì đó khác có liên quan, một cái gì đó không được đề cập. Bạn đã cài đặt phần mềm chống vi-rút? Tất cả những thứ tương tự như vậy?
lornix

Câu trả lời:


1

Tôi không chắc chắn, nhưng rất có thể là lần đầu tiên write_close ghi các thuộc tính tệp vào nó, như thời gian tạo và chỉ sau đó nó mới ghi dữ liệu thực tế. Trong thực tế, rsync tạo một tệp tạm thời và khi mọi thứ hoàn tất, nó sẽ di chuyển tệp tạm thời sang tệp thực trong cùng một thư mục để dễ dàng theo dõi đã được tạo khi bạn sử dụng rsync và di chuyển là thao tác nguyên tử. Mặt khác, có một thứ gì đó làm dịu đi một cú inotify, có lẽ là bằng cách sử dụng chúng ta có thể kích hoạt một cái gì đó trong tin nhắn sửa đổi đầu tiên, và như bạn đã đề nghị ngủ trong một khoảng thời gian hợp lý trước khi bắt đầu hoạt động. Tôi đang đào cái này bây giờ, và sẽ cập nhật khi tôi tìm thấy bất cứ điều gì mới. /superuser/1133642/traceing-the-moment-when-file-is-completely-copied-to-samba-share-with-inotify


Bạn cũng có thể đã đặt ngón tay của bạn vào một cái gì đó khá hợp lệ ở đây. Nó sẽ yêu cầu một số điều tra. Cảm ơn vì tiền hỗ trợ. Tôi sẽ đăng lại trong trường hợp tôi thấy rằng đây là một vấn đề.
DroidOS

Tôi không nghĩ rằng ATTRIB thêm bất cứ điều gì vào tập tin, tôi đã sai.
Edik Mkoyan

0

Tôi không có đủ đại diện để đăng bài này dưới dạng nhận xét, nhưng bạn có chắc chắn rằng các tệp tạm thời, có thể bị ẩn không được tạo không? Tôi đã có một vấn đề tương tự vớiinotifywait việc bắn nhiều lần, nhưng tôi nhận ra rằng đó là vì vim sẽ tạo tệp .swp khi chỉnh sửa, sẽ kích hoạt một sự kiện khi đóng. Nó cũng sẽ nhận sự kiện gần từ tập tin gốc.

Có vẻ như bạn đang chú ý đến sự kiện bắn nhiều tệp trên cùng một tệp, đó không phải là thứ tôi có thể sao chép - điều này chỉ xảy ra một lần đối với tệp tạm thời và một lần đối với tệp gốc.

Tôi đã thử một thử nghiệm nhanh với nano và tôi không nghĩ rằng nó tạo ra một tệp tạm thời (ít nhất là đối với một vài trường hợp ký tự), nhưng có điều gì khác trong thiết lập của bạn có thể dựa vào hành vi tương tự không?


Cám ơn bạn đã đóng góp ý kiến. Tôi đã chạy vào inotify nhiều vấn đề ngay cả khi tôi tạo ra một tập tin 1 byte rất tầm thường với Nano - hoặc thậm chí bằng cách chỉ cần chuyển hướng một char duy nhất từ giao diện điều khiển vào một tập tin. "Giải pháp" mà tôi đã nêu trong câu hỏi ban đầu của tôi là giữ cho tôi đi ngay bây giờ. Tuy nhiên, về lâu dài, giải pháp duy nhất tôi phải xây dựng lại máy chủ của mình bắt đầu từ đầu để xác định ngay khi lỗi bắt đầu - thiết lập của tôi với Incron, Watcher (btw đã xảy ra khi tôi vừa Incron), MariaDB, Nginx, Redis, Memcached ... không chính xác là một "đơn giản".
DroidOS

Chỉ trong trường hợp, kiểm tra lại nếu bạn không theo dõi cùng một thư mục hai lần. Nếu không, ví dụ như khi tôi sao chép tệp vào chia sẻ samba qua os x samba client thì điều này xảy ra tạo, close_write, xóa, tạo, close_write Khi tôi làm điều đó với máy khách windows, nó có vẻ hợp lý hơn, write_close và không có gì hơn. Vì vậy, tôi giải quyết vấn đề của mình bằng cách theo dõi sửa đổi đầu tiên của tệp với thư mục IN_MODIFY, IN_ONESHOT / này. ngủ một số lệnh thời gian oneshot làm điều đó.
Edik Mkoyan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.