【GlusterFS学习之四】:自动在volfile中生成需要的xlator,glusterfsvolfile


      在上一篇文章中gluster xlator的设计中,讲到通过手动修改volfile来添加相应的xlator功能,但是实际上的需求是工程在建立好之后可以在创建卷的过程中自动在volfile中生成相应的xlator,本文将探讨这个问题。


一、volfile简介

      本文主要讨论的是gluster的volfile,那么还是主要了解一下volfile的定义和意义,有两篇文章可以阅读:

http://www.gluster.org/community/documentation/index.php/Understanding_vol-file

http://blog.sina.com.cn/s/blog_6a4c492f0100qm6v.html

在此之后,我还想说一下自己的理解和认识。

volfile的删除:卷的删除操作会造成volfile的删除,也就是执行gluster volume stop img和gluster volume delete img之后。

volfile的生成:volfile是server端在创建卷的时候生成的,也就是执行gluster volume create img之后生成的。

volfile的加载:volfile的加载是在glusterfsd服务器进程执行的时候进行的,而glusterfsd是在volume start的时候启动的(create了volume之后):gluster volume start img。

glusterfs,glusterd,glusterfsd,gluster的区别何在?还是想说一声自己的理解,望指正:
>glusterfs:client端挂载server端的卷以及在client端的相关操作 >glusterd:Gluster elastic volume management daemon。glusterd与卷管理有关系,而且代码集中在xlators/mgmt/glusterd/src下面。 >glusterfsd:start a glusterfs server,server端的进程启动。 >gluster:Gluster Concole Manager,to run the program and display gluster prompt

      过程了解了,还是要深入到代码里面才能有更加深刻的认识,还是要不断的阅读源代码。      


二、自动生成volfile添加内容

      在了解了volfile之后,我们讨论其自动生成的问题。同样,我们是需要在glusterfs中加入audit功能,及加入audit xlator,前一篇已经讲过如何编写audit的代码了,那么加入到glusterfs的源代码中只需要修改一些简单的编译文件路径即可,在此不多说,主要还是讲volfile相关的函数,主要有三个:

>glusterd-volgen.c:生成volfile函数

>glusterd-volgen.h

>glusterd-volume-set.c:volfile的option设置相关

我们来看gluster-volgen.c里面生成xlator graph的函数server_graph_builder:

