摘要
- 客户端发出全局恢复完成声明后,不能再把该范围内尚未恢复的旧锁留待以后追认。完成声明有放弃剩余恢复资格的后果。
- 已完成恢复的客户端,申请新锁时仍可能遇到宽限期错误。它只能说明自己已结束,不能代表其他可能持有旧锁的客户端。
- 网络分区、租约过期与连续重启,会使已经失去连续性的旧主张重新显得合理。服务器必须保留足以识别已知危险情形的稳定记录,或者采取保守拒绝。
恢复进度并不属于同一个人
设想一台文件服务器重启,原先保存在内存中的锁状态已经丢失。两个客户端曾经在上面持有锁。甲很快回来,重新建立必要状态,完成旧锁恢复;乙仍被网络故障挡在外面。此时让甲回答“恢复好了没有”,答案可以是好了。让服务器回答,问题就不同了:乙回来时,还有没有可能提出与新业务冲突的旧锁主张?
这是假设性的协议场景,并非某家企业的事故报道。它揭示的不是谁比较积极,而是谁有资格替谁作决定。甲知道自己的待恢复清单,却没有资格宣布乙已经没有需要保护的历史。
NFSv4.1 的 RFC 8881 在第 8.4、9.11 和 18.51 节把这种分界写进了操作语义。一个客户端已经提交恢复完成声明,接下来申请新锁,仍可能收到 NFS4ERR_GRACE。把这两个结果看成互相矛盾,就把个人进度误当成了全局准入许可。
宽限期保护的是还没出现的请求
服务器丢失锁状态后,需要留出机会,让客户端重新建立原有状态,避免新授予的冲突锁抢在旧主张之前。这就是恢复宽限期的重要用途。它不是为了让所有业务无差别停摆,也不是对后来者的惩罚。
恢复已有打开状态时,客户端使用带有 CLAIM_PREVIOUS 的 OPEN,通过当前文件句柄指向目标文件;恢复字节范围锁则使用 reclaim 参数为真的 LOCK。这些操作是在申报原有状态,不是换一种口令申请任意新权利。正常的访问权限与冲突检查依然有效,恢复身份不能绕过文件权限。
宽限期内,建立客户端标识和会话仍然是正常恢复流程的一部分。如果服务器有充分信息,能够排除后续恢复请求与某项新锁或读写操作发生冲突,也可以允许相应工作继续。反过来,如果无法排除这种冲突,就不能仅凭眼前的锁表空着,断言没有别人需要保护。
因此,真正稀缺的不是一个“服务已上线”的信号,而是关于缺席者的可靠信息。缺席客户端尚未发来的请求,恰恰是当前请求列表无法完整表达的风险。
一句完成,关闭了哪些可能性
全局 RECLAIM_COMPLETE 将 rca_one_fs 设为假。客户端建立新的客户端标识后,即使没有旧锁需要恢复,也必须在第一次申请新锁之前提交全局完成声明。没有恢复任务,不等于可以省略对服务器的交代。
更重要的是,这项声明不是可以随时反悔的进度播报。对于其覆盖范围,客户端没有恢复的那些旧锁,将不再能够在本次恢复中追认,也不能等到以后另一个服务器实例或相关服务器转移后再拿出来恢复。完成包含了对剩余恢复资格的放弃。
这个代价使声明对服务器有用。服务器终于可以不再为该客户端的其他旧锁保留可能性。但这份确定性只针对声明者,不能自动扩展到仍未完成的其他客户端。甲交回的是自己的剩余选项,不是乙的。
协议另有面向文件系统迁移的完成形式,需要当前文件句柄。它不是新客户端标识建立后全局声明的替代品;在不处于相关迁移情形的文件系统上,操作可以返回成功而不产生相应效果。本文讨论服务器重启,不展开迁移工作流。区分两种范围,是为了避免拿局部成功当作全局退出。
提前结束需要一份真正的名单
若服务器稳定保存了可能持有旧锁的客户端记录,就能在所有相关客户端均完成后,判断恢复机会是否已经用尽。这使提前结束宽限期成为有依据的决定,而不是凭“今天回来的人已经都完成了”来推测那些尚未出现的人。
宽限期也可能在并非所有客户端完成的情况下结束,但不能据此推导出运营者有权任意压缩恢复机会。第 8.4.2.1 节对租约时长作出约束:它规定宽限期不应早于租约周期结束,并在讨论新旧租约值变化时,要求恢复间隔至少覆盖上一实例的租约周期。不能把这些条件改写成所有部署一律适用的固定秒数。
实际需要观测的是两条不同的进度线:这个客户端是否完成了自身恢复,以及服务器是否具备放行某项新工作的条件。前者完成而后者尚未完成,并不天然意味着故障。它可能正是服务器仍在兑现对其他客户端的恢复承诺。
现在没有冲突,不代表过去没有中断
RFC 8881 还描述了一个比“回来得慢”更棘手的情形。客户端甲持锁时发生网络分区,无法续租。租约过期,服务器释放锁;客户端乙随后取得一个本会与甲冲突的锁,执行工作,再将锁释放。之后服务器重启,网络恢复,甲在新的宽限期内试图重新取得自己的旧锁。
这时,当前锁表里可以没有乙的锁。然而,甲原先依赖的连续保护早已中断。若乙修改了受保护的对象,服务器再把甲的请求当作一项从未中断的旧状态恢复,就可能让甲在错误前提上继续工作。危险不是当前存在两个相斥的条目,而是一个已经断开的历史被当作连续历史接受。
另一个例子跨越两次重启:甲没有赶上第一次宽限期内的全部恢复,乙在其后取得并释放冲突锁;服务器再次重启,甲这才回来。第二次宽限期的开始,不能抹去第一次未完成恢复的后果。
这也是稳定恢复记录必须存在的原因。规范要求服务器采取两类策略之一:拒绝所有恢复请求,返回 NFS4ERR_NO_GRACE;或者在稳定存储中留下足够信息,以识别所有已知的重启相关危险情形。拥有较少信息时,宁可把本来可以接受的恢复保守拒绝,也是被允许的。如果稳定记录已经不可恢复地损坏,可能受影响的客户端或锁必须遭到拒绝。
规范提供了一种最小记录的示例,包括客户端身份,以及尚未得到确认的撤销、此前未完成恢复等标记。这不是要求所有产品使用同一套数据库字段。它说明的是一项交换关系:记录得越精确,越有机会缩小拒绝范围;记录越粗,恢复承诺就越需要保守。
重新拿到锁,不会补上中间那段历史
收到 NFS4ERR_NO_GRACE 后,客户端如何处理,与其运行环境有关。规范讨论过一种可能做法:检查对象的变化属性,再判断是否通过普通的打开或加锁操作重建状态。但这不是适用于所有应用的无条件继续许可。
现在成功取得新锁,不能证明刚才失去保护时没有别人介入。应用可能需要知道协调已经中断,再对尚未完成的工作作决定。服务器能恢复协议状态,却不能替业务逻辑证明中间那段空白没有后果。
官方文档记录 将 RFC 8881 列为 2020 年 8 月发布、取代 RFC 5661 的拟议标准。本文同时查阅了其勘误列表:已确认修订与尚在报告状态的建议不能混为一谈。所取得的列表没有直接修改本文依赖的三个核心章节,但这不等于整份规范毫无缺陷,更不等于所有现实产品都已得到验证。
Lu Heng 在关于代理问题的第 32 篇笔记中提出控制权与后果承担之间的关系;第 36 篇关于现实而非倡议的笔记强调描述结构,而不是塑造英雄与反派。在这里,这些笔记提供编辑视角,协议条文提供技术依据。两者不能互相冒充。
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
