Liệu inotify bắn một thông báo khi bắt đầu viết hoặc khi nó được hoàn thành?


12

Hãy tưởng tượng hai quá trình, một người đọc và một người viết, giao tiếp qua một tệp thông thường trên một ext3 fs. Reader có một IN_MODIFYđồng hồ inotify trên tập tin. Nhà văn ghi 1000 byte vào tệp, trong một write()cuộc gọi. Reader nhận được sự kiện inotify và gọi fstattrên tệp. Reader thấy gì?

  1. Có đảm bảo rằng Reader sẽ lấy lại ít nhất 1000 cho st_sizetệp không? Từ thí nghiệm của tôi, có vẻ như không.

  2. Có đảm bảo rằng Reader thực sự có thể read()1000 byte không?

Điều này đang xảy ra trên một hộp ràng buộc I / O nghiêm trọng. Ví dụ: sarhiển thị thời gian chờ khoảng 1 giây. Trong trường hợp của tôi, Reader thực sự đang đợi 10 giây SAU KHI nhận được sự kiện inotify trước khi gọistat và nhận được kết quả quá nhỏ.

Những gì tôi đã hy vọng là sự kiện inotify sẽ không được gửi cho đến khi tập tin đã sẵn sàng. Điều tôi nghi ngờ đang thực sự xảy ra là sự kiện inotify kích hoạt DURING write()cuộc gọi trong Nhà văn và dữ liệu thực sự có sẵn cho các quy trình khác trên hệ thống bất cứ khi nào nó sẵn sàng. Trong trường hợp này, 10 giây là không đủ thời gian.

Tôi đoán tôi chỉ đang tìm kiếm xác nhận rằng hạt nhân thực sự thực hiện inotify theo cách tôi đoán. Ngoài ra, nếu có bất kỳ lựa chọn, có thể, để thay đổi hành vi này?

Cuối cùng- điểm gây bất lực là gì, đưa ra hành vi này? Dù sao bạn cũng được giảm việc bỏ phiếu cho tập tin / thư mục, sau khi bạn nhận được sự kiện, cho đến khi dữ liệu thực sự có sẵn. Cũng có thể làm điều đó suốt, và quên đi việc bị kích thích.

*** BIÊN TẬP ** * * Được rồi, như thường xảy ra, hành vi tôi đang thấy thực sự có ý nghĩa, bây giờ tôi hiểu những gì tôi đang làm. ^ _ ^

Tôi thực sự đang phản hồi một sự kiện IN_CREATE trên thư mục mà tệp đang tồn tại. Vì vậy, tôi thực sự là stat () 'trong tệp để đáp ứng với việc tạo tệp, không nhất thiết là sự kiện IN_MODIFY, có thể đến sau.

Tôi sẽ thay đổi mã của mình để sau khi nhận được sự kiện IN_CREATE, tôi sẽ đăng ký IN_MODIFY trên chính tệp đó và tôi sẽ không thực sự cố đọc tệp cho đến khi tôi nhận được sự kiện IN_MODIFY. Tôi nhận ra rằng có một cửa sổ nhỏ trong đó tôi có thể bỏ lỡ ghi vào tệp, nhưng điều này có thể chấp nhận được đối với ứng dụng của tôi, vì trong trường hợp xấu nhất, tệp sẽ bị đóng sau một số giây tối đa.


Bạn có thể sử dụng một đường ống thay vì một tập tin. Xem người đàn ông mknod
daniel kullmann

Chúng ta cần sử dụng một tệp thông thường để có bộ đệm nhiều terabyte giữa hai quy trình. Ngoài ra để bảo tồn dữ liệu trong bộ đệm qua khởi động lại.
Todd Freed

Câu trả lời:


5

Từ những gì tôi thấy trong nguồn kernel , inotify chỉ kích hoạt sau khi viết xong (tức là bạn đoán sai). Sau khi thông báo được kích hoạt, chỉ còn hai điều nữa xảy ra sys_write, chức năng thực hiện s tòa nhà write: thiết lập một số tham số lịch trình và cập nhật vị trí trên bộ mô tả tệp. Mã này đã tương tự như trước đây là 2.6,14 . Vào thời điểm thông báo kích hoạt, tệp đã có kích thước mới.

Kiểm tra những thứ có thể sai:

  • Có thể người đọc đang nhận được thông báo cũ, từ lần viết trước.
  • Nếu người đọc gọi statvà sau đó gọi readhoặc ngược lại, một cái gì đó có thể xảy ra ở giữa. Nếu bạn tiếp tục gắn vào tệp, stattrước tiên hãy gọi đảm bảo rằng bạn sẽ có thể đọc được đến đó, nhưng có thể nhiều dữ liệu đã được ghi vào thời điểm người đọc gọi read, ngay cả khi nó chưa nhận được thông báo inotify.
  • Chỉ vì người viết gọi writekhông có nghĩa là kernel sẽ ghi số lượng ký tự được yêu cầu. Có rất ít trường hợp các ghi nguyên tử được đảm bảo đến bất kỳ kích thước nào. writeTuy nhiên, mỗi cuộc gọi được đảm bảo nguyên tử: tại một số điểm dữ liệu chưa được ghi và sau đó đột nhiên n byte được ghi, trong đó n là giá trị trả về của writecuộc gọi. Nếu bạn quan sát một tệp được viết một phần, điều đó có nghĩa là writetrả về ít hơn đối số kích thước của nó.

Các công cụ hữu ích để điều tra những gì đang diễn ra bao gồm:

  • strace -tt
  • hệ thống con audd

Cảm ơn bạn cho những ý tưởng. Tôi vừa xem lại mã và trên thực tế tôi chỉ kiểm tra -1 là giá trị trả về từ ghi cho trường hợp lỗi. Vì vậy, có thể là tôi không nhận được giá trị trả về từ ghi cho biết rằng tất cả dữ liệu đã được ghi. Tuy nhiên, khi tôi nhìn vào tệp sau khi thực tế, tôi biết rằng tất cả các byte "1000" trên thực tế đã được viết, bởi vì tệp có hình dạng tốt, tức là nó bao gồm các bản ghi toàn bộ, mạch lạc. Vì vậy, hồ sơ đầu tiên không được viết một phần.
Todd giải phóng
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.