nfs 中 lockd 与 statd 的作用

lockd 是内核线程,statd 是用户态进程,二者用于 nfs v3 通信协议中,锁状态的恢复(v4 版本协议是有状态协议,无需依赖 statd来恢复状态)。

statd 的监听

当客户端第一次触发 lock 时 (nfs-utils 中可以通过下面的简单c脚本来触发拿锁),

复制代码
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <fcntl.h>

int main() {
    int fd = open(fname, O_RDWR, 0644));
    struct flock    fl;
    fl.l_type = F_RDLCK;
    fl.l_whence = 0;
    fl.l_start = 0;
    fl.l_len = 20;
    if (fcntl(fd, cmd, &fl) < 0) {
        printf("fcntl: failed: %d", errno);
    }
    printf("fcntl: ok\n");
    return 0;
}

内核经过nsm_monitor调用向本地 statd 进程发起 monitor 请求:

复制代码
nfs3_proc_lock
  ->nlmclnt_proc
  ->nlmclnt_lock
  ->nsm_monitor

nsm_monitor 函数会向本地 rpc.statd 进程发起 NSMPROC_MON 请求记录服务端监听信息。之后调在 nlmclnt_call 函数,向服务端 lockd 线程发起 op_lock 请求。

服务端 lockd 解析参数发现之前没有监听过这个客户端(调用栈如下),就会向服务端本地 rpc.statd 发起 NSMPROC_MON 请求记录客户端监听信息。

复制代码
nlmsvc_proc_lock
  ->__nlmsvc_proc_lock
  ->nlmsvc_retrieve_args
  ->nsm_monitor 

rpc.statd 监听的客户端会以文件的形式放在 /var/lib/nfs.sm 目录中,至此彼此建立好了监听。

状态的恢复

有两种情况会导致 sm-notify 通知对端自己重启过:

1、rpc.statd 每次启动时会触发一次 sm-notify 进程,但只有第一次触发时会创建 /run/sm-notify.pid 文件,以后检查发现这个文件存在,就不会通知对端。也就是说服务端第一次启动时(service nfs start 时)和客户端第一次启动时(mount -t nfs -o vers=3),rpc.statd 发起的 sm-notify 会检查 /var/lib/nfs.sm 目录中的文件记录,并向其中记录的对端发起 NSMPROC_NOTIFY 请求。

2、但除此之外更一般的情况是机器重启,systemd 系统进程会启动所有注册的 target。其中 /usr/lib/systemd/system/nfs-client.target 会触发 sm-notify 进程向对端发起 NSMPROC_NOTIFY 请求。

rpc.statd 进程收到对端的 NSMPROC_NOTIFY 请求后,会将这一请求加入 notify 列表,并在主循环中将 rpc 请求转发给 lockd 内核线程。调用栈如下:

复制代码
my_svc_run
  ->process_reply
  ->process_entry 
  ->nsm_xmit_nlmcall

内核收到请求后,调用 nlmsvc_proc_sm_notify->nlm_host_rebooted 恢复或释放锁状态。

  • 服务端处理客户端reboot事件:nlmsvc_free_host_resources 释放 reboot 的客户端申请过的锁
  • 客户端处理服务端reboot事件:nlmclnt_recovery 重新向服务端申请已经申请过的锁。
相关推荐
重生之我来学Python5 分钟前
Docker套装的简介、安装、超级详细教程
linux·docker·容器·eureka·github
Ruiery34 分钟前
Linux 6.6内核 PCIe 深度解析(十):PCIe Port Driver(portdrv)— 一个物理 Port,拆出五个逻辑服务
linux·运维·服务器
码农小韩2 小时前
Linux应用开发(二)——Linux的文件IO
linux·嵌入式软件·嵌入式操作系统·linux应用
Horn Still Sounds3 小时前
Linux网络并发服务器模型与SQLite数据库学习笔记
linux·服务器·数据库
10mAh3 小时前
【Linux】CPU 100% 怎么排查?——top、pidstat、jstack 到线程定位实战
linux·运维·服务器
深念Y3 小时前
开机启动优化记录
linux·开机
Titan20244 小时前
网络基础:传输层协议知识梳理
linux·服务器·网络
一叶龙洲4 小时前
Ubuntu从图标到卸载应用
linux·windows·ubuntu
爱吃提升4 小时前
VMware虚拟机迁移系统磁盘完整教程(VMware Workstation17)
linux·运维·服务器
2401_868534784 小时前
网规备考_5.4 防火墙及访问控制技术
linux·网络协议