5

我们的应用程序在客户端服务器 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);

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

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

有趣的是,在另一个据称类似的设置中,该问题不会发生。

4

3 回答 3

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 路径访问文件,则行为会有所不同。在这种情况下,客户端不必等待 oplock break ack 超时发生。Windows 将立即授予他对该文件的访问权限,同时它会尝试向第一个客户端发送关闭请求。

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

于 2012-02-12T03:09:43.413 回答
1

当创建服务器出现故障时,没有什么可以说不再有任何句柄。为了移除句柄,必须有一些东西来启动该移除。如果服务器突然宕机,它就无法移除其句柄,因此这些句柄保持打开状态。就服务器仍然启动而言,一切都很好,不应强制关闭任何文件句柄。

直到您真正尝试对文件句柄采取行动。突然,服务器注意到文件句柄的主机已经消失,因为它试图启动与该主机的通信。一旦它意识到这一点,文件句柄就会被强制关闭。

因此,要回答您的问题,这对我来说似乎是完全可预测和预期的行为。

文件句柄在另一个环境中立即关闭的原因可能与使这些服务器保持持续通信有关:某些东西不断访问远程文件。不过,这只是一个猜测。

更新

几年前被微软收购的Sysinternals有一个很棒的工具,叫做Process Explorer,它允许您搜索进程的打开文件句柄。这可能有助于您确定哪些程序正在刷新文件句柄。

Sysinternals 还具有Process Monitor,它允许您实时查看程序对文件句柄的操作。这可能是解决问题的另一个有用程序。

编辑:哦,如果你真的想玩得开心,还有Handle

于 2012-02-09T04:57:40.210 回答
0

到目前为止,这对我来说似乎不是问题。或者一个在微软的编程之外无法处理的,一个在处理时有副作用的。基本上,您必须考虑客户端和服务器之间通信的小中断并优化网络流量,因此服务器不能与客户端永久交换数据包,只是为了查看客户端是否还在附近。

计算机编程必须尽可能地考虑到这一点,但是除非客户端应用程序正确处理,否则像这样的超时是正常的。主要问题(完全没有回答)是这是否是一个问题 - 到目前为止它看起来像“标准行为”。

有没有人知道这在这种情况下应该如何表现,创建服务器已经消失,是否应该释放句柄并自动删除文件?

服务器怎么知道?

为什么查看文件会导致它被删除?

P9可能是读取触发了超时的刷新,所以 - 最后 - 这触发了定义的行为(DELETE_ON_CLOSE)。

我会暗示对文件某些元素的任何访问都会触发这种情况,但测试人员并没有这样做,只是刷新了资源管理器。

于 2012-02-05T12:39:09.660 回答