* keepalived-0.6.9 released.
* Fixe some code dependence selection during compilation. If autoconf netlink
probe fails then unset VRRP code.
* Cleanup daemon lib. Added some logging info for the daemon processing, removed
some repeated code part.
* Added 2 new daemon arguments :
--dont-release-vrrp : Dont remove VRRP VIPs on daemon stop
--dont-release-ipvs : Dont remove IPVS topology on daemon stop
* Review the global scheduling process to clear FD queues on master thread
destroy.
* Fixed a forking issue in the MISC_CHECK.
* Review IPVS wrapper functions to use allocated IPVS rules instead of static
referencing pointer.
* Fixed the IPVS wrapper to delete IPVS entries according to their 'alive' state.
* Added IPVS support to alive flag for VS entries.
* Rewrote the previous main.c to support configuration reload on the fly. Extented
signal handling to register a conf reload_thread on SIGHUP. The software design
used here is a dynamic differential conf file reloading framework. This design
offer key decision to add/remove new/old entries to/from low-level framework:
IPVS topology and netlink IP addresses entries. This design reduce to the max
the global service interruption since only negative diff entries are removed.
For VRRP config reload on the fly, if you plan to add/remove many VIPs consider
VIP declaration into the virtual_ipaddress_excluded since they are not present
into VRRP adverts.
* Review the keepalived.init script to support restart and reload arguments.
* Fixed some typo issues.
+2002-07-31 Alexandre Cassen <acassen@linux-vs.org>
+ * keepalived-0.6.9 released.
+ * Fixe some code dependence selection during compilation. If autoconf netlink
+ probe fails then unset VRRP code.
+ * Cleanup daemon lib. Added some logging info for the daemon processing, removed
+ some repeated code part.
+ * Added 2 new daemon arguments :
+ --dont-release-vrrp : Dont remove VRRP VIPs on daemon stop
+ --dont-release-ipvs : Dont remove IPVS topology on daemon stop
+ * Review the global scheduling process to clear FD queues on master thread
+ destroy.
+ * Fixed a forking issue in the MISC_CHECK.
+ * Review IPVS wrapper functions to use allocated IPVS rules instead of static
+ referencing pointer.
+ * Fixed the IPVS wrapper to delete IPVS entries according to their 'alive' state.
+ * Added IPVS support to alive flag for VS entries.
+ * Rewrote the previous main.c to support configuration reload on the fly. Extented
+ signal handling to register a conf reload_thread on SIGHUP. The software design
+ used here is a dynamic differential conf file reloading framework. This design
+ offer key decision to add/remove new/old entries to/from low-level framework:
+ IPVS topology and netlink IP addresses entries. This design reduce to the max
+ the global service interruption since only negative diff entries are removed.
+ For VRRP config reload on the fly, if you plan to add/remove many VIPs consider
+ VIP declaration into the virtual_ipaddress_excluded since they are not present
+ into VRRP adverts.
+ * Review the keepalived.init script to support restart and reload arguments.
+ * Fixed some typo issues.
+
2002-07-16 Alexandre Cassen <acassen@linux-vs.org>
* keepalived-0.6.8 released.
* Alex Kramarov, <alex@incredimail.com> & Remi Nivet, <Remi.Nivet@atosorigin.com>
- hooks in VRRP framework for external checktools.
As state transition decision
- a VTYSH to administrate keepalived on the fly
-* Configuration file reload on signal. Extend the parser to use
- global scheduler with conf file stream.
* something I forgot right now :)
Summary: Generic HA monitor build upon VRRP and services poller, strongly recommanded for LVS HA.
Name: keepalived
Packager: Christophe Varoqui, <christophe.varoqui@free.fr>
-Version: 0.6.7
+Version: 0.6.9
Release: 1
-Source: http://www.keepalived.org/software/keepalived-0.6.7.tar.gz
+Source: http://www.keepalived.org/software/keepalived-0.6.9.tar.gz
Copyright: GPL
Group: Utilities/File
BuildRoot: /tmp/%{name}-%{version}.build
%prep
rm -rf %{buildroot}
-%setup -n keepalived-0.6.7
+%setup -n keepalived-0.6.9
%build
./configure --prefix=%{buildroot} --exec-prefix=%{buildroot} --sysconfdir=%{buildroot}/etc
INCLUDES = -I../include
CFLAGS = @CFLAGS@ $(INCLUDES) \
-Wall -Wunused -Wstrict-prototypes
-DEFS = -D@KERN@ -D@IPVS_SUPPORT@ @DFLAGS@
+DEFS = -D@KERN@ -D@IPVS_SUPPORT@ -D@VRRP_SUPPORT@ @DFLAGS@
COMPILE = $(CC) $(CFLAGS) $(DEFS)
OBJS = main.o memory.o daemon.o pidfile.o utils.o timer.o \
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: main.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* 2 of the License, or (at your option) any later version.
*/
+#include <syslog.h>
#include "daemon.h"
+#include "utils.h"
/* Daemonization function coming from zebra source code */
pid_t
/* In case of fork is error. */
pid = fork();
if (pid < 0) {
- perror("fork");
+ syslog(LOG_INFO, "xdaemon: fork error");
return -1;
}
/* Become session leader and get pid. */
pid = setsid();
if (pid < -1) {
- perror("setsid");
+ syslog(LOG_INFO, "xdaemon: setsid error");
return -1;
}
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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: data.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
SSL_DATA *ssl = (SSL_DATA *) MALLOC(sizeof (SSL_DATA));
return ssl;
}
-static void
+void
free_ssl(void)
{
SSL_DATA *ssl = conf_data->ssl;
new->adver_int = TIMER_HZ;
new->iname = (char *) MALLOC(size + 1);
memcpy(new->iname, iname, size);
+#ifdef _WITH_VRRP_
new->sync = vrrp_get_sync_group(iname);
+#endif
list_add(conf_data->vrrp, new);
}
}
void
-free_data(void)
+free_data(data * data)
{
- free_ssl();
- free_list(conf_data->email);
- free_list(conf_data->vrrp);
- free_list(conf_data->vrrp_sync_group);
- free_list(conf_data->vs);
- free_list(conf_data->group);
-
- FREE_PTR(conf_data->lvs_id);
- FREE_PTR(conf_data->email_from);
- FREE(conf_data);
+ free_list(data->email);
+ free_list(data->vrrp);
+ free_list(data->vrrp_sync_group);
+ free_list(data->vs);
+ free_list(data->group);
+
+ FREE_PTR(data->lvs_id);
+ FREE_PTR(data->email_from);
+ FREE(data);
}
void
-dump_data(void)
+dump_data(data * data)
{
- if (conf_data->lvs_id ||
- conf_data->smtp_server ||
- conf_data->smtp_connection_to || conf_data->email_from) {
+ if (data->lvs_id ||
+ data->smtp_server ||
+ data->smtp_connection_to || data->email_from) {
syslog(LOG_INFO, "------< Global definitions >------");
}
- if (conf_data->lvs_id)
- syslog(LOG_INFO, " LVS ID = %s", conf_data->lvs_id);
- if (conf_data->smtp_server)
+ if (data->lvs_id)
+ syslog(LOG_INFO, " LVS ID = %s", data->lvs_id);
+ if (data->smtp_server)
syslog(LOG_INFO, " Smtp server = %s",
- inet_ntop2(conf_data->smtp_server));
- if (conf_data->smtp_connection_to)
+ inet_ntop2(data->smtp_server));
+ if (data->smtp_connection_to)
syslog(LOG_INFO, " Smtp server connection timeout = %d",
- conf_data->smtp_connection_to);
- if (conf_data->email_from) {
+ data->smtp_connection_to);
+ if (data->email_from) {
syslog(LOG_INFO, " Email notification from = %s",
- conf_data->email_from);
- dump_list(conf_data->email);
+ data->email_from);
+ dump_list(data->email);
}
- if (conf_data->ssl) {
+ if (data->ssl) {
syslog(LOG_INFO, "------< SSL definitions >------");
dump_ssl();
}
- if (!LIST_ISEMPTY(conf_data->vrrp)) {
+ if (!LIST_ISEMPTY(data->vrrp)) {
syslog(LOG_INFO, "------< VRRP Topology >------");
- dump_list(conf_data->vrrp);
+ dump_list(data->vrrp);
}
- if (!LIST_ISEMPTY(conf_data->vrrp_sync_group)) {
+ if (!LIST_ISEMPTY(data->vrrp_sync_group)) {
syslog(LOG_INFO, "------< VRRP Sync groups >------");
- dump_list(conf_data->vrrp_sync_group);
+ dump_list(data->vrrp_sync_group);
}
- if (!LIST_ISEMPTY(conf_data->group)) {
+ if (!LIST_ISEMPTY(data->group)) {
syslog(LOG_INFO, "------< Real Servers groups >------");
- dump_list(conf_data->group);
+ dump_list(data->group);
}
#ifdef _WITH_LVS_
- if (!LIST_ISEMPTY(conf_data->vs)) {
+ if (!LIST_ISEMPTY(data->vs)) {
syslog(LOG_INFO, "------< LVS Topology >------");
syslog(LOG_INFO, " System is compiled with LVS v%d.%d.%d",
NVERSION(IP_VS_VERSION_CODE));
- dump_list(conf_data->vs);
+ dump_list(data->vs);
}
dump_checkers_queue();
#endif
* Part: Layer4 checkers handling. Register worker threads &
* upper layer checkers.
*
- * Version: $Id: layer4.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: layer4.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: List structure manipulation.
*
- * Version: $Id: list.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: list.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program structure.
*
- * Version: $Id: main.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: main.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "main.h"
+/* Daemon stop sequence */
+static void
+stop_keepalived(void)
+{
+ syslog(LOG_INFO, "Stopping " VERSION_STRING);
+ /* Just cleanup memory & exit */
+ thread_destroy_master(master);
+#ifdef _WITH_LVS_
+ free_checkers_queue();
+ free_ssl();
+ if (!(debug & 16))
+ clear_services();
+#endif
+#ifdef _WITH_VRRP_
+ if (!(debug & 8))
+ shutdown_vrrp_instances();
+ free_interface_queue();
+#endif
+ free_data(conf_data);
+
+ pidfile_rm();
+
+#ifdef _DEBUG_
+ keepalived_free_final();
+#endif
+
+ /*
+ * Reached when terminate signal catched.
+ * finally return from system
+ */
+ closelog();
+ exit(0);
+}
+
+/* Daemon init sequence */
+static void
+start_keepalived(void)
+{
+ /* Parse the configuration file */
+#ifdef _WITH_LVS_
+ init_checkers_queue();
+#endif
+ init_data(conf_file);
+ if (!conf_data) {
+ syslog(LOG_INFO, "Stopping " VERSION_STRING);
+ closelog();
+#ifdef _DEBUG_
+ keepalived_free_final();
+#endif
+ exit(0);
+ }
+
+ /* SSL load static data & initialize common ctx context */
+#ifdef _WITH_LVS_
+ if (!init_ssl_ctx()) {
+ closelog();
+#ifdef _DEBUG_
+ keepalived_free_final();
+#endif
+ exit(0);
+ }
+#endif
+
+#ifdef _WITH_LVS_
+ if (reload)
+ clear_diff_services();
+
+ if (!init_services()) {
+ syslog(LOG_INFO, "Stopping " VERSION_STRING);
+ closelog();
+ free_data(conf_data);
+ exit(0);
+ }
+
+ /* register healthcheckers workers threads */
+ register_checkers_thread();
+#endif
+
+#ifdef _WITH_VRRP_
+ kernel_netlink_init();
+ if_mii_poller_init();
+
+ if (!vrrp_complete_init()) {
+ stop_keepalived();
+ exit(0);
+ }
+
+ if (reload)
+ clear_diff_vrrp();
+
+ /* register vrrp workers threads */
+ register_vrrp_thread();
+#endif
+
+ /* Dump the configuration */
+ if (debug & 4)
+ dump_data(conf_data);
+}
+
+/* reload handler */
+int
+reload_thread(thread * thread)
+{
+ /* set the reloading flag */
+ SET_RELOAD;
+
+ /* Flushing previous configuration */
+ thread_destroy_master(master);
+ master = thread_make_master();
+#ifdef _WITH_LVS_
+ free_checkers_queue();
+ free_ssl();
+#endif
+
+ /* Save previous conf */
+ old_data = conf_data;
+ conf_data = NULL;
+
+ /* Reload the conf */
+ mem_allocated = 0;
+ start_keepalived();
+
+ free_data(old_data);
+
+ /* free the reloading flag */
+ UNSET_RELOAD;
+
+ return 0;
+}
+
/* SIGHUP handler */
void
sighup(int sig)
{
- syslog(LOG_INFO, "Terminating on signal");
+ /* register the conf reload thread */
+ syslog(LOG_INFO, "Reloading configuration file");
+ thread_add_event(master, reload_thread, NULL, 0);
+}
+/* Terminate handler */
+void
+sigend(int sig)
+{
/* register the terminate thread */
+ syslog(LOG_INFO, "Terminating on signal");
thread_add_terminate_event(master);
}
sig.sa_flags = 0;
#ifdef SA_RESTART
sig.sa_flags |= SA_RESTART;
-#endif /* SA_RESTART */
+#endif /* SA_RESTART */
ret = sigaction(signo, &sig, &osig);
signal_init(void)
{
signal_set(SIGHUP, sighup);
- signal_set(SIGINT, sighup);
- signal_set(SIGTERM, sighup);
- signal_set(SIGKILL, sighup);
+ signal_set(SIGINT, sigend);
+ signal_set(SIGTERM, sigend);
+ signal_set(SIGKILL, sigend);
signal_set(SIGCHLD, sigchld);
}
+/* Our scheduler */
+static void
+launch_scheduler(void)
+{
+ thread thread;
+
+ /*
+ * Processing the master thread queues,
+ * return and execute one ready thread.
+ */
+ while (thread_fetch(master, &thread)) {
+ /* Run until error, used for debuging only */
+#ifdef _DEBUG_
+ if ((debug & 520) == 520) {
+ debug &= ~520;
+ thread_add_terminate_event(master);
+ }
+#endif
+ thread_call(&thread);
+ }
+}
+
/* Usage function */
static void
usage(const char *prog)
fprintf(stderr,
"Commands:\n"
"Either long or short options are allowed.\n"
- " %s --dont-fork -n Dont fork the daemon process.\n"
- " %s --use-file -f Use the specified configuration file.\n"
+ " %s --dont-release-vrrp -V Dont remove VRRP VIPs on daemon stop.\n"
+ " %s --dont-release-ipvs -I Dont remove IPVS topology on daemon stop.\n"
+ " %s --dont-fork -n Dont fork the daemon process.\n"
+ " %s --use-file -f Use the specified configuration file.\n"
" Default is /etc/keepalived/keepalived.conf.\n"
- " %s --dump-conf -d Dump the configuration data.\n"
- " %s --log-console -l Log message to local console.\n"
- " %s --help -h Display this short inlined help screen.\n"
- " %s --version -v Display the version number\n",
- prog, prog, prog, prog, prog, prog);
+ " %s --dump-conf -d Dump the configuration data.\n"
+ " %s --log-console -l Log message to local console.\n"
+ " %s --help -h Display this short inlined help screen.\n"
+ " %s --version -v Display the version number\n",
+ prog, prog, prog, prog, prog, prog, prog, prog);
}
/* Command line parser */
-static char *
+static void
parse_cmdline(int argc, char **argv)
{
poptContext context;
char *optarg = NULL;
- char *conf_file = NULL;
int c;
struct poptOption options_table[] = {
{"version", 'v', POPT_ARG_NONE, NULL, 'v'},
{"help", 'h', POPT_ARG_NONE, NULL, 'h'},
{"log-console", 'l', POPT_ARG_NONE, NULL, 'l'},
+ {"dont-release-vrrp", 'V', POPT_ARG_NONE, NULL, 'V'},
+ {"dont-release-ipvs", 'I', POPT_ARG_NONE, NULL, 'I'},
{"dont-fork", 'n', POPT_ARG_NONE, NULL, 'n'},
{"dump-conf", 'd', POPT_ARG_NONE, NULL, 'd'},
{"use-file", 'f', POPT_ARG_STRING, &optarg, 'f'},
context =
poptGetContext(PROG, argc, (const char **) argv, options_table, 0);
if ((c = poptGetNextOpt(context)) < 0) {
- return NULL;
+ return;
}
/* The first option car */
case 'd':
debug |= 4;
break;
+ case 'V':
+ debug |= 8;
+ break;
+ case 'I':
+ debug |= 16;
+ break;
case 'f':
conf_file = optarg;
break;
case 'd':
debug |= 4;
break;
+ case 'V':
+ debug |= 8;
+ break;
+ case 'I':
+ debug |= 16;
+ break;
case 'f':
conf_file = optarg;
break;
/* check unexpected arguments */
if ((optarg = (char *) poptGetArg(context))) {
fprintf(stderr, "unexpected argument %s\n", optarg);
- return NULL;
+ return;
}
/* free the allocated context */
poptFreeContext(context);
-
- return ((conf_file) ? conf_file : NULL);
}
/* Entry point */
int
main(int argc, char **argv)
{
- char *conf_file = NULL;
- thread thread;
-
/* Init debugging level */
debug = 0;
* Parse command line and set debug level.
* bits 0..7 reserved by main.c
*/
- conf_file = parse_cmdline(argc, argv);
+ parse_cmdline(argc, argv);
openlog(PROG, LOG_PID | (debug & 1) ? LOG_CONS : 0, LOG_DAEMON);
syslog(LOG_INFO, "Starting " VERSION_STRING);
/* Signal handling initialization */
signal_init();
- /* Init interface queue */
- init_interface_queue();
-
- /* Parse the configuration file */
-#ifdef _WITH_LVS_
- init_checkers_queue();
-#endif
- init_data(conf_file);
- if (!conf_data) {
- syslog(LOG_INFO, "Stopping " VERSION_STRING);
- closelog();
-#ifdef _DEBUG_
- keepalived_free_final();
-#endif
- exit(0);
- }
-
- /* SSL load static data & initialize common ctx context */
-#ifdef _WITH_LVS_
- if (!init_ssl_ctx()) {
- closelog();
-#ifdef _DEBUG_
- keepalived_free_final();
-#endif
- exit(0);
- }
-#endif
-
-#ifdef _WITH_LVS_
- if (!init_services()) {
- syslog(LOG_INFO, "Stopping " VERSION_STRING);
- closelog();
- free_data();
- exit(0);
- }
-#endif
-
/* Create the master thread */
master = thread_make_master();
- /* register workers threads */
- kernel_netlink_init();
- if_mii_poller_init();
-#ifdef _WITH_LVS_
- register_checkers_thread();
-#endif
- if (!vrrp_complete_init())
- goto end;
- register_vrrp_thread();
-
- /* Dump the configuration */
- if (debug & 4)
- dump_data();
-
- /* processing the master thread queues, return and execute one ready thread */
- while (thread_fetch(master, &thread)) {
-
- /* Run until error, used for debuging only */
-#ifdef _DEBUG_
- if ((debug & 520) == 520) {
- debug &= ~520;
- thread_add_terminate_event(master);
- }
-#endif
- thread_call(&thread);
- }
-
-end:
- /* Reached when terminate signal catched */
- syslog(LOG_INFO, "Stopping " VERSION_STRING);
- /* Just cleanup memory & exit */
- thread_destroy_master(master);
-#ifdef _WITH_LVS_
- free_checkers_queue();
- clear_services();
+#ifdef _WITH_VRRP_
+ /* Init interface queue */
+ init_interface_queue();
#endif
- shutdown_vrrp_instances();
- free_interface_queue();
- free_data();
- pidfile_rm();
+ /* Init daemon data related */
+ start_keepalived();
-#ifdef _DEBUG_
- keepalived_free_final();
-#endif
+ /* Launch the scheduling I/O multiplexer */
+ launch_scheduler();
- /* finally return from system */
- closelog();
+ /* Finish daemon process */
+ stop_keepalived();
exit(0);
}
* Part: Memory management framework. This framework is used to
* find any memory leak.
*
- * Version: $Id: memory.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: memory.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
* data structure representation the conf file representing
* the loadbalanced server pool.
*
- * Version: $Id: parser.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: parser.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
static void
vrrp_int_handler(vector strvec)
{
+#ifdef _WITH_VRRP_
vrrp_rt *vrrp = LIST_TAIL_DATA(conf_data->vrrp);
char *name = VECTOR_SLOT(strvec, 1);
-
vrrp->ifp = if_get_by_ifname(name);
+#endif
}
static void
vrrp_mcastip_handler(vector strvec)
*
* Part: pidfile utility.
*
- * Version: $Id: pidfile.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: pidfile.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* the thread management routine (thread.c) present in the
* very nice zebra project (http://www.zebra.org).
*
- * Version: $Id: scheduler.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: scheduler.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
{
struct _thread *tt;
- for (tt = list->head; tt; tt = tt->next)
+ for (tt = list->head; tt; tt = tt->next) {
if (timer_cmp(thread->sands, tt->sands) <= 0)
break;
+ }
if (tt)
thread_list_add_before(list, tt, thread);
}
/* Move list element to unuse queue */
-void
+static void
thread_destroy_list(thread_master * m, thread_list thread_list)
{
thread *thread;
}
}
-/* Stop thread scheduler. */
-void
-thread_destroy_master(thread_master * m)
+/* Cleanup master */
+static void
+thread_cleanup_master(thread_master * m)
{
+ /* Unuse current thread lists */
thread_destroy_list(m, m->read);
thread_destroy_list(m, m->write);
thread_destroy_list(m, m->timer);
thread_destroy_list(m, m->event);
thread_destroy_list(m, m->ready);
+ /* Clear all FDs */
+ FD_ZERO(&m->readfd);
+ FD_ZERO(&m->writefd);
+ FD_ZERO(&m->exceptfd);
+
+ /* Clean garbage */
thread_clean_unuse(m);
+}
+
+/* Stop thread scheduler. */
+void
+thread_destroy_master(thread_master * m)
+{
+ thread_cleanup_master(m);
FREE(m);
}
* 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: smtp.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Timer manipulations.
*
- * Version: $Id: timer.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: timer.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: General program utils.
*
- * Version: $Id: utils.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: utils.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Vector structure manipulation.
*
- * Version: $Id: vector.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vector.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
kill $PID
echo
;;
+ restart)
+ echo -n "Shutting down Keepalived for LVS: "
+ PID=`cat $PID_FILE`
+ kill $PID
+ echo
+ echo -n "Starting Keepalived for LVS: "
+ keepalived
+ echo
+ ;;
+ reload)
+ echo -n "Reloading Keepalived config: "
+ killall -HUP keepalived
+ echo
+ ;;
*)
- echo "Usage: $0 {start|stop}"
+ echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
../include/memory.h ../include/ipwrapper.h ../include/smtp.h \
../include/utils.h ../include/parser.h ../include/daemon.h
ipwrapper.o: ipwrapper.c ../include/ipwrapper.h ../include/utils.h
-ipvswrapper.o: ipvswrapper.c ../include/ipvswrapper.h ../include/utils.h
+ipvswrapper.o: ipvswrapper.c ../include/ipvswrapper.h ../include/utils.h \
+ ../include/memory.h
*
* Part: Checkers registration.
*
- * Version: $Id: check_api.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_api.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
(*checker->dump) (checker);
}
-/* init the global checkers queue */
-void
-init_checkers_queue(void)
-{
- checkers_queue = alloc_list(free_checker, dump_checker);
-}
-
/* Queue a checker to the checkers_queue */
void
queue_checker(void (*free) (void *), void (*dump) (void *)
}
}
+/* init the global checkers queue */
+void
+init_checkers_queue(void)
+{
+ checkers_queue = alloc_list(free_checker, dump_checker);
+}
+
/* release the checkers_queue */
void
free_checkers_queue(void)
checker *checker;
element e;
+ /* Display netlink operation */
+ syslog(LOG_INFO, "Netlink reflector reports IP %s %s",
+ inet_ntop2(address), (enable) ? "added" : "removed");
+
/* Processing Healthcheckers queue */
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_ENABLED(checker) && enable) {
- syslog(LOG_INFO,
- "Netlink reflector reports IP %s added",
- inet_ntop2(address));
- syslog(LOG_INFO,
- "Activating healtchecker for VIP %s",
- inet_ntop2(address));
- }
- if (CHECKER_ENABLED(checker) && !enable) {
+ if (!CHECKER_ENABLED(checker) && enable)
syslog(LOG_INFO,
- "Netlink reflector reports IP %s removed",
- inet_ntop2(address));
+ "Activating healtchecker for service [%s:%d]",
+ inet_ntop2(CHECKER_RIP(checker)),
+ ntohs(CHECKER_RPORT(checker)));
+ if (CHECKER_ENABLED(checker) && !enable)
syslog(LOG_INFO,
- "Suspending healtchecker for VIP %s",
- inet_ntop2(address));
- }
+ "Suspending healtchecker for service [%s:%d]",
+ inet_ntop2(CHECKER_RIP(checker)),
+ ntohs(CHECKER_RPORT(checker)));
checker->enabled = enable;
}
}
*
* Part: CI-LINUX checker. Integration to Compaq Cluster Infrastructure.
*
- * Version: $Id: check_ci.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_ci.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Aneesh Kumar K.V, <aneesh.kumar@digital.com>
*
* Part: WEB CHECK. Common HTTP/SSL checker primitives.
*
- * Version: $Id: check_http.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_http.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
* Part: MISC CHECK. Perform a system call to run an extra
* system prog or script.
*
- * Version: $Id: check_misc.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_misc.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
}
int
-misc_check_call(char *cmdline)
-{
- int retval;
-
- retval = system(cmdline);
-
- if (retval == 127) {
- /* couldn't exec command */
- DBG("Couldn't exec command: %s", cmdline);
- } else if (retval == -1) {
- /* other error */
- DBG("Error exec-ing command: %s", cmdline);
- } else {
- /* everything is good */
- DBG("Successfully exec command: %s retval is %d",
- cmdline, retval);
- }
-
- return retval;
-}
-
-int
misc_check_thread(thread * thread)
{
checker *checker;
misc_checker *misc_chk;
int status;
+ pid_t pid;
checker = THREAD_ARG(thread);
misc_chk = CHECKER_ARG(checker);
- /* Register next timer checker */
- thread_add_timer(thread->master, misc_check_thread, checker,
- checker->vs->delay_loop);
/*
* Register a new checker thread & return
* if checker is disabled
*/
- if (!CHECKER_ENABLED(checker))
+ if (!CHECKER_ENABLED(checker)) {
+ /* Register next timer checker */
+ thread_add_timer(thread->master, misc_check_thread, checker,
+ checker->vs->delay_loop);
return 0;
+ }
/* Daemonization to not degrade our scheduling timer */
- if (xdaemon(0, 0, 1))
- return 0x80000000;
+ pid = fork();
- status = misc_check_call(misc_chk->path);
+ /* 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);
+
+ status = system_call(misc_chk->path);
if (status >= 0) { /* script error assumed not an svr error */
if (status == 0) {
/* everything is good */
- if (!checker->rs->alive) {
+ if (!ISALIVE(checker->rs)) {
smtp_alert(thread->master, checker->rs, NULL,
"UP",
"=> MISC CHECK succeed on service <=\n\n");
perform_svr_state(UP, checker->vs, checker->rs);
}
} else {
- if (checker->rs->alive) {
+ if (ISALIVE(checker->rs)) {
smtp_alert(thread->master, checker->rs, NULL,
"DOWN",
"=> MISC CHECK failed on service <=\n\n");
- perform_svr_state(DOWN, checker->vs,
- checker->rs);
+ perform_svr_state(DOWN, checker->vs, checker->rs);
}
}
}
+ /* Register next timer checker */
+ thread_add_timer(thread->master, misc_check_thread, checker,
+ checker->vs->delay_loop);
+
exit(0);
}
* url, compute a MD5 over this result and match it to the
* expected value.
*
- * Version: $Id: check_ssl.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_ssl.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: TCP checker.
*
- * Version: $Id: check_tcp.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_tcp.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* library to add/remove server MASQ rules to the kernel
* firewall framework.
*
- * Version: $Id: ipfwwrapper.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: ipfwwrapper.c,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: ipvswrapper.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "ipvswrapper.h"
#include "utils.h"
+#include "memory.h"
/* local helpers functions */
static int parse_timeout(char *, unsigned *);
int
ipvs_cmd(int cmd, virtual_server * vs, real_server * rs)
{
- struct ip_vs_rule_user urule;
+ struct ip_vs_rule_user *urule;
+ int err = 0;
- memset(&urule, 0, sizeof (struct ip_vs_rule_user));
+ urule = (struct ip_vs_rule_user *) MALLOC(sizeof (struct ip_vs_rule_user));
+ memset(urule, 0, sizeof (struct ip_vs_rule_user));
- strncpy(urule.sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
- urule.weight = 1;
- urule.conn_flags = vs->loadbalancing_kind;
- urule.netmask = ((u_int32_t) 0xffffffff);
- urule.protocol = vs->service_type;
+ strncpy(urule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
+ urule->weight = 1;
+ urule->conn_flags = vs->loadbalancing_kind;
+ urule->netmask = ((u_int32_t) 0xffffffff);
+ urule->protocol = vs->service_type;
- if (!parse_timeout(vs->timeout_persistence, &urule.timeout))
+ if (!parse_timeout(vs->timeout_persistence, &urule->timeout))
syslog(LOG_INFO,
"IPVS : Virtual service [%s:%d] illegal timeout.",
inet_ntop2(SVR_IP(vs)), ntohs(SVR_PORT(vs)));
- if (urule.timeout != 0 || vs->granularity_persistence)
- urule.vs_flags = IP_VS_SVC_F_PERSISTENT;
+ if (urule->timeout != 0 || vs->granularity_persistence)
+ urule->vs_flags = IP_VS_SVC_F_PERSISTENT;
/* VS specific */
if (vs->vfwmark) {
- urule.vfwmark = vs->vfwmark;
+ urule->vfwmark = vs->vfwmark;
} else {
- urule.vaddr = SVR_IP(vs);
- urule.vport = SVR_PORT(vs);
+ urule->vaddr = SVR_IP(vs);
+ urule->vport = SVR_PORT(vs);
}
if (cmd == IP_VS_SO_SET_ADD || cmd == IP_VS_SO_SET_DEL)
if (vs->granularity_persistence)
- urule.netmask = vs->granularity_persistence;
+ urule->netmask = vs->granularity_persistence;
/* SVR specific */
if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST) {
- urule.weight = rs->weight;
- urule.daddr = SVR_IP(rs);
- urule.dport = SVR_PORT(rs);
+ urule->weight = rs->weight;
+ urule->daddr = SVR_IP(rs);
+ urule->dport = SVR_PORT(rs);
}
/* Does the service use inhibit flag ? */
if (cmd == IP_VS_SO_SET_DELDEST && rs->inhibit) {
- urule.weight = 0;
+ urule->weight = 0;
cmd = IP_VS_SO_SET_EDITDEST;
}
if (cmd == IP_VS_SO_SET_ADDDEST && rs->inhibit && rs->alive)
cmd = IP_VS_SO_SET_EDITDEST;
/* Talk to the IPVS channel */
- return ipvs_talk(cmd, &urule);
+ err = ipvs_talk(cmd, urule);
+
+ FREE(urule);
+ return err;
}
#endif
*
* Part: Manipulation functions for IPVS & IPFW wrappers.
*
- * Version: $id: ipwrapper.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $id: ipwrapper.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "ipwrapper.h"
#include "utils.h"
+/* extern global vars */
extern data *conf_data;
+extern data *old_data;
+/* Remove a realserver IPVS rule */
static int
clear_service_rs(virtual_server * vs, list l)
{
element e;
+ real_server *rs;
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
- if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, ELEMENT_DATA(e)))
- return 0;
+ rs = ELEMENT_DATA(e);
+ if (ISALIVE(rs))
+ if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, rs))
+ return 0;
#ifdef _KRNL_2_2_
/* if we have a /32 mask, we create one nat rules per
* realserver.
*/
if (vs->nat_mask == HOST_NETMASK)
- if (!ipfw_cmd(IP_FW_CMD_DEL, vs, ELEMENT_DATA(e)))
+ if (!ipfw_cmd(IP_FW_CMD_DEL, vs, rs))
return 0;
#endif
}
return 1;
}
-int
+/* Remove a virtualserver IPVS rule */
+static int
clear_service_vs(virtual_server * vs)
{
element e;
/* Processing real server queue */
if (!LIST_ISEMPTY(vs->rs)) {
if (vs->s_svr) {
- if (vs->s_svr->alive)
+ if (ISALIVE(vs->s_svr))
if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs, vs->s_svr))
return 0;
} else if (!clear_service_rs(vs, vs->rs))
clear_services(void)
{
element e;
- list vs = conf_data->vs;
- virtual_server *vsvr;
- real_server *rsvr;
-
- for (e = LIST_HEAD(vs); e; ELEMENT_NEXT(e)) {
- vsvr = ELEMENT_DATA(e);
- rsvr = ELEMENT_DATA(LIST_HEAD(vsvr->rs));
- if (!clear_service_vs(vsvr))
+ list l = conf_data->vs;
+ virtual_server *vs;
+ real_server *rs;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vs = ELEMENT_DATA(e);
+ rs = ELEMENT_DATA(LIST_HEAD(vs->rs));
+ if (!clear_service_vs(vs))
return 0;
#ifdef _KRNL_2_2_
- if (vsvr->nat_mask != HOST_NETMASK)
- if (!ipfw_cmd(IP_FW_CMD_DEL, vsvr, rsvr))
+ if (vs->nat_mask != HOST_NETMASK)
+ if (!ipfw_cmd(IP_FW_CMD_DEL, vs, rs))
+ return 0;
+#endif
+ }
+ return 1;
+}
+
+/* Set a realserver IPVS rules */
+static int
+init_service_rs(virtual_server * vs, list l)
+{
+ element e;
+ real_server *rs;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ rs = ELEMENT_DATA(e);
+ if (!ISALIVE(rs)) {
+ if (!ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs))
+ return 0;
+ else
+ SET_ALIVE(rs);
+ }
+#ifdef _KRNL_2_2_
+ /* if we have a /32 mask, we create one nat rules per
+ * realserver.
+ */
+ if (vs->nat_mask == HOST_NETMASK)
+ if (!ipfw_cmd(IP_FW_CMD_ADD, vs, rs))
+ return 0;
+#endif
+ }
+ return 1;
+}
+
+/* Set a virtualserver IPVS rules */
+static int
+init_service_vs(virtual_server * vs)
+{
+ element e;
+ real_server_group *group;
+
+ /* Init the VS root */
+ if (!ISALIVE(vs)) {
+ if (!ipvs_cmd(LVS_CMD_ADD, vs, NULL))
+ return 0;
+ else
+ SET_ALIVE(vs);
+ }
+
+ /* Processing real server queue */
+ if (!LIST_ISEMPTY(vs->rs))
+ if (!init_service_rs(vs, vs->rs))
+ return 0;
+
+ /* Processing real server group queue */
+ if (!LIST_ISEMPTY(vs->rs_group)) {
+ for (e = LIST_HEAD(vs->rs_group); e; ELEMENT_NEXT(e)) {
+ group = ELEMENT_DATA(e);
+ if (!init_service_rs(vs, group->rs))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/* Set IPVS rules */
+int
+init_services(void)
+{
+ element e;
+ list l = conf_data->vs;
+ virtual_server *vs;
+ real_server *rs;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vs = ELEMENT_DATA(e);
+ rs = ELEMENT_DATA(LIST_HEAD(vs->rs));
+ if (!init_service_vs(vs))
+ return 0;
+#ifdef _KRNL_2_2_
+ /* work if all realserver ip address are in the
+ * same network (it is assumed).
+ */
+ if (vs->nat_mask != HOST_NETMASK)
+ if (!ipfw_cmd(IP_FW_CMD_ADD, vs, rs))
return 0;
#endif
}
return 1;
}
+/* Check if all rs for a specific vs are down */
int
all_realservers_down(virtual_server * vs)
{
for (e = LIST_HEAD(vs->rs); e; ELEMENT_NEXT(e)) {
svr = ELEMENT_DATA(e);
- if (svr->alive)
+ if (ISALIVE(svr))
return 0;
}
return 1;
}
+/* manipulate add/remove rs according to alive state */
void
perform_svr_state(int alive, virtual_server * vs, real_server * rs)
{
* we remove it from the vs pool.
*/
if (vs->s_svr) {
- if (vs->s_svr->alive) {
+ if (ISALIVE(vs->s_svr)) {
syslog(LOG_INFO,
"Removing sorry server [%s:%d] from VS [%s:%d]",
inet_ntoa2(SVR_IP(vs->s_svr), rsip)
}
}
+/* Check if rs1 = rs2 */
static int
-init_service_rs(virtual_server * vs, list l)
+rs_iseq(real_server * rs1, real_server * rs2)
+{
+ if (rs1->addr_ip == rs2->addr_ip &&
+ rs1->addr_port == rs2->addr_port &&
+ rs1->weight == rs2->weight)
+ return 1;
+ return 0;
+}
+
+/* Check if vs1 = vs2 */
+static int
+vs_iseq(virtual_server * vs1, virtual_server * vs2)
+{
+ if (vs1->addr_ip == vs2->addr_ip &&
+ vs1->vfwmark == vs2->vfwmark &&
+ vs1->addr_port == vs2->addr_port &&
+ vs1->service_type == vs2->service_type &&
+ !strcmp(vs1->sched, vs2->sched) &&
+ !strcmp(vs1->timeout_persistence, vs2->timeout_persistence) &&
+ vs1->loadbalancing_kind == vs2->loadbalancing_kind &&
+ vs1->nat_mask == vs2->nat_mask &&
+ vs1->granularity_persistence == vs2->granularity_persistence)
+ return 1;
+ return 0;
+}
+
+/* Check if a vs exist in new data */
+static int
+vs_exist(virtual_server * old_vs)
+{
+ element e;
+ list l = conf_data->vs;
+ virtual_server *vs;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vs = ELEMENT_DATA(e);
+ if (vs_iseq(old_vs, vs)) {
+ /*
+ * We reflect the previous alive
+ * flag value to not try to set
+ * already set IPVS rule.
+ */
+ vs->alive = old_vs->alive;
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* Check if rs is in new vs data */
+static int
+rs_exist(real_server * old_rs, list l)
{
element e;
real_server *rs;
for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
rs = ELEMENT_DATA(e);
- if (!ipvs_cmd(LVS_CMD_ADD_DEST, vs, rs))
- return 0;
- else
- rs->alive = 1;
-#ifdef _KRNL_2_2_
- /* if we have a /32 mask, we create one nat rules per
- * realserver.
- */
- if (vs->nat_mask == HOST_NETMASK)
- if (!ipfw_cmd(IP_FW_CMD_ADD, vs, rs))
- return 0;
-#endif
+ if (rs_iseq(rs, old_rs)) {
+ /*
+ * We reflect the previous alive
+ * flag value to not try to set
+ * already set IPVS rule.
+ */
+ rs->alive = old_rs->alive;
+ return 1;
+ }
}
- return 1;
+
+ return 0;
}
-int
-init_service_vs(virtual_server * vs)
+/* get rs list for a specific vs */
+static list
+get_rs_list(virtual_server * vs)
{
element e;
- real_server_group *group;
+ list l = conf_data->vs;
+ virtual_server *vsrv;
- /* Init the IPVS root */
- if (!ipvs_cmd(LVS_CMD_ADD, vs, NULL))
- return 0;
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vsrv = ELEMENT_DATA(e);
+ if (vs_iseq(vs, vsrv))
+ return vsrv->rs;
+ }
- /* Processing real server queue */
- if (!LIST_ISEMPTY(vs->rs))
- if (!init_service_rs(vs, vs->rs))
- return 0;
+ /* most of the time never reached */
+ return NULL;
+}
- /* Processing real server group queue */
- if (!LIST_ISEMPTY(vs->rs_group)) {
- for (e = LIST_HEAD(vs->rs_group); e; ELEMENT_NEXT(e)) {
- group = ELEMENT_DATA(e);
- if (!init_service_rs(vs, group->rs))
+/* Clear the diff rs of the old vs */
+static int
+clear_diff_rs(virtual_server * old_vs)
+{
+ element e;
+ list l = old_vs->rs;
+ list new = get_rs_list(old_vs);
+ real_server *rs;
+ char rsip[16], vsip[16];
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ rs = ELEMENT_DATA(e);
+ if (!rs_exist(rs, new) && (ISALIVE(rs) || rs->inhibit)) {
+ /* Reset inhibit flag to delete inhibit entries */
+ syslog(LOG_INFO, "service [%s:%d] no longer exist"
+ , inet_ntoa2(SVR_IP(rs), rsip)
+ , ntohs(SVR_PORT(rs)));
+ syslog(LOG_INFO, "Removing service [%s:%d] from VS [%s:%d]"
+ , inet_ntoa2(SVR_IP(rs), rsip)
+ , ntohs(SVR_PORT(rs))
+ , inet_ntoa2(SVR_IP(old_vs), vsip)
+ , ntohs(SVR_PORT(old_vs)));
+ rs->inhibit = 0;
+ if (!ipvs_cmd(LVS_CMD_DEL_DEST, old_vs, rs))
+ return 0;
+ } else if (!ISALIVE(rs) && rs->inhibit) {
+ /*
+ * We duplicate here just for optimization. We
+ * don t want to call rs_exist() 2 times.
+ */
+ rs->inhibit = 0;
+ if (!ipvs_cmd(LVS_CMD_DEL_DEST, old_vs, rs))
return 0;
}
}
+
return 1;
}
+/* When reloading configuration, remove negative diff entries */
int
-init_services(void)
+clear_diff_services(void)
{
element e;
- list vs = conf_data->vs;
- virtual_server *vsvr;
- real_server *rsvr;
-
- for (e = LIST_HEAD(vs); e; ELEMENT_NEXT(e)) {
- vsvr = ELEMENT_DATA(e);
- rsvr = ELEMENT_DATA(LIST_HEAD(vsvr->rs));
- if (!init_service_vs(vsvr))
- return 0;
-#ifdef _KRNL_2_2_
- /* work if all realserver ip address are in the
- * same network (it is assumed).
+ list l = old_data->vs;
+ virtual_server *vs;
+
+ /* Remove diff entries from previous IPVS rules */
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vs = ELEMENT_DATA(e);
+
+ /*
+ * Try to find this vs into the new conf data
+ * reloaded.
*/
- if (vsvr->nat_mask != HOST_NETMASK)
- if (!ipfw_cmd(IP_FW_CMD_ADD, vsvr, rsvr))
+ if (!vs_exist(vs)) {
+ if (!clear_service_vs(vs))
return 0;
-#endif
+ } else {
+ /* If vs exist, perform rs pool diff */
+ if (!clear_diff_rs(vs))
+ return 0;
+ if (vs->s_svr)
+ if (ISALIVE(vs->s_svr))
+ if (!ipvs_cmd(LVS_CMD_DEL_DEST, vs,
+ vs->s_svr))
+ return 0;
+ }
}
+
return 1;
}
*
* Part: Checkers arguments structures definitions.
*
- * Version: $Id: check_api.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_api.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: check_ci.c include file.
*
- * Version: $Id: check_ci.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_ci.h,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_http.h,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_misc.h,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_http.h,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: check_tcp.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Daemon process handling.
*
- * Version: $Id: daemon.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: daemon.h,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: data.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
int last_rs_type;
#define RS (1 << 0)
#define RS_GROUP (1 << 1)
+ int alive;
} virtual_server;
/* email link list */
} data;
/* macro utility */
-#define ISALIVE(R) ((R)->alive)
-#define SVR_IP(H) ((H)->addr_ip)
-#define SVR_PORT(H) ((H)->addr_port)
-#define VHOST(V) ((V)->virtualhost)
-#define LAST_RS_TYPE(V) ((V)->last_rs_type)
+#define ISALIVE(S) ((S)->alive)
+#define SET_ALIVE(S) ((S)->alive = 1)
+#define UNSET_ALIVE(S) ((S)->alive = 0)
+#define SVR_IP(H) ((H)->addr_ip)
+#define SVR_PORT(H) ((H)->addr_port)
+#define VHOST(V) ((V)->virtualhost)
+#define LAST_RS_TYPE(V) ((V)->last_rs_type)
/* prototypes */
extern void alloc_email(char *addr);
extern SSL_DATA *alloc_ssl(void);
+extern void free_ssl(void);
extern void alloc_vrrp_sync_group(char *gname);
extern void alloc_vrrp(char *iname);
extern void alloc_vrrp_vip(char *vip);
extern void set_rsgroup(char *gname);
extern data *alloc_data(void);
-extern void free_data(void);
-extern void dump_data(void);
+extern void free_data(data * data);
+extern void dump_data(data * data);
#endif
*
* Part: ipfwwrapper.c include file.
*
- * Version: $Id: ipfwwrapper.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: ipfwwrapper.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipvswrapper.c include file.
*
- * Version: $Id: ipvswrapper.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: ipvswrapper.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: ipwrapper.c include file.
*
- * Version: $Id: ipwrapper.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: ipwrapper.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
extern void perform_svr_state(int alive, virtual_server * vs, real_server * rs);
extern int init_services(void);
extern int clear_services(void);
+extern int clear_diff_services(void);
extern int ipvs_cmd(int cmd, virtual_server * vserver, real_server * rserver);
extern int ipfw_cmd(int cmd, virtual_server * vserver, real_server * rserver);
*
* Part: layer4.c include file.
*
- * Version: $Id: layer4.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: layer4.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: list.c include file.
*
- * Version: $Id: list.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: list.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: Main program include file.
*
- * Version: $Id: main.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: main.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "vrrp_netlink.h"
/* global var */
-thread_master *master = NULL;
-unsigned int debug;
-unsigned long mem_allocated = 0;
-data *conf_data;
+thread_master *master = NULL; /* Scheduling master thread */
+char *conf_file = NULL; /* Configuration file */
+int reload = 0; /* Global reloading flag */
+unsigned int debug; /* Debugging flags */
+unsigned long mem_allocated = 0; /* Total memory used in Bytes */
+data *conf_data; /* Global configuration data */
+data *old_data; /* Used during reload process */
+
+/* Reloading helpers */
+#define SET_RELOAD (reload = 1)
+#define UNSET_RELOAD (reload = 0)
+#define RELOAD_DELAY 5
/* extern prototypes */
#ifdef _WITH_LVS_
/* Build version */
#define PROG "Keepalived"
-#define VERSION_CODE 0x000608
-#define DATE_CODE 0x0F0702
+#define VERSION_CODE 0x000609
+#define DATE_CODE 0x010802
#define KEEPALIVED_VERSION(version) \
(version >> 16) & 0xFF, \
*
* Part: memory.c include file.
*
- * Version: $Id: memory.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: memory.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Authors: Alexandre Cassen, <acassen@linux-vs.org>
* Jan Holmberg, <jan@artech.net>
*
* Part: cfreader.c include file.
*
- * Version: $Id: parser.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: parser.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: pidfile.c include file.
*
- * Version: $Id: pidfile.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: pidfile.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: scheduler.c include file.
*
- * Version: $Id: scheduler.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: scheduler.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: smtp.c include file.
*
- * Version: $Id: smtp.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: smtp.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: timer.c include file.
*
- * Version: $Id: timer.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: timer.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: utils.h include file.
*
- * Version: $Id: utils.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: utils.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vector.c include file.
*
- * Version: $Id: vector.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vector.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp.c program include file.
*
- * Version: $Id: vrrp.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
extern int vrrp_ipsecah_len(void);
extern int vrrp_complete_init(void);
extern void shutdown_vrrp_instances(void);
+extern void clear_diff_vrrp(void);
#endif
*
* Part: vrrp_if.c include file.
*
- * Version: $Id: vrrp_if.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_if.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipaddress.c include file.
*
- * Version: $Id: vrrp_ipaddress.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_ipsecah.c include file.
*
- * Version: $Id: vrrp_ipsecah.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_netlink.c include file.
*
- * Version: $Id: vrrp_netlink.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_netlink.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_notify.c include file.
*
- * Version: $Id: vrrp_notify.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_notify.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_scheduler.c include file.
*
- * Version: $Id: vrrp_scheduler.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_scheduler.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: vrrp_sync.c include file.
*
- * Version: $Id: vrrp_sync.h,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_sync.h,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
* master fails, a backup server takes over.
* The original implementation has been made by jerome etienne.
*
- * Version: $Id: vrrp.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
#include "list.h"
#include "data.h"
+/* extern global vars */
extern data *conf_data;
+extern data *old_data;
/* compute checksum */
static u_short
vip_addr *vadd =
(type ==
VRRP_VIP_TYPE) ? &vrrp->vaddr[i] : &vrrp->evaddr[i];
- if (!cmd && !vadd->set)
+ if ((!cmd && !vadd->set) || (cmd && vadd->set))
continue;
retry:
if (netlink_address_ipv4(ifindex, vadd->addr, vadd->mask, cmd) <
send_gratuitous_arp(vrrp_rt * vrrp, int addr)
{
struct m_arphdr {
- unsigned short int ar_hrd; /* Format of hardware address. */
- unsigned short int ar_pro; /* Format of protocol address. */
- unsigned char ar_hln; /* Length of hardware address. */
- unsigned char ar_pln; /* Length of protocol address. */
- unsigned short int ar_op; /* ARP opcode (command). */
+ unsigned short int ar_hrd; /* Format of hardware address. */
+ unsigned short int ar_pro; /* Format of protocol address. */
+ unsigned char ar_hln; /* Length of hardware address. */
+ unsigned char ar_pln; /* Length of protocol address. */
+ unsigned short int ar_op; /* ARP opcode (command). */
+
/* Ethernet looks like this : This bit is variable sized however... */
unsigned char __ar_sha[ETH_ALEN]; /* Sender hardware address. */
- unsigned char __ar_sip[4]; /* Sender IP address. */
+ unsigned char __ar_sip[4]; /* Sender IP address. */
unsigned char __ar_tha[ETH_ALEN]; /* Target hardware address. */
- unsigned char __ar_tip[4]; /* Target IP address. */
+ unsigned char __ar_tip[4]; /* Target IP address. */
};
char buf[sizeof (struct m_arphdr) + ETHER_HDR_LEN];
{
if (vrrp->naddr == 0) {
syslog(LOG_INFO,
- "provide at least one ip for the virtual server");
+ "VRRP_Instance(%s) provide at least one ip for the virtual server",
+ vrrp->iname);
return 0;
}
if (vrrp->vrid == 0) {
- syslog(LOG_INFO, "the virtual id must be set!");
+ syslog(LOG_INFO, "VRRP_Instance(%s) the virtual id must be set!",
+ vrrp->iname);
return 0;
}
if (!vrrp->ifp) {
- syslog(LOG_INFO, "Unknown interface for instance %s !",
+ syslog(LOG_INFO, "VRRP_Instance(%s) Unknown interface !",
vrrp->iname);
return 0;
}
}
return 1;
}
+
+/* Try to find a VRRP instance */
+static vrrp_rt *
+vrrp_exist(vrrp_rt * old_vrrp)
+{
+ element e;
+ list l = conf_data->vrrp;
+ vrrp_rt *vrrp;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vrrp = ELEMENT_DATA(e);
+ if (!strcmp(vrrp->iname, old_vrrp->iname))
+ return vrrp;
+ }
+
+ return NULL;
+}
+
+/* Try to find a VIP into a VRRP instance */
+static int
+vrrp_vip_exist(vip_addr * old_vadd, vrrp_rt * vrrp, int type)
+{
+ int i, num;
+
+ num = (type == VRRP_VIP_TYPE) ? vrrp->naddr : vrrp->neaddr;
+ for (i = 0; i < num; i++) {
+ vip_addr *vadd =
+ (type ==
+ VRRP_VIP_TYPE) ? &vrrp->vaddr[i] : &vrrp->evaddr[i];
+ if (old_vadd->addr == vadd->addr &&
+ old_vadd->mask == vadd->mask) {
+ vadd->set = old_vadd->set;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Clear VIP|EVIP that are not present into the new data */
+static void
+clear_diff_vrrp_vip(vrrp_rt * old_vrrp, int type)
+{
+ vrrp_rt *vrrp = vrrp_exist(old_vrrp);
+ int i, num, old_num;
+ char vip[16];
+
+ /* Get the vip count */
+ num = (type == VRRP_VIP_TYPE) ? vrrp->naddr : vrrp->neaddr;
+ old_num = (type == VRRP_VIP_TYPE) ? old_vrrp->naddr : old_vrrp->neaddr;
+
+ /* Return if it is a positive group diff */
+ if (num && !old_num)
+ return;
+
+ /* Clear a whole E-VIP group ? */
+ if (!num && old_num) {
+ syslog(LOG_INFO, "VRRP_Instance(%s) E-VIP group no longer exist"
+ , old_vrrp->iname);
+ vrrp_handle_ipaddress(old_vrrp, VRRP_IPADDRESS_DEL, type);
+ }
+
+ /* Just clear diff entries */
+ for (i = 0; i < num; i++) {
+ vip_addr *vadd =
+ (type ==
+ VRRP_VIP_TYPE) ? &old_vrrp->vaddr[i] : &old_vrrp->evaddr[i];
+ if (!vrrp_vip_exist(vadd, vrrp, type)) {
+ syslog(LOG_INFO, "%s %s/%d no longer exist"
+ , (type == VRRP_VIP_TYPE) ? "VIP" : "E-VIP"
+ , inet_ntoa2(vadd->addr, vip)
+ , vadd->mask);
+ netlink_address_ipv4(IF_INDEX(old_vrrp->ifp)
+ , vadd->addr
+ , vadd->mask
+ , VRRP_IPADDRESS_DEL);
+
+ }
+ }
+}
+
+/* Diff when reloading configuration */
+void
+clear_diff_vrrp(void)
+{
+ element e;
+ list l = old_data->vrrp;
+ vrrp_rt *vrrp;
+
+ for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+ vrrp = ELEMENT_DATA(e);
+
+ /*
+ * Try to find this vrrp into the new conf data
+ * reloaded.
+ */
+ if (!vrrp_exist(vrrp)) {
+ vrrp_restore_interface(vrrp, 0);
+ } else {
+ /*
+ * If this vrrp instance exist in new
+ * data, then perform a VIP|EVIP diff.
+ */
+ clear_diff_vrrp_vip(vrrp, VRRP_VIP_TYPE);
+ clear_diff_vrrp_vip(vrrp, VRRP_EVIP_TYPE);
+ }
+ }
+}
*
* Part: Interfaces manipulation.
*
- * Version: $Id: vrrp_if.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_if.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK IPv4 address manipulation.
*
- * Version: $Id: vrrp_ipaddress.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_ipaddress.c,v 0.6.9 2002/07/31 01:33:12 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.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_ipsecah.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: NETLINK kernel command channel.
*
- * Version: $Id: vrrp_netlink.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_netlink.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
*
* Part: VRRP state transition notification scripts handling.
*
- * Version: $Id: vrrp_notify.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_notify.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
/* local include */
#include "vrrp_notify.h"
#include "memory.h"
-
-/* Close all FDs >= a specified value */
-void
-closeall(int fd)
-{
- int fdlimit = sysconf(_SC_OPEN_MAX);
- while (fd < fdlimit)
- close(fd++);
-}
+#include "daemon.h"
static char *
get_iscript(vrrp_rt * vrrp, int state)
/* Execute extern script/program */
static int
-notify_exec(const char *cmd)
+notify_exec(char *cmd)
{
- int err;
pid_t pid;
pid = fork();
dup(0);
dup(0);
- err = system(cmd);
- if (err != 0) {
- if (err == 127)
- syslog(LOG_ALERT, "Failed to exec [%s]", cmd);
- else
- syslog(LOG_ALERT, "Error running [%s], error: %d", cmd,
- err);
- } else
- syslog(LOG_INFO, "Success executing [%s]", cmd);
+ system_call(cmd);
exit(0);
}
*
* Part: Sheduling framework for vrrp code.
*
- * Version: $Id: vrrp_scheduler.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_scheduler.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*
}
/* Register VRRP thread */
+extern int reload;
void
register_vrrp_thread(void)
{
*
* Part: VRRP synchronization framework.
*
- * Version: $Id: vrrp_sync.c,v 0.6.8 2002/07/16 02:41:25 acassen Exp $
+ * Version: $Id: vrrp_sync.c,v 0.6.9 2002/07/31 01:33:12 acassen Exp $
*
* Author: Alexandre Cassen, <acassen@linux-vs.org>
*