代码版本:

VRRP 状态机

VRRP_FSM

  • Read_to: read timeout
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] =
{
/* Stream Read Handlers | Stream Read_to handlers *
*------------------------------+------------------------------*/
{NULL, NULL},
{vrrp_backup, vrrp_goto_master}, /* BACKUP */
{vrrp_leave_master, vrrp_master}, /* MASTER */
{vrrp_leave_fault, vrrp_fault}, /* FAULT */
{vrrp_become_master, vrrp_goto_master} /* GOTO_MASTER */
};

VRRP FSM Macro

1
2
3
4
5
6
7
8
9
10
11
12
/* VRRP FSM Macro */
#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] =
{
/* From: To: > BACKUP MASTER FAULT */
/* v */ { {NULL}, {NULL}, {NULL}, {NULL} },
/* BACKUP */ { {NULL}, {vrrp_sync_master_election}, {vrrp_sync_master}, {vrrp_sync_fault} },
/* MASTER */ { {NULL}, {vrrp_sync_backup}, {vrrp_sync_master}, {vrrp_sync_fault} },
/* 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)

状态图

  1. 初始化期间,从 INIT(初始化)状态开始

  2. 若所有检查均通过,则转换至 BACKUP(备份)状态

  3. 若未从优先级更高的主用(MASTER)设备接收到通告消息,则转换至 MASTER(主用)状态

  4. 若接收到优先级更高的通告消息,则转换至 BACKUP(备份)状态

  5. 若任何被跟踪的资源发生故障,则转换至 FAULT(故障)状态

  6. 当故障条件清除后,返回至 BACKUP(备份)状态

INIT 状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/* Initialize state handling */
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 状态

  1. 当处于 BACKUP(备份)状态时,该实例会设置一个 master_down_timer(主用设备下线计时器)。

  2. 每当从优先级更高的主用(MASTER)设备接收到有效的通告消息(advertisement)时,此计时器就会重置。

  3. 若计时器超时(即在超时周期内未接收到任何通告消息),该实例将转换至 MASTER(主用)状态。

1
2
3
4
5
6
7
8
9
10
11
/* Handle dispatcher read timeout */
static int
vrrp_dispatcher_read_to(int fd)
{
/* Run the FSM handler */
prev_state = vrrp->state;
VRRP_FSM_READ_TO(vrrp); // vrrp_goto_master

/* handle instance synchronization */
VRRP_TSM_HANDLE(prev_state, vrrp);
}

MASTER 状态

  1. 拥有并维护虚拟 IP 地址(VIPs)。

  2. 按照配置的时间间隔发送定期的 VRRP 通告消息。

  3. 处理接收的 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