Выдает ли inotify уведомление при начале или завершении записи?

Выдает ли inotify уведомление при начале или завершении записи?

Представьте себе два процесса, читатель и писатель, взаимодействующие через обычный файл на файловой системе ext3. Читатель IN_MODIFYследит за файлом inotify. Писатель записывает 1000 байт в файл за один write()вызов. Читатель получает событие inotify и вызывает fstatфайл. Что видит Читатель?

  1. Есть ли гарантия, что Reader получит обратно хотя бы 1000 за st_sizeфайл? Из моих экспериментов, похоже, нет.

  2. Есть ли гарантия, что Reader действительно сможет прочитать read()1000 байт?

Это происходит на блоке с серьезными ограничениями ввода-вывода. Например, sarпоказывает время ожидания около 1 секунды. В моем случае Reader на самом деле ждет 10 секунд ПОСЛЕ получения события inotify перед вызовом statи получает слишком маленькие результаты.

Я надеялся, что событие inotify не будет доставлено, пока файл не будет готов. Я подозреваю, что на самом деле происходит то, что событие inotify срабатывает ВО ВРЕМЯ вызова write()в Writer, и данные фактически доступны другим процессам в системе, когда они будут готовы. В этом случае 10 секунд недостаточно.

Думаю, я просто ищу подтверждение того, что ядро ​​действительно реализует inotify так, как я предполагаю. Также, если есть какие-то варианты, возможно, изменить это поведение?

Наконец, в чем смысл inotify, учитывая такое поведение? Вам в любом случае придется опрашивать файл/каталог после получения события, пока данные не станут доступны. Можно было бы делать это все время и забыть об inotify.

***РЕДАКТИРОВАТЬ**** Хорошо, как это часто бывает, поведение, которое я наблюдаю, на самом деле имеет смысл, теперь, когда я понимаю, что я на самом деле делаю. ^_^

На самом деле я реагирую на событие IN_CREATE в каталоге, в котором находится файл. Таким образом, я фактически запускаю stat() для файла в ответ на создание файла, а не обязательно на событие IN_MODIFY, которое может появиться позже.

Я собираюсь изменить свой код так, чтобы, как только я получу событие IN_CREATE, я подписался на IN_MODIFY в самом файле, и я не буду фактически пытаться прочитать файл, пока не получу событие IN_MODIFY. Я понимаю, что есть небольшое окно, в котором я могу пропустить запись в файл, но это приемлемо для моего приложения, потому что в худшем случае файл будет закрыт через максимальное количество секунд.

решение1

Из того, что я вижу висходный код ядра, inotify запускается только после завершения записи (т. е. ваша догадка неверна). После срабатывания уведомления в , sys_writeфункции, реализующей writeсистемный вызов, происходят еще две вещи: установка некоторых параметров планировщика и обновление позиции в дескрипторе файла. Этот код был похож еще в2.6.14К моменту срабатывания уведомления файл уже имеет новый размер.

Проверьте, что может пойти не так:

  • Возможно, читатель получает старые уведомления от предыдущей записи.
  • Если читатель вызывает stat, а затем вызывает readили наоборот, что-то может произойти между ними. Если вы продолжаете добавлять данные в файл, вызов statfirst гарантирует, что вы сможете прочитать это расстояние, но возможно, что к моменту вызова читателя будет записано больше данных read, даже если он еще не получил уведомление inotify.
  • Просто потому, что вызывается writer, writeэто не означает, что ядро ​​запишет требуемое количество символов. Существует очень мало обстоятельств, когда атомарная запись гарантирована до любого размера. writeОднако каждый вызов гарантированно атомарен: в какой-то момент данные еще не записаны, а затем внезапнонбайты были записаны, гденэто возвращаемое значение вызова write. Если вы наблюдаете частично записанный файл, это означает, что он writeвернул меньше своего аргумента размера.

Полезные инструменты для расследования происходящего включают в себя:

  • strace -tt
  • подсистема аудита

Связанный контент