keepalived-0.6.9 v0.6.9
authorAlexandre Cassen <acassen@freebox.fr>
Wed, 31 Jul 2002 20:41:00 +0000 (22:41 +0200)
committerAlexandre Cassen <acassen@freebox.fr>
Mon, 28 Sep 2009 08:58:56 +0000 (10:58 +0200)
* 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.

67 files changed:
ChangeLog
TODO
VERSION
keepalived.spec
keepalived/core/Makefile.in
keepalived/core/daemon.c
keepalived/core/data.c
keepalived/core/layer4.c
keepalived/core/list.c
keepalived/core/main.c
keepalived/core/memory.c
keepalived/core/parser.c
keepalived/core/pidfile.c
keepalived/core/scheduler.c
keepalived/core/smtp.c
keepalived/core/timer.c
keepalived/core/utils.c
keepalived/core/vector.c
keepalived/etc/init.d/keepalived.init
keepalived/healthcheck/Makefile.in
keepalived/healthcheck/check_api.c
keepalived/healthcheck/check_ci.c
keepalived/healthcheck/check_http.c
keepalived/healthcheck/check_misc.c
keepalived/healthcheck/check_ssl.c
keepalived/healthcheck/check_tcp.c
keepalived/healthcheck/ipfwwrapper.c
keepalived/healthcheck/ipvswrapper.c
keepalived/healthcheck/ipwrapper.c
keepalived/include/check_api.h
keepalived/include/check_ci.h
keepalived/include/check_http.h
keepalived/include/check_misc.h
keepalived/include/check_ssl.h
keepalived/include/check_tcp.h
keepalived/include/daemon.h
keepalived/include/data.h
keepalived/include/ipfwwrapper.h
keepalived/include/ipvswrapper.h
keepalived/include/ipwrapper.h
keepalived/include/layer4.h
keepalived/include/list.h
keepalived/include/main.h
keepalived/include/memory.h
keepalived/include/parser.h
keepalived/include/pidfile.h
keepalived/include/scheduler.h
keepalived/include/smtp.h
keepalived/include/timer.h
keepalived/include/utils.h
keepalived/include/vector.h
keepalived/include/vrrp.h
keepalived/include/vrrp_if.h
keepalived/include/vrrp_ipaddress.h
keepalived/include/vrrp_ipsecah.h
keepalived/include/vrrp_netlink.h
keepalived/include/vrrp_notify.h
keepalived/include/vrrp_scheduler.h
keepalived/include/vrrp_sync.h
keepalived/vrrp/vrrp.c
keepalived/vrrp/vrrp_if.c
keepalived/vrrp/vrrp_ipaddress.c
keepalived/vrrp/vrrp_ipsecah.c
keepalived/vrrp/vrrp_netlink.c
keepalived/vrrp/vrrp_notify.c
keepalived/vrrp/vrrp_scheduler.c
keepalived/vrrp/vrrp_sync.c

index cc0d5f4..d3ded15 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+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>
diff --git a/TODO b/TODO
index 05f4b42..66e7dd1 100644 (file)
--- a/TODO
+++ b/TODO
@@ -22,6 +22,4 @@
        - 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 :)
diff --git a/VERSION b/VERSION
index fae59ca..1a5ac0d 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.6.8
+0.6.9
index 1fd9877..d9596cd 100644 (file)
@@ -1,9 +1,9 @@
 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
@@ -14,7 +14,7 @@ The main goal of the keepalived project is to add a strong & robust keepalive fa
 
 %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
index 37062ef..ec5c89a 100644 (file)
@@ -8,7 +8,7 @@ CC       = @CC@
 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 \
index f5aed58..fc3d06e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -20,7 +20,9 @@
  *              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
@@ -31,7 +33,7 @@ xdaemon(int nochdir, int noclose, int exitflag)
        /* In case of fork is error. */
        pid = fork();
        if (pid < 0) {
-               perror("fork");
+               syslog(LOG_INFO, "xdaemon: fork error");
                return -1;
        }
 
@@ -46,7 +48,7 @@ xdaemon(int nochdir, int noclose, int exitflag)
        /* Become session leader and get pid. */
        pid = setsid();
        if (pid < -1) {
-               perror("setsid");
+               syslog(LOG_INFO, "xdaemon: setsid error");
                return -1;
        }
 
@@ -71,3 +73,35 @@ xdaemon(int nochdir, int noclose, int exitflag)
        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;
+}
index fbe3dac..9346007 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -61,7 +61,7 @@ alloc_ssl(void)
        SSL_DATA *ssl = (SSL_DATA *) MALLOC(sizeof (SSL_DATA));
        return ssl;
 }
