通过 sshfs 修改文件

use*_*001 5 filesystems ssh sshfs synchronization touch

机器A的文件系统B通过sshfs. 运行在 上的进程,由es 已挂载的文件系统上的一个文件B启动,以传递信号;然后信号(文件)被删除。这在第一次创建/销毁文件 ( / ) 时可靠地工作。Assh touchAAtouchrm

但是,如果第二个进程(再次在 上运行B,从 生成A)尝试访问完全相同的文件,则会偶尔抛出以下错误:

`touch: cannot touch '/path/to/file': No such file or directory`.
Run Code Online (Sandbox Code Playgroud)

该路径是有效的,根据以下事实来判断:touch抛出错误后手动尝试该路径均会成功。如前所述,该错误是偶发的(使调试尝试变得复杂),但仅在已经经历了创建/删除循环后触摸文件时才会发生。

touch间歇性产生错误 ( 、rm、 )的操作touch在时间上是分开的,因此并发访问不太可能是罪魁祸首(即,直到第一次触摸生成的文件被删除后,第二次触摸才会发生)。认为原因可能源于文件系统缓冲,在删除文件后sync调用A,但无济于事。在触摸文件之前立即调用也没有帮助,尽管我不知道 的调用是否会sync影响( on的版本缺少显式文件系统规范的选项;我尝试从运行于 的进程中调用via before ing,但在sync-over-ssh调用之后,该进程似乎没有错误地退出,因为包括该语句在内的其余行都没有执行;也许是因为在由以下启动的进程中不可能从服务器返回到客户端从客户端到服务器)。BBsyncAsyncB-fsyncABssh user@A synctouchtouchsshssh

如何确定此文件系统相关错误的原因?

meu*_*euh 2

You can investigate what might be happening by running sshfs with option -o debug. It prints a lot of information on the basic filesystem operations done by a touch test command. An example operation is:

unique: 209, opcode: LOOKUP (1), nodeid: 1, insize: 45, pid: 10641
LOOKUP /test
getattr /test
   NODEID: 44
   unique: 209, success, outsize: 144
Run Code Online (Sandbox Code Playgroud)

The relevant part is that a getattr call was done, and it ended in success. When you do a successful touch on a non-existant file the operations we see are (removing the details):

getattr /test
   unique: 190, error: -2 (No such file or directory), outsize: 16
create flags: 0x8841 /test 0100644 umask=0022
fgetattr[140469187119648] /test
flush[140469187119648]
utime /test 1507647885 1507647885
getattr /test
flush[140469187119648]
release[140469187119648] flags: 0x8801
Run Code Online (Sandbox Code Playgroud)

We see the getattr test for the file fails, which is normal as it does not exist, so we go on to create the file.

If the file is now removed on the server, and we do the touch again on the client we see a different sequence:

getattr /test
   unique: 215, success, outsize: 144
open flags: 0x8801 /test
   unique: 216, error: -2 (No such file or directory), outsize: 16
Run Code Online (Sandbox Code Playgroud)

Now the getattr says the file still exists, so touch goes on to open() the file, but this results in your error message: the file does not really exist at all.

So it all seems to be a problem of the client cache of what files exist being too slow to catch up with changes at the remote. The simplest answer is to mount your remote with a shorter timeout for the getattr call, i.e. the stat() system call. This should work for you

sshfs -o cache_stat_timeout=0 ...
Run Code Online (Sandbox Code Playgroud)