hyperv 发表于 2019-2-1 10:22:28

GlusterFS初始化过程分析

  其实整个glusterfs的初始化过程就是这4个进程(gluster、glusterd、glusterfs和glusterfsd)的初始化过程,下面就详细说明下这4个进程的初始化过程。
  整个glusterfs的代码目录结构截图如下:
  图3:
http://blog.运维网.com/e/u261/themes/default/images/spacer.gif
  一、gluster进程的初始化过程:
  gluster作为一个cli命令执行工具,初始化代码位于glusterfs/cli/Src/cli.c的main函数里面,具体初始化过程为:
  ①Cli开始:全局变量的初始化包括glusterfs_ctx, global_xlator, gf_mem_acct_enable等
  ②命令行参数解析:解析命令行参数并存到state里,这里主要包括参数的格式和合法性进行判断
  ③Rpc初始化:这里主要初始化rpc通信环境,注册epoll读写事件和相应的处理函数。值得注意的是这里也注册了rpc请求通知函数(在glusterd中会调用),具体的rpc通信协议有不了解的自行脑补吧!
  ④注册命令:这里会将所有的命令和其对应的回调函数迚行注册,这里主要分为4类注册命令:cli_cmd_volume_register、cli_cmd_probe_register、cli_cmd_system_register和cli_cmd_misc_register其格式如下(跟进入gluster后我们输入的命令完全一样):
  ⑤接收命令并执行(即我们输入命令后的处理过程):
  a)如果存在有效的命令行参数,则创建新线程进行处理。
  b)如果没有命令行参数,则等待用户交互式输入命令。用户输入命令后,则对命令迚行解析,若无误,则创建新线程进行处理。
  c)在新线程中根据解析的命令查询并调用相应的回调函数,如上面命令的回调函数为:cli_cmd_colume_add_brick_cbk;
  处理完成后整个gluster进程即 初始化完成,也能够开始接收命令进行处理了;
  整个代码如下:
  图4:
http://blog.运维网.com/e/u261/themes/default/images/spacer.gif
  二、glusterd的初始化过程:
  Glusterd的主要负责管理daemon进程和处理gluster 发送过来的请求,其初始化代码应该是在(笔者自己理解的,不确定对否):glusterfs/glusterfsd/src/Glusterfsd.c的main函数,具体初始化过程为:
  ①glusterfs_globals_init()//初始化全局变量
  ②glusterfs_ctx_defaults_init(ctx)//初始化ctx缺省参数
  ③parse_cmdline(argc, argv, ctx)//解析命令行参数
  ④logging_init(ctx)//初始化日志
  ⑤create_fuse_mount(ctx)//这里不处理,直接返回
  ⑥daemonize(ctx)//根据是否debug等参数,确定进入前台或后台运行模式
  ⑦glusterfs_volumes_init(ctx)//负责创建监听端口,与监听端口建立连接,或通过RPC从daemon上获取卷配置信息等工作
  ⑧event_dispatch(ctx->event_pool)//监听事件池中注册的句柄,并调用事件池中注册的函数处理(通过rpc协议获得对应的请求,来触发对应的事件)!这样,整个glusterd的初始化完成。
  图5:
