在 Linux 中获取 CIFS 挂载的文件创建通知

发布于 2024-12-15 14:01:55 字数 342 浏览 3 评论 0原文

我在 ubuntu 服务器上通过 CIFS 安装了一个 Windows 共享。我需要一种方法来知道新文件何时添加到 Windows 共享中。我尝试了这个inotify程序:

http://www.thegeekstuff.com/ 2010/04/inotify-c-program-example/

它适用于标准目录,但无法捕获任何 CIFS 更改。我不一定需要使用 inotify,尽管我愿意,但任何有关如何完成获取文件创建通知的建议都会很棒。

I have a windows share mounted via CIFS on an ubuntu server. I need to a way to know when a new file has been added to the Windows share. I tried this inotify program:

http://www.thegeekstuff.com/2010/04/inotify-c-program-example/

Which works fine with standard directories, but is unable to catch any CIFS changes. I don't neccessarily need to use inotify, although I would like to, but any suggestions on how to accomplish getting file create notifications would be great.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

四叶草在未来唯美盛开 2024-12-22 14:01:55

我也一直在研究这个问题,并遇到了同样的问题 - 不幸的是,似乎(在谷歌上进行了一些搜索之后),不可能在 CIFS 安装分区上使用 inotify - 以下是来自 Redhat 论坛的帖子几年前:

“目前,CIFS 无法实现这一点。VFS 挂钩允许
用于设置额外通知的文件系统最近已被删除。这
其中唯一的“用户”是 CIFS,而且它从来没有正常工作过。这
其内核接口也存在严重问题。

我认为史蒂夫计划重新实现它,但这是一个重大项目
这意味着向内核的 VFS 层添加新功能。”

虽然这是几年前的事,但我们似乎离拥有此功能还很远 - 遗憾的是,我也可以真正使用它!

I have also been working on this and ran into the same issue - it seems (after a little trawling on google) that, unfortunately, it is not possible to use inotify on CIFS mounted partitions - The following was in a redhat forum post from a couple of years ago:

"Currently, no this isn't possible with CIFS. The VFS hooks to allow a
filesystem to set up extra notfications were removed recently. The
only "user" of them was CIFS and it never worked properly anyway. The
kernel interface for this had serious problems too.

I think Steve has plans to reimplement it, but it's a major project
that means adding new functionality to the VFS layer of the kernel."

While this was a couple of years ago, it seems we are no closer to having this facility available - shame, I could have really used it too!

假情假意假温柔 2024-12-22 14:01:55

我也遇到了这个问题,并得出了与 Stephen Sullivan 相同的结论(CIFS + inotify = 不行)。

然而,由于我的工作流程恰好依赖于远程安装和依赖 inotify 的自动编译工具,所以我最终构建了一个(相当绝望和黑客)解决方案,该解决方案基本上只是使用轮询来监视更改,然后触及相同的文件再次在安装端,这似乎会触发 inotify 事件。这不是我最自豪的时刻。

话虽如此,它确实有效,所以,享受:http://github.com/rubyruy/watchntouch

I too ran into this and reached the same conclusion as Stephen Sullivan (CIFS + inotify = no go).

However, since my workflow happened to depend on both remote mounts and auto-compile tools that rely on inotify, I ended up building a (fairly desperate & hacky) solution which basically just uses polling to watch for changes and then touches the same files again on the mounted side, which does seem to fire off inotify events. It is not my proudest moment.

Having said that, it does work, so, enjoy: http://github.com/rubyruy/watchntouch

鱼窥荷 2024-12-22 14:01:55

老话题,依然重要!
我对此的回答是:“这要看情况!”。
从我这次的实证测试来看,这种行为是相当清楚的。如果 Linux 主机发起文件系统事件 [在 CIFS 安装时],那么 inotify 会很好地看到它。如果托管 CIFS 挂载的 Windows 计算机启动文件系统事件,那么 inotify [在 Linux 计算机上]将根本看不到它。

如果您的目标是让 Linux 主机收到 Windows 主机创建或写入文件的通知,那么您就不走运了。由于这可能是该机制最理想的用途,因此它确实使这个微妙的“取决于”答案不再那么有用!

