ทำให้ไฟแจ้งเตือนเมื่อการเขียนเริ่มต้นหรือเมื่อเสร็จสิ้นหรือไม่?


12

ลองนึกภาพสองกระบวนการผู้อ่านและนักเขียนสื่อสารผ่านไฟล์ปกติบน ext3 fs Reader มี inotify IN_MODIFYwatch ในไฟล์ Writer เขียน 1,000 ไบต์ไปยังไฟล์ในการwrite()โทรครั้งเดียว Reader รับเหตุการณ์ inotify และเรียกfstatใช้ไฟล์ Reader เห็นอะไร

  1. มีการรับประกันว่า Reader จะได้รับคืนอย่างน้อย 1,000 st_sizeไฟล์หรือไม่? จากการทดลองของฉันดูเหมือนจะไม่

  2. มีการรับประกันว่า Reader สามารถread()1,000 ไบต์จริงหรือไม่?

สิ่งนี้เกิดขึ้นใน I / O bound box ที่จริงจัง ตัวอย่างเช่นsarแสดงเวลาที่รอประมาณ 1 วินาที ในกรณีของฉัน Reader กำลังรอ 10 วินาทีหลังจากได้รับการแจ้งเตือนเหตุการณ์ก่อนที่จะโทรstatและรับผลลัพธ์ที่น้อยเกินไป

สิ่งที่ฉันหวังไว้คือเหตุการณ์ inotify จะไม่ถูกส่งจนกว่าไฟล์จะพร้อม สิ่งที่ฉันสงสัยว่าจริง ๆ แล้วเกิดขึ้นคือเหตุการณ์ inotify เกิดเพลิงไหม้ในระหว่างการwrite()โทรใน Writer และข้อมูลนั้นพร้อมใช้งานสำหรับกระบวนการอื่น ๆ ในระบบเมื่อใดก็ตามที่เกิดความพร้อม ในกรณีนี้ 10 วินาทีมีเวลาไม่เพียงพอ

ฉันเดาว่าฉันแค่กำลังมองหาการยืนยันว่าเคอร์เนลใช้งานจริงแจ้งวิธีที่ฉันคาดเดา นอกจากนี้หากมีตัวเลือกใด ๆ อาจเป็นไปได้ที่จะแก้ไขพฤติกรรมนี้

ในที่สุด - อะไรคือประเด็นของการระบุไม่ถูกต้องเนื่องจากพฤติกรรมนี้ คุณจะถูกลดขนาดให้ทำการสำรวจไฟล์ / ไดเรกทอรีหลังจากคุณได้รับเหตุการณ์จนกระทั่งข้อมูลมีอยู่จริง อาจจะทำเช่นนั้นมาตลอดและลืมเกี่ยวกับการไม่พูดถึง

*** แก้ไข ** * * โอเคบ่อยครั้งที่เกิดขึ้นพฤติกรรมที่ฉันเห็นมีเหตุผลจริง ๆ ตอนนี้ฉันเข้าใจแล้วว่าฉันกำลังทำอะไรอยู่ ^ _ ^

ฉันกำลังตอบกลับเหตุการณ์ IN_CREATE ในไดเรกทอรีที่ไฟล์นั้นอาศัยอยู่ดังนั้นฉันจึงกำลัง stat () ในการตอบสนองต่อการสร้างไฟล์ไม่จำเป็นต้องเป็นเหตุการณ์ IN_MODIFY ซึ่งอาจมาถึงในภายหลัง

ฉันจะเปลี่ยนรหัสของฉันดังนั้นเมื่อฉันได้รับเหตุการณ์ IN_CREATE ฉันจะสมัครสมาชิก IN_MODIFY ในไฟล์เองและฉันจะไม่พยายามอ่านไฟล์จนกว่าจะได้รับ IN_MODIFY ฉันรู้ว่ามีหน้าต่างเล็ก ๆ ที่ฉันอาจพลาดเขียนไฟล์ แต่นี่เป็นที่ยอมรับสำหรับแอปพลิเคชันของฉันเพราะในกรณีที่เลวร้ายที่สุดไฟล์จะถูกปิดหลังจากจำนวนวินาทีสูงสุด