-static void
+void
 free_ssl(void)
 {
        SSL_DATA *ssl = conf_data->ssl;
@@ -233,7 +233,9 @@ alloc_vrrp(char *iname)
        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);
 }
@@ -519,63 +521,62 @@ alloc_data(void)
 }
 
 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
index cec750c..f009b0f 100644 (file)
@@ -6,7 +6,7 @@
  * 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>
  *
index 76b1fb2..2a15d28 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *              
index d2337bc..37ce22d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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);
 }
 
@@ -53,7 +191,7 @@ signal_set(int signo, void (*func) (int))
        sig.sa_flags = 0;
 #ifdef SA_RESTART
        sig.sa_flags |= SA_RESTART;
-#endif                         /* SA_RESTART */
+#endif /* SA_RESTART */
 
        ret = sigaction(signo, &sig, &osig);
 
@@ -68,12 +206,34 @@ void
 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)
@@ -89,29 +249,32 @@ 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'},
@@ -121,7 +284,7 @@ parse_cmdline(int argc, char **argv)
        context =
            poptGetContext(PROG, argc, (const char **) argv, options_table, 0);
        if ((c = poptGetNextOpt(context)) < 0) {
-               return NULL;
+               return;
        }
 
        /* The first option car */
@@ -143,6 +306,12 @@ parse_cmdline(int argc, char **argv)
        case 'd':
                debug |= 4;
                break;
+       case 'V':
+               debug |= 8;
+               break;
+       case 'I':
+               debug |= 16;
+               break;
        case 'f':
                conf_file = optarg;
                break;
@@ -160,6 +329,12 @@ parse_cmdline(int argc, char **argv)
                case 'd':
                        debug |= 4;
                        break;
+               case 'V':
+                       debug |= 8;
+                       break;
+               case 'I':
+                       debug |= 16;
+                       break;
                case 'f':
                        conf_file = optarg;
                        break;
@@ -169,22 +344,17 @@ parse_cmdline(int argc, char **argv)
        /* 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;
 
@@ -192,7 +362,7 @@ main(int argc, char **argv)
         * 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);
@@ -218,93 +388,21 @@ main(int argc, char **argv)
        /* 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);
 }
index 81a3168..a40a82b 100644 (file)
@@ -6,7 +6,7 @@
  * 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>
index 05e7893..be2cc3c 100644 (file)
@@ -7,7 +7,7 @@
  *              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>
  *              
@@ -381,10 +381,11 @@ vrrp_state_handler(vector strvec)
 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)
index 4704b47..237d8de 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index 9e0b1b7..89e1561 100644 (file)
@@ -7,7 +7,7 @@
  *              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>
  *
@@ -70,9 +70,10 @@ thread_list_add_timeval(thread_list * list, thread * thread)
 {
        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);
@@ -130,7 +131,7 @@ thread_add_unuse(thread_master * m, thread * thread)
 }
 
 /* Move list element to unuse queue */
-void
+static void
 thread_destroy_list(thread_master * m, thread_list thread_list)
 {
        thread *thread;
@@ -149,17 +150,31 @@ thread_destroy_list(thread_master * m, thread_list thread_list)
        }
 }
 
-/* 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);
 }
 
index c89b938..26c60f6 100644 (file)
@@ -7,7 +7,7 @@
  *              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>
  *
index f2dd62f..02cb93d 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *              
index e1fe45d..7373862 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index de15241..f4fb2a8 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *              
index 8a0431a..f0d1407 100755 (executable)
@@ -24,8 +24,22 @@ case "$1" in
        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
 
index 4ec5a89..91b6fcd 100644 (file)
@@ -54,4 +54,5 @@ check_misc.o: check_misc.c ../include/check_misc.h ../include/check_api.h \
   ../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
index e231780..d34f81b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -53,13 +53,6 @@ dump_checker(void *data)
        (*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 *)
@@ -92,6 +85,13 @@ dump_checkers_queue(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)
@@ -120,27 +120,25 @@ update_checker_activity(uint32_t address, int enable)
        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;
                        }
                }
index 52e6ada..d7d9e0c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index b467dc1..77fcd4f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index 4dd513f..b3cc52a 100644 (file)
@@ -6,7 +6,7 @@
  * 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>
@@ -81,72 +81,70 @@ install_misc_check_keyword(void)
 }
 
 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);
 }
index 8f0f7ef..97f4ec6 100644 (file)
@@ -7,7 +7,7 @@
  *              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>
index c829ec2..5e09134 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index 14eebba..c37773d 100644 (file)
@@ -7,7 +7,7 @@
  *              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>
  *
index c3de759..e3c5927 100644 (file)
@@ -6,7 +6,7 @@
  * 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>
  *              
@@ -23,6 +23,7 @@
 
 #include "ipvswrapper.h"
 #include "utils.h"
+#include "memory.h"
 
 /* local helpers functions */
 static int parse_timeout(char *, unsigned *);
