Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix issue: vrrp master switchover lead to disconnection of tcp connections #2255

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/source/configuration_synopsis.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ VRRP Instance Definitions Synopsis
**priority** num
**advert_int** num
**smtp_alert**
**exec_before_vip**
**authentication** {
**auth_type** *PASS|AH*
**auth_pass** string
Expand Down Expand Up @@ -185,6 +186,7 @@ notify_master specify a shell script to be executed during transit
notify_backup specify a shell script to be executed during transition to backup state path
notify_fault specify a shell script to be executed during transition to fault state path
vrrp_sync_group Identify the VRRP synchronization instances group string
exec_before_vip notify_master script executed before vip setted if this setted true
========================== ======================================================================= =========

Path type: A system path to a script eg: “/usr/local/bin/transit.sh <arg_list>”
3 changes: 2 additions & 1 deletion keepalived/include/vrrp.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,8 @@ typedef struct _vrrp_t {
notify_script_t *script_deleted;
notify_script_t *script_master_rx_lower_pri;
notify_script_t *script;
int notify_priority_changes;
int exec_before_vip; /* exec script_master first before set vip address */
int notify_priority_changes;

/* rfc2338.6.2 */
uint32_t ms_down_timer;
Expand Down
9 changes: 7 additions & 2 deletions keepalived/vrrp/vrrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1709,8 +1709,10 @@ vrrp_state_become_master(vrrp_t * vrrp)
vrrp->vmac_garp_timer = timer_add_now(vrrp->vmac_garp_intvl);
#endif

/* Check if notify is needed */
send_instance_notifies(vrrp);
if (!vrrp->exec_before_vip) {
/* Check if notify is needed */
send_instance_notifies(vrrp);
}

#ifdef _WITH_LVS_
/* Check if sync daemon handling is needed */
Expand Down Expand Up @@ -2026,6 +2028,9 @@ vrrp_state_master_tx(vrrp_t * vrrp)
if (!VRRP_VIP_ISSET(vrrp)) {
log_message(LOG_INFO, "(%s) Entering MASTER STATE"
, vrrp->iname);
if (vrrp->exec_before_vip) {
send_instance_notifies(vrrp);
}
vrrp_state_become_master(vrrp);
/*
* If we catch the master transition
Expand Down
3 changes: 2 additions & 1 deletion keepalived/vrrp/vrrp_notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ send_instance_notifies(vrrp_t *vrrp)
{
notify_script_t *script = get_iscript(vrrp);
notify_script_t *gscript = get_igscript(vrrp);
bool sync_exec = vrrp->state == VRRP_STATE_MAST && vrrp->exec_before_vip;

if (vrrp->notifies_sent && vrrp->sync && vrrp->state == vrrp->sync->state) {
/* We are already in the required state due to our sync group,
Expand All @@ -290,7 +291,7 @@ send_instance_notifies(vrrp_t *vrrp)
if (vrrp->state == VRRP_STATE_STOP)
system_call_script(master, child_killed_thread, NULL, TIMER_HZ, script);
else
notify_exec(script);
system_call_script_0(NULL, NULL, NULL, 0, script, sync_exec);
}

/* Launch the generic notify script */
Expand Down
18 changes: 17 additions & 1 deletion keepalived/vrrp/vrrp_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -1165,6 +1165,21 @@ vrrp_notify_handler(const vector_t *strvec)
current_vrrp->notify_exec = true;
}
static void
vrrp_script_exec_handler(const vector_t *strvec)
{
vrrp_t *vrrp = list_last_entry(&vrrp_data->vrrp, vrrp_t, e_list);
int res = true;

if (vector_size(strvec) >= 2) {
res = check_true_false(strvec_slot(strvec, 1));
if (res == -1) {
report_config_error(CONFIG_GENERAL_ERROR, "Invalid vrrp_group exec_before_vip parameter %s", strvec_slot(strvec, 1));
return;
}
}
vrrp->exec_before_vip = res;
}
static void
vrrp_notify_master_rx_lower_pri(const vector_t *strvec)
{
if (current_vrrp->script_master_rx_lower_pri) {
Expand Down Expand Up @@ -2159,7 +2174,8 @@ init_vrrp_keywords(bool active)
install_keyword("notify_stop", &vrrp_notify_stop_handler);
install_keyword("notify_deleted", &vrrp_notify_deleted_handler);
install_keyword("notify", &vrrp_notify_handler);
install_keyword("notify_master_rx_lower_pri", vrrp_notify_master_rx_lower_pri);
install_keyword("exec_before_vip", &vrrp_script_exec_handler);
install_keyword("notify_master_rx_lower_pri", vrrp_notify_master_rx_lower_pri);
install_keyword("smtp_alert", &vrrp_smtp_handler);
install_keyword("notify_priority_changes", &vrrp_notify_priority_changes_handler);
#ifdef _WITH_LVS_
Expand Down
16 changes: 16 additions & 0 deletions lib/notify.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <sys/resource.h>
#include <limits.h>
#include <sys/prctl.h>
#include <sys/wait.h>

#include "notify.h"
#include "signals.h"
Expand Down Expand Up @@ -151,6 +152,12 @@ cmd_str(const notify_script_t *script)

int
system_call_script(thread_master_t *m, thread_func_t func, void * arg, unsigned long timer, const notify_script_t* script)
{
return system_call_script_0(m, func, arg, timer, script, false);
}

int
system_call_script_0(thread_master_t *m, thread_func_t func, void * arg, unsigned long timer, const notify_script_t* script, bool sync_exec)
{
pid_t pid;
const char *str;
Expand All @@ -172,6 +179,15 @@ system_call_script(thread_master_t *m, thread_func_t func, void * arg, unsigned
}

if (pid) {
int wait_ret;
pid_t wait_pid;
if (sync_exec) {
wait_pid = waitpid(pid, &wait_ret, 0);
if (wait_pid != pid || !WIFEXITED(wait_ret)) {
log_message(LOG_INFO, "Failed wait script process completed");
return -1;
}
}
/* parent process */
if (func) {
thread_add_child(m, func, arg, pid, timer);
Expand Down
1 change: 1 addition & 0 deletions lib/notify.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ extern const char *cmd_str(const notify_script_t *);
extern void notify_fifo_open(notify_fifo_t*, notify_fifo_t*, thread_func_t, const char *);
extern void notify_fifo_close(notify_fifo_t*, notify_fifo_t*);
extern int system_call_script(thread_master_t *, thread_func_t, void *, unsigned long, const notify_script_t *);
extern int system_call_script_0(thread_master_t *, thread_func_t, void *, unsigned long, const notify_script_t *, bool);
extern int notify_exec(const notify_script_t *);
extern void child_killed_thread(thread_ref_t);
extern void script_killall(thread_master_t *, int, bool);
Expand Down