所以我有一台 Linux 机器作为 NFS 服务器。许多程序已安装到正在导出的文件夹中。
在另一台 Linux 机器上,我已经运行了位于导出的 NFS 文件夹中的一个程序很长一段时间,并且它不会很快完成。
原来现在我需要对网络做一些紧急的维护工作,所以网络会宕机一段时间。
我想知道正在运行的程序会发生什么?
我的理解是程序以惰性方式加载到RAM中。因此,在最好的情况下,假设程序正在执行一些属于循环一部分的代码,这些代码已经加载到 RAM 中,那么在网络中断期间,它根本不需要访问可执行文件,并且程序会继续正常执行,就像什么都没发生一样,对吗?
但是,如果事实证明程序确实需要将可执行文件的其他部分加载到 RAM 中并且网络当前已关闭。它会“冻结”一段时间,然后在网络恢复时继续正常执行吗?
我认为这个加载过程最终会调用一些与io相关的系统调用,而这些系统调用最终将由NFS客户端库处理。如果网络中断,则 NFS 客户端库将在网络中断期间不断重试,然后在网络恢复时返回成功。所以从系统的角度来看,这似乎是一个系统调用需要很长时间。
我不确定我的推理,尤其是加载过程的部分。当将一部分可执行文件加载到RAM中时,操作系统会调用io相关的系统调用吗?或者它可以绕过系统调用并以更低级别的方法执行然后失败,以便我的程序的执行将因失败而停止?
另外,我在推理时是否需要考虑 NFS 缓存策略?
谢谢~!
答案1
你的理解不完全正确,但也很接近。程序确实是延迟加载的,页按页。 (其中一些实际上可能在使用前加载,但这是性能与内存的权衡,而不是您可以指望的。)
系统中负责加载的部分是内核本身。最迟当程序需要该内存块来访问数据或跳转到机器指令时,才会加载页面。其工作方式是处理器中的每次内存访问都经过内存管理单元;如果包含所请求访问的页面映射到进程的 MMU 表中,则 CPU 只需访问内存;如果页面未映射,则会触发陷阱它在内核中执行一段代码,分析陷阱的原因,分配物理内存页面,加载所需的页面内容,并将控制权返回给程序以再次执行访问。
当程序修改了内存页时,其内容可能会被放置在交换然后加载回来。当内存页面直接来自文件(可执行或不可执行)时,其内容将从该文件加载。这不会通过系统调用,因为这一切都发生在内核内部,但它会进行与访问文件的系统调用相同的低级访问。
结果是,如果存储正在运行的可执行文件的文件系统变得无法访问,则进程将挂起。它将保留在不间断的睡眠直到文件系统满足请求。
如果可执行文件位于 NFS 上并且使用该选项挂载 NFS 文件系统,hard
则可执行文件将永远等待或直到服务器回复(以先到者为准)。如果使用该选项挂载 NFS 文件系统,soft
则 NFS 请求将在超时后失败,这会转换为进程的信号(SIGSEGV,即段错误,我认为)。
答案2
如果您的程序不尝试访问 NFS 共享中的任何文件,则将继续工作。如果不需要从 NFS 共享文件夹中读取或写入文件,那就没问题了。