如果配置的instance的初始优先级是255的话, 则不受track weight的影响. 见vrrp_update_priority函数的内容.
1. keepalived/vrrp/vrrp_scheduler.c
/* if run after vrrp_init_state(), it will be able to detect scripts that
* have been disabled because of a sync group and will avoid to start them.
*/
static void
vrrp_init_script(list l)
{
vrrp_script_t *vscript;
element e;
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
vscript = ELEMENT_DATA(e);
if (vscript->inuse == 0)
vscript->result = VRRP_SCRIPT_STATUS_DISABLED;
if (vscript->result == VRRP_SCRIPT_STATUS_INIT) {
vscript->result = vscript->rise - 1; /* one success is enough */ // 初始化过程中设置result=rise-1
thread_add_event(master, vrrp_script_thread, vscript, vscript->interval);
} else if (vscript->result == VRRP_SCRIPT_STATUS_INIT_GOOD) {
vscript->result = vscript->rise; /* one failure is enough */ // 初始化成功, 设置result=rise
thread_add_event(master, vrrp_script_thread, vscript, vscript->interval);
}
}
}
static int
vrrp_script_child_thread(thread_t * thread)
{
int wait_status;
vrrp_script_t *vscript = THREAD_ARG(thread);
if (thread->type == THREAD_CHILD_TIMEOUT) {
pid_t pid;
pid = THREAD_CHILD_PID(thread);
/* The child hasn't responded. Kill it off. */
if (vscript->result > vscript->rise) {
vscript->result--;
} else {
if (vscript->result == vscript->rise)
log_message(LOG_INFO, "VRRP_Script(%s) timed out", vscript->sname);
vscript->result = 0; // 初始化时, 脚本调用超时, 将result改成0(最小)
}
kill(pid, SIGTERM);
thread_add_child(thread->master, vrrp_script_child_timeout_thread,
vscript, pid, 2);
return 0;
}
wait_status = THREAD_CHILD_STATUS(thread);
if (WIFEXITED(wait_status)) {
int status;
status = WEXITSTATUS(wait_status); // 脚本返回值为0, 表示执行成功, 非0表示失败.
if (status == 0) {
/* success */
if (vscript->result < vscript->rise - 1) { // result < rise-1, 表示当前还是KO状态
vscript->result++; // KO状态下, 调用成功则result+1.
} else {
if (vscript->result < vscript->rise) // result = rise 表示当前是KO状态转变成OK状态
log_message(LOG_INFO, "VRRP_Script(%s) succeeded", vscript->sname);
vscript->result = vscript->rise + vscript->fall - 1; // 脚本从failed状态转变到success状态后, 直接把result改成最大.
}
} else {
/* failure */
if (vscript->result > vscript->rise) { // result > rise, 表示当前是OK状态
vscript->result--; //OK状态下, 脚本调用失败的话, result-1.
} else {
if (vscript->result >= vscript->rise) // result=rise, 表示当前是OK状态转变成KO状态
log_message(LOG_INFO, "VRRP_Script(%s) failed", vscript->sname);
vscript->result = 0; // 脚本从success状态转变到failed状态后, 直接把result改到最小.
}
}
}
return 0;
}
/* Update VRRP effective priority based on multiple checkers.
* This is a thread which is executed every adver_int.
*/
static int
vrrp_update_priority(thread_t * thread)
{
vrrp_t *vrrp = THREAD_ARG(thread);
int prio_offset, new_prio;
/* compute prio_offset right here */
prio_offset = 0;
/* Now we will sum the weights of all interfaces which are tracked. */
if ((!vrrp->sync || vrrp->sync->global_tracking) && !LIST_ISEMPTY(vrrp->track_ifp))
prio_offset += vrrp_tracked_weight(vrrp->track_ifp);
/* Now we will sum the weights of all scripts which are tracked. */
if ((!vrrp->sync || vrrp->sync->global_tracking) && !LIST_ISEMPTY(vrrp->track_script))
prio_offset += vrrp_script_weight(vrrp->track_script);
if (vrrp->base_priority == VRRP_PRIO_OWNER) {
/* we will not run a PRIO_OWNER into a non-PRIO_OWNER */
vrrp->effective_priority = VRRP_PRIO_OWNER;
} else {
/* WARNING! we must compute new_prio on a signed int in order
to detect overflows and avoid wrapping. */
new_prio = vrrp->base_priority + prio_offset;
if (new_prio < 1)
new_prio = 1;
else if (new_prio > 254)
new_prio = 254;
vrrp->effective_priority = new_prio;
}
/* Register next priority update thread */
thread_add_timer(master, vrrp_update_priority, vrrp, vrrp->adver_int);
return 0;
}
2. keepalived/include/vrrp_track.h
/* VRRP script tracking results.
* The result is an integer between 0 and rise-1 to indicate a DOWN state,
* or between rise-1 and rise+fall-1 to indicate an UP state. Upon failure,
* we decrease result and set it to zero when we pass below rise. Upon
* success, we increase result and set it to rise+fall-1 when we pass above
* rise-1.
*/
#define VRRP_SCRIPT_STATUS_DISABLED -3
#define VRRP_SCRIPT_STATUS_INIT_GOOD -2
#define VRRP_SCRIPT_STATUS_INIT -1
/* external script we call to track local processes */
typedef struct _vrrp_script {
char *sname; /* instance name */
char *script; /* the command to be called */
long interval; /* interval between script calls */
long timeout; /* seconds before script timeout */
int weight; /* weight associated to this script */
int result; /* result of last call to this script: 0..R-1 = KO, R..R+F-1 = OK */
int inuse; /* how many users have weight>0 ? */
int rise; /* R: how many successes before OK */
int fall; /* F: how many failures before KO */
} vrrp_script_t;
/* Tracked script structure definition */
typedef struct _tracked_sc {
int weight; /* tracking weight when non-zero */
vrrp_script_t *scr; /* script pointer, cannot be NULL */
} tracked_sc_t;
[参考]