Old topic, still important!
My answer to this is: "it depends!".
From my empirical tests at this time, the behavior is quite clear. If the Linux host initiates the filesystem event [upon a CIFS mount], then inotify will see it just fine. If the Windows machine which hosts the CIFS mount initiates the filesystem event, then inotify [on the Linux machine] will not see it at all.

If your goal is for the Linux host to get notification that the Windows host created or wrote to a file, then you are out of luck. Since this is probably the most desired use of this mechanism, it does make this subtle "it depends" answer not so terribly useful!

掩于岁月 2024-12-22 14:01:55

只是想补充一点,我最近在使用安装到系统中的 Azure 文件Azure 容器实例 时也遇到了这个问题。 Inotify 也无法看到 Azure 文件 挂载上的任何更改,我猜是因为它使用的是 CIFS

我偶然发现了一个有用的工具,它也可以使用轮询而不是inotify

它称为fswatch

https://emcrisostomo.github.io/fswatch/

我必须为有问题的基于 Alpine 的容器,但使用 Alpine 网站上的说明并不太困难。

https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package

这是我的APKBUILD< /code> 如果有人觉得它有帮助(无耻地基于 Alpine 提供的示例!:))

# Contributor: 
# Maintainer: 
pkgname=fswatch
pkgver=1.17.1
pkgrel=0
pkgdesc="A cross-platform file change monitor with multiple backends"
url="https://emcrisostomo.github.io/fswatch/"
arch="all"
license="GPL"
depends=""
depends_dev="alpine-sdk"
makedepends="$depends_dev"
install=""
subpackages="$pkgname-doc"
source="https://github.com/emcrisostomo/$pkgname/releases/download/$pkgver/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"

prepare() {
        default_prepare
        # this function can be omitted if no extra steps are needed
}

build() {
    ./configure --prefix=/usr \
        --sysconfdir=/etc \
        --mandir=/usr/share/man \
        --infodir=/usr/share/info \
        --localstatedir=/var \
        --disable-wxwidgets \
        --disable-qt
    make
}

check() {
        make check
}

package() {
    make DESTDIR="$pkgdir" install
}

sha512sums="c38e341c567f5f16bfa64b72fc48bba5e93873d8572522e670e6f320bbc2122f  fswatch-1.17.1.tar.gz"

我使用了多阶段 Dockerfile 然后将生成的包复制到目标容器中。我必须使用 --allow-untrusted 标志来进行安装。

apk add --allow-untrusted /tmp/fswatch-1.17.1-r0.apk

这是 Dockerfile 更新的相关部分


## ==========
## FSWatcher Builder
# IMPORTANT: Build this package on the same Alpine version used by the target container
FROM ${ALPINE_CONTAINER}:${ALPINE_VERSION} AS fswatch

COPY /scripts/fswatch.apkbuild /tmp/APKBUILD

USER root
WORKDIR /app

