用NFS进行inotify

ajw*_*ood 57 nfs inotify

我最近使用inotify创建了一个Dropbox系统,用于查看在特定目录中创建的文件.我正在观看的目录是从NFS服务器挂载的,而inotify的行为与我预期的不同.考虑以下场景:在机器A上运行inotify脚本,观察/ some/nfs/dir/also/visible/to/B.

- 使用机器A在/ some/nfs/dir/also/visible/to/B中创建文件,脚本按预期运行.使用机器B执行相同的操作,不会通知脚本有关目录中丢弃的新文件.
- 当在NFS服务器上运行脚本时,从机器A和机器B创建文件时会收到通知.

这是我用来访问inotofy的包中的错误,还是这个预期的行为?

问候,

安德鲁

Sin*_*ion 66

inotify需要内核的支持才能工作.当应用程序跟踪目录时,它会要求内核在发生这些更改时通知它.发生更改时,除了将这些更改写入磁盘外,内核还会通知观察过程.

在远程NFS计算机上,内核看不到更改; 它完全是远程发生的.NFS早于inotify,并且在NFS中没有网络级别支持,或任何等效的.

如果您想解决这个问题,您可以在存储服务器上运行服务(因为该内核将始终看到文件系统的更改),代理会为远程计算机输入请求,并将数据转发到远程客户端.

编辑:对我来说,似乎很奇怪NFS应该因缺乏对inotify的支持而受到指责.

网络文件系统(NFS)是一种分布式文件系统协议,最初由Sun Microsystems于1984年开发,维基百科文章

然而:

Inotify(inode notify)是一个Linux内核子系统,用于扩展文件系统以注意对文件系统的更改.[...]它已经从2.6.13版本(2005年 6月18 )[...]中包含在主线Linux内核中.维基百科文章

很难期望便携式网络协议/应用程序能够支持为不同操作系统开发的特定内核功能,并且这种功能在二十多年后出现.即使它确实包含扩展,它们也不可用于其他操作系统或对其他操作系统有用.

*在所有情况下都强调我的


这个的另一个问题; 让我们假设我们根本不使用网络,而是一个具有良好inotify支持的本地文件系统:ext3(假设它安装在/mnt/foo).但是,不是真正的磁盘,文件系统是从环回设备安装的; 然后可以在vfs中的不同位置访问底层文件(比方说/var/images/foo.img).

现在,您不应该修改已安装的ext3文件系统,但如果更改是文件内容而不是元数据,那么这样做仍然相当安全.

因此,假设一个聪明的用户/var/images/foo.img在十六进制编辑器中修改文件系统image(),用一些其他数据替换文件的内容,同时inotify监视正在观察挂载的文件系统上的相同文件.

没有合理的方法可以安排inotify始终告知观看过程中的这种变化.虽然可能会有一些旋转可以采取ext3通知并尊重变化,但这些都不适用于xfs drtiver,否则非常相似.

也不应该.你是在作弊!inotify只能告知您在观察的实际挂载点上通过vfs发生的更改.如果更改发生在VFS之外,由于对基础数据的更改,inotify无法帮助您,也不能解决该问题.

您是否考虑过使用消息队列进行网络通知?

  • 这似乎只是一个错误.是的,更改是在其他地方进行的,但事实是NFS客户端最终会发现新添加的文件.即使事件被延迟,NFS客户端也应该可以在发现新添加/删除的资源时通知inotify侦听器. (13认同)
  • 当然,NFS不能因不支持inotify而受到指责.但是,你的例子是完全有缺陷的.NFS实现可以支持像inotify这样的东西,它可以映射其(NFS内部协议)的东西以使其无法通知.它不是.就是这样 (6认同)
  • @JamesBlackburn:这可能是出于性能原因.NFS客户端可能只会根据请求懒惰地发现更改. (3认同)
  • @meder:听起来很像[问题!](http://stackoverflow.com/questions/ask) (2认同)

小智 6

我找到了一个使用supervisor守护程序的SGI FAM来监视文件修改.它支持NFS,你可以在wiki上看到一些描述

  • 似乎 FAM 需要在远程 FS 上运行的 FAM 服务器才能工作。鉴于 FAM 甚至比 inotify 还要老,我想知道为什么后者不支持远程 FS。 (2认同)

小智 6

对于在寻找为什么在 Docker 上绑定安装不会检测到主机目录中的文件更改(用于热重载应用程序)的答案时遇到此问题的任何人,这是因为主机和容器之间的文件更改传播不是与容器内核通信。

只有来自容器本身的更改才会传达给内核。解决方案是让您的实时重新加载实用程序打开“轮询模式”,而不是使用 fsnotify。

  • 在 Docker 中,不存在容器内核这样的东西:只有一个内核在主机和容器之间共享。因此,如果在主机本地文件系统的绑定挂载上使用 inotify,则 inotify 在容器内工作。但是,如果绑定挂载是 NFS 文件系统,其中 docker 主机是 NFS 客户端,并且文件系统被其他 NFS 客户端或直接在 NFS 服务器上更改,则它不起作用。 (2认同)