机器保留文件存在/锁定客户端停电

Sam*_*gan 5 c# handle createfile

我们的应用程序在客户端服务器A上运行并使用以下命令在服务器2008 R2文件服务器上创建文件:

CreateFile(LockFileName,
                  GENERIC_READ or GENERIC_WRITE,
                  FILE_SHARE_READ, nil,
                  CREATE_ALWAYS,
                  FILE_FLAG_WRITE_THROUGH or FILE_FLAG_DELETE_ON_CLOSE,
                  0);
Run Code Online (Sandbox Code Playgroud)

客户端正在测试灾难情况并关闭"服务器A"并将其关闭.他们报告我们使用相同文件名和相同代码片段在'服务器B'上运行的应用程序失败(即文件继续存在)至少15分钟,直到我们相信他们浏览到包含该文件的文件夹Windows资源管理器,此时文件将自动删除.

是否有人知道在这种情况下应该如何表现,创建服务器已经消失,是否应该释放句柄并自动删除文件?为什么查看该文件会导致它被删除?

有趣的是,在另一个假设相似的设置上,问题不会发生.

afr*_*hke 4

[...] 如果创建服务器已经消失,是否应该释放句柄并自动删除文件?

最终是的,但不是立即。当您运行 Windows Server 2008 R2(以及 SMBv2,请注意,我假设服务器和客户端都在 Windows Server 2008 R2 上运行)时,客户端将请求持久文件句柄。根据 SMBv2规范,第 3.3.6.2 和 3.3.7.1 节,服务器必须启动持久打开清道夫计时器(默认情况下在 Windows Server 上设置为 16 分钟)。一旦计时器到期,服务器必须检查所有打开的句柄并关闭那些尚未被客户端回收的句柄。

当然,在您的场景中,一个悬而未决的问题是服务器是否检测到与客户端的连接丢失,因为根据您的描述,客户端(即整个服务器,而不仅仅是进程)会立即被终止。

现在假设另一个客户端正在尝试打开该文件,而持久超时仍在运行/服务器仍然认为该文件是由第一个客户端打开的。然后它应该向最初打开该文件的客户端发送一个 oplock 中断通知(第 2.2.23.1 节)。由于客户端无法响应(已被杀死),服务器将等待 oplock 中断确认超时到期(第 3.3.2.1 节,默认情况下为 35 秒),然后才授予新客户端对该文件的访问权限。

还有一件事需要注意:如果第二个客户端通过本地路径而不是通过 UNC 路径访问文件,则行为会有所不同。在这种情况下,客户端不必等待机会锁中断确认超时发生。Windows 将立即授予他对该文件的访问权限,同时尝试向第一个客户端发送关闭请求。

这就是系统应有的行为方式。至于为什么您会遇到所描述的问题,我无法告诉您。如果您偶然发现 Win Server 2008 的文件服务器实现中的错误,我不会感到惊讶。我会尝试使用其他答案中提到的工具来解决问题(procmon 非常好),并且 Wireshark 也有很大帮助。