RPC请求处理过程

这篇文章讲讲服务器端RPC报文的处理流程。服务器端RPC报文的处理函数是svc_process,这个函数位于net/sunrpc/svc.c中。这个函数需要一个svc_rqst结构的指针作为参数,svc_rqst是与RPC请求相关的一个数据结构,这里包含了接收到的RPC消息,RPC消息的解析结果也放在这个数据结构中,RPC消息的处理结果也放在这个消息中了。这个数据结构的定义在include/lin
摘要由CSDN通过智能技术生成

这篇文章讲讲服务器端RPC报文的处理流程。服务器端RPC报文的处理函数是svc_process,这个函数位于net/sunrpc/svc.c中。这个函数需要一个svc_rqst结构的指针作为参数,svc_rqst是与RPC请求相关的一个数据结构,这里包含了接收到的RPC消息,RPC消息的解析结果也放在这个数据结构中,RPC消息的处理结果也放在这个消息中了。这个数据结构的定义在include/linux/sunrpc/svc.h。由于我主要想讲解NFS,所以很多RPC的知识就略过不讲了。

/*
 * Process the RPC request.
 */
int
svc_process(struct svc_rqst *rqstp)
{
        // 这是一块缓存,服务器从网卡中接收到RPC消息后存放在这里(已经去掉了IP头,TCP或UDP报文头)
        // argv指向了缓存的起始地址,从这里开始就是RPC报文头了。
        struct kvec             *argv = &rqstp->rq_arg.head[0];
        // 这是一块缓存,这块缓存用来存放RPC应答消息,现在还没有分配内存。
        struct kvec             *resv = &rqstp->rq_res.head[0];
        struct svc_serv         *serv = rqstp->rq_server;
        u32                     dir;

        /*
         * Setup response xdr_buf.
         * Initially it has just one page
         */
        rqstp->rq_resused = 1;
        // 为RPC应答消息分配内存
        resv->iov_base = page_address(rqstp->rq_respages[0]);
        resv->iov_len = 0; 
        rqstp->rq_res.pages = rqstp->rq_respages + 1;
        rqstp->rq_res.len = 0;
        rqstp->rq_res.page_base = 0;
        rqstp->rq_res.page_len = 0;
        rqstp->rq_res.buflen = PAGE_SIZE;
        rqstp->rq_res.tail[0].iov_base = NULL;
        rqstp->rq_res.tail[0].iov_len = 0;

        rqstp->rq_xid = svc_getu32(argv);   // 这里开始解析RPC报文了,按照RPC报文格式,这是RPC消息的XID。

        dir  = svc_getnl(argv);   // 这个函数解析出了RPC保本中的第二个字段(Message Type)
        if (dir != 0) {           // RPC协议规定,RPC应答消息中Message Type字段必须为0.如果不是0就不处理了。
                /* direction != CALL */
                svc_printk(rqstp, "bad direction %d, dropping request\n", dir);
                serv->sv_stats->rpcbadfmt++;
                svc_drop(rqstp);   // 丢弃这个RPC报文。
                return 0;
        }

        // 现在可以确定这是一个RPC请求报文了,调用svc_process_common()进行处理,这是RPC请求的主处理函数,并且会填充RPC应答报文。
        // 返回值1表示处理过程正常,已经正常填充了RPC应答消息,可以发送给客户端了。
        // 返回值0表示RPC请求报文格式异常,直接丢弃这个报文。
        /* Returns 1 for send, 0 for drop */
        if (svc_process_common(rqstp, argv, resv))
                return svc_send(rqstp);    // 这是发送RPC应答消息的报文,不会深入分析这个函数了。
        else {
                svc_drop(rqstp);    // 丢弃RPC报文。
                return 0;
        }
}

svc_process_common是主要的处理函数,这个函数的定义如下:

static int svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv)

参数rqstp 表示一个RPC请求。

参数argv是一块缓存,这块缓存中保存了接收到的RPC请求报文。

参数resv是一块缓存,这块缓存用来保存组装后的RPC应答报文。

这个函数的处理流程就比较复杂了,基本上包含下面五个处理步骤:

(1)组装RPC报文头基本信息

(2)解析RPC服务信息

(3)对用户身份进行验证

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值