ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Linux 内核 pNFS Block Layout 服务器使用指南:MDS 角色、共享块设备与客户端 fencing 实战

Linux 内核 pNFS Block Layout 服务器使用指南:MDS 角色、共享块设备与客户端 fencing 实战 Linux 内核 pNFS Block Layout 服务器使用指南MDS 角色、共享块设备与客户端 fencing 实战【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux导读本文基于 Linux 内核源码树中的 Documentation/admin-guide/nfs/pnfs-block-server.rst 编写系统讲解 Linux NFS 服务器nfsd对 pNFS block layout块布局扩展的支持方式NFS 服务器如何以 Metadata ServerMDS身份向客户端下发布局layout、客户端如何绕过 MDS 直接读写共享块设备以及当客户端不再响应布局召回layout recall时服务器如何通过/sbin/nfsd-recall-failed脚本完成 fencing 并恢复文件访问。读完本文你将掌握从内核配置、文件系统挂载到故障恢复手动过期客户端的完整实战链路并理解其背后的源码实现机制。pNFS block layout 架构NFS 服务器扮演 MDS 角色Linux NFS 服务器现已支持 pNFS block layout 扩展。在这种模式下NFS 服务器充当 pNFS 的Metadata ServerMDS它一方面照常处理 NFS 导出上的全部元数据访问目录、权限、文件属性、open/close 等另一方面向客户端签发布局layout授权客户端直接访问与 MDS 共享的底层块设备。这种控制面与数据面分离的设计是 pNFS 的核心思想客户端拿到布局后数据 I/O 不再全部经由 MDS 转发而是直接下发到块设备从而分摊数据通路负载。在内核源码中服务端一侧的布局操作由struct nfsd4_layout_ops描述block 布局对应scsi_layout_ops见 fs/nfsd/blocklayout.c其proc_getdeviceinfo等回调负责向客户端通告块设备信息客户端一侧则由fs/nfs/blocklayout/目录下的实现负责解析设备并构造 BIO 直写底层设备。使用前提文件系统、共享存储与内核配置要使用 pNFS block layouts需同时满足以下条件导出文件系统必须支持 pNFS block layouts目前内核中只有XFS满足该要求文件系统必须位于共享存储典型为 iSCSI之上且该共享存储除了 MDS 之外还必须对客户端可见可访问目前文件系统必须直接位于导出的卷volume之上MDS 与客户端上的卷条带化striping或拼接concatenation尚未得到支持。从实现层面看客户端对块设备拓扑的解析确实关注底层设备结构fs/nfs/blocklayout/dev.c中的设备解析逻辑会读取服务端通告的 SCSI 标识符code_set、designator_type、designator_len等字段见 fs/nfs/blocklayout/dev.c并结合设备映射关系把文件偏移换算成设备偏移后再提交 BIO。这正是卷需直接可寻址、暂不支持条带/拼接这一约束在客户端侧的体现。服务端自动启用无需额外开关在服务器端只要文件系统本身支持 block layout即 XFS 且位于合适的块设备上pNFS block volume 支持会自动生效无需额外手工配置。客户端三个必要条件客户端要正常使用 block layout必须同时满足内核开启CONFIG_PNFS_BLOCK选项。该选项定义于 fs/nfs/Kconfig类型为 tristate依赖NFS_V4 BLK_DEV_DM默认取值跟随NFS_V4。当其为y或m时fs/nfs/Makefile 会把blocklayout/目录编译进内核或编译为模块其中的blocklayout.c、dev.c、extent_tree.c、rpc_pipefs.c共同构成客户端 block layout 实现。nfs-utils 包中的blkmapd守护进程正在运行。blkmapd负责把 pNFS 通告的设备映射到客户端本地块设备是客户端正确解析布局的前提。文件系统必须使用 NFSv4.1 协议版本挂载即mount -o vers4.1 server:/export /mntpNFS 布局协商LAYOUTGET、CB_LAYOUTRECALL 等操作由 NFSv4.1 协议引入因此低版本协议NFSv4.0/NFSv3无法使用 block layout。客户端 fencing非响应客户端的隔离机制当 nfsd 需要隔离fence一个不再响应的客户端时它会调用/sbin/nfsd-recall-failed并传入两个参数第一个参数客户端的IP 地址第二个参数需要被隔离的文件系统所对应的设备节点名不带/dev前缀。该调用在内核中的实现位于nfsd4_cb_layout_fail()见 fs/nfsd/nfs4layouts.c当客户端对布局召回layout recall的回调不响应时内核通过call_usermodehelper()以UMH_WAIT_PROC方式执行/sbin/nfsd-recall-failedargv[1]为用rpc_ntop()格式化的客户端 IP 地址字符串argv[2]为挂载点所在文件系统的设备标识mnt_sb-s_id同时以受限环境HOME/、TERMlinux、PATH/sbin:/usr/sbin:/bin:/usr/bin启动该脚本。调用失败时内核会打印nfsd: fence failed for client %s: %d!的错误日志。参考脚本把设备翻译为 SCSI EVPD 0x80 序列号以下是文档给出的示例脚本展示了如何把设备节点翻译成 SCSI EVPD page 0x80Unit Serial Number序列号并写入 fencing 日志。这是让nfsd-recall-failed可用的最小可运行实现cat /sbin/nfsd-recall-failed EOF #!/bin/sh CLIENT$1 DEV/dev/$2 EVPDsg_inq --page0x80 ${DEV} | \ grep Unit serial number: | \ awk -F : {print $2} echo fencing client ${CLIENT} serial ${EVPD} /var/log/pnfsd-fence.log EOF脚本使用sg_inq --page0x80读取设备的 VPD 页再用awk提取序列号最后把client IP 序列号追加到/var/log/pnfsd-fence.log便于管理员事后审计是哪台客户端、哪块盘触发了 fencing。实际部署时可根据存储栈的具体能力替换脚本内部实现例如对接存储阵列的管理接口执行 LUN 隔离只要保证脚本可执行且参数约定与内核调用一致即可。FENCE 失败日志格式与无限重试语义如果 nfsd 需要隔离某个非响应客户端、但fencing 操作失败服务器会在系统日志中记录一条警告消息格式如下FENCE failed client[IP_address] clid[#n] device[dev_name]各字段含义IP_address受影响客户端的 IP 地址#n该客户端的唯一客户端标识client identifierdev_name与本次 fencing 尝试相关的块设备名称。服务器会无限期反复重试该操作。在重试期间所有其他客户端对受影响文件的访问都会被限制这是为了防止多个客户端同时访问同一文件时可能引发的数据损坏。从源码角度看这一重试与防并发的语义由 SCSI 持久预留Persistent Reservation机制承载nfsd4_scsi_fence_client()见 fs/nfsd/blocklayout.c在cl_fence_mutex保护下通过块设备pr_ops-pr_preempt()以NFSD_MDS_PR_KEY抢占客户端的预留键PR_EXCLUSIVE_ACCESS_REG_ONLYpreempt 标志为 true从而在共享存储层面剥夺客户端的访问权cl_dev_fencesxarray 上的NFSD_MDS_PR_FENCED标记用于去重避免对同一设备重复发起抢占。代码注释特别指出只有当命令可能根本没有送达设备如-ENOMEM、PR_STS_PATH_FAILED等传输路径失败时才允许重试而对于PR_STS_IOERR、PR_STS_RESERVATION_CONFLICT这类命令可能已生效的结果则视为成功以防止对已成功的 preempt 重试导致无限循环。故障恢复手动过期expire被隔离客户端要恢复其他客户端对受影响文件的访问管理员需要执行以下步骤关闭或断电被隔离fencing的客户端确保它彻底停止对共享存储的一切访问手动过期该客户端释放其在服务器上的全部状态echo expire /proc/fs/nfsd/clients/clid/ctl其中clid系统日志中显示的唯一客户端标识即上面FENCE failed日志中clid[#n]的编号。/proc/fs/nfsd/clients/是 nfsd 暴露客户端状态的 procfs 接口每个子目录对应一个已注册客户端向对应clid目录下的ctl文件写入expire即可强制使该客户端过期。在内核实现中客户端过期后其持有的所有状态含布局 stateid 与相关预留会被清理其对应的 fencing 标记也会被清除参见 fs/nfsd/blocklayout.c 中nfsd4_scsi_fence_clear对NFSD_MDS_PR_FENCED标记的撤销逻辑以及 fs/nfsd/nfs4state.c 中客户端过期与状态回收的相关路径从而解除对其他客户端的访问限制。关键参数与配置速查项目配置/操作位置与说明客户端内核选项CONFIG_PNFS_BLOCKtristate依赖NFS_V4 BLK_DEV_DM默认随NFS_V4fs/nfs/Kconfig客户端构建obj-$(CONFIG_PNFS_BLOCK) blocklayout/fs/nfs/Makefile客户端实现blocklayout.c、dev.c、extent_tree.c、rpc_pipefs.cfs/nfs/blocklayout/服务端布局回调scsi_layout_ops含proc_getdeviceinfofs/nfsd/blocklayout.cfencing 脚本调用点nfsd4_cb_layout_fail()通过call_usermodehelper执行/sbin/nfsd-recall-failedfs/nfsd/nfs4layouts.cfencing 预留实现pr_preemptNFSD_MDS_PR_KEYcl_fence_mutexNFSD_MDS_PR_FENCED标记fs/nfsd/blocklayout.c挂载协议mount -o vers4.1NFSv4.1 引入布局相关操作设备映射守护进程nfs-utils 的blkmapd客户端侧必选客户端过期echo expire /proc/fs/nfsd/clients/clid/ctl故障恢复第 2 步部署检查清单共享存储如 iSCSI已挂载到 MDS 与所有客户端且各方看到的卷一致在 MDS 上把该共享卷直接格式化为XFS并导出不做条带/拼接服务端确认 pNFS block volume 支持自动生效客户端内核确认开启CONFIG_PNFS_BLOCKblkmapd守护进程运行中客户端以mount -o vers4.1挂载导出预先安装/sbin/nfsd-recall-failed脚本可执行并验证sg_inq --page0x80能读取设备序列号出现FENCE failed日志时定位clid编号关闭对应客户端后执行echo expire /proc/fs/nfsd/clients/clid/ctl恢复访问。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进