【问题标题】:"Stale file handle" error, when process trying read the file, that other process already had deleted“过时文件句柄”错误,当进程尝试读取文件时,其他进程已删除
【发布时间】:2017-03-08 20:26:45
【问题描述】:

我正在编写压力测试套件,用于通过 NFS 测试分布式文件系统。

在某些情况下,当某个进程删除文件,而其他进程尝试从中读取文件时,我会收到“过时文件句柄”错误 (116)。

在这种引发条件下,这种错误是预期的和可接受的吗?

测试工作如下:

  1. 启动 x 台客户端计算机
  2. 每台客户端机器运行 y 个进程
  3. 每个进程都可以执行任何文件操作,如 stat/read/delete/open
  4. 提到的文件操作是标准的 Python 方法 - os.stat/read/os.remove/open
  5. 所有文件都是空的0字节数据

文件存在,stat操作成功显示:

controller_debug.log.2:2016-10-26 15:02:30,156;INFO - [LG-E27A-LNX:0xa]:完成 640522b4d94c453ea545cb86568320ca,结果: 成功|统计 | /JUyw481MfvsBHOm1KQu7sHRB6ffAXKjwIATlsXmOgWh8XKQaIrPbxLgAo7sucdAM/o6V266xE8bTaUGzk8YDMfDAJp0YIfbT4fIK1oZ2R20tRX3xFCvjISj7WuMEwEV41 |数据:{} | 2016/10/26 15:02:30.156

客户端CLIENT-A上的进程0x1完成成功删除:

controller_debug.log.2:2016-10-26 15:02:30,164;INFO - [CLIENT-A:0x1]:完成 5f5dfe6a06de495f851745a78857eec1,结果: 成功|删除 | /JUyw481MfvsBHOm1KQu7sHRB6ffAXKjwIATlsXmOgWh8XKQaIrPbxLgAo7sucdAM/o6V266xE8bTaUGzk8YDMfDAJp0YIfbT4fIK1oZ2R20tRX3xFCvjISj7WuMEwEV41 |数据:{} | 2016/10/26 15:02:30.161

3 毫秒后,客户端 CLIENT-B 上的进程 0xb 由于“陈旧文件句柄”而“读取”操作失败

controller_debug.log.2:2016-10-26 15:02:30,164;INFO - [CLIENT-B:0xb]:完成 e84e2064ead042099310af1bd44821c0,结果: 失败 |阅读 | /mnt/DIRSPLIT-node0.b27-1/JUyw481MfvsBHOm1KQu7sHRB6ffAXKjwIATlsXmOgWh8XKQaIrPbxLgAo7sucdAM/o6V266xE8bTaUGzk8YDMfDAJp0YIfbT4fIK1oZ2R20tRX3xFCvjISj7WuMEwEV1 | [错误号:116] |陈旧的文件句柄 | 142 |数据:{} | 2016/10/26 15:02:30.160 controller_debug.log.2:2016-10-26 15:02:30,164;错误- 文件上的操作读取意外失败 JUyw481MfvsBHOm1KQu7sHRB6ffAXKjwIATlsXmOgWh8XKQaIrPbxLgAo7sucdAM/o6V266xE8bTaUGzk8YDMfDAJp0YIfbT4fIK1oZ2R20tRX3xFCvjISj7WuMEwEV41 由于过时的文件句柄

谢谢

【问题讨论】:

  • 是的,考虑到具体情况,这是一个可接受的错误代码(请参阅access.redhat.com/solutions/29626,条件 2),但它可能不是唯一可能的响应。您必须阅读规格和来源才能确定。你能否澄清一下,如果有的话,这表明这可能不是一个适当的回应?
  • @JakeMitchell 感谢杰克的链接。我确实知道 ESTALE 对于目录是可以接受的,但是可以在文件中找到有关 ESTALE 的任何信息,而且由于我正在测试正在开发的文件系统,我无法相信它如何处理 nfs 错误。你也有来源和规格的链接吗?
  • 您使用的是哪个版本的 python 以及如何启动您的测试流程?这可能与 fork 的行为有关,因为文件描述符依赖于 POSIX,它不允许使用分叉进程。
  • @ThomasMoreau ESTALE 错误是在通过 NFS 对文件进行操作期间导致的错误,而不是在进程本身中
  • @Samuel 是的,但文件描述符为进程操作和 NFS 操作共享。如果一个 fd 被关闭,无论谁试图访问它,它都会失败。

标签: python linux nfs


【解决方案1】:

这完全在意料之中。 NFS 规范清楚地说明了在对象(无论是文件还是目录)被删除之后文件句柄的使用。 Section 4 清楚地解决了这个问题。例如:

删除文件系统对象后,持久文件句柄将变得陈旧或无效。当服务器收到引用已删除对象的持久文件句柄时,它必须返回 NFS4ERR_STALE 错误。

这是一个很常见的问题,它甚至在NFS FAQ 的 A.10 节中都有自己的条目,其中说 ESTALE 错误的一个常见原因是:

文件句柄指的是已删除的文件。在服务器上删除文件后,客户端直到尝试使用从以前的 LOOKUP 中缓存的文件句柄访问文件时才发现。使用 rsync 或 mv 替换正在另一个客户端上使用的文件是导致 ESTALE 错误的常见方案。

预期的解决方案是您的客户端应用程序必须关闭并重新打开文件才能查看发生了什么。或者,正如常见问题解答所述:

...要从 ESTALE 错误中恢复,应用程序必须关闭发生错误的文件或目录,然后重新打开它,以便 NFS 客户端可以再次解析路径名并检索新的文件句柄。

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    相关资源
    最近更新 更多