쓰기가 시작되거나 완료될 때 inotify가 알림을 실행합니까?

쓰기가 시작되거나 완료될 때 inotify가 알림을 실행합니까?

ext3 fs의 일반 파일을 통해 통신하는 두 프로세스, 리더와 라이터를 상상해 보세요. Reader에는 IN_MODIFY파일에 대한 inotify watch가 있습니다 . Writer는 단일 호출로 파일에 1000바이트를 씁니다 write(). 리더는 inotify 이벤트를 받고 fstat파일을 호출합니다. 리더는 무엇을 봅니까?

  1. st_sizeReader가 파일에 대해 최소 1000을 돌려받을 것이라는 보장이 있습니까 ? 내 실험에 따르면 그렇지 않은 것 같습니다.

  2. Reader가 실제로 1000바이트를 처리할 수 있다는 보장이 있습니까 read()?

이는 심각한 I/O 바인딩 상자에서 발생합니다. 예를 들어 sar약 1초의 대기 시간을 보여줍니다. 내 경우에는 Reader가 를 호출하기 전에 inotify 이벤트를 받은 후 실제로 10초를 기다리고 stat너무 작은 결과를 얻었습니다.

내가 바랐던 것은 파일이 준비될 때까지 inotify 이벤트가 전달되지 않기를 바랐던 것입니다. 실제로 발생하고 있다고 의심되는 것은 write()Writer에서 호출하는 동안 inotify 이벤트가 발생하고 데이터가 준비될 때마다 시스템의 다른 프로세스에서 실제로 사용할 수 있다는 것입니다. 이 경우 10초는 시간이 부족합니다.

나는 커널이 실제로 내가 추측하는 방식으로 inotify를 구현한다는 확인을 찾고 있는 것 같습니다. 또한 이 동작을 변경할 수 있는 옵션이 있다면?

마지막으로, 이 동작을 고려할 때 inotify의 요점은 무엇입니까? 어쨌든 이벤트를 받은 후 데이터를 실제로 사용할 수 있을 때까지 파일/디렉토리를 폴링하는 작업이 줄어듭니다. 계속해서 그렇게 하고 inotify를 잊어버리는 것이 나을 수도 있습니다.

***편집하다**** 좋아요, 종종 그렇듯이, 제가 보고 있는 행동은 실제로 의미가 있습니다. 이제 제가 실제로 하고 있는 일을 이해하고 있기 때문입니다. ^_^

실제로 파일이 있는 디렉터리의 IN_CREATE 이벤트에 응답하고 있습니다. 따라서 실제로 IN_MODIFY 이벤트가 아닌 파일 생성에 대한 응답으로 파일을 stat()하고 있습니다. 이 이벤트는 나중에 도착할 수 있습니다.

IN_CREATE 이벤트가 발생하면 파일 자체에서 IN_MODIFY를 구독하고 IN_MODIFY 이벤트가 발생할 때까지 실제로 파일 읽기를 시도하지 않도록 코드를 변경하겠습니다. 파일 쓰기를 놓칠 수 있는 작은 창이 있다는 것을 알고 있지만 최악의 경우 최대 몇 초 후에 파일이 닫히기 때문에 이는 내 응용 프로그램에 허용됩니다.

답변1

내가 본 것에서커널 소스, inotify는 쓰기가 완료된 후에만 실행됩니다(즉, 추측이 틀렸습니다). 알림이 트리거된 후 syscall을 sys_write구현하는 함수 에서 write일부 스케줄러 매개변수 설정 및 파일 설명자 위치 업데이트라는 두 가지 작업만 더 발생합니다. 이 코드는 이전에도 비슷했습니다.2.6.14. 알림이 실행될 때쯤에는 파일의 크기가 이미 변경되었습니다.

잘못될 수 있는 사항을 확인하세요.

  • 어쩌면 독자가 이전 쓰기로부터 오래된 알림을 받고 있을 수도 있습니다.
  • 독자가 전화를 stat한 다음 전화 read를 걸거나 그 반대로 전화를 걸면 그 사이에 어떤 일이 발생할 수 있습니다. 파일에 계속 추가하는 경우 statfirst를 호출하면 그 부분까지 읽을 수 있다는 것이 보장되지만, read아직 inotify 알림을 받지 않았더라도 리더가 호출할 때까지 더 많은 데이터가 기록되었을 가능성이 있습니다.
  • 작성자가 호출한다고 해서 write커널이 요청한 문자 수만큼 쓸 것이라는 의미는 아닙니다. 임의의 크기까지 원자 쓰기가 보장되는 상황은 거의 없습니다. 각 write호출은 원자성이 보장됩니다. 그러나 어떤 시점에서는 데이터가 아직 기록되지 않았으나 갑자기 기록됩니다.N바이트가 기록되었습니다.N호출 의 반환 값입니다 write. 부분적으로 작성된 파일을 관찰하면 write해당 크기 인수보다 작은 값을 반환했음을 의미합니다.

무슨 일이 일어나고 있는지 조사하는 데 유용한 도구는 다음과 같습니다.

  • strace -tt
  • auditd 하위 시스템

관련 정보