glusterd中的状态机浅析

当RPC请求到达Glusterd守护进程后, 它会根据rpcsvc_actor_t gd_svc_cli_actors[] 数组来选择相应的处理函数。


一般函数名为glusterd_handle_XXX 


这类函数一般负责从xdr中提取出请求数据,比如卷名,主机名等等。


然后调用glusterd_op_begin 或者其他函数 向请求队列里面注入事件(inject event)。


glusterd有两个状态机(state machine):  friend sm 和 operation sm ,

friend sm负责处理peer之间的事件

operation sm负责处理自身的事件


它们分别通过函数 glusterd_friend_sm ()和 glusterd_op_sm ()启动运行。两个队列 gd_friend_sm_queue和gd_op_sm_queue, 即为两个状态机的消息队列。


下面以glusterd_op_sm为例,介绍下状态机的原理,glusterd_friend_sm与之类似。

 

C代码  收藏代码

  1. //循环直到清空消息队列  

  2. while (!list_empty (&gd_op_sm_queue)) {  

  3.          //遍历消息队列  

  4.          list_for_each_entry_safe (event, tmp, &gd_op_sm_queue, list) {  

  5.                  //先从队列中去掉当前要处理的消息  

  6.                  list_del_init (&event->list);  

  7.   

  8.                  event_type = event->event;  

  9.                  ...  

  10.                  //获得当前状态的事件响应列表  

  11.                  state = glusterd_op_state_table[opinfo.state.state];  

  12.                  //根据事件响应表找到处理函数  

  13.                  handler = state[event_type].handler;  

  14.                  //执行处理函数  

  15.                  ret = handler (event, event->ctx);  

  16.   

  17.                 //处理完毕后,进行状态转移  

  18.                 opinfo->state.state = state[event_type].next_state  

  19.   

  20.                  //删除event以及其context  

  21.                  glusterd_destroy_op_event_ctx (event);  

  22.                  GF_FREE (event);  

  23.          }  

  24.  }  

 

其中,各种状态的事件响应函数表定义在xlators/mgmt/glusterd/src/glusterd-op-sm.c,应该是状态机中比较繁琐的部分,状态如何处理以及转换,都是由这些表定义的。

 

 

 

下面以命令 volume status 为例,介绍状态机执行流程。


当命令请求到达glusterd时候,会触发glusterd_handle_status_volume函数,它将解析请求参数,并将事件GD_OP_EVENT_START_LOCK注入gd_op_sm_queue。

 

然后,friend sm开始运行。我们假设gd_friend_sm_queue为空,那么这个函数就跳过了。

接着,op sm开始运行, 它会从gd_op_sm_queue取出我们刚注入的事件,根据当前的状态和事件类型选择相应的事件处理函数。

初始状态是Default,发送流程如下:


先发start-lock请求,

待所有peer都回复后,开始发送stage op请求, 

待所有peer都回复后,开始brick op请求。

待所有peer都回复后,开始commit op请求。

待所有peer都回复后,开始unlock op请求。

待所有peer都回复后,状态回到default。

 

Transitioning from 'Lock sent' to 'Lock sent' due to event 'GD_OP_EVENT_RCVD_ACC'

Transitioning from 'Lock sent' to 'Stage op sent' due to event 'GD_OP_EVENT_ALL_ACC'
Transitioning from 'Stage op sent' to 'Stage op sent' due to event 'GD_OP_EVENT_RCVD_ACC'

Transitioning from 'Stage op sent' to 'Brick op sent' due to event 'GD_OP_EVENT_STAGE_ACC'

Transitioning from 'Brick op sent' to 'Commit op sent' due to event 'GD_OP_EVENT_ALL_ACK'

Transitioning from 'Commit op sent' to 'Commit op sent' due to event 'GD_OP_EVENT_RCVD_ACC'

Transitioning from 'Commit op sent' to 'Unlock sent' due to event 'GD_OP_EVENT_COMMIT_ACC'
Transitioning from 'Unlock sent' to 'Unlock sent' due to event 'GD_OP_EVENT_RCVD_ACC'
Transitioning from 'Unlock sent' to 'Default' due to event 'GD_OP_EVENT_ALL_ACC'

转自:http://glusterfs.iteye.com/blog/1750921


你可能感兴趣的:(状态机,GlusterFS)