NFS 挂载:设备或资源繁忙

Tou*_*one 7 rhel python lock files

我参考了以下链接,解决方案有效。

如何克服“设备或资源繁忙”?

当您手动删除文件时,上述解决方案有效。但我有一个删除文件的 python 脚本(自动过程)。有时,当脚本尝试删除文件时,我会收到“设备或资源繁忙错误”。因此,我的脚本失败了。我不知道如何使用我的 python 脚本解决这个问题。

编辑: 脚本从日志服务器下载日志文件。然后这些文件由我的脚本处理。处理完成后,脚本会删除这些日志文件。我不认为设计有什么问题。

确切错误:

OSError: [Errno 16] Device or resource busy: '/home/johndoe/qwerty/.nfs000000000471494300000944'
Run Code Online (Sandbox Code Playgroud)

roa*_*ima 15

这些文件是 NFS 占位符:

/home/johndoe/qwerty/.nfs000000000471494300000944
Run Code Online (Sandbox Code Playgroud)

一些背景

在典型的 UNIX 文件系统中,可以删除当前正在使用和打开的文件,但它的内容实际上不会消失,直到它的最后一个文件句柄关闭。您可以使用如下代码查看此操作:

$ ps -ef >/tmp/temporaryfile
$ ls -l /tmp/temporaryfile
-rw-r--r-- 1 roaima roaima 6758 Mar  2 14:02 /tmp/temporaryfile

$ ( sleep 60 ; cat ) </tmp/temporaryfile &
[1] 4864

$ rm /tmp/temporaryfile
$ ls -l /tmp/temporaryfile
ls: cannot access /tmp/temporaryfile: No such file or directory

$ fg    # Wait for the rest of the minute
( sleep 60; cat ) < /tmp/temporaryfile
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:44 ?        00:00:02 init [2]
root         2     0  0 09:44 ?        00:00:00 [kthreadd]
root         3     2  0 09:44 ?        00:00:00 [ksoftirqd/0]
root         5     2  0 09:44 ?        00:00:00 [kworker/0:0H]
...
roaima    4857  4786  0 14:02 pts/1    00:00:00 -bash
roaima    4858  4857  0 14:02 pts/1    00:00:00 ps -ef
Run Code Online (Sandbox Code Playgroud)

(请注意,这与 Microsoft Windows 相反,在 Microsoft Windows 中,文件在打开时无法删除。)

解释

NFS 服务器上的文件可能有一个或多个客户端访问它。NFS 本身(大部分)是无状态的,因此需要模拟允许访问打开的文件的功能,即使它被删除。

通过将文件从文件系统中的位置移除,但将其作为名称以.nfs. 当最后一个读取器/写入器关闭此文件的文件句柄时,它将从文件系统中正确删除。

这是一个实际的例子:

$ ps -ef > /var/autofs/net/nfsserver/tmp/temporaryfile
$ ls -l /var/autofs/net/nfsserver/tmp/temporaryfile
-rw-r--r-- 1 roaima roaima 6766 Mar  2 14:14 /var/autofs/net/nfsserver/tmp/temporaryfile

$ ( sleep 60 ; cat ) </var/autofs/net/nfsserver/tmp/temporaryfile &
[1] 4987

$ rm /var/autofs/net/nfsserver/tmp/temporaryfile
$ ls -l /var/autofs/net/nfsserver/tmp/temporaryfile
ls: cannot access /var/autofs/net/nfsserver/tmp/temporaryfile: No such file or directory

$ ls -lA /var/autofs/net/nfsserver/tmp/
total 8
-rw-r--r-- 1 roaima roaima 6766 Mar  2 14:14 .nfs000000000100000300000001

$ rm /var/autofs/net/nfsserver/tmp/.nfs000000000100000300000001
rm: cannot remove ‘/var/autofs/net/nfsserver/tmp/.nfs000000000100000300000001’: Device or resource busy

$ fg    # Wait for the rest of the minute
( sleep 60; cat ) < /var/autofs/net/nfsserver/tmp/temporaryfile
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 09:44 ?        00:00:02 init [2]
root         2     0  0 09:44 ?        00:00:00 [kthreadd]
root         3     2  0 09:44 ?        00:00:01 [ksoftirqd/0]
...
roaima    4983  4712  0 14:14 pts/0    00:00:00 ps -ef
Run Code Online (Sandbox Code Playgroud)

推论

您应该忽略 NFS 挂载上名称以.nfs. 此外,您的代码需要应对在所有这些文件真正消失之前无法删除远程目录的可能性。

NFS 对应用程序并不像人们所希望的那样透明。

注释

日志文件仍然打开的原因可能是远程系统上的记录器进程仍在使用它们。通常,这种方法是循环日志文件,只下载和删除以前的日志文件,将当前的文件留在文件系统中以供记录器进程使用。

诸如此类的实用程序logrotate使用特定的配置元素来处理此问题,例如delaycompress(尝试)确保日志文件在仍在使用时不会被压缩。(请参阅/etc/logrotate.d/apache2至少在 Debian 系统上的示例。)