inotify с NFS
недавно я создал систему dropbox с помощью inotify, наблюдая за файлами, созданными в определенном каталоге. Каталог, который я смотрю, монтируется с сервера NFS, и inotify ведет себя иначе, чем я ожидал. Рассмотрим следующий сценарий, в котором сценарий inotify запускается на машине A, наблюдая /some/nfs/dir/also/visible/to / B.
-используя машину A для создания файла в /some/nfs/dir/also/visible/to/B, скрипт ведет себя так, как ожидалось. Использование машины B для переноски из того же действия скрипт не уведомляется о новом файле, удаленном в каталог.
- Когда скрипт запускается на сервере NFS, он получает уведомление, когда файлы создаются как с машины A, так и с машины B.
Это ошибка в ошибке в пакете, который я использую для доступа к inotofy, или это ожидаемое поведение?
с уважением,
Андрей
4 ответов
для работы inotify требуется поддержка ядра. Когда приложение отслеживает каталог, оно просит ядро сообщить ему, когда происходят эти изменения. Когда происходит изменение, в дополнение к записи этих изменений на диск ядро также уведомляет процесс наблюдения.
на удаленной машине NFS изменение не видно ядру; оно происходит полностью удаленно. NFS предшествует inotify, и в NFS нет поддержки сетевого уровня или чего-либо эквивалентного.
Если вы хотите обойти это, вы можете запустить службу на сервере хранения (так как это ядро всегда будет видеть изменения в файловой системе), который брокеры inotify запросы для удаленных машин, и пересылать данные на удаленных клиентов.
Edit: мне кажется, что NFS следует винить за отсутствие поддержки inotify.
:сетевая файловая система (NFS) - это протокол распределенной файловой системы первоначально разработанный Sun Microsystems в 1984 году, статья в Википедии
Inotify (inode notify) является подсистема ядра Linux это действует для расширения файловых систем, чтобы заметить изменения в файловой системе. [...] Он был включен в ядро Linux mainline с версии 2.6.13 (18 июня, 2005 ) [...]. статья в Википедии
Это сложно ожидать, что портативный сетевой протокол / приложение будет поддерживать определенную функцию ядра, разработанную для другой операционной системы, и которая появилась более двадцати лет спустя. Даже если это сделал включить расширения для него, они не будут доступны и полезны на других операционных системах.
*акцент мой во всех случаях
другая проблема с этим; предположим, что мы вообще не используем сеть, но скорее, локальная файловая система с хорошей поддержкой inotify: ext3 (предположим, что она установлена на /mnt/foo
). Но вместо реального диска файловая система монтируется с петлевого устройства ; и базовый файл, в свою очередь, доступен в другом месте в vfs (скажем,/var/images/foo.img
).
Теперь вы не должны изменять смонтированные файловые системы ext3, но это все еще достаточно безопасно, если изменение заключается в содержимом файла вместо метаданных.
поэтому предположим, что умный пользователь изменяет образ файловой системы (/var/images/foo.img
) в шестнадцатеричном редакторе, заменяя содержимое файла некоторыми другими данными, в то же время часы inotify наблюдают за тем же файлом в смонтированной файловой системе.
нет разумного способа организовать inotify, чтобы всегда информировать процесс просмотра такого рода изменений. Хотя, вероятно, есть некоторые вращения, которые можно было бы предпринять, чтобы ext3 заметил и почтил изменение, ничто из этого не будет применяться, скажем, к XFS drtiver, который в остальном очень похоже.
не должно. Ты жульничаешь!. inotify может сообщить вам только об изменениях, которые произошли через vfs на фактической наблюдаемой точке монтирования. Если изменения произошли вне этого VFS из-за изменения базовых данных, inotify не может помочь вам и не предназначен для решения этой проблемы.
вы рассматривали возможность использования очереди сообщений для сетевого уведомления?
Я согласен с объяснением SingleNegationElimination и хотел бы добавить, что цели iSCSI будут работать, так как они предупреждают ядро.
таким образом, вещи в "реальных" файловых системах (относительно системы, то есть) вызовут Inotify для оповещения. Как Rsync'ING, net-catting что-то в установленный раздел.
Если вам нужно получать уведомления через inotify (или использовать inotify), вы можете сделать cron для rsync-avz в файловой системе. Недостатки, конечно, что вы используете реальное системное пространство hdd.
для всех, кто столкнулся с этим вопросом в поиске ответа на вопрос, почему привязка монтажа на Docker не будет обнаруживать изменения файлов из каталога хоста (для горячей перезагрузки приложения), это потому, что распространение изменений файлов между хостом и контейнером не сообщается ядру контейнера.
только изменения из самого контейнера передаются ядру. Решение для этого заключается в том, чтобы ваша утилита live reload включила "режим опроса" вместо использования fsnotify.