【问题标题】:Treat hard mounted NFS volume as soft将硬安装的 NFS 卷视为软卷
【发布时间】:2014-02-07 20:45:03
【问题描述】:

我正在为 Linux 编写一个 C 程序,用于读取和写入 NFS 服务器上的文件。共享是硬挂载的;访问它的尝试将无限期地阻塞,直到它们工作。无限期地阻止我的程序是不好的。即使文件不可用,它仍然能够做有用的工作。重新安装共享软件不是一种选择。

有两个进程,其中一个可以工作并且不会阻塞,另一个处理文件 IO 并且可能会阻塞是一个选项,但会构成重大更改。我想避免这种情况。真的,我想说,“我知道你是硬挂载的,所以天真的程序可以假装你是一个高度可靠的本地磁盘。但我知道得更好,我准备应对任何访问失败,类似于行为如果你是软装的话。”所以:

在 C 中,我如何访问硬挂载的 NFS 共享上的文件,如果服务器不可用而不是无限期地阻塞,则会出现错误?

如有必要,我可以以 root 身份运行,但不希望如此。使用 root 重新安装共享是正确的。我可以潜在地依赖新功能,但越往后支持越好。

我的研究表明答案是不可能的,但也许我错过了一些东西。

【问题讨论】:

  • 为什么不设置一个超时信号在合适的超时后中断阻塞调用。每当您进行阻塞调用(open()fopen()readdir()chdir()stat() 等)时启动计时器,如果调用返回 errno==EINTR,并且设置了超时信号处理程序一个标志,您可以判断呼叫在分配的时间内没有进行,并将其视为呼叫出错。超时信号处理的额外开销是值得的;这是 Apache 等服务器软件的常见做法。将超时设置为用户可配置,然后您就设置好了。
  • 这是一个潜在的解决方法。这可靠吗?我相信不可用的 NFS 挂载可能会使进程进入不可中断的睡眠状态,而信号本身会阻止这种睡眠。
  • 啊。在 2.6.25 之前的内核 nointr 挂载选项确实使它可靠,但在以后的内核中它被忽略了。 SIGKILL 是唯一有效的方法。因此,您需要使用子进程来访问挂载,并通过 Unix 域套接字辅助消息返回描述符(文件或目录)。如果操作时间过长,原始进程会使用超时KILL 子进程。使用为每个操作派生一个子子的长寿命最小子应将开销降低到可接受的水平。也许在每次访问之前解析 /proc/mounts 也只能绕过 NFS。
  • 实际上,您必须让子(或子子)提供数据流,因为文件系统随时可能无法访问。仅提供描述符只能保护打开,而不是访问,以免陷入不间断的睡眠。此外,超时会稍微复杂一些:一个用于初始访问,另一个用于每个单独的数据包。

标签: c linux nfs


【解决方案1】:

您没有错过任何东西,您永远不会收到服务器不可用错误,因为内核永远不会在硬挂载的 nfs 挂载点上传递它们。

由于硬选项是挂载点的一个属性,因此您不能让应用程序进行选择,因为内核并未设置为以这种方式运行。

但是,您确实提到您可以以 root 身份运行该应用程序。为什么不将文件系统挂载到其他地方软,然后得到你预期的行为?

【讨论】:

  • 在其他地方进行软安装对于某些环境来说绝对是一个有效的选择!可悲的是,我不能假设系统管理员会接受新的安装。目标是最大的,只是以最小的惊喜工作。鉴于我的限制,不可能是一个有效的答案。接受。
猜你喜欢
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
  • 2016-05-29
  • 2018-05-05
  • 1970-01-01
  • 2015-07-22
  • 2017-10-19
  • 2023-03-12
相关资源
最近更新 更多