代码版本:
VRRP 状态机 VRRP_FSM
1 2 3 4 5 6 7 8 9 10 11 12 13 struct { void (*read) (vrrp_rt *, char *, int ); void (*read_to) (vrrp_rt *); } VRRP_FSM[VRRP_MAX_FSM_STATE + 1 ] = { {NULL , NULL }, {vrrp_backup, vrrp_goto_master}, {vrrp_leave_master, vrrp_master}, {vrrp_leave_fault, vrrp_fault}, {vrrp_become_master, vrrp_goto_master} };
VRRP FSM Macro 1 2 3 4 5 6 7 8 9 10 11 12 #define VRRP_FSM_READ_TO(V) \ do { \ if ((*(VRRP_FSM[(V)->state].read_to))) \ (*(VRRP_FSM[(V)->state].read_to)) (V); \ } while (0) #define VRRP_FSM_READ(V, B, L) \ do { \ if ((*(VRRP_FSM[(V)->state].read))) \ (*(VRRP_FSM[(V)->state].read)) (V, B, L); \ } while (0)
VRRP_TSM 当某个 VRRP 实例发生状态变更,且需要与其同步组(sync group)内的其他实例进行协调时,将使用 VRRP_TSM 。
使用方式可以理解为:VRRP_TSM[from_state][to_state]
1 2 3 4 5 6 7 8 9 10 struct { void (*handler) (vrrp_rt *); } VRRP_TSM[VRRP_MAX_TSM_STATE + 1 ][VRRP_MAX_TSM_STATE + 1 ] = { { {NULL }, {NULL }, {NULL }, {NULL } }, { {NULL }, {vrrp_sync_master_election}, {vrrp_sync_master}, {vrrp_sync_fault} }, { {NULL }, {vrrp_sync_backup}, {vrrp_sync_master}, {vrrp_sync_fault} }, { {NULL }, {vrrp_sync_backup}, {vrrp_sync_master}, {vrrp_sync_fault} } };
VRRP TSM Macro 1 2 3 4 5 6 7 #define VRRP_TSM_HANDLE(S,V) \ do { \ if ((V)->sync && \ S != VRRP_STATE_GOTO_MASTER) \ if ((*(VRRP_TSM[S][(V)->state].handler))) \ (*(VRRP_TSM[S][(V)->state].handler)) (V); \ } while (0)
状态图
初始化期间,从 INIT(初始化)状态开始
若所有检查均通过,则转换至 BACKUP(备份)状态
若未从优先级更高的主用(MASTER)设备接收到通告消息,则转换至 MASTER(主用)状态
若接收到优先级更高的通告消息,则转换至 BACKUP(备份)状态
若任何被跟踪的资源发生故障,则转换至 FAULT(故障)状态
当故障条件清除后,返回至 BACKUP(备份)状态
INIT 状态 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 static void vrrp_init_state (list l) { for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) { vrrp = ELEMENT_DATA(e); if (vrrp->priority == VRRP_PRIO_OWNER || vrrp->wantstate == VRRP_STATE_MAST) { vrrp->state = VRRP_STATE_GOTO_MASTER; } else { vrrp->ms_down_timer = 3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp); vrrp->state = VRRP_STATE_BACK; } } }
BACKUP 状态
当处于 BACKUP(备份)状态时,该实例会设置一个 master_down_timer(主用设备下线计时器)。
每当从优先级更高的主用(MASTER)设备接收到有效的通告消息(advertisement)时,此计时器就会重置。
若计时器超时(即在超时周期内未接收到任何通告消息),该实例将转换至 MASTER(主用)状态。
1 2 3 4 5 6 7 8 9 10 11 static int vrrp_dispatcher_read_to (int fd) { prev_state = vrrp->state; VRRP_FSM_READ_TO(vrrp); VRRP_TSM_HANDLE(prev_state, vrrp); }
MASTER 状态
拥有并维护虚拟 IP 地址(VIPs)。
按照配置的时间间隔发送定期的 VRRP 通告消息。
处理接收的 VRRP 通告消息,若接收到优先级更高的通告消息,该实例将转换至 BACKUP 状态。
1 2 3 4 5 6 7 static void vrrp_master (vrrp_rt * vrrp) { if (vrrp->state == VRRP_STATE_MAST) { vrrp_state_master_tx(vrrp, 0 ); } }
FAULT 状态 由于出现错误条件,该 VRRP 实例无法以 MASTER(主用)或 BACKUP(备份)状态正常运行。
keepalived