GlusterFS:xlator基础源码研究

本文深入探讨了GlusterFS客户端的xlator树加载过程,详细介绍了如何将卷配置文件解析成图,并进行xlator节点的初始化和参数检查。接着,文章阐述了xlator之间的调用机制,包括父节点如何调用子节点以及子节点如何回调父节点。此外,还讨论了xlator的重要数据结构以及Linux操作系统的相关知识,如文件描述符、目录项和重要参数。

1.xlator树加载过程

对于glusterfs,在客户端,有一个由xlator组成的树,在树中,xlator层层调用,在当服务器端挂载到客户端后,gluster会将树解析为一张图中,在此我们从图中xlator的初始化过程开始讲解。


客户端卷部分配置文件截图

在glusterfs中,当挂载到客户端时,客户端会将卷配置文件解析成graph,然后会发起对graph中每个节点的参数合法性检查,节点xlator的初始化等,在此处大概讲解一下:

首先将配置文件如v2-fuse.vol读取解析成一个图graph;

检查图的第一个节点卷类型是否为mount/fuse,即是否通过fuse实现的文件系统接口,如果不是将报错;

一些参数的合法性验证,及其对ctx初始化;

Graph中xlator节点参数合法性检查,如数据类型是否合法等等;然后初始化每个xlator;初始化成功后通知,父节点通知每个字节点就绪,子节点也会通知父节点等等;

由于该部分的分析会在其他部分由其他同事分析,此处不再详解;

graph的初始化

graph的初始化过程,其实就是遍历xlator树,依次调用它们的init函数的过程

trav = graph->first;

while (trav) {

                ret = xlator_init (trav);

                if (ret) {

                        gf_log (trav->name, GF_LOG_ERROR,

                                "initializing translator failed");

                        return ret;

                }

                trav = trav->next;

        }

 

从上面代码可以看出,一旦在调用任何一个xlator的init函数失败,则直接返回,即整棵树直接初始化失败。

 在函数xlator_init内部,其实就是调用对xlator的init的封装函数,如果初始化成功,置xl->init_succeeded = 1;

2.xlator之间的调用

     我们大家都知道Xlator形成树,每个xlator为这棵树中的节点,glusterfs要工作,就必然会涉及到节点之间的通信。

     通信主要包括2个方面,父节点调用子节点,子节点调用父节点,如当父节点向子节点发出写请求则要调用子节点的写操作,当子节点写操作完成后,会调用父节点的写回调操作。父子节点的调用关系可用下图说明:

Xlator调用关系图


     在glusterfs中,父子节点的通信通过3个主要的函数来完成STACK_WIND,STACK_UNWIND,STACK_UNWIND_STRICT,其中STACK_UNWIND,STACK_UNWIND_STRICT作用一样,接下来我们要分析到节点间调用关系的时候,只分析STACK_WIND和STACK_UNWIND_STRICT。

下面我们以dht部分的dht_writev与dht_writev_cbk两个方法为例,来说明这种调用关系。为了突出重点,我们只说明与父子节点调用关系相关的部分。

dht_writev父节点调用子节点:

STACK_WIND (frame, dht_writev_cbk,

                    subvol, subvol->fops->writev,

                    fd, vector, count, off, iobref);

 

代码说明:

frame:代表该xlator的frame,一个frame对象主要用于记录一个xlator与父子节点间的调用关系,比如记录其子节点的frame信息,父节点的frame信息。Frame相当于一个纽带,将原本独立的xlator的信息联系到了一起。

dht_writev_cbk:写操作的回调函数,该函数名会记录到子节点的frame的ret参数内部,用于当子节点调用父节点的回调函数;

subvol:子卷,即要调用的子节点对象;

subvol->fops->writev:调用的子节点的操作,此处为调用子节点的写操作;

fd:文件描述符,即对应的文件,在linux系统中,文件描述符这个概念一般针对打开的文件或者文件夹。

Vector:io流,真实的数据存储在该集合内部;

Count:vector数据集合内的元素个数;

Off:偏移量

 

然后进入STACK_WIND函数分析:

宏定义头

#defineSTACK_WIND(frame, rfn, obj, fn, params ...)  

宏定义重要片段

                typeof(fn##_cbk) tmp_cbk = rfn;                         \

                _new->root = frame->root;                               \

                _new->next = frame->root->frames.next;                  \

                _new->prev = &frame->root->frames;                      \

                if (frame->root->frames.next)                           \

                        frame->root->frames.next->prev = _new;          \

                frame->root->frames.next = _new;                        \

                _new->this = obj;       &

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值