RUN apk upgrade --update-cache --available && apk add alpine-sdk sudo && rm -rf /var/cache/apk/*; \
  adduser -D -h /home/build build; \
  addgroup build abuild; \
  mkdir -p /var/cache/distfiles; \
  chmod a+w /var/cache/distfiles; \
  chgrp abuild /var/cache/distfiles; \
  chmod g+w /var/cache/distfiles; \
  abuild-keygen -a -i -n

USER build
WORKDIR /home/build

RUN abuild-keygen -a -n; \
  mkdir fswatch; \
  cd fswatch; \
  cp /tmp/APKBUILD ./; \
  dos2unix ./APKBUILD; \
  abuild checksum; \
  abuild -r

:这是我的 entrypoint.sh 也是如此,我在其中运行 fswatch (我必须在基于 debian 的系统上使用 bash shebang...YMMV。

#!/bin/sh
set -e
{ /usr/bin/fswatch -0 -o -r -m poll_monitor /etc/nginx/ssl | while read -d "" event;do echo "$(date -Ins) Event Fired: ${event}";/opt/reload.sh;done; } &
exec "$@"

reload.sh 脚本:

#!/bin/sh
set -e
/usr/sbin/nginx -s reload && echo "nginx reloaded"

希望这些对有同样想法的人有用!

just wanted to add that I also recently ran into this issue when using Azure Container Instances with a Azure Files mounted into the system. Inotify also fails to see any changes on the Azure Files mount, I guess since it's using CIFS.

I stumbled upon a useful tool that can also use polling instead of inotify.

It's called fswatch.

https://emcrisostomo.github.io/fswatch/

I had to create my own package for the Alpine based container in question, but it wasn't too difficult using the instructions on Alpine's site.

https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package

Here's my APKBUILD if anyone finds it helpful (shamelessly based on the sample provided by Alpine! :) )

# Contributor: 
# Maintainer: 
pkgname=fswatch
pkgver=1.17.1
pkgrel=0
pkgdesc="A cross-platform file change monitor with multiple backends"
url="https://emcrisostomo.github.io/fswatch/"
arch="all"
license="GPL"
depends=""
depends_dev="alpine-sdk"
makedepends="$depends_dev"
install=""
subpackages="$pkgname-doc"
source="https://github.com/emcrisostomo/$pkgname/releases/download/$pkgver/$pkgname-$pkgver.tar.gz"
builddir="$srcdir/$pkgname-$pkgver"

prepare() {
        default_prepare
        # this function can be omitted if no extra steps are needed
}

build() {
    ./configure --prefix=/usr \
        --sysconfdir=/etc \
        --mandir=/usr/share/man \
        --infodir=/usr/share/info \
        --localstatedir=/var \
        --disable-wxwidgets \
        --disable-qt
    make
}

check() {
        make check
}

package() {
    make DESTDIR="$pkgdir" install
}

sha512sums="c38e341c567f5f16bfa64b72fc48bba5e93873d8572522e670e6f320bbc2122f  fswatch-1.17.1.tar.gz"

I used a multi-stage Dockerfile and then copied the resulting package into the target container. I had to use the --allow-untrusted flag to do the install.

apk add --allow-untrusted /tmp/fswatch-1.17.1-r0.apk

Here's the relavent section of the Dockerfile


## ==========
## FSWatcher Builder
# IMPORTANT: Build this package on the same Alpine version used by the target container
FROM ${ALPINE_CONTAINER}:${ALPINE_VERSION} AS fswatch

COPY /scripts/fswatch.apkbuild /tmp/APKBUILD

USER root
WORKDIR /app

RUN apk upgrade --update-cache --available && apk add alpine-sdk sudo && rm -rf /var/cache/apk/*; \
  adduser -D -h /home/build build; \
  addgroup build abuild; \
  mkdir -p /var/cache/distfiles; \
  chmod a+w /var/cache/distfiles; \
  chgrp abuild /var/cache/distfiles; \
  chmod g+w /var/cache/distfiles; \
  abuild-keygen -a -i -n

USER build
WORKDIR /home/build

RUN abuild-keygen -a -n; \
  mkdir fswatch; \
  cd fswatch; \
  cp /tmp/APKBUILD ./; \
  dos2unix ./APKBUILD; \
  abuild checksum; \
  abuild -r

UPDATE: Here's my entrypoint.sh as well, where I run fswatch (I had to use a bash shebang on debian based system...YMMV.)

#!/bin/sh
set -e
{ /usr/bin/fswatch -0 -o -r -m poll_monitor /etc/nginx/ssl | while read -d "" event;do echo "$(date -Ins) Event Fired: ${event}";/opt/reload.sh;done; } &
exec "$@"

And the reload.sh script:

#!/bin/sh
set -e
/usr/sbin/nginx -s reload && echo "nginx reloaded"

Hope those are useful for someone in the same boat!

好菇凉咱不稀罕他 2024-12-22 14:01:55

我的 OCR 项目遇到了此类问题,该项目监视远程 samba 共享以提供 Tesseract (https://github.com /deajan/pmOCR

最终使用了基于轮询目录的嵌入式 inotifywait 替换,请参阅 https://github.com/javanile/inotifywait-polling

事实上,也有像 fsobserver 这样的 Python 解决方案也允许轮询模式。

Got that kind of problem for my OCR project which monitors a remote samba share to feed Tesseract (https://github.com/deajan/pmOCR)

Ended up using a drop-in inotifywait replacment based on polling directories, see https://github.com/javanile/inotifywait-polling

Indeed there are python solutions as fsobserver that allow polling mode too.

故事还在继续 2024-12-22 14:01:55

它可以完成..

如果您设置了一个 webdav 服务器并将共享包含为 webdav 位置,那么您可以在从 Windows 计算机通过 webdav 访问它时监视 samba 服务器上的位置。

最大的问题是文件权限是 ab*tch... 与 apache2 webdav 一样,因为它缺少直通身份验证

It can be done.. sort of

If you set up an webdav server and include the share as webdav location, you can monitor the location on you samba server while accessing it through webdav from your windows machine.

The big problem with this is that file permissions are a b*tch... as usual with apache2 webdav since its missing pass-through authentication

败给现实 2024-12-22 14:01:55

对于运行 Linux docker 容器的 Windows 主机,有一篇关于此问题的详细文章,其中提供了适用于“docker-windows-volume-watcher”的解决方案:http://blog.subjectify.us/miscellaneous/2017/04/24/docker-for-windows-watch-bindings.html

看起来 Linux 实施 CIFS 不会很快提供支持inotify。

For Windows hosts running Linux docker containers there is a detailed article on t his issue with a provided solution that works "docker-windows-volume-watcher": http://blog.subjectify.us/miscellaneous/2017/04/24/docker-for-windows-watch-bindings.html

Looks like support is not coming any time soon from Linux implementation of CIFS inotify.

苏佲洛 2024-12-22 14:01:55

如果您反过来并从 Linux 主机提供 CIFS 共享,并让网络客户端将文件上传到此共享,则服务器上的 inotify 将能够检测新文件何时上传(通过 CLOSE_WRITE 事件)。

If you flip this around and have a CIFS share served from a Linux host, and have a network client upload files to this share, then inotify on the server will be able to detect when a new file has been uploaded (via the CLOSE_WRITE event).

江南月 2024-12-22 14:01:55

我建议使用 fileschanged

我刚刚用 Mounted 测试了它来自 Windows 的 CIFS 驱动器。它的工作就像一个魅力,几乎没有延迟或服务器负载。看来还是蛮靠谱的。

  • 要安装:

sudo apt-get install fileschanged

  • 要监视/触发:

    文件更改文件夹/

  • 输出将如下所示:

文件夹/test1

  • 您可以通过管道输出:

    文件已更改
    文件夹/
    |
    while read -r 文件名;做
    文件名=“${文件名##*/}”
    echo "触发$filename">> /var/log/fileschanged.log
    # 使用 $filename 做任何你喜欢做的事情
    完成

