SETCLIENTID

本文详细解析Linux NFSv4协议中SETCLIENTID请求的处理过程,包括客户端和服务器端的代码细节。客户端涉及nfs4_setclientid数据结构,服务器端通过nfs4_client结构管理客户端信息,并在不同链表中存储。SETCLIENTID请求用于协商clientid,服务器端根据请求创建或更新客户端状态。
摘要由CSDN通过智能技术生成

    上篇文章中我们讲到了Linux中clientid的协商过程,这个过程是由函数nfs4_init_clientid()实现的。这个函数包含两个步骤:(1)发起SETCLIENTID请求,由函数nfs4_proc_setclientid()实现;(2)发起SETCLIENTID_CONFIRM请求,由函数nfs4_proc_setclientid_confirm()实现。这篇文章中我们详细详解SETCLIENTID请求。


1.客户端代码

首先介绍两个数据结构:nfs4_setclientid和nfs4_setclientid_res。

nfs4_setclientid是SETCLIENTID请求报文使用的数据结构。

struct nfs4_setclientid {
        const nfs4_verifier *           sc_verifier;    // 客户端重启信息
        // 客户端信息字符串实际长度
        unsigned int                    sc_name_len;
        // 客户端信息(客户端地址/服务器地址 传输层协议)
        char                            sc_name[NFS4_SETCLIENTID_NAMELEN + 1];
        // CALLBACK服务编号
        u32                             sc_prog;
        // CALLBACK服务中传输层协议名称的长度
        unsigned int                    sc_netid_len;
        // CALLBACK服务中传输层协议名称
        char                            sc_netid[RPCBIND_MAXNETIDLEN + 1];
        // CALLBACK服务中RPC服务器地址的长度
        unsigned int                    sc_uaddr_len;
        // CALLBACK服务中RPC服务器地址(RPC服务器地址.端口号)
        char                            sc_uaddr[RPCBIND_MAXUADDRLEN + 1];
        // 客户端编号
        u32                             sc_cb_ident;
};
nfs4_setclientid_res是存储SETCLIENTID应答报文数据的数据结构。

struct nfs4_setclientid_res {
        u64                             clientid;
        nfs4_verifier                   confirm;
};
客户端发起SETCLIENTID请求的函数是nfs4_proc_setclientid(),这个函数的流程很简单,就是设法设置SETCLIENTID请求报文中各个字段的值,然后发起RPC调用。函数流程如下:

参数clp:一个NFS客户端的数据结构
参数program:这是CALLBACK服务的编号,固定为0x40000000
参数port:CALLBACK服务中RPC服务器端(NFS客户端)使用的端口号
参数cred:这是一个用户信息,发起SETCLIENTID请求的用户信息
参数res:这是输出参数,用于保存SETCLIENTID请求应答报文中的信息.

int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                unsigned short port, struct rpc_cred *cred,
                struct nfs4_setclientid_res *res)
{
        nfs4_verifier sc_verifier;      // 8字节
        struct nfs4_setclientid setclientid = {
                .sc_verifier = &sc_verifier,	// 这是客户端的开机时间
                .sc_prog = program,     // CALLBACK服务编号
                .sc_cb_ident = clp->cl_cb_ident,        // 这是NFSv4客户端的一个编号,创建NFSv4客户端时就设置了这个编号.
        };
        struct rpc_message msg = {
                .rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],	// SETCLIENTID请求编号
                .rpc_argp = &setclientid,	// SETCLIENTID请求的输入参数
                .rpc_resp = res,	// SETCLIENTID请求的返回值
                .rpc_cred = cred,       // 用户信息
        };

        int status;
        /* nfs_client_id4 */   // 初始化sc_verifier,初始化为客户端的开机时间(确切说是nfs模块的加载时间)
        nfs4_init_boot_verifier(clp, &sc_verifier);
        rcu_read_lock();
        // 客户端信息
        setclientid.sc_name_len = scnprintf(setclientid.sc_name,
                        sizeof(setclientid.sc_name), "%s/%s %s",
                        clp->cl_ipaddr,                                 // 这是NFS客户端的地址
                        rpc_peeraddr2str(clp->cl_rpcclient,
                                                RPC_DISPLAY_ADDR),      // NFS服务器的地址
                        rpc_peeraddr2str(clp->cl_rpcclient,
                                                RPC_DISPLAY_PROTO));    // NFS服务器传输层协议
        /* cb_client4 */
        // CALLBACK使用的传输层协议
        setclientid.sc_netid_len = scnprintf(setclientid.sc_netid,
                                sizeof(setclientid.sc_netid),
                                rpc_peeraddr2str(clp->cl_rpcclient,
                                                        RPC_DISPLAY_NETID));    // 这是NFSv4使用的传输层协议  tcp
        rcu_read_unlock();
        // CALLBACK服务地址和端口号
        setclientid.sc_u
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值