static int
server_graph_builder (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
                      dict_t *set_dict, void *param)
{
        char                 *volname       = NULL;
        char                 *path          = NULL;
        int                   pump          = 0;
        xlator_t             *xl            = NULL;
        xlator_t             *txl           = NULL;
        xlator_t             *rbxl          = NULL;
        char      transt[16]                = {0,};
        char                 *ptranst       = NULL;
        char      volume_id[64]             = {0,};
        char      tstamp_file[PATH_MAX]     = {0,};
        int                   ret           = 0;
        char                 *xlator        = NULL;
        char                 *loglevel      = NULL;
        char                 *username      = NULL;
        char                 *password      = NULL;
        char     index_basepath[PATH_MAX]   = {0};
        char     key[1024]                  = {0};
        glusterd_brickinfo_t *brickinfo     = NULL;
        char changelog_basepath[PATH_MAX]   = {0,};
        gf_boolean_t          quota_enabled = _gf_true;
        gf_boolean_t          pgfid_feat    = _gf_false;
        char                 *value         = NULL;
        char                 *ssl_user      = NULL;

        brickinfo = param;
        path      = brickinfo->path;
        volname = volinfo->volname;
        get_vol_transport_type (volinfo, transt);

        ret = dict_get_str (set_dict, "xlator", &xlator);

        /* got a cli log level request */
        if (!ret) {
                ret = dict_get_str (set_dict, "loglevel", &loglevel);
                if (ret) {
                        gf_log ("glusterd", GF_LOG_ERROR, "could not get both"
                                " translator name and loglevel for log level request");
                        goto out;
                }
        }

        ret = glusterd_volinfo_get (volinfo, VKEY_FEATURES_QUOTA, &value);
        if (value) {
                ret = gf_string2boolean (value, "a_enabled);
                if (ret)
                        goto out;
        }

        xl = volgen_graph_add (graph, "storage/posix", volname);
        if (!xl)
                return -1;

        ret = xlator_set_option (xl, "directory", path);
        if (ret)
                return -1;

        ret = xlator_set_option (xl, "volume-id",
                                 uuid_utoa (volinfo->volume_id));
        if (ret)
                return -1;

        ret = check_and_add_debug_xl (graph, set_dict, volname,
                                      "posix");
        if (ret)
                return -1;

        xl = volgen_graph_add (graph, "features/access-control", volname);
        if (!xl)
                return -1;

        ret = check_and_add_debug_xl (graph, set_dict, volname, "acl");
        if (ret)
                return -1;

        xl = volgen_graph_add (graph, "features/locks", volname);
        if (!xl)
                return -1;

        ret = check_and_add_debug_xl (graph, set_dict, volname, "locks");
        if (ret)
                return -1;

        xl = volgen_graph_add (graph, "performance/io-threads", volname);
        if (!xl)
                return -1;

        ret = check_and_add_debug_xl (graph, set_dict, volname, "io-threads");
        if (ret)
                return -1;

        xl = volgen_graph_add (graph, "features/barrier", volname);
        if (!xl)
               return -1;

        xl = volgen_graph_add (graph, "features/quota", volname);
        if (!xl)
                return -1;
        ret = xlator_set_option (xl, "volume-uuid", volname);
        if (ret)
                return -1;

		/* add the audit xlator to the graph*/
        xl = volgen_graph_add(graph, "features/audit", volname);
        if(!xl)	
                return -1;	
			        ret = xlator_set_option (xl, "audit", "off");	
        if (ret)	
                return -1;

        /* Check for read-only volume option, and add it to the graph */
        if (dict_get_str_boolean (set_dict, "features.read-only", 0)){
                xl = volgen_graph_add (graph, "features/read-only", volname);
                if (!xl) {
                        ret = -1;
                        goto out;
                }
        }

        xl = volgen_graph_add_as (graph, "debug/io-stats", path);
        if (!xl)
                return -1;

        xl = volgen_graph_add (graph, "protocol/server", volname);
        if (!xl)
                return -1;
        ret = xlator_set_option (xl, "transport-type", transt);
        if (ret)
                return -1;
 out:
        return ret;
}
只是选择了主要的一部分代码来进行说明,可以看到server_graph_builder这个函数里面相关xlator的设置生成顺序和最后生成的volfile文件是一致的,主要就是两个函数将xlator添加到volfile中去:volgen_graph_add和xlator_set_option,一个是根据volname添加到graph中,另一个是则是设置相关的option。在代码的Line106~Line112中,添加了自己需要生成的xlator的代码,就完成了。当然还需要在glusterd-volgen.c这个文件中的get_server_xlator函数中加入相应代码:

static glusterd_server_xlator_t
get_server_xlator (char *xlator)
{
        glusterd_server_xlator_t subvol = GF_XLATOR_NONE;

        if (strcmp (xlator, "posix") == 0)
                subvol = GF_XLATOR_POSIX;
        if (strcmp (xlator, "acl") == 0)
                subvol = GF_XLATOR_ACL;
        if (strcmp (xlator, "locks") == 0)
                subvol = GF_XLATOR_LOCKS;
        if (strcmp (xlator, "io-threads") == 0)
                subvol = GF_XLATOR_IOT;
        if (strcmp (xlator, "index") == 0)
                subvol = GF_XLATOR_INDEX;
        if (strcmp (xlator, "marker") == 0)
                subvol = GF_XLATOR_MARKER;
        if (strcmp (xlator, "io-stats") == 0)
                subvol = GF_XLATOR_IO_STATS;
        if (strcmp (xlator, "bd") == 0)
                subvol = GF_XLATOR_BD;
	if (strcmp(xlator,"audit") == 0)
		subvol = GF_XLATOR_AUDIT;
        return subvol;
}
见Line22-Line23。至此,glusterd-volgen.c的代码添加修改完成。然后在glusterd-volgen.h头文件中添加宏:

#define VKEY_FEATURE_AUDTI "features.audit"
以及在glusterd_server_xlator_t结构体中加入:GF_XLATOR_AUDIT即可。

再看gluster-volume-set.c这个文件,它主要是对volfile中的xlator的option进行设置,在glusterd_volopt_map中添加代码:

{	
    .key   = "features.audit",
    .voltype     = "features/audit",	
    .op_version  = 1,
 },
最后修改一下audit.c中的volume_options:

 {
	 .key = {"audit"},
	 .type = GF_OPTION_TYPE_BOOL,
	 .default_value = "off",
 }
对Makefile进行简单的添加和修改之后就可以编译安装了,因为主要是操作server端,那么在server端进行。

首先先卸载:

make uninstall 
make distclean
编译安装:

./configure
make && make install
然后是重新启动glusterd进程,停止卷,删除卷,创建卷,启动卷,查看volfile。

service glusterd restart
gluster volume stop img
gluster volume delete img
gluster volume create img replica 2 10.23.85.48:/data/gluster 10.23.85.49:/data/gluster
gluster volume start img

创建volume的时候遇到两个问题:

1./data/gluster已经是volume的一部分,删除即可。

2.Peer Rejected,重新启动所有server的glusterd即可(解决方法)。

我们可以看一下创建好的volfile:



有一点需要特别注意的是,之前修改过代码之后编译安装,不断的删除卷,创建卷,启动卷重复做了很多遍,但是volfile中没有生成想要的xlator内容,以为是在卸载过程中没有卸载干净的原因,其实际原因是没有重新启动glusterd进程glusterd一直是老的进程(确切点说是尼玛半个月前启动的进程)。那么glusterd虽然在卸载编译之后更新了,但是我们没有重启glusterd服务,那么半个月前的老glusterd进程并不是修改过的源代码(也就是在glusterd-volgen.c中增加代码之前)编译得到的进程,因此,修改过的代码并没有起作用,那么无论我怎么创建create volume卷,执行的都是老的glusterd-volgen.c的代码流程,因此没有改变,仅仅只要restart glusterd服务就好了,执行的就是修改过的代码的流程,主要还是自己对问题理解不够深刻,对代码不够敏感。

下面我们再来看gluster volume set对问题的影响。我们设置了一个option,也就是开关,来控制这个xlator是否起作用,默认情况是off,那么我们就看看off和on之后的区别。

在默认off情况下(也就是没有进行启用audit操作),我们在客户端挂载运行,并在挂载点创建文件:aa,bb,cc,dd和文件夹:AA,BB,CC,DD,再进行删除aa和AA:

touch aa bb cc dd 
mkdir AA BB CC DD

可以看到server端的日志:


我们将audit功能启用:

gluster volume set img features.audit on

可以看到option值由off变成了on,说明启动了audit功能,那么现在重新启动glusterfsd,再进行删除文件bb和文件夹BB的操作,观察server端的日志情况。


可以清晰的看到,在开启audit功能之后,成功的实现了审查到了删除文件和文件夹的操作。



Author:忆之独秀

Email:leaguenew@qq.com

注明出处:http://blog.csdn.net/lavorange/article/details/45246175



相关内容