คุณสามารถใช้ไพพ์แทนไฟล์ได้ ดู man mknod
daniel kullmann

เราจำเป็นต้องใช้ไฟล์ปกติเพื่อให้มีบัฟเฟอร์หลายเทราไบต์ระหว่างสองกระบวนการ นอกจากนี้เพื่อรักษาข้อมูลในบัฟเฟอร์ข้ามรีบูต
ทอดด์อิสระ

คำตอบ:


5

จากสิ่งที่ฉันเห็นในแหล่งเคอร์เนล inotify จะเริ่มทำงานหลังจากเขียนเสร็จแล้วเท่านั้น (เช่นคุณเดาว่าผิด) หลังจากมีการเรียกใช้การแจ้งเตือนเกิดขึ้นอีกสองสิ่งเท่านั้นที่เกิดขึ้นในsys_writeฟังก์ชั่นที่ใช้writesyscall: การตั้งค่าพารามิเตอร์ตัวกำหนดตารางเวลาบางตัวและการอัปเดตตำแหน่งบนตัวอธิบายไฟล์ รหัสนี้ได้รับการที่คล้ายกันไกลกลับเป็น2.6.14 เมื่อถึงเวลาที่การแจ้งเตือนเริ่มขึ้นไฟล์มีขนาดใหม่แล้ว

ตรวจสอบสิ่งที่อาจผิดพลาด:

  • บางทีผู้อ่านอาจได้รับการแจ้งเตือนเก่าจากการเขียนครั้งก่อน
  • หากผู้อ่านโทรstatแล้วโทรreadหรือกลับกันอาจมีบางสิ่งเกิดขึ้นระหว่างนั้น หากคุณต่อท้ายไฟล์การโทรstatก่อนรับรองได้ว่าคุณจะสามารถอ่านได้ไกล แต่อาจเป็นไปได้ว่ามีการเขียนข้อมูลเพิ่มเติมในเวลาที่ผู้อ่านเรียกreadแม้ว่ามันจะยังไม่ได้รับการแจ้งเตือนแบบ inotify ก็ตาม
  • เพียงเพราะการเรียกตัวเขียนwriteไม่ได้หมายความว่าเคอร์เนลจะเขียนจำนวนอักขระที่ร้องขอ มีสถานการณ์น้อยมากที่รับประกันการเขียนของอะตอมจนถึงขนาดใดก็ได้ อย่างไรก็ตามการwriteเรียกแต่ละครั้งจะมีการรับประกันอะตอมมิก: ในบางจุดข้อมูลยังไม่ได้ถูกเขียนและจากนั้นก็มีการเขียนnไบต์โดยที่nคือค่าส่งคืนของการwriteโทร หากคุณสังเกตเห็นไฟล์ที่เขียนบางส่วนก็หมายความว่าไฟล์นั้นwriteมีขนาดเล็กกว่าอาร์กิวเมนต์

เครื่องมือที่มีประโยชน์ในการตรวจสอบสิ่งที่เกิดขึ้น ได้แก่ :

  • strace -tt
  • ระบบย่อย auditd

ขอบคุณสำหรับความคิด ฉันเพิ่งตรวจสอบรหัสและในความเป็นจริงฉันเพียงตรวจสอบ -1 เป็นค่าตอบแทนจากการเขียนสำหรับกรณีข้อผิดพลาด ดังนั้นอาจเป็นได้ว่าฉันไม่ได้รับค่าส่งคืนจากการเขียนระบุว่าข้อมูลทั้งหมดถูกเขียน อย่างไรก็ตามเมื่อฉันดูไฟล์หลังจากความจริงฉันรู้ว่าไบต์ทั้งหมด 1,000 อันถูกเขียนขึ้นเพราะไฟล์นั้นอยู่ในสภาพที่ดีนั่นคือมันประกอบด้วยบันทึกที่เชื่อมโยงกันทั้งหมด ดังนั้นบันทึกแรกไม่ได้ถูกเขียนเพียงบางส่วน
ทอดด์อิสระ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.