Inotify с помощью NFS - программирование
Подтвердить что ты не робот

Inotify с помощью NFS

Недавно я создал систему Dropbox, используя inotify, наблюдая за файлами, созданными в определенном каталоге. Каталог, который я наблюдаю, монтируется с сервера NFS, а inotify ведет себя не так, как я ожидал. Рассмотрим следующий сценарий, в котором сценарий inotify запускается на компьютере A, просматривая /some/nfs/dir/также /visible/to/B.

-Using машина A для создания файла в /some/nfs/dir/также /visible/to/B, скрипт ведет себя как положено. Используя компьютер B для выполнения того же действия, сценарий не уведомляется о новом файле, добавленном в каталог.
-When скрипт запускается на сервере NFS, он получает уведомление, когда файлы создаются как на компьютере A, так и на компьютере B.

Это ошибка в пакете в пакете, который я использую для доступа к inotofy, или это ожидаемое поведение?

4b9b3361

Ответ 1

inotify требует поддержки ядра для работы. Когда приложение отслеживает каталог, оно запрашивает ядро, чтобы сообщить об этом, когда произойдут эти изменения. Когда происходит изменение, помимо записи этих изменений на диск, ядро ​​также уведомляет процесс просмотра.

На удаленной машине NFS изменение не отображается в ядре; это происходит совершенно удаленно. NFS предшествует inotify, и в NFS нет поддержки сетевого уровня или что-либо эквивалентное.

Если вы хотите обойти это, вы можете запустить службу на сервере хранения (так как это ядро ​​всегда будет видеть изменения в файловой системе), которая броузерит inotify запросы на удаленные компьютеры и перенаправляет данные удаленным клиентам.

Изменить: Мне кажется странным, что NFS следует обвинять в отсутствии поддержки inotify.

Сетевая файловая система (NFS) - это протокол распределенной файловой системы, первоначально разработанный компанией Sun Microsystems в 1984 году, статья wikipedia

Однако:

Inotify (inode notify) - это подсистема ядра Linux, которая действует, чтобы расширить файловые системы, чтобы заметить изменения в файловой системе. [...] Он включен в основное ядро ​​Linux из версии 2.6.13 (18 июня, 2005) [...]. статья в википедии

Жестко ожидать, что переносимый сетевой протокол/приложение будет поддерживать определенную функцию ядра, разработанную для другой операционной системы, и которая появилась более двадцати лет спустя. Даже если бы он включал расширения для него, они не были бы доступны или полезны в других операционных системах.

* подчеркивание во всех случаях


Другая проблема с этим; Предположим, мы вообще не используем сеть, а локальную файловую систему с хорошей поддержкой inotify: ext3 (предположим, что она установлена ​​в /mnt/foo). Но вместо реального диска файловая система монтируется из устройства loopback; и основной файл, в свою очередь, доступен в другом месте в vfs (скажем, /var/images/foo.img).

Теперь вы не должны модифицировать смонтированные файловые системы ext3, но это все равно достаточно безопасно, если это изменение относится к содержимому файла вместо метаданных.

Итак, предположим, что умный пользователь изменяет образ файловой системы (/var/images/foo.img) в шестнадцатеричном редакторе, заменяя содержимое файла другими данными, в то время как часы inotify наблюдают один и тот же файл на смонтированной файловой системе.

Там нет разумного способа организовать inotify, чтобы всегда информировать процесс просмотра такого рода изменений. Несмотря на то, что, возможно, есть некоторые повороты, которые могут потребоваться, чтобы уведомить ext3 и почитать это изменение, ничто из этого не применимо, скажем, к файлу xfs drtiver, который в противном случае очень похож.

И не должен. Ты обманываешь! inotify может информировать вас только об изменениях, происходящих через vfs, при просмотре фактической точки монтирования. Если изменения произошли за пределами этой VFS, из-за изменения базовых данных, inotify не может помочь вам и не предназначен для решения этой проблемы.

Рассматривали ли вы использование очереди сообщений для сетевого уведомления?

Ответ 2

Я нашел SGI FAM, используя демон супервизора для мониторинга изменения файла. Он поддерживает NFS, и вы можете увидеть некоторое описание на wiki

Ответ 3

Любой, кто сталкивался с этим вопросом в поисках ответа на вопрос, почему монтирование привязки в Docker не будет обнаруживать изменения файлов из каталога хоста (для горячей перезагрузки приложения), это потому, что распространение изменений файла между хостом и контейнером не связался с ядром контейнера.

Только изменения из самого контейнера передаются ядру. Решение этой проблемы состоит в том, чтобы ваша утилита перезагрузки в реальном времени включила "режим опроса" вместо использования fsnotify.

Ответ 4

Я согласен с объяснением SingleNegationElimination и хотел бы добавить, что цели iSCSI будут работать, поскольку они предупреждают ядро.

Таким образом, вещи в "реальных" файловых системах (относительно системы, то есть) вызовут Inotify для предупреждения. Как и Rsync'ing, net-catting что-то вмонтированный раздел.

Если вам нужно получать уведомления через inotify (или использовать inotify), вы можете сделать cron для rsync -avz в файловой системе. Конечно, недостатками являются то, что вы используете реальное пространство hdd системы.

Ответ 5

Я второй @SingleNegationElimination.

Также вы можете попробовать уведомить-пересылку.

  • Машина A следит за локальными событиями inotify, а затем передает их на машину B (через UDP).
  • Машина B не (не может?) Воспроизводить события, но запускает событие ATTRIB для измененного файла.

Если вы используете vagrant, используйте vagrant-notify-forwarder.