@@ -179,53 +180,58 @@ ipvs_syncd_cmd(int cmd, char *ifname, int state)
 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
index c8ff5a9..0af763c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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;
@@ -54,7 +61,7 @@ clear_service_vs(virtual_server * vs)
        /* 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))
@@ -80,24 +87,109 @@ int
 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)
 {
@@ -106,12 +198,13 @@ 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)
 {
@@ -123,7 +216,7 @@ 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)
@@ -191,77 +284,168 @@ perform_svr_state(int alive, virtual_server * vs, real_server * rs)
        }
 }
 
+/* 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;
 }
index 801cd95..559f13b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index b09ab4e..124eb3c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index 7cc474f..73226e0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index 4a910e2..766758a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index c884925..5af6873 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index 0d7f939..c2e104f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index e4d842a..01144b2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -35,5 +35,7 @@
 
 /* prototype */
 extern pid_t xdaemon(int, int, int);
+extern void closeall(int fd);
+extern int system_call(char *cmdline);
 
 #endif
index 474d1bc..486ebc7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -102,6 +102,7 @@ typedef struct _virtual_server {
        int last_rs_type;
 #define RS             (1 << 0)
 #define RS_GROUP       (1 << 1)
+       int alive;
 } virtual_server;
 
 /* email link list */
@@ -124,15 +125,18 @@ typedef struct _data {
 } 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);
@@ -145,7 +149,7 @@ extern void alloc_rsgroup(char *ip, char *port);
 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
index beb5901..75464a3 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index aed62ef..1ddc8b9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index a2b4936..95a01d4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -60,6 +60,7 @@
 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);
index cf303d0..b88c61b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index d836fab..65eed93 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *
index b12ef26..3fd48cc 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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_
@@ -58,8 +66,8 @@ extern void register_vrrp_thread(void);
 /* 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,         \
index 2bef49a..8571acd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
index 8364813..7808bca 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *
index 14300ec..8597e36 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index 0dcc927..a30fcec 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index 6501459..f45ff3b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index e80c184..c902347 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *
index b030ea7..6ba2eb7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index 60ab2f1..3b99681 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * 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>
  *
index 3b82dd8..c211cb3 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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>
  *
@@ -204,5 +204,6 @@ extern void vrrp_state_leave_master(vrrp_rt * vrrp);
 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
index 405d687..bf97d35 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index a32d0be..67221a5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index de30dba..5ac7d9d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *              
index 1aa3fcc..b41b4dd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index d7455b7..ef11bba 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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>
  *
index 4691ad3..8ff27f8 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *              
index 7b2ae06..a79def7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *              
index bdaa55b..d71adcc 100644 (file)
@@ -8,7 +8,7 @@
  *              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>
  *
@@ -33,7 +33,9 @@
 #include "list.h"
 #include "data.h"
 
+/* extern global vars */
 extern data *conf_data;
+extern data *old_data;
 
 /* compute checksum */
 static u_short
@@ -89,7 +91,7 @@ vrrp_handle_ipaddress(vrrp_rt * vrrp, int cmd, int type)
                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) <
@@ -634,16 +636,17 @@ static int
 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];
@@ -940,15 +943,17 @@ chk_min_cfg(vrrp_rt * vrrp)
 {
        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;
        }
@@ -1146,3 +1151,110 @@ vrrp_complete_init(void)
        }
        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);
+               }
+       }
+}
index c583da5..bdac681 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index 7644de7..7e89b88 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index b745679..15c86bf 100644 (file)
@@ -7,7 +7,7 @@
  *              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>
  *
index b8bd0d2..40d85b0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
index def6944..39e82c2 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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)
@@ -85,9 +77,8 @@ notify_script_name(char *cmdline)
 
 /* Execute extern script/program */
 static int
-notify_exec(const char *cmd)
+notify_exec(char *cmd)
 {
-       int err;
        pid_t pid;
 
        pid = fork();
@@ -108,15 +99,7 @@ notify_exec(const char *cmd)
        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);
 }
index 2363f1d..e8c4288 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *
@@ -744,6 +744,7 @@ vrrp_read_dispatcher_thread(thread * thread)
 }
 
 /* Register VRRP thread */
+extern int reload;
 void
 register_vrrp_thread(void)
 {
index b647049..548a4ba 100644 (file)
@@ -5,7 +5,7 @@
  *
  * 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>
  *