Linux 内核 NFS/RDMA 部署实战:从内核配置到 mount -o rdma 的完整指南
Linux 内核 NFS/RDMA 部署实战从内核配置到 mount -o rdma 的完整指南【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux导读NFS/RDMA也称 RPC-over-RDMA让 NFS 客户端与服务端通过 InfiniBand、iWARP 或 RoCE 等 RDMA 传输层直接交换数据绕开 TCP/IP 协议栈的拷贝与中断开销可在较低客户端 CPU 占用下跑满 10Gbit 线速带宽。本文以 Linux 内核官方文档 nfs-rdma.rst 为主线结合当前内核源码树中的 net/sunrpc/xprtrdma 实现系统讲解 NFS/RDMA 的安装前提、内核配置、双向客户端与服务端搭建步骤、挂载验证方法与底层原理读完即可在真实集群上完成一套可用的 NFS/RDMA 环境。提示文档开头带有 This document is probably obsolete 的警告文中命令与配置基于早期内核2.6.24/2.6.25 时代书写但现代内核中的核心配置项、挂载参数与端口约定基本沿袭自该文本文会结合当前源码逐一核对并标注差异。一、NFS/RDMA 是什么背景与动机NFS/RDMA 是 SUNRPC 框架下的一种 RPC 传输层transport实现。普通 NFS 走 TCP/UDP socket而 NFS/RDMA 让 RPC 消息直接通过 RDMA 硬件传输由网卡HCA/RNIC负责数据搬移减少了内核协议栈的参与。文档给出的关键时间线NFS/RDMA 客户端首次进入主线内核是Linux 2.6.24NFS/RDMA 服务端在下一个版本Linux 2.6.25加入。也就是说自 2.6.25 起客户端与服务端就已同时包含在主线上无需额外内核补丁。文档作者NetApp 与 Open Grid Computing2008 年 5 月在测试中称获得了优秀的性能结果——多种工作负载下满 10Gbit 线速带宽、客户端 CPU 占用极低且通过了完整的 Connectathon 测试套件可运行在 InfiniBand 与 iWARP 两类 RDMA 适配器上。这些属于文档所述的历史测试结论不代表当前内核的量化承诺读者应将其理解为低 CPU 高吞吐的定性参考。如果搭建过程遇到问题可以到文档提到的 nfs-rdma-devellists.sourceforge.net 邮件列表提问该列表至今仍活跃于内核 NFS 开发社区。二、安装前置条件文档将安装过程组织为一系列递进步骤本小节完整继承并补充细节。1. 准备 RDMA 设备任何由 drivers/infiniband/hw 下驱动支持的设备均可。文档当年实测过的硬件包括多款 Mellanox 的 InfiniBand 网卡HCAAmmasso AMS1100 iWARP 适配器Chelsio cxgb3 iWARP 适配器。从当前源码树的 drivers/infiniband/hw 看支持的厂商与驱动已大幅扩展mlx4、mlx5、hfi1、qib、irdma、bnxt_re、efa 等现代选择远多于文档时代。2. 准备 Linux 发行版与工具使用Linux 2.6.25 及之后的内核发行版首个同时包含 NFS/RDMA 客户端与服务端的版本客户端需要nfs-utils-1.1.2 或更高版本。注意nfs-utils-1.1.1 是首个支持 NFS/RDMA 挂载的版本但文档明确建议使用 1.1.2。检查 mount.nfs 版本$ /sbin/mount.nfs -V若版本低于 1.1.2 或命令不存在需安装最新 nfs-utils。若不需要 idmapper 与 gssd创建 NFS/RDMA 挂载命令并不需要它们可在 configure 时精简编译$ ./configure --disable-gss --disable-nfsv4构建 nfs-utils 需要 tcp_wrappers 包细节参见该包自带 README 与 INSTALL。构建完成后utils/mount目录下会生成 mount.nfs 二进制它可用于发起 NFS v2/v3/v4 挂载v4 挂载要求二进制以 mount.nfs4 名被调用标准做法是建立符号链接$ sudo cp utils/mount/mount.nfs /sbin/mount.nfs安装到 /sbin/mount.nfs 后系统的 mount 命令会自动为 NFS 挂载调用它。重要mount.nfs以及 nfs-utils-1.1.2只需要安装在 NFS 客户端。服务端不要求该特定版本客户端也只需要其中的 mount.nfs 命令。3. 准备内核从主线下载 2.6.25 或更新的内核源码现代环境建议直接使用当前发行版内核或本仓库对应的主线版本解压到合适位置。三、内核配置RDMA 栈与 NFS 的开启方式1. 配置 RDMA 栈在Device Drivers - InfiniBand support下开启 InfiniBand 支持。文档特别提醒该选项名称具有误导性——开启 InfiniBand 支持是所有 RDMA 设备IB、iWARP 等的必需前提无论你最终使用哪类硬件。随后按硬件选择具体驱动IB HCA 驱动mlx4、mthca、ehca、ipath 等iWARP 适配器驱动amso、cxgb3 等。如果使用 InfiniBand务必同时启用IP-over-InfiniBandIPoIB支持因为客户端地址解析、ping 联通性测试都依赖 IPoIB 接口。2. 配置 NFS 客户端与服务端在File Systems - Network File Systems下启用 NFS 文件系统支持客户端和/或 NFS 服务器支持服务端及相关选项。3. 隐藏开关 SUNRPC_XPRT_RDMA 的取值逻辑NFS/RDMA 代码由隐藏配置项SUNRPC_XPRT_RDMA控制它依赖 SUNRPC 与 INFINIBAND。当前源码中的定义位于 net/sunrpc/Kconfigconfig SUNRPC_XPRT_RDMA tristate RPC-over-RDMA transport depends on SUNRPC INFINIBAND INFINIBAND_ADDR_TRANS default SUNRPC INFINIBAND select SG_POOL help This option allows the NFS client and server to use RDMA transports (InfiniBand, iWARP, or RoCE). To compile this support as a module, choose M. The module will be called rpcrdma.ko.与文档描述一致SUNRPC_XPRT_RDMA 的最终取值遵循三态推导前提SUNRPC / INFINIBANDSUNRPC_XPRT_RDMANFS/RDMA 构建结果任一为 NN不构建 NFS/RDMA 客户端与服务端二者均开启M 或 Y且至少一个为 MM以模块形式构建rpcrdma.ko二者均为 YY内建到内核因此在配置界面按上述步骤同时打开 NFS 与 RDMA 后NFS/RDMA 客户端与服务端会自动纳入构建。从 net/sunrpc/Makefile 可见obj-$(CONFIG_SUNRPC_XPRT_RDMA) xprtrdma/而 net/sunrpc/xprtrdma/Makefile 则把所有客户端与服务端源文件统一编入rpcrdma.o单模块obj-$(CONFIG_SUNRPC_XPRT_RDMA) rpcrdma.o rpcrdma-y : transport.o rpc_rdma.o verbs.o frwr_ops.o ib_client.o \ svc_rdma.o svc_rdma_backchannel.o svc_rdma_transport.o \ svc_rdma_sendto.o svc_rdma_recvfrom.o svc_rdma_rw.o \ svc_rdma_pcl.o module.o rpcrdma-$(CONFIG_SUNRPC_BACKCHANNEL) backchannel.o由此可以看出一个与文档不同的现代细节文档写的是modprobe xprtrdma.ko而当前内核模块实际名为rpcrdma.ko。好在模块声明了兼容别名见 module.cMODULE_AUTHOR(Open Grid Computing and Network Appliance, Inc.); MODULE_DESCRIPTION(RPC/RDMA Transport); MODULE_LICENSE(Dual BSD/GPL); MODULE_ALIAS(svcrdma); MODULE_ALIAS(xprtrdma); MODULE_ALIAS(rpcrdma6);由于存在MODULE_ALIAS(xprtrdma)modprobe xprtrdma依然可用但现代推荐直接使用 rpcrdma。另外MODULE_ALIAS(svcrdma)说明服务端 RDMA 传输svc_rdma也被纳入同一模块modprobe svcrdma实际加载的也是 rpcrdma.ko。完成上述配置后构建新内核、安装并重启。四、搭建前自检验证 RDMA 与 NFS 基线在配置 NFS/RDMA 之前先确认内核基本工作正常重点验证两点RDMA 栈可用、传统 NFS over TCP/UDP 可用。1. 检查 RDMA 栈若 RDMA 组件编译为模块先加载。以 Mellanox Tavor/Sinai/Arbel 卡为例$ modprobe ib_mthca $ modprobe ib_ipoib现代 Mellanox 网卡对应驱动为 mlx4_ib / mlx5_ib可按实际硬件调整。使用 InfiniBand 时网络上必须存在子网管理器Subnet Manager, SM若 IB 交换机内嵌 SM 可直接使用否则需要在某个端节点运行 SM如 OpenSM。SM 正常运行时端口状态应显示 ACTIVE$ cat /sys/class/infiniband/driverX/ports/1/state 4: ACTIVE其中 driverX 是 mthca0、ipath5、ehca3 等实际设备名。当前内核的 RDMA 子系统同样通过/sys/class/infiniband/暴露设备状态state文件数值 4 对应 ACTIVE是链路就绪的标准判据。进一步用 IPoIB 做联通性测试假设两台 IB 主机 host1 与 host2host1$ ip link set dev ib0 up host1$ ip address add dev ib0 a.b.c.x host2$ ip link set dev ib0 up host2$ ip address add dev ib0 a.b.c.y host1$ ping a.b.c.y host2$ ping a.b.c.x其他设备类型iWARP/RoCE按各自厂商流程验证。2. 检查 NFS 基线对前面启用的 NFS 组件客户端和/或服务端先通过标准以太网 TCP/IP 或 UDP/IP 验证其功能正常确保问题不被 RDMA 层干扰。五、NFS/RDMA 正式搭建客户端与服务端双机配置文档推荐使用两台机器一台作客户端、一台作服务端。1. 一次性配置服务端 /etc/exports在服务端配置 /etc/exports 并启动 NFS/RDMA 服务。以下两种格式的导出条目经过文档实测/vol0 192.168.0.47(fsid0,rw,async,insecure,no_root_squash) /vol0 192.168.0.0/255.255.255.0(fsid0,rw,async,insecure,no_root_squash)地址部分若使用 InfiniBand HCA填写客户端的 IPoIB 地址若使用 iWARP RNIC填写客户端的 iWARP 地址。关键点insecure 选项必须使用因为 NFS/RDMA 客户端不使用保留端口reserved port即 1024 的源端口发起请求。这对应内核中的NFS_MOUNT_INSECURE语义服务端不校验请求源端口是否为特权端口。2. 每次开机加载驱动并启动服务服务端——加载与配置 RDMA 驱动Mellanox 适配器 InfiniBand 示例$ modprobe ib_mthca $ modprobe ib_ipoib $ ip li set dev ib0 up $ ip addr add dev ib0 a.b.c.d注意客户端与服务端务必使用互不相同的唯一 IP 地址服务端——启动 NFS 服务。若服务端 NFS/RDMA 以模块构建内核配置中 CONFIG_SUNRPC_XPRT_RDMAm加载 RDMA 传输模块$ modprobe svcrdma无论内建还是模块随后启动 NFS 服务$ /etc/init.d/nfs start或$ service nfs start现代 systemd 发行版对应systemctl start nfs-server等单元。服务端——让 NFS 服务监听 RDMA 传输$ echo rdma 20049 /proc/fs/nfsd/portlist该 proc 接口在内核中由 fs/nfsd/nfsctl.c 注册[NFSD_Ports] {portlist, transaction_ops, S_IWUSR|S_IRUGO},transaction_ops的 write 路径会解析transport port格式并调用 nfsd 的传输注册逻辑向内核 nfsd 添加一个监听在 20049 端口的 RDMA 传输端点。20049 是 NFS over RDMA 的标准端口IANA 分配客户端挂载时需与之对齐。客户端——加载 RDMA 客户端模块。若以模块构建CONFIG_SUNRPC_XPRT_RDMAm$ modprobe xprtrdma.ko如前述现代内核模块名为 rpcrdma.koxprtrdma仅是兼容别名$ modprobe rpcrdma客户端——发起 NFS/RDMA 挂载$ mount -o rdma,port20049 IPoIB-server-name-or-address:/export /mnt其中export对应 /etc/exports 中导出的路径IPoIB-server-name-or-address是服务端的 IPoIB或 iWARP地址或主机名。3. 验证挂载确实走 RDMA$ cat /proc/mounts检查对应挂载行的proto 字段若为protordma或显示 rdma 传输即说明挂载已通过 RDMA 传输。至此一套 NFS/RDMA 环境搭建完成。六、从当前源码看 NFS/RDMA 的实现与可调参数1. 客户端传输实现与关键可调项客户端 RDMA 传输的顶层实现在 net/sunrpc/xprtrdma/transport.c其 tunables 定义如下static unsigned int xprt_rdma_slot_table_entries RPCRDMA_DEF_SLOT_TABLE; unsigned int xprt_rdma_max_inline_read RPCRDMA_DEF_INLINE; unsigned int xprt_rdma_max_inline_write RPCRDMA_DEF_INLINE; unsigned int xprt_rdma_memreg_strategy RPCRDMA_FRWR; int xprt_rdma_pad_optimize; static struct xprt_class xprt_rdma;这些变量对应用户可调参数slot_table_entriesRPC 并发槽位数影响在途 RPC 请求数即 I/O 深度有 min/max 上下限保护RPCRDMA_MIN/MAX_SLOT_TABLEmax_inline_read / max_inline_write内联inline读/写阈值小于该值的数据直接随 RPC 消息内联传输无需额外内存注册memreg_strategy内存注册策略当前默认 RPCRDMA_FRWRFast Registration Work Request这是现代 RDMA 网卡普遍支持的高效注册方式pad_optimizeXDR 填充优化开关。文件注释This file contains the top-level implementation of an RPC RDMA transport与命名约定xprt_ 前缀函数属于传输交换层其余为 RPC/RDMA 内部函数表明客户端以struct xprt_class xprt_rdma形式注册进 SUNRPC 传输框架与 TCP/UDP socket 传输xprtsock.c平级。这正是mount -o rdma能直接生效的架构基础。2. 服务端实现与 sysctl 参数服务端 RDMA 传输svc_rdma位于 net/sunrpc/xprtrdma/svc_rdma.cunsigned int svcrdma_ord 16; /* historical default */ static unsigned int min_ord 1; static unsigned int max_ord 255; unsigned int svcrdma_max_requests RPCRDMA_MAX_REQUESTS; unsigned int svcrdma_max_bc_requests RPCRDMA_MAX_BC_REQUESTS; static unsigned int min_max_requests 4; static unsigned int max_max_requests 16384; unsigned int svcrdma_max_req_size RPCRDMA_DEF_INLINE_THRESH;该文件通过 ctl_table 注册了/proc/sys/sunrpc/svcrdma_*系列可调项svcrdma_ordoutstanding RDMA read/write 深度历史默认 16范围 1–255svcrdma_max_requests可同时处理的请求数上限范围 4–16384svcrdma_max_req_size请求消息大小阈值即服务端内联阈值用于决定何时需要额外 RDMA 读/写另有一组只读计数器 svcrdma_stat_read / svcrdma_stat_recv / svcrdma_stat_sq_starve / svcrdma_stat_write可观察服务端 RDMA 流量与发送队列饥饿情况写入计数文件可将计数器清零。这些参数解释了文档所述 20049 端口行为之外的服务端资源控制维度也是排查请求过大被拒绝/拆分类问题时的关键旋钮。3. 现代内核中 rdma 挂载参数的解析位置文档给出的mount -o rdma,port20049在现代内核中由 NFS 挂载参数解析器处理。在 fs/nfs/fs_context.c 中fsparam_u32 (port, Opt_port), ... fsparam_flag (rdma, Opt_rdma),以及传输协议枚举映射同一文件 第 261 行附近{ rdma, Opt_xprt_rdma },这说明当前内核同时接受rdma标志位形式-o rdma与protordma形式-o protordma二者最终都会把挂载指向 xprt_rdma 传输并配合port指定 20049 端口。这也与 /proc/mounts 中protordma字段的呈现一致——该字段正是挂载参数解析结果的直接输出。七、常见问题与排障要点结合文档步骤与源码整理几个高频排障方向端口状态不是 ACTIVE确认子网管理器SM在运行/sys/class/infiniband/*/ports/*/state必须为4: ACTIVE否则 IPoIB 与 RDMA 均不可用。挂载后 proto 不是 rdma检查/proc/fs/nfsd/portlist是否已写入rdma 20049确认服务端模块已加载modprobe svcrdma/modprobe rpcrdma确认客户端使用-o rdma,port20049端口必须与服务端一致。挂载被拒绝确认 /etc/exports 中包含 insecure 选项——NFS/RDMA 客户端不使用保留端口缺少 insecure 会被服务端以源端口非法拒绝同时确认导出的地址写的是客户端的 IPoIB/iWARP 地址而非以太网地址。模块名不一致文档时代的xprtrdma.ko在现代内核中叫rpcrdma.ko但modprobe xprtrdma因 MODULE_ALIAS 仍可加载查看 net/sunrpc/xprtrdma/module.c 可确认别名。性能未达预期检查服务端 svcrdma_max_requests / svcrdma_ord 与客户端 slot_table_entries、max_inline_read/write 等可调项是否匹配工作负载svcrdma_stat_sq_starve计数器可提示发送队列是否饥饿。八、结语NFS/RDMA 从 2.6.24/2.6.25 进入主线至今其架构骨架SUNRPC_XPRT_RDMA 三态推导、20049 端口约定、rdma 挂载参数、/proc/fs/nfsd/portlist 接口基本保持稳定。当前内核把客户端与服务端实现统一收拢进 net/sunrpc/xprtrdma 目录、编译为 rpcrdma.ko 单模块并扩展出 FRWR 内存注册、svcrdma 系列 sysctl 等现代能力。本文所述的搭建流程——硬件与发行版准备、内核三层配置RDMA 栈 / NFS / SUNRPC_XPRT_RDMA、双机一次性配置与开机流程、mount 与 /proc/mounts 验证——在任何带 RDMA 硬件的现代内核上依然直接适用只需把驱动名与 init 脚本替换为当前发行版对应形式即可。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考