Glusterfs使用了xlator模块化架构,用户可以通过编辑卷的配置文件来自定义xlator的结构。下面本人结合源码,说说从配置文件构建xlator结构的流程。
首先要说明的是glusterfs根据执行程序名字的不同,有三种启动方式:glusterd, server , client, 具体可见函数glusterfsd/src/glusterfsd.c:gf_get_process_mode
static uint8_t gf_get_process_mode (char *exec_name) { char *dup_execname = NULL, *base = NULL; uint8_t ret = 0; dup_execname = gf_strdup (exec_name); base = basename (dup_execname); if (!strncmp (base, "glusterfsd", 10)) { ret = GF_SERVER_PROCESS; } else if (!strncmp (base, "glusterd", 8)) { ret = GF_GLUSTERD_PROCESS; } else { ret = GF_CLIENT_PROCESS; } GF_FREE (dup_execname); return ret; }
然后请跳到glusterfsd/src/glusterfsd.c: main 函数,它是glusterfs的入口函数。
之后有glusterfs_volumes_init 这样一个函数, 我们将从这个函数分析起
int glusterfs_volumes_init (glusterfs_ctx_t *ctx) { FILE *fp = NULL; cmd_args_t *cmd_args = NULL; int ret = 0; cmd_args = &ctx->cmd_args; if (cmd_args->sock_file) { ret = glusterfs_listener_init (ctx); if (ret) goto out; } //如果在启动的时候指定volfile_server(意味着启动的是client),将会返回。 if (cmd_args->volfile_server) { ret = glusterfs_mgmt_init (ctx); /* return, do not emancipate() yet */ return ret; } //获得cmd_args->volfile文件的fp fp = get_volfp (ctx); if (!fp) { gf_log ("glusterfsd", GF_LOG_ERROR, "Cannot reach volume specification file"); ret = -1; goto out; } //解析volfile文件,构建xlator结构 ret = glusterfs_process_volfp (ctx, fp); if (ret) goto out; out: emancipate (ctx, ret); return ret; }
下面进入glusterfs_process_volfp函数:
int glusterfs_process_volfp (glusterfs_ctx_t *ctx, FILE *fp) { glusterfs_graph_t *graph = NULL; int ret = -1; xlator_t *trav = NULL; //glusterfs使用flex和bison为volfile发明了一种简单的编程语言 //这个函数定义在libglusterfs/src/y.tab.c 中 graph = glusterfs_graph_construct (fp); if (!graph) { gf_log ("", GF_LOG_ERROR, "failed to construct the graph"); goto out; } //如果有fuse xlator在volfile中,则报错返回。 for (trav = graph->first; trav; trav = trav->next) { if (strcmp (trav->type, "mount/fuse") == 0) { gf_log ("glusterfsd", GF_LOG_ERROR, "fuse xlator cannot be specified " "in volume file"); goto out; } } ret = glusterfs_graph_prepare (graph, ctx); if (ret) { glusterfs_graph_destroy (graph); goto out; } ret = glusterfs_graph_activate (graph, ctx); if (ret) { glusterfs_graph_destroy (graph); goto out; } gf_log_volume_file (fp); ret = 0; out: if (fp) fclose (fp); if (ret && !ctx->active) { /* there is some error in setting up the first graph itself */ cleanup_and_exit (0); } return ret; }