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


12

ext3 fs에서 일반 파일을 통해 통신하는 리더와 라이터라는 두 가지 프로세스를 상상해보십시오. 리더는 IN_MODIFY파일에 대한 무결점 감시 기능을 가지고 있습니다. Writer는 한 번의 write()호출로 파일에 1000 바이트를 씁니다 . Reader는 inotify 이벤트 fstat를 받고 파일을 호출 합니다. 리더는 무엇을 봅니까?

  1. Reader가 st_size파일 에서 최소 1000을 되 찾을 것이라는 보장이 있습니까? 내 실험에서 그렇지 않은 것 같습니다.

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

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

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

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

마지막으로,이 행동을 고려할 때, 무결점의 요점은 무엇입니까? 어쨌든 이벤트가 발생한 후 데이터를 실제로 사용할 수있을 때까지 파일 / 디렉토리를 폴링하는 횟수가 줄어 듭니다. 뿐만 아니라 그 모든 일을하고, inotify에 대해 잊어 버릴 수 있습니다.

*** 편집하다 ** * * 자주 발생하는 것처럼 내가보고있는 행동은 실제로 의미가 있습니다. ^ _ ^

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

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


파일 대신 파이프를 사용할 수 있습니다. 사람 mknod 참조
다니엘 쿨만

두 프로세스 사이에 테라 바이트 크기의 버퍼를 갖기 위해서는 일반 파일을 사용해야합니다. 또한 재부팅 동안 버퍼의 데이터를 보존합니다.
Todd는

답변:


5

커널 소스 에서 볼 수 있듯이 , inotify는 쓰기가 완료된 후에 만 ​​실행됩니다 (예 : 추측이 틀립니다). 알림이 트리거 된 후 syscall sys_write을 구현하는 함수 인 write스케줄러 매개 변수 설정 및 파일 디스크립터의 위치 업데이트 에서 두 가지만 더 발생 합니다. 이 코드는 2.6.14 와 비슷 합니다. 알림이 실행될 때 파일의 크기는 이미 새로운 것입니다.

잘못 될 수있는 사항을 확인하십시오.

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

진행 상황을 조사하는 유용한 도구는 다음과 같습니다.

  • strace -tt
  • 감사 서브 시스템

아이디어 주셔서 감사합니다. 방금 코드를 검토했으며 실제로 오류 사례에 대한 쓰기의 반환 값으로 -1 만 확인하고 있습니다. 따라서 모든 데이터가 기록되었음을 나타내는 쓰기 값에서 반환 값을 얻지 못할 수 있습니다. 그럼에도 불구하고, 사실 이후에 파일을 볼 때, 파일이 양호한 형태, 즉 전체적이고 일관된 레코드로 구성되어 있기 때문에 모든 "1000"바이트가 실제로 쓰여졌다는 것을 알고 있습니다. 따라서 첫 번째 레코드는 부분적으로 작성되지 않습니다.
Todd
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.