I suggest using fileschanged

I just tested it with mounted CIFS drives from Windows. It worked like a charme with almost no latency or server load. It seems pretty reliable.

  • To install:

sudo apt-get install fileschanged

  • To monitor/trigger:

    fileschanged folder/

  • The output will look like this:

folder/test1

  • You can pipe the output:

    fileschanged
    folder/
    |
    while read -r filename; do
    filename="${filename##*/}"
    echo "Triggering $filename" >> /var/log/fileschanged.log
    # do whatever you like with $filename
    done

若沐 2024-12-22 14:01:55

我已经处理过我的文档搜索引擎的主题。并开发了该项目的以下部分。我已经提交了初稿。不幸的是,我必须先处理我的其他项目。找出“smbclient”命令。当我准备好时,您可以将此项目用作库或将其作为系统挂钩应用程序启动,该应用程序会将信息提供给其他应用程序。

https://github.com/stefanwerfling/smbeye/blob/ main/src/inc/SmbClientNotif.ts

我希望这可以作为您的解决方法。或者你等我准备好。 ;)

I have already dealt with the topic for my document search engine. And the following part of the project developed. I have committed the first draft. Unfortunately, I have to take care of my other projects first. Fish out the "smbclient" command. When I'm ready, you can use this project as a lib or start it as a system hook app which will give the info to other apps.

https://github.com/stefanwerfling/smbeye/blob/main/src/inc/SmbClientNotif.ts

I hope this can serve as a workaround for you. Or you wait until I'm ready. ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文