* keepalived-1.0.0 released.
* After fixed all bugs users reported during 2 months, I am glad to
announce the first STABLE production ready Keepalived release.
* Rename keepalived.init to keepalived RedHat startup script. Fixed
some issues to be RedHat release generic. Thanks go to
Jeroen Simonetti <jeroens@q-go.com> & Jason Gilbert <jason@doozer.com>
* Jason Gilbert, <jason@doozer.com> cleaned keepalived.spec.
* Added support to "ha_suspend" for healthcheckers. This option, if set,
inform Keepalived to active/suspend checkers according to netlink
IP address information reflection. If one IP is removed and this is
a virtual_server VIP then the healthcheckers corresponding will be
desactivated. (and reciprocity).
* Added support to "notify_up" & "notify_down" for realserver config.
These options specify a script to be run according to healthchecker
activity. If healthchecking fails then "notify_down" script is
launched (and reciprocity for healthcheck succeed). This can be
usefull for global monitoring system, to send alert to Unicenter TNG
or HPOV.
* Set default realserver weight to 1. So, realserver will be active
if no weight is specified into the configuration file.
* Review the layer4.c/tcp_socket_state to return connection in progress
only if SOL_SOCKET/SO_ERROR return EINPROGRESS. Thanks go to
Mark Weaver, <mark@npsl.co.uk>
* Reviewed the global SIGCHLD handler to not suspend execution of the
calling process if status is not immediately available for one of the
child processes. This remove zombies by reaping.
* Extended the parser.c/set_value() code to accept encapsulated quoted
string.
* Review SMTP DBG() message to LOG_INFO message for more verbose
error handling.
* Review the check_tcp.c/check_http.c logging messages to be more
detailed.
* Review the check_tcp.c/check_http.c retry facility to fixes some
stalled issues.
* VRRP : Added support to sync_group smtp notification in addition to
the per instances approach.
* VRRP : Fixed some IPSEC-AH seq_num synchronizations issues. Force
seq_num sync if vrrp instance is linked to a group.
* VRRP : In BACKUP state, force a new MASTER election is received adv.
has a lower priority as locale instance.
* VRRP : vrrp.c/vrrp_state_master_rx(), sync IPSEC-AH seq_num counter
(decrement) if receiving higher prio advert in MASTER state.
* VRRP : Reviewed the TSM to be fully filled. Extended speed-up
synchronization handling MASTER sync if group is not already synced.
* VRRP : Leaving fault state, force MASTER transition is received adv
priority is lower than locale.
* VRRP : Extended the parser to not be borred with sync_group
declaration position in the conf file. vrrp_sync_group can be
declared before or after vrrp_instance. Done by adding a reverse
instance lookup during parsing.
* VRRP : sync_master_election cleanup.
* Some cosmetics patches.
* Created the keepalived/samples/keepalived.conf.SYNOPSIS to describe
all keywords available.
+2003-01-06 Alexandre Cassen <acassen@linux-vs.org>
+ * keepalived-1.0.0 released.
+ * After fixed all bugs users reported during 2 months, I am glad to
+ announce the first STABLE production ready Keepalived release.
+ * Rename keepalived.init to keepalived RedHat startup script. Fixed
+ some issues to be RedHat release generic. Thanks go to
+ Jeroen Simonetti <jeroens@q-go.com> & Jason Gilbert <jason@doozer.com>
+ * Jason Gilbert, <jason@doozer.com> cleaned keepalived.spec.
+ * Added support to "ha_suspend" for healthcheckers. This option, if set,
+ inform Keepalived to active/suspend checkers according to netlink
+ IP address information reflection. If one IP is removed and this is
+ a virtual_server VIP then the healthcheckers corresponding will be
+ desactivated. (and reciprocity).
+ * Added support to "notify_up" & "notify_down" for realserver config.
+ These options specify a script to be run according to healthchecker
+ activity. If healthchecking fails then "notify_down" script is
+ launched (and reciprocity for healthcheck succeed). This can be
+ usefull for global monitoring system, to send alert to Unicenter TNG
+ or HPOV.
+ * Set default realserver weight to 1. So, realserver will be active
+ if no weight is specified into the configuration file.
+ * Review the layer4.c/tcp_socket_state to return connection in progress
+ only if SOL_SOCKET/SO_ERROR return EINPROGRESS. Thanks go to
+ Mark Weaver, <mark@npsl.co.uk>
+ * Reviewed the global SIGCHLD handler to not suspend execution of the
+ calling process if status is not immediately available for one of the
+ child processes. This remove zombies by reaping.
+ * Extended the parser.c/set_value() code to accept encapsulated quoted
+ string.
+ * Review SMTP DBG() message to LOG_INFO message for more verbose
+ error handling.
+ * Review the check_tcp.c/check_http.c logging messages to be more
+ detailed.
+ * Review the check_tcp.c/check_http.c retry facility to fixes some
+ stalled issues.
+ * VRRP : Added support to sync_group smtp notification in addition to
+ the per instances approach.
+ * VRRP : Fixed some IPSEC-AH seq_num synchronizations issues. Force
+ seq_num sync if vrrp instance is linked to a group.
+ * VRRP : In BACKUP state, force a new MASTER election is received adv.
+ has a lower priority as locale instance.
+ * VRRP : vrrp.c/vrrp_state_master_rx(), sync IPSEC-AH seq_num counter
+ (decrement) if receiving higher prio advert in MASTER state.
+ * VRRP : Reviewed the TSM to be fully filled. Extended speed-up
+ synchronization handling MASTER sync if group is not already synced.
+ * VRRP : Leaving fault state, force MASTER transition is received adv
+ priority is lower than locale.
+ * VRRP : Extended the parser to not be borred with sync_group
+ declaration position in the conf file. vrrp_sync_group can be
+ declared before or after vrrp_instance. Done by adding a reverse
+ instance lookup during parsing.
+ * VRRP : sync_master_election cleanup.
+ * Some cosmetics patches.
+ * Created the keepalived/samples/keepalived.conf.SYNOPSIS to describe
+ all keywords available.
+
2002-11-20 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.7.6 released.
* Created a common library for code modularization. This lib will
* Insert LDAP, FTP, SSH, IMAP, POP, RADIUS checkers.
* Add minimum configuration verification (realserver must have
a checker defined, ...)
-* VRRP : finish IPSEC-AH integration for seqnum synchronization when
- using vrrp_sync_group in fallback mode.
* documentation:
- hackers guide
- code documentation
* code cleanup:
- name space cleanup
- function returnval check
- - beautifull the genhash code
- check_ssl.c audit the password_cb() call back func
for buffer overflow.
- check smtp.c to release allocated buffer when terminate
-Summary: Generic HA monitor build upon VRRP and services poller, strongly recommanded for LVS HA.
Name: keepalived
+Summary: HA monitor built upon LVS, VRRP and services poller
Packager: Christophe Varoqui, <christophe.varoqui@free.fr>
-Version: 0.7.6
+Version: 1.0.0
Release: 1
-Source: http://www.keepalived.org/software/keepalived-0.7.6.tar.gz
+Source: http://www.keepalived.org/software/%{name}-%{version}.tar.gz
Copyright: GPL
-Group: Utilities/File
+Group: Applications/System
BuildRoot: /tmp/%{name}-%{version}.build
-BuildArchitectures: i386
+
+%define _exec_prefix /
%description
The main goal of the keepalived project is to add a strong & robust keepalive facility to the Linux Virtual Server project. This project is written in C with multilayer TCP/IP stack checks. Keepalived implements a framework based on three family checks : Layer3, Layer4 & Layer5. This framework gives the daemon the ability of checking a LVS server pool states. When one of the server of the LVS server pool is down, keepalived informs the linux kernel via a setsockopt call to remove this server entrie from the LVS topology. In addition keepalived implements a VRRPv2 stack to handle director failover. So in short keepalived is a userspace daemon for LVS cluster nodes healthchecks and LVS directors failover.
%prep
rm -rf %{buildroot}
-%setup -n keepalived-0.7.6
+%setup -q
%build
./configure --prefix=%{buildroot} --exec-prefix=%{buildroot} --sysconfdir=%{buildroot}/etc
make
%install
-make install
+rm -rf %{buildroot}
+%makeinstall
+
+%clean
+rm -rf %{buildroot}
+
+%post
+/sbin/chkconfig --add keepalived
+
+%preun
+/sbin/chkconfig --del keepalived
%files
%defattr(-,root,root)
-/bin/genhash
-/sbin/keepalived
-/etc/init.d/keepalived.init
-%config /etc/keepalived/keepalived.conf
-%config /etc/keepalived/samples/*
+%{_bindir}/genhash
+%{_sbindir}/keepalived
+%{_sysconfdir}/init.d/keepalived
+%dir %{_sysconfdir}/keepalived/
+%doc keepalived/samples
%doc AUTHOR CONTRIBUTORS TODO COPYING README INSTALL VERSION ChangeLog
+
+%changelog
+* Fri Dec 20 2002 Jason Gilbert <jason@doozer.com> 0.7.6-dzr1
+- Move the samples to be %doc instead of %config
+- Install the init script as 'keepalived' instead of 'keepalived.init'
+- Use the rpm %configure macro
+- No initial config file supplied in /etc/keepalived since it's hard to say what
+ a default config should be
install -d $(sbindir)
install -m 700 $(BIN)/$(EXEC) $(sbindir)/
install -d $(sysconfdir)/init.d
- install -m 755 $(init_script) $(sysconfdir)/init.d/
+ install -m 755 $(init_script) $(sysconfdir)/init.d/keepalived
install -d $(sysconfdir)/keepalived/samples
install -m 644 $(conf_file) $(sysconfdir)/keepalived/
install -m 644 samples/* $(sysconfdir)/keepalived/samples/
data.o: data.c ../include/data.h ../../lib/memory.h ../../lib/utils.h \
../include/check_api.h ../include/vrrp.h ../include/vrrp_sync.h
parser.o: parser.c ../include/parser.h ../../lib/memory.h ../include/vrrp.h \
- ../include/vrrp_if.h ../include/check_api.h
+ ../include/vrrp_if.h ../include/vrrp_sync.h ../include/check_api.h
layer4.o: layer4.c ../include/layer4.h ../include/check_api.h ../../lib/utils.h
smtp.o: smtp.c ../include/smtp.h ../../lib/memory.h ../../lib/list.h \
../../lib/utils.h
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: main.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
umask(0);
return 0;
}
-
-/* Close all FDs >= a specified value */
-void
-closeall(int fd)
-{
- int fdlimit = sysconf(_SC_OPEN_MAX);
- while (fd < fdlimit)
- close(fd++);
-}
-
-/* perform a system call */
-int
-system_call(char *cmdline)
-{
- int retval;
-
- retval = system(cmdline);
-
- if (retval == 127) {
- /* couldn't exec command */
- syslog(LOG_ALERT, "Couldn't exec command: %s", cmdline);
- } else if (retval == -1) {
- /* other error */
- syslog(LOG_ALERT, "Error exec-ing command: %s", cmdline);
- } else {
- /* everything is good */
- DBG("Successfully exec command: %s retval is %d",
- cmdline, retval);
- }
-
- return retval;
-}
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: data.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
if (vgroup->script_fault)
syslog(LOG_INFO, " Fault state transition script = %s",
vgroup->script_fault);
+ if (vgroup->smtp_alert)
+ syslog(LOG_INFO, " Using smtp notification");
}
static void
inet_ntop2(vs->granularity_persistence));
syslog(LOG_INFO, " protocol = %s",
(vs->service_type == IPPROTO_TCP) ? "TCP" : "UDP");
+ if (vs->ha_suspend)
+ syslog(LOG_INFO, " Using HA suspend");
switch (vs->loadbalancing_kind) {
#ifdef _WITH_LVS_
free_rs(void *data)
{
real_server *rs = data;
+ FREE_PTR(rs->notify_up);
+ FREE_PTR(rs->notify_down);
FREE(rs);
}
static void
, rs->weight);
if (rs->inhibit)
syslog(LOG_INFO, " -> Inhibit service on failure");
+ if (rs->notify_up)
+ syslog(LOG_INFO, " -> Notify script UP = %s",
+ rs->notify_up);
+ if (rs->notify_down)
+ syslog(LOG_INFO, " -> Notify script DOWN = %s",
+ rs->notify_down);
}
void
inet_ston(ip, &new->addr_ip);
new->addr_port = htons(atoi(port));
+ new->weight = 1;
if (LIST_ISEMPTY(vs->rs))
vs->rs = alloc_list(free_rs, dump_rs);
* Part: Layer4 checkers handling. Register worker threads &
* upper layer checkers.
*
- * Version: $Id: layer4.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: layer4.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* and other error code until connection is established.
* Recompute the write timeout (or pending connection).
*/
- if (status != 0) {
+ if (status == EINPROGRESS) {
DBG("TCP connection to [%s:%d] still IN_PROGRESS.",
inet_ntop2(addr_ip), ntohs(addr_port));
THREAD_ARG(thread)
, thread->u.fd, TIMER_SEC(timer_min));
return connect_in_progress;
+ } else if (status != 0) {
+ close(thread->u.fd);
+ return connect_error;
}
return connect_success;
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: main.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
thread_add_terminate_event(master);
}
-/* SIGCHLD handler */
+/*
+ * SIGCHLD handler. Reap any zombie child.
+ * WNOHANG prevent against parent process get
+ * stuck waiting child termination.
+ */
void
sigchld(int sig)
{
- int child;
- wait(&child);
+ waitpid(-1, NULL, WNOHANG);
}
/* Signal wrapper */
* data structure representation the conf file representing
* the loadbalanced server pool.
*
- * Version: $Id: parser.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: parser.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "memory.h"
#include "vrrp.h"
#include "vrrp_if.h"
+#include "vrrp_sync.h"
#include "check_api.h"
/* global defs */
int i = 0;
int len = 0;
char *alloc = NULL;
+ char *tmp;
if (*str == '"') {
for (i = 2; i < VECTOR_SIZE(strvec); i++) {
else {
alloc =
REALLOC(alloc, sizeof (char *) * (len + 1));
- strncat(alloc, " ", 1);
+ tmp = VECTOR_SLOT(strvec, i-1);
+ if (*str != '"' && *tmp != '"')
+ strncat(alloc, " ", 1);
}
- if (*str != '"')
+
+ if (i != VECTOR_SIZE(strvec)-1)
strncat(alloc, str, strlen(str));
}
} else {
{
vrrp_sgroup *vgroup = LIST_TAIL_DATA(conf_data->vrrp_sync_group);
vgroup->iname = read_value_block();
+ vrrp_sync_set_group(vgroup);
}
static void
vrrp_gnotify_backup_handler(vector strvec)
vgroup->notify_exec = 1;
}
static void
+vrrp_gsmtp_handler(vector strvec)
+{
+ vrrp_sgroup *vgroup = LIST_TAIL_DATA(conf_data->vrrp_sync_group);
+ vgroup->smtp_alert = 1;
+}
+static void
vrrp_handler(vector strvec)
{
alloc_vrrp(VECTOR_SLOT(strvec, 1));
vector vips = read_value_block();
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
int i;
- int nbvip = 0;
+ int nbvip = VECTOR_SIZE(vips);
if (VECTOR_SIZE(vips) > VRRP_MAX_VIP) {
syslog(LOG_INFO,
syslog(LOG_INFO,
" => Declare another VRRP instance to handle all the VIPs");
nbvip = VRRP_MAX_VIP;
- } else
- nbvip = VECTOR_SIZE(vips);
+ }
for (i = 0; i < nbvip; i++)
alloc_vrrp_vip(VECTOR_SLOT(vips, i));
vs->service_type = (!strcmp(str, "TCP")) ? IPPROTO_TCP : IPPROTO_UDP;
}
static void
+hasuspend_handler(vector strvec)
+{
+ virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
+ vs->ha_suspend = 1;
+}
+static void
virtualhost_handler(vector strvec)
{
virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
real_server *rs = LIST_TAIL_DATA(vs->rs);
rs->inhibit = 1;
}
+static void
+notify_up_handler(vector strvec)
+{
+ virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
+ real_server *rs = LIST_TAIL_DATA(vs->rs);
+ rs->notify_up = set_value(strvec);
+}
+static void
+notify_down_handler(vector strvec)
+{
+ virtual_server *vs = LIST_TAIL_DATA(conf_data->vs);
+ real_server *rs = LIST_TAIL_DATA(vs->rs);
+ rs->notify_down = set_value(strvec);
+}
/* Real Servers Groups for VS handlers */
static void
install_keyword("notify_backup", &vrrp_gnotify_backup_handler);
install_keyword("notify_master", &vrrp_gnotify_master_handler);
install_keyword("notify_fault", &vrrp_gnotify_fault_handler);
+ install_keyword("smtp_alert", &vrrp_gsmtp_handler);
install_keyword_root("vrrp_instance", &vrrp_handler);
install_keyword("state", &vrrp_state_handler);
install_keyword("interface", &vrrp_int_handler);
install_keyword("persistence_timeout", &pto_handler);
install_keyword("persistence_granularity", &pgr_handler);
install_keyword("protocol", &proto_handler);
+ install_keyword("ha_suspend", &hasuspend_handler);
install_keyword("virtualhost", &virtualhost_handler);
/* Real server mapping */
install_sublevel();
install_keyword("weight", &weight_handler);
install_keyword("inhibit_on_failure", &inhibit_handler);
+ install_keyword("notify_up", ¬ify_up_handler);
+ install_keyword("notify_down", ¬ify_down_handler);
/* Checkers mapping */
install_checkers_keyword();
*
* Part: pidfile utility.
*
- * Version: $Id: pidfile.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: pidfile.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* using the smtp protocol according to the RFC 821. A non blocking
* timeouted connection is used to handle smtp protocol.
*
- * Version: $Id: smtp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: smtp.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
{
smtp_thread_arg *smtp_arg = THREAD_ARG(thread);
- DBG("SMTP connection ERROR to [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "SMTP connection ERROR to [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
free_smtp_all(smtp_arg);
return 0;
}
{
smtp_thread_arg *smtp_arg = THREAD_ARG(thread);
- DBG("Timeout connecting SMTP server [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Timeout connecting SMTP server [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
free_smtp_all(smtp_arg);
return 0;
}
{
smtp_thread_arg *smtp_arg = THREAD_ARG(thread);
- DBG("Remote SMTP server [%s:%d] connected.",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Remote SMTP server [%s:%d] connected.",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
smtp_arg->stage = connect_success;
thread_add_read(thread->master, smtp_read_thread, smtp_arg,
smtp_arg = THREAD_ARG(thread);
if (thread->type == THREAD_READ_TIMEOUT) {
- DBG("Timeout reading data to remote SMTP server [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Timeout reading data to remote SMTP server [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
SMTP_FSM_READ(QUIT, thread, 0);
return -1;
}
if (rcv_buffer_size == -1) {
if (errno == EAGAIN)
goto end;
- DBG("Error reading data from remote SMTP server [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Error reading data from remote SMTP server [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
SMTP_FSM_READ(QUIT, thread, 0);
return 0;
}
/* received data overflow buffer size ? */
if (smtp_arg->buflen >= SMTP_BUFFER_MAX) {
- DBG("Received buffer from remote SMTP server [%s:%d]"
- " overflow our get read buffer length.",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Received buffer from remote SMTP server [%s:%d]"
+ " overflow our get read buffer length."
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT);
SMTP_FSM_READ(QUIT, thread, 0);
return 0;
} else {
thread_add_write(thread->master, smtp_send_thread, smtp_arg,
smtp_arg->fd, conf_data->smtp_connection_to);
} else {
- DBG("Can not read data from remote SMTP server [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Can not read data from remote SMTP server [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
SMTP_FSM_READ(QUIT, thread, 0);
}
smtp_thread_arg *smtp_arg = THREAD_ARG(thread);
if (thread->type == THREAD_WRITE_TIMEOUT) {
- DBG("Timeout sending data to remote SMTP server [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Timeout sending data to remote SMTP server [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
SMTP_FSM_READ(QUIT, thread, 0);
return 0;
}
thread_add_read(thread->master, smtp_read_thread, smtp_arg,
thread->u.fd, conf_data->smtp_connection_to);
} else {
- DBG("Can not send data to remote SMTP server [%s:%d].",
- inet_ntop2(conf_data->smtp_server), SMTP_PORT);
+ syslog(LOG_INFO, "Can not send data to remote SMTP server [%s:%d].",
+ inet_ntop2(conf_data->smtp_server), SMTP_PORT);
SMTP_FSM_READ(QUIT, thread, 0);
}
if (status == 220) {
smtp_arg->stage++;
} else {
- DBG("Error connecting smtp server");
+ syslog(LOG_INFO, "Error connecting SMTP server[%s:%d]."
+ " SMTP status code = %d"
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT, status);
smtp_arg->stage = ERROR;
}
if (status == 250) {
smtp_arg->stage++;
} else {
- DBG("Error processing HELO cmd");
+ syslog(LOG_INFO, "Error processing HELO cmd on SMTP server [%s:%d]."
+ " SMTP status code = %d"
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT, status);
smtp_arg->stage = ERROR;
}
if (status == 250) {
smtp_arg->stage++;
} else {
- DBG("Error processing MAIL cmd");
+ syslog(LOG_INFO, "Error processing MAIL cmd on SMTP server [%s:%d]."
+ " SMTP status code = %d"
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT, status);
smtp_arg->stage = ERROR;
}
if (!fetched_email)
smtp_arg->stage++;
} else {
- DBG("Error processing RCPT cmd");
+ syslog(LOG_INFO, "Error processing RCPT cmd on SMTP server [%s:%d]."
+ " SMTP status code = %d"
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT, status);
smtp_arg->stage = ERROR;
}
if (status == 354) {
smtp_arg->stage++;
} else {
- DBG("Error processing DATA cmd");
+ syslog(LOG_INFO, "Error processing DATA cmd on SMTP server [%s:%d]."
+ " SMTP status code = %d"
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT, status);
smtp_arg->stage = ERROR;
}
syslog(LOG_INFO, "SMTP alert successfully sent.");
smtp_arg->stage++;
} else {
- DBG("Error processing DOT cmd");
+ syslog(LOG_INFO, "Error processing DOT cmd on SMTP server [%s:%d]."
+ " SMTP status code = %d"
+ , inet_ntop2(conf_data->smtp_server), SMTP_PORT, status);
smtp_arg->stage = ERROR;
}
/* Main entry point */
void
smtp_alert(thread_master * master, real_server * rs, vrrp_rt * vrrp,
- const char *subject, const char *body)
+ vrrp_sgroup *vgroup, const char *subject, const char *body)
{
smtp_thread_arg *smtp_arg;
snprintf(smtp_arg->subject, MAX_HEADERS_LENGTH,
"[%s] VRRP Instance %s - %s",
conf_data->lvs_id, vrrp->iname, subject);
+ else if (vgroup)
+ snprintf(smtp_arg->subject, MAX_HEADERS_LENGTH,
+ "[%s] VRRP Group %s - %s",
+ conf_data->lvs_id, vgroup->gname, subject);
else if (conf_data->lvs_id)
snprintf(smtp_arg->subject, MAX_HEADERS_LENGTH,
"[%s] %s", conf_data->lvs_id, subject);
# processname: keepalived
# pidfile: /var/run/keepalived.pid
# config: /etc/keepalived/keepalived.conf
-# chkconfig: 2345 92 08
+# chkconfig: 35 21 79
# description: Start and stop Keepalived
# Global definitions
start)
echo -n "Starting Keepalived for LVS: "
keepalived
+ touch /var/lock/subsys/keepalived
echo
;;
stop)
echo -n "Shutting down Keepalived for LVS: "
PID=`cat $PID_FILE`
kill $PID
+ rm -rf /var/lock/subsys/keepalived
echo
;;
restart)
../../lib/utils.h
check_misc.o: check_misc.c ../include/check_misc.h ../include/check_api.h \
../../lib/memory.h ../include/ipwrapper.h ../include/smtp.h \
- ../../lib/utils.h ../include/parser.h ../include/daemon.h
-ipwrapper.o: ipwrapper.c ../include/ipwrapper.h ../../lib/utils.h
+ ../../lib/utils.h ../../lib/notify.h ../include/parser.h ../include/daemon.h
+ipwrapper.o: ipwrapper.c ../include/ipwrapper.h ../../lib/utils.h \
+ ../../lib/notify.h
ipvswrapper.o: ipvswrapper.c ../include/ipvswrapper.h ../../lib/utils.h \
../../lib/memory.h
*
* Part: Checkers registration.
*
- * Version: $Id: check_api.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_api.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
checker = ELEMENT_DATA(e);
+ syslog(LOG_INFO,
+ "Activating healtchecker for service [%s:%d]",
+ inet_ntop2(CHECKER_RIP(checker)),
+ ntohs(CHECKER_RPORT(checker)));
+ CHECKER_ENABLE(checker);
thread_add_timer(master, checker->launch, checker,
BOOTSTRAP_DELAY);
}
if (!LIST_ISEMPTY(checkers_queue))
for (e = LIST_HEAD(checkers_queue); e; ELEMENT_NEXT(e)) {
checker = ELEMENT_DATA(e);
- if (CHECKER_VIP(checker) == address) {
+ if (CHECKER_VIP(checker) == address && CHECKER_HA_SUSPEND(checker)) {
if (!CHECKER_ENABLED(checker) && enable)
syslog(LOG_INFO,
"Activating healtchecker for service [%s:%d]",
*
* Part: CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
*
- * Version: $Id: check_ci.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_ci.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Aneesh Kumar K.V, <aneesh.kumar@digital.com>
switch (status) {
case UP:
if (!ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "UP",
+ smtp_alert(thread->master, checker->rs, NULL, NULL, "UP",
"=> CI-Linux CHECK succeed on service <=\n\n");
perform_svr_state(UP, checker->vs, checker->rs);
}
break;
case DOWN:
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "DOWN",
+ smtp_alert(thread->master, checker->rs, NULL, NULL, "DOWN",
"=> CI-Linux CHECK failed on service <=\n\n");
perform_svr_state(DOWN, checker->vs, checker->rs);
}
*
* Part: WEB CHECK. Common HTTP/SSL checker primitives.
*
- * Version: $Id: check_http.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_http.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
http_get_chk->proto =
(!strcmp(proto, "HTTP_GET")) ? PROTO_HTTP : PROTO_SSL;
http_get_chk->url = alloc_list(free_url, dump_url);
+ http_get_chk->nb_get_retry = 1;
return http_get_chk;
}
http_get_checker *http_get_check = CHECKER_ARG(checker);
http_arg *http_arg = HTTP_ARG(http_get_check);
REQ *req = HTTP_REQ(http_arg);
+ uint16_t addr_port = get_service_port(checker);
int delay = 0;
if (method) {
http_arg->retry_it += c ? c : -http_arg->retry_it;
}
+ /*
+ * The get retry implementation mean that we retry performing
+ * a GET on the same url until the remote web server return
+ * html buffer. This is sometime needed with some applications
+ * servers.
+ */
+ if (http_arg->retry_it > http_get_check->nb_get_retry-1) {
+ if (ISALIVE(checker->rs)) {
+ syslog(LOG_INFO, "Check on service [%s:%d] failed after %d retry."
+ , inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port), http_arg->retry_it);
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
+ "DOWN",
+ "=> CHECK failed on service"
+ " : MD5 digest mismatch <=\n\n");
+ perform_svr_state(DOWN, checker->vs, checker->rs);
+ }
+
+ /* Reset it counters */
+ http_arg->url_it = 0;
+ http_arg->retry_it = 0;
+ }
+
/* register next timer thread */
switch (method) {
case 1:
delay = checker->vs->delay_loop;
else
delay =
- checker->vs->delay_loop -
http_get_check->delay_before_retry;
break;
case 2:
- delay = http_get_check->delay_before_retry;
+ if (http_arg->url_it == 0 && http_arg->retry_it == 0)
+ delay = checker->vs->delay_loop;
+ else
+ delay = http_get_check->delay_before_retry;
break;
}
timeout_epilog(thread * thread, char *smtp_msg, char *debug_msg)
{
checker *checker = THREAD_ARG(thread);
- http_get_checker *http_get_check = CHECKER_ARG(checker);
- http_arg *http_arg = HTTP_ARG(http_get_check);
-#ifdef _DEBUG_
uint16_t addr_port = get_service_port(checker);
-#endif
- /*
- * The get retry implementation mean that we retry performing
- * a GET on the same url until the remote web server return
- * html buffer. This is sometime needed with some applications
- * servers.
- */
- if (++http_arg->retry_it <= http_get_check->nb_get_retry) {
- DBG("Retry %s server [%s:%d] after %d retry.",
- debug_msg, inet_ntop2(CHECKER_RIP(checker)),
- ntohs(addr_port), http_arg->retry_it - 1);
- return epilog(thread, 2, 0, 1);
+ syslog(LOG_INFO, "Timeout %s server [%s:%d].",
+ debug_msg
+ , inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
- } else {
- if (checker->rs)
- DBG("Timeout %s server [%s:%d].",
- debug_msg, inet_ntop2(CHECKER_RIP(checker)),
- ntohs(addr_port));
- /* check if server is currently alive */
- if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "DOWN",
- smtp_msg);
- perform_svr_state(DOWN, checker->vs, checker->rs);
- }
-
- return epilog(thread, 1, 0, 0);
+ /* check if server is currently alive */
+ if (ISALIVE(checker->rs)) {
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
+ "DOWN", smtp_msg);
+ perform_svr_state(DOWN, checker->vs, checker->rs);
}
- return 0;
+ return epilog(thread, 1, 0, 0);
}
/* return the url pointer of the current url iterator */
/* check if server is currently alive */
if (ISALIVE(checker->rs)) {
syslog(LOG_INFO,
- "HTTP status code error to [%s:%d] url[%s]"
+ "HTTP status code error to [%s:%d] url(%s)"
", status_code [%d].",
inet_ntop2(CHECKER_RIP(checker)),
ntohs(addr_port), fetched_url->path,
req->status_code);
- smtp_alert(thread->master, checker->rs, NULL,
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
"DOWN",
"=> CHECK failed on service"
" : HTTP status code mismatch <=\n\n");
perform_svr_state(DOWN, checker->vs, checker->rs);
+ } else {
+ DBG("HTTP Status_code to [%s:%d] url(%d) = [%d].",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port)
+ , http_arg->url_it + 1
+ , req->status_code);
+ /*
+ * We set retry iterator to max value to not retry
+ * when service is already know as die.
+ */
+ http_arg->retry_it = http_get_check->nb_get_retry;
}
- return epilog(thread, 1, 0, 0);
+ return epilog(thread, 2, 0, 1);
+ } else {
+ if (!ISALIVE(checker->rs))
+ syslog(LOG_INFO,
+ "HTTP status code success to [%s:%d] url(%d).",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port)
+ , http_arg->url_it + 1);
+ return epilog(thread, 1, 1, 0) + 1;
}
}
for (di = 0; di < 16; di++)
sprintf(digest_tmp + 2 * di, "%02x", digest[di]);
- DBG("MD5SUM to [%s:%d] url(%d) = [%s].",
- inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port),
- http_arg->url_it + 1, digest_tmp);
-
r = strcmp(fetched_url->digest, digest_tmp);
if (r) {
inet_ntop2(CHECKER_RIP(checker)),
ntohs(addr_port), fetched_url->path,
digest_tmp);
- smtp_alert(thread->master, checker->rs, NULL,
- "DOWN",
- "=> CHECK failed on service"
- " : MD5 digest mismatch <=\n\n");
- perform_svr_state(DOWN, checker->vs, checker->rs);
+ } else {
+ DBG("MD5SUM to [%s:%d] url(%d) = [%s].",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port)
+ , http_arg->url_it + 1
+ , digest_tmp);
+ /*
+ * We set retry iterator to max value to not retry
+ * when service is already know as die.
+ */
+ http_arg->retry_it = http_get_check->nb_get_retry;
}
FREE(digest_tmp);
- return epilog(thread, 1, 0, 0);
+ return epilog(thread, 2, 0, 1);
} else {
- DBG("MD5 digest success to [%s:%d] url(%d).",
- inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port),
- http_arg->url_it + 1);
+ if (!ISALIVE(checker->rs))
+ syslog(LOG_INFO, "MD5 digest success to [%s:%d] url(%d).",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port)
+ , http_arg->url_it + 1);
FREE(digest_tmp);
return epilog(thread, 1, 1, 0) + 1;
}
http_get_checker *http_get_check = CHECKER_ARG(checker);
http_arg *http_arg = HTTP_ARG(http_get_check);
REQ *req = HTTP_REQ(http_arg);
-#ifdef _DEBUG_
uint16_t addr_port = get_service_port(checker);
-#endif
unsigned char digest[16];
int r = 0;
if (r == -1) {
/* We have encourred a real read error */
- DBG("Read error with server [%s:%d]: %s",
- inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port),
- strerror(errno));
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL,
+ syslog(LOG_INFO, "Read error with server [%s:%d]: %s",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port)
+ , strerror(errno));
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
"DOWN",
"=> HTTP CHECK failed on service"
" : cannot receive data <=\n\n");
(vhost) ? vhost : inet_ntop2(CHECKER_RIP(checker))
, ntohs(addr_port));
DBG("Processing url(%d) of [%s:%d].",
- http_arg->url_it + 1, inet_ntop2(CHECKER_RIP(checker)),
- ntohs(addr_port));
+ http_arg->url_it + 1
+ , inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
/* Send the GET request to remote Web server */
if (http_get_check->proto == PROTO_SSL)
/* check if server is currently alive */
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "DOWN",
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
+ "DOWN",
"=> CHECK failed on service"
" : cannot send data <=\n\n");
perform_svr_state(DOWN, checker->vs, checker->rs);
, addr_port, http_check_thread);
switch (status) {
case connect_error:
- DBG("Error connecting server [%s:%d].",
- inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port));
/* check if server is currently alive */
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "DOWN",
+ syslog(LOG_INFO, "Error connecting server [%s:%d].",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
+ "DOWN",
"=> CHECK failed on service"
" : connection error <=\n\n");
perform_svr_state(DOWN, checker->vs, checker->rs);
thread->u.fd,
http_get_check->connection_to);
} else {
- DBG("Connection trouble to: [%s:%d].",
- inet_ntop2(CHECKER_RIP(checker)),
- ntohs(addr_port));
+ syslog(LOG_INFO, "Connection trouble to: [%s:%d].",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
#ifdef _DEBUG_
if (http_get_check->proto == PROTO_SSL)
ssl_printerr(SSL_get_error
* check if server is currently alive.
*/
if (!ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "UP",
+ syslog(LOG_INFO, "Remote Web server [%s:%d] succeed on service.",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
+ smtp_alert(thread->master, checker->rs, NULL, NULL, "UP",
"=> CHECK succeed on service <=\n\n");
perform_svr_state(UP, checker->vs, checker->rs);
- DBG("Remote Web server [%s:%d] succeed on service.",
- inet_ntop2(CHECKER_RIP(checker)),
- ntohs(addr_port));
}
http_arg->req = NULL;
return epilog(thread, 1, 0, 0) + 1;
* Part: MISC CHECK. Perform a system call to run an extra
* system prog or script.
*
- * Version: $Id: check_misc.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_misc.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
#include "smtp.h"
#include "utils.h"
#include "parser.h"
-#include "daemon.h"
+#include "notify.h"
int misc_check_thread(thread *);
return -1;
}
- /* In case of this is parent process. */
+ /* In case of this is parent process */
if (pid)
- return (0);
+ return 0;
+ /* Child part */
closeall(0);
open("/dev/null", O_RDWR);
if (status == 0) {
/* everything is good */
if (!ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL,
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
"UP",
"=> MISC CHECK succeed on service <=\n\n");
perform_svr_state(UP, checker->vs, checker->rs);
}
} else {
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL,
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
"DOWN",
"=> MISC CHECK failed on service <=\n\n");
perform_svr_state(DOWN, checker->vs, checker->rs);
* url, compute a MD5 over this result and match it to the
* expected value.
*
- * Version: $Id: check_ssl.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_ssl.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
switch (err) {
case SSL_ERROR_ZERO_RETURN:
- DBG(" SSL error: (zero return)");
+ syslog(LOG_INFO, " SSL error: (zero return)");
break;
case SSL_ERROR_WANT_READ:
- DBG(" SSL error: (read error)");
+ syslog(LOG_INFO, " SSL error: (read error)");
break;
case SSL_ERROR_WANT_WRITE:
- DBG(" SSL error: (write error)");
+ syslog(LOG_INFO, " SSL error: (write error)");
break;
case SSL_ERROR_WANT_CONNECT:
- DBG(" SSL error: (connect error)");
+ syslog(LOG_INFO, " SSL error: (connect error)");
break;
case SSL_ERROR_WANT_X509_LOOKUP:
- DBG(" SSL error: (X509 lookup error)");
+ syslog(LOG_INFO, " SSL error: (X509 lookup error)");
break;
case SSL_ERROR_SYSCALL:
- DBG(" SSL error: (syscall error)");
+ syslog(LOG_INFO, " SSL error: (syscall error)");
break;
case SSL_ERROR_SSL:{
ssl_strerr = (char *) MALLOC(500);
extended_error = ERR_get_error();
ERR_error_string(extended_error, ssl_strerr);
- DBG(" SSL error: (%s)", ssl_strerr);
+ syslog(LOG_INFO, " SSL error: (%s)", ssl_strerr);
FREE(ssl_strerr);
break;
}
if (r && !req->extracted) {
/* check if server is currently alive */
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL,
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
"DOWN",
"=> SSL CHECK failed on service"
" : cannot receive data <=\n\n");
*
* Part: TCP checker.
*
- * Version: $Id: check_tcp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_tcp.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Otherwise we have a real connection error or connection timeout.
*/
if (status == connect_success) {
- DBG("TCP connection to [%s:%d] success.",
- inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port));
close(thread->u.fd);
if (!ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "UP",
+ syslog(LOG_INFO, "TCP connection to [%s:%d] success.",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
+ "UP",
"=> TCP CHECK succeed on service <=\n\n");
perform_svr_state(UP, checker->vs, checker->rs);
}
} else {
- DBG("TCP connection to [%s:%d] failed !!!",
- inet_ntop2(CHECKER_RIP(checker)), ntohs(addr_port));
if (ISALIVE(checker->rs)) {
- smtp_alert(thread->master, checker->rs, NULL, "DOWN",
+ syslog(LOG_INFO, "TCP connection to [%s:%d] failed !!!",
+ inet_ntop2(CHECKER_RIP(checker))
+ , ntohs(addr_port));
+ smtp_alert(thread->master, checker->rs, NULL, NULL,
+ "DOWN",
"=> TCP CHECK failed on service <=\n\n");
perform_svr_state(DOWN, checker->vs, checker->rs);
}
* library to add/remove server MASQ rules to the kernel
* firewall framework.
*
- * Version: $Id: ipfwwrapper.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: ipfwwrapper.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: IPVS Kernel wrapper. Use setsockopt call to add/remove
* server to/from the loadbalanced server pool.
*
- * Version: $Id: ipvswrapper.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: ipvswrapper.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Manipulation functions for IPVS & IPFW wrappers.
*
- * Version: $id: ipwrapper.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $id: ipwrapper.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "ipwrapper.h"
#include "utils.h"
+#include "notify.h"
/* extern global vars */
extern data *conf_data;
, inet_ntoa2(SVR_IP(vs), vsip)
, ntohs(SVR_PORT(vs)));
ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs);
+ if (rs->notify_up) {
+ syslog(LOG_INFO, "Executing [%s] for service [%s:%d]"
+ " in VS [%s:%d]"
+ , rs->notify_up
+ , inet_ntoa2(SVR_IP(rs), rsip)
+ , ntohs(SVR_PORT(rs))
+ , inet_ntoa2(SVR_IP(vs), vsip)
+ , ntohs(SVR_PORT(vs)));
+ notify_exec(rs->notify_up);
+ }
#ifdef _KRNL_2_2_
if (vs->nat_mask == HOST_NETMASK)
ipfw_cmd(IP_FW_CMD_ADD, vs, rs);
/* server is down, it is removed from the LVS realserver pool */
ipvs_cmd(LVS_CMD_DEL_DEST, vs, rs);
+ if (rs->notify_down) {
+ syslog(LOG_INFO, "Executing [%s] for service [%s:%d]"
+ " in VS [%s:%d]"
+ , rs->notify_down
+ , inet_ntoa2(SVR_IP(rs), rsip)
+ , ntohs(SVR_PORT(rs))
+ , inet_ntoa2(SVR_IP(vs), vsip)
+ , ntohs(SVR_PORT(vs)));
+ notify_exec(rs->notify_down);
+ }
#ifdef _KRNL_2_2_
if (vs->nat_mask == HOST_NETMASK)
*
* Part: Checkers arguments structures definitions.
*
- * Version: $Id: check_api.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_api.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define CHECKER_ENABLED(C) ((C)->enabled)
#define CHECKER_ENABLE(C) ((C)->enabled = 1)
#define CHECKER_DISABLE(C) ((C)->enabled = 0)
+#define CHECKER_HA_SUSPEND(C) ((C)->vs->ha_suspend)
/* Prototypes definition */
extern void init_checkers_queue(void);
*
* Part: check_ci.c include file.
*
- * Version: $Id: check_ci.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_ci.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Aneesh Kumar K.V, <aneesh.kumar@digital.com>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_http.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_misc.c include file.
*
- * Version: $Id: check_misc.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_misc.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
*
* Part: check_http.c include file.
*
- * Version: $Id: check_http.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_http.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: check_tcp.c include file.
*
- * Version: $Id: check_tcp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: check_tcp.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Daemon process handling.
*
- * Version: $Id: daemon.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: daemon.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* prototype */
extern pid_t xdaemon(int, int, int);
-extern void closeall(int fd);
-extern int system_call(char *cmdline);
#endif
*
* Part: Dynamic data structure definition.
*
- * Version: $Id: data.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: data.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int inhibit; /* Set weight to 0 instead of removing
* the service from IPVS topology.
*/
+ char *notify_up; /* Script to launch when RS is added to LVS */
+ char *notify_down; /* Script to launch when RS is removed from LVS */
int alive;
} real_server;
uint16_t addr_port;
uint16_t service_type;
int delay_loop;
+ int ha_suspend;
char sched[SCHED_MAX_LENGTH];
char timeout_persistence[MAX_TIMEOUT_LENGTH];
unsigned loadbalancing_kind;
*
* Part: ipfwwrapper.c include file.
*
- * Version: $Id: ipfwwrapper.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: ipfwwrapper.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipvswrapper.c include file.
*
- * Version: $Id: ipvswrapper.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: ipvswrapper.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipwrapper.c include file.
*
- * Version: $Id: ipwrapper.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: ipwrapper.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: layer4.c include file.
*
- * Version: $Id: layer4.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: layer4.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program include file.
*
- * Version: $Id: main.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: main.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* Build version */
#define PROG "Keepalived"
-#define VERSION_CODE 0x000706
-#define DATE_CODE 0x140A02
+#define VERSION_CODE 0x010000
+#define DATE_CODE 0x060103
#define KEEPALIVED_VERSION(version) \
(version >> 16) & 0xFF, \
*
* Part: cfreader.c include file.
*
- * Version: $Id: parser.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: parser.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile.c include file.
*
- * Version: $Id: pidfile.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: pidfile.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: smtp.c include file.
*
- * Version: $Id: smtp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: smtp.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define SMTP_QUIT_CMD "QUIT\r\n"
/* Prototypes defs */
-extern void smtp_alert(thread_master *, real_server *, vrrp_rt *, const char *,
- const char *);
+extern void smtp_alert(thread_master *,
+ real_server *, vrrp_rt *, vrrp_sgroup *,
+ const char *, const char *);
#endif
*
* Part: vrrp.c program include file.
*
- * Version: $Id: vrrp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
char *script_backup;
char *script_master;
char *script_fault;
+ int smtp_alert;
} vrrp_sgroup;
/* parameters per virtual router -- rfc2338.6.1.2 */
*
* Part: vrrp_arp.c include file.
*
- * Version: $Id: vrrp_arp.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_arp.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_if.c include file.
*
- * Version: $Id: vrrp_if.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_if.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define IF_NAME(X) ((X)->ifname)
#define IF_INDEX(X) ((X)->ifindex)
#define IF_ADDR(X) ((X)->address)
+#define IF_MTU(X) ((X)->mtu)
#define IF_HWADDR(X) ((X)->hw_addr)
#define IF_MII_SUPPORTED(X) ((X)->lb_type & LB_MII)
#define IF_ETHTOOL_SUPPORTED(X) ((X)->lb_type & LB_ETHTOOL)
*
* Part: vrrp_ipaddress.c include file.
*
- * Version: $Id: vrrp_ipaddress.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipsecah.c include file.
*
- * Version: $Id: vrrp_ipsecah.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_netlink.c include file.
*
- * Version: $Id: vrrp_netlink.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_netlink.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_notify.c include file.
*
- * Version: $Id: vrrp_notify.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_notify.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_scheduler.c include file.
*
- * Version: $Id: vrrp_scheduler.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_scheduler.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_sync.c include file.
*
- * Version: $Id: vrrp_sync.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_sync.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#define GROUP_NAME(G) ((G)->gname)
/* extern prototypes */
-extern void vrrp_init_instance_sands(vrrp_rt * vrrp);
-extern vrrp_sgroup *vrrp_get_sync_group(char *iname);
-extern int vrrp_sync_group_up(vrrp_sgroup * vgroup);
-extern int vrrp_sync_leave_fault(vrrp_rt * vrrp);
+extern void vrrp_init_instance_sands(vrrp_rt *);
+extern vrrp_sgroup *vrrp_get_sync_group(char *);
+extern void vrrp_sync_set_group(vrrp_sgroup *);
+extern int vrrp_sync_group_up(vrrp_sgroup *);
+extern int vrrp_sync_leave_fault(vrrp_rt *);
extern void vrrp_sync_backup(vrrp_rt *);
extern void vrrp_sync_master(vrrp_rt *);
extern void vrrp_sync_master_election(vrrp_rt *);
--- /dev/null
+This file describe all the Keepalived available keywords. The keepalived.conf
+file is compounded by three configurations parts :
+
+ * Globals configurations
+ * VRRP configuration
+ * LVS configuration
+
+0. Comment string
+
+There is 2 valid comment valid string : # or ! If you want to add comment
+in you configuration file use this char.
+
+1. Globals configurations
+
+The configuration block looks like :
+
+global_defs { # Block identification
+ notification_email { # Email to send alertes to
+ <EMAIL ADDRESS> # Standard email address
+ <EMAIL ADDRESS>
+ ...
+ }
+ notification_email_from <EMAIL ADDRESS> # Email From dealing with SMTP proto
+ smtp_server <IP ADDRESS> # SMTP server IP address
+ smtp_connect_timeout <INTEGER> # Number of seconds timeout connect
+ # remote SMTP server
+ lvs_id <STRING> # String identifying router
+}
+
+
+2. VRRP configuration
+
+This block is divided in 2 sub-block :
+
+ * VRRP synchronization group
+ * VRRP instance
+
+ 2.1. VRRP synchronization group
+
+ The configuration block looks like :
+
+vrrp_sync_group <STRING> { # VRRP sync group declaration
+ group { # group of instance to sync together
+ <STRING> # a
+ <STRING> # set
+ ... # of VRRP_Instance string
+ }
+ notify_master <STRING>|<QUOTED-STRING> # Script to run during MASTER transit
+ notify_backup <STRING>|<QUOTED-STRING> # Script to run during BACKUP transit
+ notify_fault <STRING>|<QUOTED-STRING> # Script to run during FAULT transit
+ smtp_alert # Send email notif during state transit
+}
+
+ 2.2. VRRP instance
+
+ The configuration block looks like :
+
+vrrp_instance <STRING> { # VRRP instance declaration
+ state MASTER|BACKUP # Start-up default state
+ interface <STRING> # Binding interface
+ mcast_src_ip <IP ADDRESS> # src_ip to use into the VRRP packets
+ lvs_sync_daemon_interface <STRING> # Binding interface for lvs syncd
+ garp_master_delay <INTEGER> # delay for gratuitous ARP after MASTER
+ # state transition
+ virtual_router_id <INTEGER-0..255> # VRRP VRID
+ priority <INTEGER-0..255> # VRRP PRIO
+ advert_int <INTEGER> # VRRP Advert interval (use default)
+ authentication { # Authentication block
+ auth_type PASS|AH # Simple Passwd or IPSEC AH
+ auth_pass <STRING> # Password string
+ }
+ virtual_ipaddress { # VRRP IP addres block
+ <IP ADDRESS>
+ <IP ADDRESS>
+ ...
+ }
+ virtual_ipaddress_excluded { # VRRP IP to excluded from VRRP
+ <IP ADDRESS> # packets
+ <IP ADDRESS>
+ ...
+ }
+ preempt # VRRP preempt mode (default set)
+ debug # Debug level
+ notify_master <STRING>|<QUOTED-STRING> # Same as vrrp_sync_group
+ notify_backup <STRING>|<QUOTED-STRING> # Same as vrrp_sync_group
+ notify_fault <STRING>|<QUOTED-STRING> # Same as vrrp_sync_group
+ smtp_alert # Same as vrrp_sync_group
+}
+
+
+3. LVS configuration
+
+The configuration block looks like :
+
+
+virtual_server <IP ADDRESS> <PORT> { # VS declaration
+ delay_loop <INTEGER> # delay timer for service polling
+ lb_algo rr|wrr|lc|wlc|lblc|sh|dh # LVS scheduler used
+ lb_kind NAT|DR|TUN # LVS method used
+ persistence_timeout <INTEGER> # LVS persistence timeout
+ persistence_granularity <NETMASK> # LVS granularity mask
+ protocol TCP # Only TCP is implemented
+ ha_suspend # If VS IP address is not set, suspend
+ # healthcheckers activity
+ virtualhost <STRING> # VirtualHost string to use for
+ # HTTP_GET or SSL_GET
+
+ sorry_server <IP ADDRESS> <PORT> # RS to add to LVS topology when all
+ # realserver are down
+
+ real_server <IP ADDRESS> <PORT> { # RS declaration
+ weight <INTEGER> # weight to use (default: 1)
+ inhibit_on_failure # Set weight to 0 on healtchecker
+ # failure
+ notify_up <STRING>|<QUOTED-STRING> # Script to launch when
+ # healthchecker consider service
+ # as up.
+ notify_down <STRING>|<QUOTED-STRING> # Script to launch when
+ # healthchecker consider service
+ # as down.
+
+ HTTP_GET|SSL_GET { # HTTP and SSL healthcheckers
+ url { # A set of url to test
+ path <STRING> # Path
+ digest <STRING> # Digest computed with genhash
+ status_code <INTEGER> # status code returned into the HTTP
+ } # header.
+ url {
+ path <STRING>
+ digest <STRING>
+ status_code <INTEGER>
+ }
+ ...
+ connect_port <PORT> # TCP port to connect
+ connect_timeout <INTEGER> # Timeout connection
+ nb_get_retry <INTEGER> # number of get retry
+ delay_before_retry <INTEGER> # delay before retry
+ }
+ }
+
+ real_server <IP ADDRESS> <PORT> { # Idem
+ weight <INTEGER> # Idem
+ inhibit_on_failure # Idem
+ notify_up <STRING>|<QUOTED-STRING> # Idem
+ notify_down <STRING>|<QUOTED-STRING> # Idem
+
+ TCP_CHECK { # TCP healthchecker
+ connect_port <PORT> # TCP port to connect
+ connect_timeout <INTEGER> # Timeout connection
+ }
+ }
+}
+
vrrp.o: vrrp.c ../include/vrrp.h ../include/vrrp_scheduler.h \
../include/vrrp_notify.h ../include/ipvswrapper.h ../../lib/memory.h \
../../lib/list.h ../include/data.h ../include/vrrp_arp.h
-vrrp_notify.o: vrrp_notify.c ../include/vrrp_notify.h ../../lib/memory.h
+vrrp_notify.o: vrrp_notify.c ../include/vrrp_notify.h ../../lib/memory.h \
+ ../../lib/notify.h
vrrp_scheduler.o: vrrp_scheduler.c ../include/vrrp_scheduler.h \
../include/vrrp_ipsecah.h ../include/vrrp_if.h ../include/vrrp.h \
../include/vrrp_sync.h ../include/vrrp_notify.h ../include/ipvswrapper.h \
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
- * Version: $Id: vrrp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* sender counter.
*/
vrrp->ipsecah_counter->seq_number++;
- if (ah->seq_number >= vrrp->ipsecah_counter->seq_number) {
+ if (ah->seq_number >= vrrp->ipsecah_counter->seq_number || vrrp->sync) {
vrrp->ipsecah_counter->seq_number = ah->seq_number;
} else {
syslog(LOG_INFO,
"VRRP_Instance(%s) IPSEC-AH : sequence number %d"
- " already proceeded. Packet dropped", vrrp->iname
- , ah->seq_number);
+ " already proceeded. Packet dropped. Local(%d)", vrrp->iname
+ , ah->seq_number, vrrp->ipsecah_counter->seq_number);
return 1;
}
vrrp->ms_down_timer =
3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
} else if (hd->priority < vrrp->priority) {
+ syslog(LOG_INFO,
+ "VRRP_Instance(%s) forcing a new MASTER election",
+ vrrp->iname);
vrrp->wantstate = VRRP_STATE_GOTO_MASTER;
+ vrrp_send_adv(vrrp, vrrp->priority);
}
}
if (iph->protocol == IPPROTO_IPSEC_AH) {
ah = (ipsec_ah *) (buf + sizeof(struct iphdr));
syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : Syncing seq_num"
- " with received = %d", vrrp->iname, ah->seq_number);
+ " - Increment seq"
+ , vrrp->iname);
vrrp->ipsecah_counter->seq_number = ah->seq_number + 1;
vrrp->ipsecah_counter->cycle = 0;
}
syslog(LOG_INFO,
"VRRP_Instance(%s) Received higher prio advert",
vrrp->iname);
+ if (iph->protocol == IPPROTO_IPSEC_AH) {
+ ah = (ipsec_ah *) (buf + sizeof(struct iphdr));
+ syslog(LOG_INFO, "VRRP_Instance(%s) IPSEC-AH : Syncing seq_num"
+ " - Decrement seq"
+ , vrrp->iname);
+ vrrp->ipsecah_counter->seq_number = ah->seq_number - 1;
+ vrrp->ipsecah_counter->cycle = 0;
+ }
vrrp->ms_down_timer =
3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
vrrp->wantstate = VRRP_STATE_BACK;
*
* Part: ARP primitives.
*
- * Version: $Id: vrrp_arp.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_arp.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Interfaces manipulation.
*
- * Version: $Id: vrrp_if.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_if.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK IPv4 address manipulation.
*
- * Version: $Id: vrrp_ipaddress.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* authentication data encryption using HMAC MD5 according to
* RFCs 2085 & 2104.
*
- * Version: $Id: vrrp_ipsecah.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK kernel command channel.
*
- * Version: $Id: vrrp_netlink.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_netlink.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: VRRP state transition notification scripts handling.
*
- * Version: $Id: vrrp_notify.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_notify.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* local include */
#include "vrrp_notify.h"
#include "memory.h"
-#include "daemon.h"
+#include "notify.h"
static char *
get_iscript(vrrp_rt * vrrp, int state)
return script;
}
-/* Execute extern script/program */
-static int
-notify_exec(char *cmd)
-{
- pid_t pid;
-
- pid = fork();
-
- /* In case of fork is error. */
- if (pid < 0) {
- syslog(LOG_INFO, "Failed fork process");
- return -1;
- }
-
- /* In case of this is parent process. */
- if (pid)
- return (0);
-
- closeall(0);
-
- open("/dev/null", O_RDWR);
- dup(0);
- dup(0);
-
- system_call(cmd);
-
- exit(0);
-}
-
static int
script_open(char *script)
{
*
* Part: Sheduling framework for vrrp code.
*
- * Version: $Id: vrrp_scheduler.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_scheduler.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
{
{ {NULL}, {NULL}, {NULL}, {NULL} },
{ {NULL}, {vrrp_sync_master_election}, {vrrp_sync_master}, {vrrp_sync_fault} },
- { {NULL}, {vrrp_sync_backup}, {NULL}, {vrrp_sync_fault} },
+ { {NULL}, {vrrp_sync_backup}, {vrrp_sync_master}, {vrrp_sync_fault} },
{ {NULL}, {vrrp_sync_backup}, {vrrp_sync_master}, {vrrp_sync_fault} }
};
{
if (vrrp->smtp_alert) {
if (vrrp->state == VRRP_STATE_MAST)
- smtp_alert(master, NULL, vrrp,
+ smtp_alert(master, NULL, vrrp, NULL,
"Entering MASTER state",
"=> VRRP Instance is now owning VRRP VIPs <=\n\n");
if (vrrp->state == VRRP_STATE_BACK)
- smtp_alert(master, NULL, vrrp,
+ smtp_alert(master, NULL, vrrp, NULL,
"Entering BACKUP state",
"=> VRRP Instance is nolonger owning VRRP VIPs <=\n\n");
}
void
dump_sock(void *data)
{
-#ifdef _DEBUG_
sock *sock = data;
- DBG("sockpool -> ifindex(%d), proto(%d), fd(%d)",
- sock->ifindex, sock->proto, sock->fd);
-#endif
+ syslog(LOG_INFO, "VRRP sockpool: [ifindex(%d), proto(%d), fd(%d)]",
+ sock->ifindex
+ , sock->proto
+ , sock->fd);
}
void
}
static void
+vrrp_ah_sync(vrrp_rt *vrrp)
+{
+ /*
+ * Transition to BACKUP state for AH
+ * seq number synchronization.
+ */
+ syslog(LOG_INFO, "VRRP_Instance(%s) in FAULT state jump to AH sync",
+ vrrp->iname);
+ vrrp->wantstate = VRRP_STATE_BACK;
+ vrrp_state_leave_master(vrrp);
+}
+
+static void
vrrp_leave_fault(vrrp_rt * vrrp, char *vrrp_buffer, int len)
{
if (vrrp_state_fault_rx(vrrp, vrrp_buffer, len)) {
vrrp_sgroup *vgroup = vrrp->sync;
if (vgroup) {
- if (vrrp_sync_group_up(vgroup)) {
- if (vgroup->state == VRRP_STATE_FAULT) {
- syslog(LOG_INFO,
- "VRRP_Group(%s) Leaving FAULT state",
- GROUP_NAME(vgroup));
- notify_group_exec(vgroup, vrrp->init_state);
+ if (vrrp_sync_leave_fault(vrrp)) {
+ if (vgroup->state == VRRP_STATE_FAULT)
vgroup->state = vrrp->init_state;
- }
} else
return;
} else if (IF_ISUP(vrrp->ifp))
* instance.
*/
if (vrrp->auth_type == VRRP_AUTH_AH) {
- /*
- * Transition to BACKUP state for AH
- * seq number synchronization.
- */
- syslog(LOG_INFO,
- "VRRP_Instance(%s) in FAULT state jump to AH sync",
- vrrp->iname);
- vrrp->wantstate = VRRP_STATE_BACK;
- vrrp_state_leave_master(vrrp);
+ vrrp_ah_sync(vrrp);
} else {
/* Otherwise, we transit to init state */
if (vrrp->init_state == VRRP_STATE_BACK)
*
* Part: VRRP synchronization framework.
*
- * Version: $Id: vrrp_sync.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vrrp_sync.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "vrrp_if.h"
#include "vrrp_notify.h"
#include "data.h"
+#include "smtp.h"
/* extern global vars */
+extern thread_master *master;
extern data *conf_data;
/* Compute the new instance sands */
return NULL;
}
+/* Set instances group pointer */
+void
+vrrp_sync_set_group(vrrp_sgroup *vgroup)
+{
+ vrrp_rt *vrrp;
+ char *str;
+ int i;
+
+ for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
+ str = VECTOR_SLOT(vgroup->iname, i);
+ vrrp = vrrp_get_instance(str);
+ if (vrrp)
+ vrrp->sync = vgroup;
+ }
+}
+
/* All interface are UP in the same group */
int
vrrp_sync_group_up(vrrp_sgroup * vgroup)
return 0;
}
+/* SMTP alert group notifier */
+static void
+vrrp_sync_smtp_notifier(vrrp_sgroup *vgroup)
+{
+ if (vgroup->smtp_alert) {
+ if (GROUP_STATE(vgroup) == VRRP_STATE_MAST)
+ smtp_alert(master, NULL, NULL, vgroup,
+ "Entering MASTER state",
+ "=> All VRRP group instances are now in MASTER state <=\n\n");
+ if (GROUP_STATE(vgroup) == VRRP_STATE_BACK)
+ smtp_alert(master, NULL, NULL, vgroup,
+ "Entering BACKUP state",
+ "=> All VRRP group instances are now in BACKUP state <=\n\n");
+ }
+}
+
/* Leaving fault state */
int
vrrp_sync_leave_fault(vrrp_rt * vrrp)
if (vrrp_sync_group_up(vgroup)) {
syslog(LOG_INFO, "VRRP_Group(%s) Leaving FAULT state",
GROUP_NAME(vgroup));
- vgroup->state = VRRP_STATE_MAST;
- notify_group_exec(vgroup, VRRP_STATE_MAST);
return 1;
}
return 0;
if (vrrp->wantstate != VRRP_STATE_GOTO_MASTER)
return;
- if (GROUP_STATE(vrrp->sync) == VRRP_STATE_FAULT)
+ if (GROUP_STATE(vgroup) == VRRP_STATE_FAULT)
return;
syslog(LOG_INFO, "VRRP_Group(%s) Transition to MASTER state",
for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
str = VECTOR_SLOT(vgroup->iname, i);
isync = vrrp_get_instance(str);
- if (isync != vrrp)
+ if (isync != vrrp) {
+ /* Force a new protocol master election */
isync->wantstate = VRRP_STATE_GOTO_MASTER;
-
- /* Force a new protocol master election */
- syslog(LOG_INFO,
- "VRRP_Instance(%s) forcing a new MASTER election",
- isync->iname);
- vrrp_send_adv(isync, isync->priority);
+ syslog(LOG_INFO,
+ "VRRP_Instance(%s) forcing a new MASTER election",
+ isync->iname);
+ vrrp_send_adv(isync, isync->priority);
+ }
}
- vgroup->state = VRRP_STATE_MAST;
- notify_group_exec(vgroup, VRRP_STATE_MAST);
}
void
vrrp_sgroup *vgroup = vrrp->sync;
syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to BACKUP state",
- GROUP_NAME(vrrp->sync));
+ GROUP_NAME(vgroup));
for (i = 0; i < VECTOR_SIZE(vgroup->iname); i++) {
str = VECTOR_SLOT(vgroup->iname, i);
}
}
vgroup->state = VRRP_STATE_BACK;
+ vrrp_sync_smtp_notifier(vgroup);
notify_group_exec(vgroup, VRRP_STATE_BACK);
}
vrrp_rt *isync;
vrrp_sgroup *vgroup = vrrp->sync;
+ if (GROUP_STATE(vrrp->sync) == VRRP_STATE_MAST)
+ return;
+
syslog(LOG_INFO, "VRRP_Group(%s) Syncing instances to MASTER state",
GROUP_NAME(vrrp->sync));
}
}
vgroup->state = VRRP_STATE_MAST;
+ vrrp_sync_smtp_notifier(vgroup);
notify_group_exec(vgroup, VRRP_STATE_MAST);
}
DEFS = @DFLAGS@
COMPILE = $(CC) $(CFLAGS) $(DEFS)
-OBJS = memory.o utils.o timer.o scheduler.o vector.o list.o html.o
+OBJS = memory.o utils.o notify.o timer.o scheduler.o \
+ vector.o list.o html.o
HEADERS = $(OBJS:.o=.h)
.c.o:
distclean: clean
rm -f Makefile
-
memory.o: memory.c memory.h
utils.o: utils.c utils.h
+notify.o: notify.c notify.h
timer.o: timer.c timer.h
scheduler.o: scheduler.c scheduler.h memory.h utils.h
vector.o: vector.c vector.h memory.h
*
* Part: HTML stream parser utility functions.
*
- * Version: $Id: html.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: html.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: parser.c include file.
*
- * Version: $Id: html.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: html.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: List structure manipulation.
*
- * Version: $Id: list.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: list.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: list.c include file.
*
- * Version: $Id: list.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: list.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* Part: Memory management framework. This framework is used to
* find any memory leak.
*
- * Version: $Id: memory.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: memory.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: memory.c include file.
*
- * Version: $Id: memory.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: memory.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: Forked system call to launch an extra script.
+ *
+ * Version: $Id: notify.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
+ *
+ * Author: Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include "notify.h"
+
+/* perform a system call */
+int
+system_call(char *cmdline)
+{
+ int retval;
+
+ retval = system(cmdline);
+
+ if (retval == 127) {
+ /* couldn't exec command */
+ syslog(LOG_ALERT, "Couldn't exec command: %s", cmdline);
+ } else if (retval == -1) {
+ /* other error */
+ syslog(LOG_ALERT, "Error exec-ing command: %s", cmdline);
+ }
+
+ return retval;
+}
+
+/* Close all FDs >= a specified value */
+void
+closeall(int fd)
+{
+ int fdlimit = sysconf(_SC_OPEN_MAX);
+ while (fd < fdlimit)
+ close(fd++);
+}
+
+/* Execute external script/program */
+int
+notify_exec(char *cmd)
+{
+ pid_t pid;
+
+ pid = fork();
+
+ /* In case of fork is error. */
+ if (pid < 0) {
+ syslog(LOG_INFO, "Failed fork process");
+ return -1;
+ }
+
+ /* In case of this is parent process */
+ if (pid)
+ return 0;
+
+ closeall(0);
+
+ open("/dev/null", O_RDWR);
+ dup(0);
+ dup(0);
+
+ system_call(cmd);
+
+ exit(0);
+}
--- /dev/null
+/*
+ * Soft: Keepalived is a failover program for the LVS project
+ * <www.linuxvirtualserver.org>. It monitor & manipulate
+ * a loadbalanced server pool using multi-layer checks.
+ *
+ * Part: notify.c include file.
+ *
+ * Version: $Id: notify.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
+ *
+ * Author: Alexandre Cassen, <acassen@linux-vs.org>
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _NOTIFY_H
+#define _NOTIFY_H
+
+/* system includes */
+extern int system_call(char *cmdline);
+extern void closeall(int fd);
+extern int notify_exec(char *cmd);
+
+#endif
* the thread management routine (thread.c) present in the
* very nice zebra project (http://www.zebra.org).
*
- * Version: $Id: scheduler.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: scheduler.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: scheduler.c include file.
*
- * Version: $Id: scheduler.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: scheduler.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Timer manipulations.
*
- * Version: $Id: timer.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: timer.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: timer.c include file.
*
- * Version: $Id: timer.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: timer.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: utils.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: utils.h include file.
*
- * Version: $Id: utils.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: utils.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Vector structure manipulation.
*
- * Version: $Id: vector.c,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vector.c,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vector.c include file.
*
- * Version: $Id: vector.h,v 0.7.6 2002/11/20 21:34:18 acassen Exp $
+ * Version: $Id: vector.h,v 1.0.0 2003/01/06 19:40:11 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*