http://blog.运维网.com/e/u261/themes/default/images/spacer.gif
  三、glusterfsd的初始化过程:
  Glusterfsd作为服务进程,主要根据卷配置信息执行从glusterfs发送过来的请求,同时也负责glusterd的请求处理;其初始化代码跟glusterd的初始化代码在一个位置,即:glusterfs/glusterfsd/src/Glusterfsd.c的main函数,具体初始化过程为:
  ①glusterfs_globals_init()//初始化全局变量;
  ②glusterfs_ctx_defaults_init(ctx)//初始化ctx缺省参数;
  ③parse_cmdline(argc, argv, ctx)//解析命令行参数;
  ④logging_init(ctx)//初始化日志;
  ⑤create_fuse_mount(ctx)//这里不处理,直接返回;
  ⑥daemonize(ctx)//根据是否debug等参数,确定进入前台或后台运行模式;
  ⑦glusterfs_volumes_init(ctx)//创建brick监听端口,同daemon建立连接获取相关brick配置信息;
  ⑧event_dispatch(ctx->event_pool)//调用创建socket时候注册的事件处理函数处理事件,这里的事件包括glusterd进程发过来的事件和glusterfs进程发过来的事件,具体见后面的业务处理流程!
  这样,整个glusterfsd的初始化完成,整个初始化代码如图5。
  四、glusterfs的初始化过程:
  Glusterfs作为客户端的进程,根据卷配置信息将fuse发过来的操作请求逐层传递到最底层的protocol/client的xlator上,该xlator通过rpc与glusterfs连接,将请求发送到glusterfsd服务器执行;其初始化代码跟glusterd的初始化代码在一个位置,即:glusterfs/glusterfsd/src/Glusterfsd.c的main函数,具体初始化过程为:
  ①glusterfs_globals_init()//初始化全局变量;
  ②glusterfs_ctx_defaults_init(ctx)//初始化ctx缺省参数;
  ③parse_cmdline(argc, argv, ctx)//解析命令行参数;
  ④logging_init(ctx)//初始化日志;
  ⑤create_fuse_mount(ctx)//该根据mount 时候的参数,判断是否有mount point,如果有创建一个translator结构体,并初始化。
  ⑥daemonize(ctx)//这里不处理,直接返回;
  ⑦glusterfs_volumes_init(ctx)//利用rpc的sokcet库与glusterfs的damon建立连接,获取卷信息文件,初始化client端的translator 并初始化,注册事件处理函数。
  ⑧event_dispatch(ctx->event_pool)//监听注册事件处理函数的文件句柄。进入监听socket 过程,首先监听socket 建立连接事件,启动fuse 的while 循环进入客户端工作流程。
  这样,整个glusterfs的初始化完成,整个初始化代码如图5。
  这里重点说明下translator 的初始化过程:
  根据配置文件创建树,创建一个xlator后即进行初始化工作,主要是调用每个xlator的init函数(初始化的一个很重要工作就是根据xlator_fops来对事件进行注册,方便后面进行处理)。再来看看整个fops的结构体,下面是以afr模块来进行举例说明的:
  struct xlator_fops fops = {
  .lookup      = afr_lookup,查询指定的目录(这里是将请求发向所有的节点)
  .open      = afr_open,以指定方式打开文件
  .lk          = afr_lk,
  .flush       = afr_flush, 将文件从内存写到磁盘
  .statfs      = afr_statfs, 搜集磁盘的容量状态
  .fsync       = afr_fsync,
  .fsyncdir    = afr_fsyncdir,
  .xattrop   = afr_xattrop,
  .fxattrop    = afr_fxattrop,
  .inodelk   = afr_inodelk,
  .finodelk    = afr_finodelk,
  .entrylk   = afr_entrylk,
  .fentrylk    = afr_fentrylk,
  /* inode read */
  .access      = afr_access, 检查调用进程是否可以对指定的文件执行某种操作
  .stat      = afr_stat, 通过文件名获取文件的信息
  .fstat       = afr_fstat, 以fd的方式来获取文件的信息
  .readlink    = afr_readlink,读取链接文件
  .getxattr    = afr_getxattr, 以路径参数得到对应文件扩展属性
  .fgetxattr   = afr_fgetxattr,以fs作为参数得到对应文件扩展属性
  .readv       = afr_readv,读取对应文件内容
  /* inode write */
  .writev      = afr_writev,写文件
  .truncate    = afr_truncate, 以路径参数改变和修辞文件的大小
  .ftruncate   = afr_ftruncate,以fd参数改变和修辞文件的大小
  .setxattr    = afr_setxattr, 以路径参数设置文件的扩展属性
  .fsetxattr   = afr_fsetxattr,以fd参数设置文件的扩展属性
  .setattr   = afr_setattr, 以路径参数设置文件的属性
  .fsetattr    = afr_fsetattr, 以fd参数设置文件的属性
  .removexattr = afr_removexattr,以路径参数删除文件的扩展属性
  .fremovexattr = afr_fremovexattr,以fd参数删除文件的扩展属性
  /* dir read */
  .opendir   = afr_opendir,打开目录
  .readdir   = afr_readdir,读取目录
  .readdirp    = afr_readdirp,读取目录
  /* dir write */
  .create      = afr_create,以指定的格式创建文件
  .mknod       = afr_mknod, 创建文件,主要是fifo文件
  .mkdir       = afr_mkdir,创建目录
  .unlink      = afr_unlink, 删除目录项,并且减少一个链接数
  .rmdir       = afr_rmdir, 删除目录
  .link      = afr_link, 创建硬链接
  .symlink   = afr_symlink, 创建软链接
  .rename      = afr_rename, 重命名文件
  };
  整个fops即我们后面要处理的对应事件的函数(包括对应的cbk回调函数),xlator的初始化即主要通过fops来对事件进行注册,方便后面进行处理。
  Ok,整个初始化工作基本上完成,初始化完成后,整个树的结构以及对应的注册函数都已经形成,后面就开始进入到事件处理过程。
  转自:http://blog.csdn.net/york_1986/article/details/38864789

页: [1]
查看完整版本: GlusterFS初始化过程分析