keepalived-1.1.13 v1.1.13
authorAlexandre Cassen <acassen@freebox.fr>
Wed, 11 Oct 2006 10:01:45 +0000 (12:01 +0200)
committerAlexandre Cassen <acassen@freebox.fr>
Mon, 28 Sep 2009 08:59:01 +0000 (10:59 +0200)
* keepalived-1.1.13 released.
* VRRP : Added a new notify script to be launch during vrrp
  instances shutdown. This new notify hook is configured
  using notify_stop keyword inside vrrp_instance block.
* VRRP : Willy Tarreau <w at 1wt.eu> fixed an errno issue in
  thread_fetch(), errno is lost during set_time_now(). This
  patch saves it across the call to set_time_now() in order
  to get the valid error.
* VRRP : Willy Tarreau <w at 1wt.eu> extended timer framework
  to save errno in timer_now() and set_time_now() just in
  case other functions do not expect these functions to modify
  it. This is a safer approach than the initial patch to
  thread_fetch(), while still compatible.
* VRRP : Willy Tarreau <w at 1wt.eu> fixed an FSM silent issue.
  By default, the VRRP daemon stops sending during new MASTER
  elections. This causes 3 to 4 seconds of silence depending on
  the local priority, and sometimes causes flapping when the
  differences in priorities are very low, due to the kernel timer's
  resolution : sometimes, the old master receives a first
  advertisement, enters backup, waits 3 seconds, sees nothing and
  finally becomes master again, which forces a new reelection on
  the other one.
* VRRP : Willy Tarreau <w at 1wt.eu> extended VRRP framework to
  support floating priority. Replace the priority in each
  vrrp_instance with a base priority and an effective priority,
  to prepare the support for floating priorities. The configuration
  sets the base_priority, and all comparisons use the new
  effective_priority value. This one is computed in the
  vrrp_update_priority() thread by adding an offset to base_priority,
  based on the result of various checks.
* VRRP : Willy Tarreau <w at 1wt.eu> extended notify script to add
  the priority in "$4" when calling a notify script. This is
  important in labs and datacenters when systems can display the
  priority on a front LCD, because it allows workers to carefully
  operate without causing unexpected reelections.
* VRRP : Willy Tarreau <w at 1wt.eu> extended interface tracking
  framework to let interface tracking change the priority by adding
  a "weight" parameter. If the weight is positive, it will be added
  to the priority when the interface is UP. If the weight is negative,
  it will be subtracted from the priority when the interface is down.
  If the weight is zero (default), a down interface will switch the
  instance to the FAULT state.
* VRRP : Willy Tarreau <w at 1wt.eu> added a new "vrrp_script" section
  to monitor local processes or do any type of local processing to
  decide whether the machine is in good enough health to be elected
  as master. A same script will be run once for all instances which
  monitor it. If no instance use it, it will not be run, so that it's
  safe to declare a lot of useful scripts. A weight is associated to
  the script result. If the weight is positive, it will be added to
  the priority when the result is OK (exit 0). If the weight is
  negative, it will be subtracted from the priority when the result
  is KO (exit != 0). If the weight is zero, the script will not be
  monitored. The default value is 2.
* VRRP : Willy Tarreau <w at 1wt.eu> extended vrrp scheduler so that
  when a VRRP is part of a SYNC group, it must not use floating
  priorities, otherwise this may lead to infinite re-election after
  every advertisement because some VRRPs will announce higher prios
  than the peer, while others will announce lower prios. The solution
  is to set all weights to 0 to enable standard interface tracking,
  and to disable the update prio thread if VRRP SYNC is enabled on a
  VRRP.
* VRRP : Willy Tarreau <w at 1wt.eu> added some documentation and
  examples for the brand new VRRP tracking mechanisms.
* VRRP : Ranko Zivojnovic, <ranko at spidernet.net> fixed vrrp
  scheduler to execute notify* scripts in transition from the
  failed state to the backup state.
* Nick Couchman, <nick.couchman at seakr.com>, added support for
  real server upper and lower thresholds.  This allows you to set
  a minimum and maximum number of connections to each real server
  using the "uthreshold" (maximum) and "lthreshold" (minimum)
  options in the real_server section of the configuration file.
* Chris Caputo, <ccaputo at alt.net> extended autoconf script
  to support recent move of UTS_RELEASE from linux/version.h to
  linux/utsrelease.h.
* Chris Caputo, <ccaputo at alt.net> extended ipvswrapper 2.4
  code to support misc_dynamic weight.

99 files changed:
CONTRIBUTORS
ChangeLog
VERSION
configure
configure.in
doc/keepalived.conf.SYNOPSIS
doc/samples/keepalived.conf.vrrp.localcheck [new file with mode: 0644]
genhash/Makefile.in
keepalived/Makefile.in
keepalived/check/check_api.c
keepalived/check/check_daemon.c
keepalived/check/check_data.c
keepalived/check/check_http.c
keepalived/check/check_misc.c
keepalived/check/check_parser.c
keepalived/check/check_smtp.c
keepalived/check/check_ssl.c
keepalived/check/check_tcp.c
keepalived/check/ipfwwrapper.c
keepalived/check/ipvswrapper.c
keepalived/check/ipwrapper.c
keepalived/core/daemon.c
keepalived/core/global_data.c
keepalived/core/global_parser.c
keepalived/core/layer4.c
keepalived/core/main.c
keepalived/core/pidfile.c
keepalived/core/smtp.c
keepalived/include/check_api.h
keepalived/include/check_daemon.h
keepalived/include/check_data.h
keepalived/include/check_http.h
keepalived/include/check_misc.h
keepalived/include/check_parser.h
keepalived/include/check_smtp.h
keepalived/include/check_ssl.h
keepalived/include/check_tcp.h
keepalived/include/config.h.in
keepalived/include/daemon.h
keepalived/include/global_data.h
keepalived/include/global_parser.h
keepalived/include/ipfwwrapper.h
keepalived/include/ipvswrapper.h
keepalived/include/ipwrapper.h
keepalived/include/layer4.h
keepalived/include/main.h
keepalived/include/pidfile.h
keepalived/include/smtp.h
keepalived/include/vrrp.h
keepalived/include/vrrp_arp.h
keepalived/include/vrrp_daemon.h
keepalived/include/vrrp_data.h
keepalived/include/vrrp_if.h
keepalived/include/vrrp_index.h
keepalived/include/vrrp_ipaddress.h
keepalived/include/vrrp_iproute.h
keepalived/include/vrrp_ipsecah.h
keepalived/include/vrrp_netlink.h
keepalived/include/vrrp_notify.h
keepalived/include/vrrp_parser.h
keepalived/include/vrrp_scheduler.h
keepalived/include/vrrp_sync.h
keepalived/include/vrrp_track.h
keepalived/vrrp/Makefile.in
keepalived/vrrp/vrrp.c
keepalived/vrrp/vrrp_arp.c
keepalived/vrrp/vrrp_daemon.c
keepalived/vrrp/vrrp_data.c
keepalived/vrrp/vrrp_if.c
keepalived/vrrp/vrrp_index.c
keepalived/vrrp/vrrp_ipaddress.c
keepalived/vrrp/vrrp_iproute.c
keepalived/vrrp/vrrp_ipsecah.c
keepalived/vrrp/vrrp_netlink.c
keepalived/vrrp/vrrp_notify.c
keepalived/vrrp/vrrp_parser.c
keepalived/vrrp/vrrp_scheduler.c
keepalived/vrrp/vrrp_sync.c
keepalived/vrrp/vrrp_track.c
lib/html.c
lib/html.h
lib/list.c
lib/list.h
lib/memory.c
lib/memory.h
lib/notify.c
lib/notify.h
lib/parser.c
lib/parser.h
lib/scheduler.c
lib/scheduler.h
lib/signals.c
lib/signals.h
lib/timer.c
lib/timer.h
lib/utils.c
lib/utils.h
lib/vector.c
lib/vector.h

index 6370f0a..de4fdcc 100644 (file)
@@ -20,3 +20,10 @@ Chris Caputo, <ccaputo@alt.net> :
 Kevin Lindsay, <kevinl@netnation.com> :
        o Fixed shadowed declaration reported by -Wshadow.
        o Redesigned signal handling.
+
+Nick Couchman, <nick.couchman at seakr.com> :
+        o Patch for u_threshold and l_threshold support.
+
+Willy Tarreau, <w at 1wt.eu> :
+       o Extended VRRP framework to support floating
+         priority.
index 8a99983..aedbcc8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,81 @@
+2006-10-11  Alexandre Cassen  <acassen@linux-vs.org>
+       * keepalived-1.1.13 released.
+       * VRRP : Added a new notify script to be launch during vrrp
+         instances shutdown. This new notify hook is configured
+         using notify_stop keyword inside vrrp_instance block.
+       * VRRP : Willy Tarreau <w at 1wt.eu> fixed an errno issue in
+         thread_fetch(), errno is lost during set_time_now(). This
+         patch saves it across the call to set_time_now() in order
+         to get the valid error.
+       * VRRP : Willy Tarreau <w at 1wt.eu> extended timer framework
+         to save errno in timer_now() and set_time_now() just in
+         case other functions do not expect these functions to modify
+         it. This is a safer approach than the initial patch to
+         thread_fetch(), while still compatible.
+       * VRRP : Willy Tarreau <w at 1wt.eu> fixed an FSM silent issue.
+         By default, the VRRP daemon stops sending during new MASTER
+         elections. This causes 3 to 4 seconds of silence depending on
+         the local priority, and sometimes causes flapping when the
+         differences in priorities are very low, due to the kernel timer's
+         resolution : sometimes, the old master receives a first
+         advertisement, enters backup, waits 3 seconds, sees nothing and
+         finally becomes master again, which forces a new reelection on
+         the other one.
+       * VRRP : Willy Tarreau <w at 1wt.eu> extended VRRP framework to
+         support floating priority. Replace the priority in each
+         vrrp_instance with a base priority and an effective priority,
+         to prepare the support for floating priorities. The configuration
+         sets the base_priority, and all comparisons use the new
+         effective_priority value. This one is computed in the
+         vrrp_update_priority() thread by adding an offset to base_priority,
+         based on the result of various checks.
+       * VRRP : Willy Tarreau <w at 1wt.eu> extended notify script to add
+         the priority in "$4" when calling a notify script. This is
+         important in labs and datacenters when systems can display the
+         priority on a front LCD, because it allows workers to carefully
+         operate without causing unexpected reelections.
+       * VRRP : Willy Tarreau <w at 1wt.eu> extended interface tracking
+         framework to let interface tracking change the priority by adding
+         a "weight" parameter. If the weight is positive, it will be added
+         to the priority when the interface is UP. If the weight is negative,
+         it will be subtracted from the priority when the interface is down.
+         If the weight is zero (default), a down interface will switch the
+         instance to the FAULT state.
+       * VRRP : Willy Tarreau <w at 1wt.eu> added a new "vrrp_script" section
+         to monitor local processes or do any type of local processing to
+         decide whether the machine is in good enough health to be elected
+         as master. A same script will be run once for all instances which
+         monitor it. If no instance use it, it will not be run, so that it's
+         safe to declare a lot of useful scripts. A weight is associated to
+         the script result. If the weight is positive, it will be added to
+         the priority when the result is OK (exit 0). If the weight is
+         negative, it will be subtracted from the priority when the result
+         is KO (exit != 0). If the weight is zero, the script will not be
+         monitored. The default value is 2.
+       * VRRP : Willy Tarreau <w at 1wt.eu> extended vrrp scheduler so that
+         when a VRRP is part of a SYNC group, it must not use floating
+         priorities, otherwise this may lead to infinite re-election after
+         every advertisement because some VRRPs will announce higher prios
+         than the peer, while others will announce lower prios. The solution
+         is to set all weights to 0 to enable standard interface tracking,
+         and to disable the update prio thread if VRRP SYNC is enabled on a
+         VRRP.
+       * VRRP : Willy Tarreau <w at 1wt.eu> added some documentation and
+         examples for the brand new VRRP tracking mechanisms.
+       * VRRP : Ranko Zivojnovic, <ranko at spidernet.net> fixed vrrp
+         scheduler to execute notify* scripts in transition from the
+         failed state to the backup state.
+       * Nick Couchman, <nick.couchman at seakr.com>, added support for
+         real server upper and lower thresholds.  This allows you to set
+         a minimum and maximum number of connections to each real server
+         using the "uthreshold" (maximum) and "lthreshold" (minimum)
+         options in the real_server section of the configuration file.
+       * Chris Caputo, <ccaputo at alt.net> extended autoconf script
+         to support recent move of UTS_RELEASE from linux/version.h to
+         linux/utsrelease.h.
+       * Chris Caputo, <ccaputo at alt.net> extended ipvswrapper 2.4
+         code to support misc_dynamic weight.
+
 2006-03-09  Alexandre Cassen  <acassen@linux-vs.org>
        * keepalived-1.1.12 released.
        * VRRP : Christophe Varoqui, <Christophe.Varoqui@free.fr> extended
diff --git a/VERSION b/VERSION
index ccad953..9ea63db 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.1.12
+1.1.13
index 4556b31..3b6a43d 100755 (executable)
--- a/configure
+++ b/configure
@@ -3580,6 +3580,9 @@ cat >>conftest.$ac_ext <<_ACEOF
     #include <stdlib.h>
     #include <stdio.h>
     #include <linux/version.h>
+    #if !defined(UTS_RELEASE)
+    #include <linux/utsrelease.h>
+    #endif
     int main (void) {
       FILE *fp = fopen ("linuxinfo", "w");
       if (!fp) return 1;
index bc93edf..4d7aa34 100644 (file)
@@ -54,6 +54,9 @@ AC_TRY_RUN([
     #include <stdlib.h>
     #include <stdio.h>
     #include <linux/version.h>
+    #if !defined(UTS_RELEASE)
+    #include <linux/utsrelease.h>
+    #endif
     int main (void) {
       FILE *fp = fopen ("linuxinfo", "w");
       if (!fp) return 1;
index 069d8ee..79184e8 100644 (file)
@@ -70,12 +70,34 @@ SCOPE can take the following values :
 
 2. VRRP configuration
 
-This block is divided in 2 sub-block :
+This block is divided in 3 sub-block :
 
+       * VRRP scripts
        * VRRP synchronization group
        * VRRP instance
 
-       2.1. VRRP synchronization group
+       2.1. VRRP scripts
+
+       The configuration block looks like :
+
+vrrp_script <STRING> {         # VRRP script declaration
+    script <QUOTED_STRING>     # script to run periodically
+    interval <INTEGER>         # run the script this every seconds
+    weight <INTEGER:-254..254>  # adjust priority by this weight
+}
+
+The script will be executed periodically, every <interval> seconds. Its exit
+code will be recorded for all VRRP instances which will want to monitor it.
+Note that the script will only be executed if at least one VRRP instance
+monitors it with a non-zero weight. Thus, any number of scripts may be
+declared without taking the system down.
+
+If unspecified, the weight equals 2, which means that a success will add +2
+to the priority of all VRRP instances which monitor it. On the opposite, a
+negative weight will be subtracted from the initial priority in case of
+failure.
+
+       2.2. VRRP synchronization group
 
        The configuration block looks like :
 
@@ -103,7 +125,15 @@ vrrp_sync_group <STRING> { # VRRP sync group declaration
     $1 and $3 are ALWAYS sent in uppercase, and the possible strings sent are the
     same ones listed above ("GROUP"/"INSTANCE", "MASTER"/"BACKUP"/"FAULT").
 
-       2.2. VRRP instance
+Important: for a SYNC group to run reliably, it is vital that all instances in
+           the group are MASTER or that they are all either BACKUP or FAULT. A
+           situation with half instances having higher priority on machine A
+           half others with higher priority on machine B will lead to constant
+           re-elections. For this reason, when instances are grouped, their
+           tracking weights are automatically set to zero, in order to avoid
+           inconsistent priorities across instances.
+
+       2.3. VRRP instance
 
        The configuration block looks like :
 
@@ -113,6 +143,12 @@ vrrp_instance <STRING> {           # VRRP instance declaration
     track_interface {                  # Interfaces state we monitor
       <STRING>
       <STRING>
+      <STRING> weight <INTEGER:-254..254>
+      ...
+    }
+    track_script {                     # Scripts state we monitor
+      <STRING>
+      <STRING> weight <INTEGER:-254..254>
       ...
     }
     dont_track_primary                  # (default unset) ignore VRRP interface faults.
@@ -150,6 +186,7 @@ vrrp_instance <STRING> {            # VRRP instance declaration
     notify_master <STRING>|<QUOTED-STRING>     # Same as vrrp_sync_group
     notify_backup <STRING>|<QUOTED-STRING>     # Same as vrrp_sync_group
     notify_fault <STRING>|<QUOTED-STRING>      # Same as vrrp_sync_group
+    notify_stop <STRING>|<QUOTED-STRING>       # Script to launch when stopping vrrp
     notify <STRING>|<QUOTED-STRING>            # Same as vrrp_sync_group
     smtp_alert                                 # Same as vrrp_sync_group
 }
@@ -161,6 +198,23 @@ SCOPE can take the following values :
        * nowhere
        * global
 
+When a weight is specified in track_interface, instead of setting the vrrp
+instance to the FAULT state in case of failure, its priority will be
+increased by the weight when the interface is up (for positive weights),
+or decreased by the weight's absolute value when the interface is down
+(for negative weights). The weight must be comprised between -254 and +254
+inclusive. 0 is the default behaviour which means that a failure implies a
+FAULT state. The common practise is to use positive weights to count a
+limited number of good services so that the server with the highest count
+becomes master. Negative weights are better to count unexpected failures
+among a high number of interfaces, as it will not saturate even with high
+number of interfaces.
+
+The same principle can be applied to track_script entries, except that an
+unspecified weight means that the default weight declared in the script
+will be used.
+
+
 3. LVS configuration
 
 This block is divided in 2 sub-block :
diff --git a/doc/samples/keepalived.conf.vrrp.localcheck b/doc/samples/keepalived.conf.vrrp.localcheck
new file mode 100644 (file)
index 0000000..1929a30
--- /dev/null
@@ -0,0 +1,142 @@
+! Configuration File for keepalived
+
+vrrp_script chk_sshd {
+       script "killall -0 sshd"        # cheaper than pidof
+       interval 2                      # check every 2 seconds
+       weight -4                       # default prio: -4 if KO
+}
+
+vrrp_script chk_haproxy {
+       script "killall -0 haproxy"     # cheaper than pidof
+       interval 2                      # check every 2 seconds
+}
+
+vrrp_script chk_http_port {
+       script "</dev/tcp/127.0.0.1/80" # connects and exits
+       interval 1                      # check every second
+       weight -2                       # default prio: -2 if connect fails
+}
+
+vrrp_script chk_https_port {
+       script "</dev/tcp/127.0.0.1/443"
+       interval 1
+       weight -2
+}
+
+vrrp_script chk_smtp_port {
+       script "</dev/tcp/127.0.0.1/25"
+       interval 1
+       weight -2
+}
+
+vrrp_instance VI_1 {
+    interface eth0
+    state MASTER
+    virtual_router_id 51
+    priority 100
+    virtual_ipaddress {
+        192.168.200.18/25
+    }
+    track_interface {
+       eth1 weight 2   # prio = +2 if UP
+       eth2 weight -2  # prio = -2 if DOWN
+       eth3            # no weight, fault if down
+    }
+    track_script {
+       chk_sshd                # use default weight from the script
+       chk_haproxy weight 2    # +2 if process is present
+       chk_http_port
+       chk_https_port
+       chk_smtp_port
+    }
+}
+
+vrrp_instance VI_2 {
+    interface eth1
+    state MASTER
+    virtual_router_id 52
+    priority 100
+    virtual_ipaddress {
+        192.168.201.18/26
+    }
+    track_interface {
+       eth0 weight 2   # prio = +2 if UP
+       eth2 weight -2  # prio = -2 if DOWN
+       eth3            # no weight, fault if down
+    }
+    track_script {
+       chk_haproxy weight 2
+       chk_http_port
+       chk_https_port
+       chk_smtp_port
+    }
+}
+
+vrrp_instance VI_3 {
+    interface eth0
+    virtual_router_id 53
+    priority 100
+    virtual_ipaddress {
+        192.168.200.19/27
+    }
+}
+
+vrrp_instance VI_4 {
+    interface eth1
+    virtual_router_id 54
+    priority 100
+    virtual_ipaddress {
+        192.168.201.19/28
+    }
+}
+
+vrrp_instance VI_5 {
+    state MASTER
+    interface eth0
+    virtual_router_id 55
+    priority 100
+    virtual_ipaddress {
+        192.168.200.20/27
+    }
+}
+
+
+vrrp_instance VI_6 {
+    state MASTER
+    interface eth0
+    virtual_router_id 56
+    priority 100
+    virtual_ipaddress {
+        192.168.200.21/27
+    }
+}
+
+vrrp_instance VI_7 {
+    state MASTER
+    interface eth0
+    virtual_router_id 57
+    priority 100
+    virtual_ipaddress {
+        192.168.200.22/27
+    }
+}
+
+vrrp_instance VI_8 {
+    state MASTER
+    interface eth0
+    virtual_router_id 58
+    priority 100
+    virtual_ipaddress {
+        192.168.200.23/27
+    }
+}
+
+vrrp_instance VI_9 {
+    state MASTER
+    interface eth0
+    virtual_router_id 59
+    priority 100
+    virtual_ipaddress {
+        192.168.200.24/27
+    }
+}
index 19de7dc..85a5d46 100644 (file)
@@ -1,6 +1,6 @@
 # Makefile.in
 #
-# Copyright (C) 2001-2005 Alexandre Cassen, <acassen@linux-vs.org>
+# Copyright (C) 2001-2006 Alexandre Cassen, <acassen@linux-vs.org>
 
 EXEC = genhash
 BIN  = ../bin
index 1443efb..38aa4a3 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Keepalived OpenSource project.
 #
-# Copyright (C) 2001, 2002, 2003 Alexandre Cassen, <acassen@linux-vs.org>
+# Copyright (C) 2001-2006 Alexandre Cassen, <acassen@linux-vs.org>
 
 EXEC      = keepalived
 BIN       = ../bin
index 02c4907..a5d6ceb 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers registration.
  *
- * Version:     $Id: check_api.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_api.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index fff7cdc..dc639b6 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Healthcheckrs child process handling.
  *
- * Version:     $Id: check_daemon.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_daemon.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index dc6b8d2..8bfbf9d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Healthcheckers dynamic data structure definition.
  *
- * Version:     $Id: check_data.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_data.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 63e2ef5..3595789 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        WEB CHECK. Common HTTP/SSL checker primitives.
  *
- * Version:     $Id: check_http.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_http.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 87eb29c..c98f7ab 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 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_misc.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index bcde285..4a9dd68 100644 (file)
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: check_parser.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_parser.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -181,6 +181,22 @@ weight_handler(vector strvec)
        real_server *rs = LIST_TAIL_DATA(vs->rs);
        rs->weight = atoi(VECTOR_SLOT(strvec, 1));
 }
+#ifdef _KRNL_2_6_
+static void
+uthreshold_handler(vector strvec)
+{
+       virtual_server *vs = LIST_TAIL_DATA(check_data->vs);
+       real_server *rs = LIST_TAIL_DATA(vs->rs);
+       rs->u_threshold = atoi(VECTOR_SLOT(strvec, 1));
+}
+static void
+lthreshold_handler(vector strvec)
+{
+       virtual_server *vs = LIST_TAIL_DATA(check_data->vs);
+       real_server *rs = LIST_TAIL_DATA(vs->rs);
+       rs->l_threshold = atoi(VECTOR_SLOT(strvec, 1));
+}
+#endif
 static void
 inhibit_handler(vector strvec)
 {
@@ -236,6 +252,10 @@ check_init_keywords(void)
        install_keyword("real_server", &rs_handler);
        install_sublevel();
        install_keyword("weight", &weight_handler);
+#ifdef _KRNL_2_6_
+       install_keyword("uthreshold", &uthreshold_handler);
+       install_keyword("lthreshold", &lthreshold_handler);
+#endif
        install_keyword("inhibit_on_failure", &inhibit_handler);
        install_keyword("notify_up", &notify_up_handler);
        install_keyword("notify_down", &notify_down_handler);
index 27045d0..1502e6a 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        SMTP CHECK. Check an SMTP-server.
  *
- * Version:     $Id: check_smtp.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_smtp.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Jeremy Rumpf, <jrumpf@heavyload.net>
  *              Alexandre Cassen, <acassen@linux-vs.org>
index f5f2ca0..b42d8bf 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 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_ssl.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 1ee1b1e..f4f3f58 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        TCP checker.
  *
- * Version:     $Id: check_tcp.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_tcp.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index fbddafc..2751b59 100644 (file)
@@ -7,7 +7,7 @@
  *              library to add/remove server MASQ rules to the kernel 
  *              firewall framework.
  *
- * Version:     $Id: ipfwwrapper.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: ipfwwrapper.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 1a99cb2..2109a00 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 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: ipvswrapper.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -601,6 +601,8 @@ ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
        memset(drule, 0, sizeof (struct ip_vs_dest_user));
 
        drule->weight = 1;
+       drule->u_threshold = 0;
+       drule->l_threshold = 0;
        drule->conn_flags = vs->loadbalancing_kind;
        strncpy(srule->sched_name, vs->sched, IP_VS_SCHEDNAME_MAXLEN);
        srule->netmask = ((u_int32_t) 0xffffffff);
@@ -620,10 +622,14 @@ ipvs_set_rule(int cmd, virtual_server * vs, real_server * rs)
 
        /* SVR specific */
        if (rs) {
-               if (cmd == IP_VS_SO_SET_ADDDEST || cmd == IP_VS_SO_SET_DELDEST) {
+               if (cmd == IP_VS_SO_SET_ADDDEST
+                   || cmd == IP_VS_SO_SET_DELDEST
+                   || cmd == IP_VS_SO_SET_EDITDEST) {
                        drule->weight = rs->weight;
                        drule->addr = SVR_IP(rs);
                        drule->port = SVR_PORT(rs);
+                       drule->u_threshold = rs->u_threshold;
+                       drule->l_threshold = rs->l_threshold;
                }
        }
 }
@@ -702,6 +708,8 @@ ipvs_group_remove_entry(virtual_server *vs, virtual_server_group_entry *vsge)
                                srule->fwmark = vsge->vfwmark;
                                srule->addr = SVR_IP(vsge);
                                srule->port = SVR_PORT(vsge);
+                               drule->u_threshold = rs->u_threshold;
+                               drule->l_threshold = rs->l_threshold;
 
                                /* Talk to the IPVS channel */
                                ipvs_talk(IP_VS_SO_SET_DELDEST);
index b21123a..81d5f2e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Manipulation functions for IPVS & IPFW wrappers.
  *
- * Version:     $Id: ipwrapper.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: ipwrapper.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index efb8c20..bc0eb5c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: main.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2ed4ac8..df6518f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: global_data.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: global_data.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index b370ddb..a05f2c5 100644 (file)
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: global_parser.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: global_parser.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index e51f1b9..347e956 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        Layer4 checkers handling. Register worker threads &
  *              upper layer checkers.
  *
- * Version:     $Id: layer4.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: layer4.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index b59000e..fc5bc80 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program structure.
  *
- * Version:     $Id: main.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: main.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2e95292..4483f5d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile utility.
  *
- * Version:     $Id: pidfile.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: pidfile.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index acfaa36..732707a 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 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: smtp.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 1904a82..40f8bb0 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Checkers arguments structures definitions.
  *
- * Version:     $Id: check_api.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_api.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index a0fd6b6..8e979ec 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_daemon.c include file.
  * 
- * Version:     $Id: check_daemon.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_daemon.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index b642171..445042d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Healthcheckers dynamic data structure definition.
  *
- * Version:     $Id: check_data.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_data.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -75,6 +75,10 @@ typedef struct _real_server {
        uint32_t addr_ip;
        uint16_t addr_port;
        int weight;
+#ifdef _KRNL_2_6_
+       uint32_t u_threshold;   /* Upper connection limit. */
+       uint32_t l_threshold;   /* Lower connection limit. */
+#endif
        int inhibit;            /* Set weight to 0 instead of removing
                                 * the service from IPVS topology.
                                 */
index ec79093..39771f1 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_http.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index c34640f..c3e418b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_misc.c include file.
  *
- * Version:     $Id: check_misc.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_misc.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Eric Jarman, <ehj38230@cmsu2.cmsu.edu>
index 0c706e9..1d6dc62 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        check_parser.c include file.
  *  
- * Version:     $Id: check_parser.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_parser.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 94fc827..de9663e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_smtp.c include file.
  *
- * Version:     $Id: check_smtp.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_smtp.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              Jeremy Rumpf, <jrumpf@heavyload.net>
index dadb487..89b3a3d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_http.c include file.
  *
- * Version:     $Id: check_http.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_http.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 75b4409..877b861 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        check_tcp.c include file.
  *
- * Version:     $Id: check_tcp.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: check_tcp.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2332e45..1730333 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Configuration include file.
  *
- * Version:     $Id: config.h.in,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: config.h.in,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Jacob Rief, <jacob.rief@tiscover.com>
  *
index 04d4fd3..1496ef5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Daemon process handling.
  *
- * Version:     $Id: daemon.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: daemon.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 88d6c92..ab138d1 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: global_data.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: global_data.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 278e4e0..d55cc14 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        vrrp_parser.c include file.
  *  
- * Version:     $Id: global_parser.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: global_parser.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 2d43b15..c9f2dc9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipfwwrapper.c include file.
  *
- * Version:     $Id: ipfwwrapper.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: ipfwwrapper.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index b132f4d..c7eba93 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipvswrapper.c include file.
  *
- * Version:     $Id: ipvswrapper.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: ipvswrapper.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 34084b1..dce0cfd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ipwrapper.c include file.
  *
- * Version:     $Id: ipwrapper.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: ipwrapper.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index c6ae2c1..f56d0fe 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        layer4.c include file.
  *
- * Version:     $Id: layer4.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: layer4.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index f407cbe..c72574b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Main program include file.
  *
- * Version:     $Id: main.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: main.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index dd87c02..a954cf5 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        pidfile.c include file.
  *
- * Version:     $Id: pidfile.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: pidfile.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 8a05f04..6e47a60 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        smtp.c include file.
  *
- * Version:     $Id: smtp.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: smtp.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index dd93106..794cf95 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp.c program include file.
  *
- * Version:     $Id: vrrp.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -93,6 +93,7 @@ typedef struct _vrrp_rt {
        interface *ifp;         /* Interface we belong to */
        int dont_track_primary; /* If set ignores ifp faults */
        list track_ifp;         /* Interface state we monitor */
+       list track_script;      /* Script state we monitor */
        uint32_t mcast_saddr;   /* Src IP address to use in VRRP IP header */
        char *lvs_syncd_if;     /* handle LVS sync daemon state using this
                                 * instance FSM & running on specific interface
@@ -100,7 +101,8 @@ typedef struct _vrrp_rt {
                                 */
        int garp_delay;         /* Delay to launch gratuitous ARP */
        int vrid;               /* virtual id. from 1(!) to 255 */
-       int priority;           /* priority value */
+       int base_priority;      /* configured priority value */
+       int effective_priority; /* effective priority value */
        int vipset;             /* All the vips are set ? */
        list vip;               /* list of virtual ip addresses */
        list evip;              /* list of protocol excluded VIPs.
@@ -129,6 +131,7 @@ typedef struct _vrrp_rt {
        char *script_backup;
        char *script_master;
        char *script_fault;
+       char *script_stop;
        char *script;
 
        /* rfc2336.6.2 */
@@ -191,7 +194,7 @@ typedef struct _vrrp_rt {
 #define VRRP_SEND_BUFFER(V)            ((V)->send_buffer)
 #define VRRP_SEND_BUFFER_SIZE(V)       ((V)->send_buffer_size)
 
-#define VRRP_TIMER_SKEW(svr)   ((256-(svr)->priority)*TIMER_HZ/256)
+#define VRRP_TIMER_SKEW(svr)   ((256-(svr)->base_priority)*TIMER_HZ/256)
 #define VRRP_VIP_ISSET(V)      ((V)->vipset)
 
 #define VRRP_MIN(a, b) ((a) < (b)?(a):(b))
index 7917374..cb919a4 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_arp.c include file.
  *
- * Version:     $Id: vrrp_arp.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_arp.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 6806cce..8d7d41e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_daemon.c include file.
  * 
- * Version:     $Id: vrrp_daemon.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_daemon.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index a2fcbde..8a1f149 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: vrrp_data.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_data.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -57,6 +57,7 @@ typedef struct _vrrp_conf_data {
        list vrrp_index;
        list vrrp_index_fd;
        list vrrp_socket_pool;
+       list vrrp_script;
 } vrrp_conf_data;
 
 /* Global Vars exported */
@@ -70,6 +71,8 @@ extern void alloc_sroute(vector strvec);
 extern void alloc_vrrp_sync_group(char *gname);
 extern void alloc_vrrp(char *iname);
 extern void alloc_vrrp_track(vector strvec);
+extern void alloc_vrrp_script(char *sname);
+extern void alloc_vrrp_track_script(vector strvec);
 extern void alloc_vrrp_vip(vector strvec);
 extern void alloc_vrrp_evip(vector strvec);
 extern void alloc_vrrp_vroute(vector strvec);
index 35e83a4..82824ee 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_if.c include file.
  *
- * Version:     $Id: vrrp_if.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_if.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -70,6 +70,12 @@ typedef struct _interface {
        int linkbeat;           /* LinkBeat from MII BMSR req */
 } interface;
 
+/* Tracked interface structure definition */
+typedef struct _tracked_if {
+       int weight;             /* tracking weight when non-zero */
+       interface *ifp;         /* interface backpointer, cannot be NULL */
+} tracked_if;
+
 /* Macros */
 #define IF_NAME(X) ((X)->ifname)
 #define IF_INDEX(X) ((X)->ifindex)
index d6b17fe..bc9b41b 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_index.c include file.
  *
- * Version:     $Id: vrrp_index.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_index.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 8a7da2f..9a97bc1 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipaddress.c include file.
  *
- * Version:     $Id: vrrp_ipaddress.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 84e7c6b..b9e764f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_iproute.c include file.
  *
- * Version:     $Id: vrrp_iproute.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_iproute.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index df45413..bc69547 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_ipsecah.c include file.
  * 
- * Version:     $Id: vrrp_ipsecah.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index fc39e22..d570ddf 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_netlink.c include file.
  *
- * Version:     $Id: vrrp_netlink.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_netlink.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 04fe029..1439778 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Part:        vrrp_notify.c include file.
  *
- * Version:     $Id: vrrp_notify.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_notify.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 7cdb6f8..3457681 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        vrrp_parser.c include file.
  *  
- * Version:     $Id: vrrp_parser.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_parser.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 0e4e3d2..0c65278 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_scheduler.c include file.
  * 
- * Version:     $Id: vrrp_scheduler.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 97d65a3..d06e573 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_sync.c include file.
  * 
- * Version:     $Id: vrrp_sync.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_sync.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index cbccc61..df1607e 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        vrrp_track.c include file.
  *
- * Version:     $Id: vrrp_track.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_track.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 /* Macro definition */
 #define TRACK_ISUP(L)  (vrrp_tracked_up((L)))
 
+/* VRRP script tracking defaults */
+#define VRRP_SCRIPT_DI 1       /* external script track interval (in sec) */
+#define VRRP_SCRIPT_DW 2       /* external script default weight */
+
+/* VRRP script tracking results */
+#define VRRP_SCRIPT_STATUS_DISABLED  0
+#define VRRP_SCRIPT_STATUS_INIT      1
+#define VRRP_SCRIPT_STATUS_NONE      2
+#define VRRP_SCRIPT_STATUS_GOOD      3
+
+/* external script we call to track local processes */
+typedef struct _vrrp_script {
+       char *sname;            /* instance name */
+       char *script;           /* the command to be called */
+       int interval;           /* interval between script calls */
+       int weight;             /* weight associated to this script */
+       int result;             /* result of last call to this script */
+       int inuse;              /* how many users have weight>0 ? */
+} vrrp_script;
+
+/* Tracked script structure definition */
+typedef struct _tracked_sc {
+       int weight;             /* tracking weight when non-zero */
+       vrrp_script *scr;       /* script pointer, cannot be NULL */
+} tracked_sc;
+
 /* prototypes */
 extern void dump_track(void *track_data_obj);
 extern void alloc_track(list track_list, vector strvec);
+extern void dump_track_script(void *track_data_obj);
+extern void alloc_track_script(list track_list, vector strvec);
 extern int vrrp_tracked_up(list l);
 extern void vrrp_log_tracked_down(list l);
+extern int vrrp_tracked_weight(list l);
+extern int vrrp_script_weight(list l);
 
 #endif
index 497d0bb..6384c9b 100644 (file)
@@ -35,8 +35,8 @@ vrrp_daemon.o: vrrp_daemon.c ../include/vrrp_daemon.h ../include/vrrp_scheduler.
   ../include/ipvswrapper.h ../../lib/list.h ../../lib/memory.h ../../lib/parser.h \
   ../../lib/signals.h
 vrrp_data.o: vrrp_data.c ../include/vrrp_data.h \
-  ../include/vrrp_sync.h ../include/vrrp_index.h ../include/vrrp.h ../../lib/memory.h \
-  ../../lib/utils.h
+  ../include/vrrp_sync.h ../include/vrrp_if.h ../include/vrrp_index.h \
+  ../include/vrrp.h ../../lib/memory.h ../../lib/utils.h ../../lib/notify.h
 vrrp_parser.o: vrrp_parser.c ../include/vrrp_parser.h \
   ../include/vrrp_data.h ../include/vrrp_sync.h ../include/vrrp_index.h \
   ../include/vrrp.h ../include/global_data.h ../include/global_parser.h \
@@ -51,7 +51,7 @@ vrrp_scheduler.o: vrrp_scheduler.c ../include/vrrp_scheduler.h \
   ../include/vrrp_ipsecah.h ../include/vrrp_if.h ../include/vrrp.h \
   ../include/vrrp_sync.h ../include/vrrp_notify.h ../include/ipvswrapper.h \
   ../../lib/memory.h ../../lib/list.h ../include/vrrp_data.h ../include/vrrp_index.h \
-  ../include/smtp.h
+  ../include/smtp.h ../../lib/notify.h
 vrrp_sync.o: vrrp_sync.c ../include/vrrp_sync.h ../include/vrrp_if.h \
   ../include/vrrp_notify.h ../include/vrrp_data.h
 vrrp_index.o: vrrp_index.c ../include/vrrp_index.h ../include/vrrp.h \
index 73ffadc..4ff51b7 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 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -40,6 +40,7 @@
 #include "list.h"
 #include "main.h"
 #include "utils.h"
+#include "notify.h"
 
 /* add/remove Virtual IP addresses */
 static int
@@ -641,7 +642,7 @@ vrrp_state_goto_master(vrrp_rt * vrrp)
         * Send an advertisement. To force a new master
         * election.
         */
-       vrrp_send_adv(vrrp, vrrp->priority);
+       vrrp_send_adv(vrrp, vrrp->effective_priority);
 
        vrrp->state = VRRP_STATE_MAST;
        syslog(LOG_INFO, "VRRP_Instance(%s) Transition to MASTER STATE",
@@ -741,16 +742,16 @@ vrrp_state_backup(vrrp_rt * vrrp, char *buf, int buflen)
                    3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
        } else if (hd->priority == 0) {
                vrrp->ms_down_timer = VRRP_TIMER_SKEW(vrrp);
-       } else if (vrrp->nopreempt || hd->priority >= vrrp->priority ||
+       } else if (vrrp->nopreempt || hd->priority >= vrrp->effective_priority ||
                   timer_cmp(vrrp->preempt_time, timer_now()) > 0) {
                vrrp->ms_down_timer =
                    3 * vrrp->adver_int + VRRP_TIMER_SKEW(vrrp);
-       } else if (hd->priority < vrrp->priority) {
+       } else if (hd->priority < vrrp->effective_priority) {
                syslog(LOG_INFO,
                       "VRRP_Instance(%s) forcing a new MASTER election",
                       vrrp->iname);
                vrrp->wantstate = VRRP_STATE_GOTO_MASTER;
-               vrrp_send_adv(vrrp, vrrp->priority);
+               vrrp_send_adv(vrrp, vrrp->effective_priority);
        }
 }
 
@@ -768,8 +769,8 @@ vrrp_state_master_tx(vrrp_rt * vrrp, const int prio)
        }
 
        vrrp_send_adv(vrrp,
-                     (prio ==
-                      VRRP_PRIO_OWNER) ? VRRP_PRIO_OWNER : vrrp->priority);
+                     (prio == VRRP_PRIO_OWNER) ? VRRP_PRIO_OWNER :
+                                                 vrrp->effective_priority);
        return ret;
 }
 
@@ -809,7 +810,7 @@ vrrp_state_master_rx(vrrp_rt * vrrp, char *buf, int buflen)
                       "VRRP_Instance(%s) Dropping received VRRP packet...",
                       vrrp->iname);
                return 0;
-       } else if (hd->priority < vrrp->priority) {
+       } else if (hd->priority < vrrp->effective_priority) {
                /* We receive a lower prio adv we just refresh remote ARP cache */
                syslog(LOG_INFO, "VRRP_Instance(%s) Received lower prio advert"
                       ", forcing new election", vrrp->iname);
@@ -821,14 +822,14 @@ vrrp_state_master_rx(vrrp_rt * vrrp, char *buf, int buflen)
                        vrrp->ipsecah_counter->seq_number = ntohl(ah->seq_number) + 1;
                        vrrp->ipsecah_counter->cycle = 0;
                }
-               vrrp_send_adv(vrrp, vrrp->priority);
+               vrrp_send_adv(vrrp, vrrp->effective_priority);
                vrrp_send_gratuitous_arp(vrrp);
                return 0;
        } else if (hd->priority == 0) {
-               vrrp_send_adv(vrrp, vrrp->priority);
+               vrrp_send_adv(vrrp, vrrp->effective_priority);
                return 0;
-       } else if (hd->priority > vrrp->priority ||
-                  (hd->priority == vrrp->priority &&
+       } else if (hd->priority > vrrp->effective_priority ||
+                  (hd->priority == vrrp->effective_priority &&
                    ntohl(iph->saddr) > VRRP_PKT_SADDR(vrrp))) {
                syslog(LOG_INFO,
                       "VRRP_Instance(%s) Received higher prio advert",
@@ -878,7 +879,7 @@ vrrp_state_fault_rx(vrrp_rt * vrrp, char *buf, int buflen)
                       "VRRP_Instance(%s) Dropping received VRRP packet...",
                       vrrp->iname);
                return 0;
-       } else if (vrrp->priority > hd->priority ||
+       } else if (vrrp->effective_priority > hd->priority ||
                   hd->priority == VRRP_PRIO_OWNER)
                return 1;
 
@@ -1000,6 +1001,10 @@ shutdown_vrrp_instances(void)
                if (vrrp->state == VRRP_STATE_MAST)
                        vrrp_restore_interface(vrrp, 1);
 
+               /* Run stop script */
+               if (vrrp->script_stop)
+                       notify_exec(vrrp->script_stop);
+
 #ifdef _HAVE_IPVS_SYNCD_
                /*
                 * Stop stalled syncd. IPVS syncd state is the
@@ -1023,8 +1028,8 @@ vrrp_complete_instance(vrrp_rt * vrrp)
        vrrp->state = VRRP_STATE_INIT;
        if (!vrrp->adver_int)
                vrrp->adver_int = VRRP_ADVER_DFL * TIMER_HZ;
-       if (!vrrp->priority)
-               vrrp->priority = VRRP_PRIO_DFL;
+       if (!vrrp->effective_priority)
+               vrrp->effective_priority = VRRP_PRIO_DFL;
 
        return (chk_min_cfg(vrrp));
 }
index e4916cf..52782fd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        ARP primitives.
  *
- * Version:     $Id: vrrp_arp.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_arp.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 9b9d8d6..06ee674 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP child process handling.
  *
- * Version:     $Id: vrrp_daemon.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_daemon.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 33d9d25..49296a7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Dynamic data structure definition.
  *
- * Version:     $Id: vrrp_data.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_data.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -25,6 +25,7 @@
 #include "vrrp_data.h"
 #include "vrrp_index.h"
 #include "vrrp_sync.h"
+#include "vrrp_if.h"
 #include "vrrp.h"
 #include "memory.h"
 #include "utils.h"
@@ -96,6 +97,40 @@ dump_vgroup(void *data)
                syslog(LOG_INFO, "   Using smtp notification");
 }
 
+static void
+free_vscript(void *data)
+{
+       vrrp_script *vscript = data;
+
+       FREE(vscript->sname);
+       FREE_PTR(vscript->script);
+       FREE(vscript);
+}
+static void
+dump_vscript(void *data)
+{
+       vrrp_script *vscript = data;
+       char *str;
+
+       syslog(LOG_INFO, " VRRP Script = %s", vscript->sname);
+       syslog(LOG_INFO, "   Command = %s", vscript->script);
+       syslog(LOG_INFO, "   Interval = %d sec", vscript->interval / TIMER_HZ);
+       syslog(LOG_INFO, "   Weight = %d", vscript->weight);
+
+       switch (vscript->result) {
+       case VRRP_SCRIPT_STATUS_INIT:
+               str = "INIT"; break;
+       case VRRP_SCRIPT_STATUS_NONE:
+               str = "BAD"; break;
+       case VRRP_SCRIPT_STATUS_GOOD:
+               str = "GOOD"; break;
+       case VRRP_SCRIPT_STATUS_DISABLED:
+       default:
+               str = "DISABLED"; break;
+       }
+       syslog(LOG_INFO, "   Status = %s", str);
+}
+
 /* Socket pool functions */
 static void
 free_sock(void *sock_data_obj)
@@ -122,6 +157,7 @@ static void
 free_vrrp(void *data)
 {
        vrrp_rt *vrrp = data;
+       element e;
 
        FREE(vrrp->iname);
        FREE_PTR(vrrp->send_buffer);
@@ -129,9 +165,20 @@ free_vrrp(void *data)
        FREE_PTR(vrrp->script_backup);
        FREE_PTR(vrrp->script_master);
        FREE_PTR(vrrp->script_fault);
+       FREE_PTR(vrrp->script_stop);
        FREE_PTR(vrrp->script);
        FREE(vrrp->ipsecah_counter);
+
+       if (!LIST_ISEMPTY(vrrp->track_ifp))
+               for (e = LIST_HEAD(vrrp->track_ifp); e; ELEMENT_NEXT(e))
+                       FREE(ELEMENT_DATA(e));
        free_list(vrrp->track_ifp);
+
+       if (!LIST_ISEMPTY(vrrp->track_script))
+               for (e = LIST_HEAD(vrrp->track_script); e; ELEMENT_NEXT(e))
+                       FREE(ELEMENT_DATA(e));
+       free_list(vrrp->track_script);
+
        free_list(vrrp->vip);
        free_list(vrrp->evip);
        free_list(vrrp->vroutes);
@@ -160,7 +207,7 @@ dump_vrrp(void *data)
                syslog(LOG_INFO, "   Gratuitous ARP delay = %d",
                       vrrp->garp_delay/TIMER_HZ);
        syslog(LOG_INFO, "   Virtual Router ID = %d", vrrp->vrid);
-       syslog(LOG_INFO, "   Priority = %d", vrrp->priority);
+       syslog(LOG_INFO, "   Priority = %d", vrrp->base_priority);
        syslog(LOG_INFO, "   Advert interval = %dsec",
               vrrp->adver_int / TIMER_HZ);
        if (vrrp->nopreempt)
@@ -178,6 +225,11 @@ dump_vrrp(void *data)
                syslog(LOG_INFO, "   Tracked interfaces = %d", LIST_SIZE(vrrp->track_ifp));
                dump_list(vrrp->track_ifp);
        }
+       if (!LIST_ISEMPTY(vrrp->track_script)) {
+               syslog(LOG_INFO, "   Tracked scripts = %d",
+                      LIST_SIZE(vrrp->track_script));
+               dump_list(vrrp->track_script);
+       }
        if (!LIST_ISEMPTY(vrrp->vip)) {
                syslog(LOG_INFO, "   Virtual IP = %d", LIST_SIZE(vrrp->vip));
                dump_list(vrrp->vip);
@@ -199,6 +251,9 @@ dump_vrrp(void *data)
        if (vrrp->script_fault)
                syslog(LOG_INFO, "   Fault state transition script = %s",
                       vrrp->script_fault);
+       if (vrrp->script_stop)
+               syslog(LOG_INFO, "   Stop state transition script = %s",
+                      vrrp->script_stop);
        if (vrrp->script)
                syslog(LOG_INFO, "   Generic state transition script = '%s'",
                       vrrp->script);
@@ -256,6 +311,16 @@ alloc_vrrp_track(vector strvec)
 }
 
 void
+alloc_vrrp_track_script(vector strvec)
+{
+       vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
+
+       if (LIST_ISEMPTY(vrrp->track_script))
+               vrrp->track_script = alloc_list(NULL, dump_track_script);
+       alloc_track_script(vrrp->track_script, strvec);
+}
+
+void
 alloc_vrrp_vip(vector strvec)
 {
        vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
@@ -284,6 +349,23 @@ alloc_vrrp_vroute(vector strvec)
        alloc_route(vrrp->vroutes, strvec);
 }
 
+void
+alloc_vrrp_script(char *sname)
+{
+       int size = strlen(sname);
+       vrrp_script *new;
+
+       /* Allocate new VRRP group structure */
+       new = (vrrp_script *) MALLOC(sizeof (vrrp_script));
+       new->sname = (char *) MALLOC(size + 1);
+       memcpy(new->sname, sname, size);
+       new->interval = VRRP_SCRIPT_DI * TIMER_HZ;
+       new->weight = VRRP_SCRIPT_DW;
+       new->result = VRRP_SCRIPT_STATUS_INIT;
+       new->inuse = 0;
+       list_add(vrrp_data->vrrp_script, new);
+}
+
 /* data facility functions */
 void
 alloc_vrrp_buffer(void)
@@ -307,6 +389,7 @@ alloc_vrrp_data(void)
        new->vrrp_index = alloc_mlist(NULL, NULL, 255);
        new->vrrp_index_fd = alloc_mlist(NULL, NULL, 1024+1);
        new->vrrp_sync_group = alloc_list(free_vgroup, dump_vgroup);
+       new->vrrp_script = alloc_list(free_vscript, dump_vscript);
        new->vrrp_socket_pool = alloc_list(free_sock, dump_sock);
 
        return new;
@@ -321,6 +404,7 @@ free_vrrp_data(vrrp_conf_data * vrrp_data_obj)
        free_mlist(vrrp_data_obj->vrrp_index_fd, 1024+1);
        free_list(vrrp_data_obj->vrrp);
        free_list(vrrp_data_obj->vrrp_sync_group);
+       free_list(vrrp_data_obj->vrrp_script);
        free_list(vrrp_data_obj->vrrp_socket_pool);
        FREE(vrrp_data_obj);
 }
@@ -344,4 +428,8 @@ dump_vrrp_data(vrrp_conf_data * vrrp_data_obj)
                syslog(LOG_INFO, "------< VRRP Sync groups >------");
                dump_list(vrrp_data_obj->vrrp_sync_group);
        }
+       if (!LIST_ISEMPTY(vrrp_data_obj->vrrp_script)) {
+               syslog(LOG_INFO, "------< VRRP Scripts >------");
+               dump_list(vrrp_data_obj->vrrp_script);
+       }
 }
index 11df6c2..2c96194 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Interfaces manipulation.
  *
- * Version:     $Id: vrrp_if.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_if.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 767cdda..7c4cf00 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP instance index table.
  *
- * Version:     $Id: vrrp_index.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_index.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 0c71457..e824b6c 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 address manipulation.
  *
- * Version:     $Id: vrrp_ipaddress.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_ipaddress.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 93bf914..ff5dbde 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK IPv4 routes manipulation.
  *
- * Version:     $Id: vrrp_iproute.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_iproute.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index cb5193c..241197d 100644 (file)
@@ -7,7 +7,7 @@
  *              authentication data encryption using HMAC MD5 according to
  *              RFCs 2085 & 2104.
  *
- * Version:     $Id: vrrp_ipsecah.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_ipsecah.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 6a821f5..0e1a10d 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        NETLINK kernel command channel.
  *
- * Version:     $Id: vrrp_netlink.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_netlink.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 7e6555f..6cc3d52 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP state transition notification scripts handling.
  *
- * Version:     $Id: vrrp_notify.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_notify.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -113,7 +113,7 @@ script_open(char *script)
 }
 
 static int
-notify_script_exec(char* script, char *type, int state_num, char* name)
+notify_script_exec(char* script, char *type, int state_num, char* name, int prio)
 {
        char *state = "{UNKNOWN}";
        char *command_line = NULL;
@@ -123,23 +123,28 @@ notify_script_exec(char* script, char *type, int state_num, char* name)
         * Determine the length of the buffer that we'll need to generate the command
         * to run:
         *
-        * "script" {GROUP|INSTANCE} "NAME" {MASTER|BACKUP|FAULT}
+        * "script" {GROUP|INSTANCE} "NAME" {MASTER|BACKUP|FAULT} PRIO
         *
         * Thus, the length of the buffer will be:
         *
-        *     ( strlen(script) + 3 ) + ( strlen(type) + 1 ) + ( strlen(state) + 1 ) + ( strlen(name) + 2 ) + 1
+        *     ( strlen(script) + 3 ) + ( strlen(type) + 1 ) + ( strlen(name) + 1 ) +
+        *      ( strlen(state) + 2 ) + ( strlen(prio) + 1 ) + 1 
+        *
+        * Note that the prio will be indicated as zero for a group.
         *
         * Which is:
         *     - The length of the script plus two enclosing quotes plus adjacent space
         *     - The length of the type string plus the adjacent space
-        *     - The length of the state string plus the adjacent space
         *     - The length of the name of the instance or group, plus two enclosing
         *       quotes (just in case)
+        *     - The length of the state string plus the adjacent space
+        *     - The length of the priority value (3 digits) plus the adjacent
+        *       space
         *     - The null-terminator
         *
         * Which results in:
         *
-        *     strlen(script) + strlen(type) + strlen(state) + strlen(name) + 8
+        *     strlen(script) + strlen(type) + strlen(state) + strlen(name) + 12
         */
        switch (state_num) {
                case VRRP_STATE_MAST  : state = "MASTER" ; break;
@@ -147,13 +152,14 @@ notify_script_exec(char* script, char *type, int state_num, char* name)
                case VRRP_STATE_FAULT : state = "FAULT" ; break;
        }
 
-       size = strlen(script) + strlen(type) + strlen(state) + strlen(name) + 8;
+       size = strlen(script) + strlen(type) + strlen(state) + strlen(name) + 12;
        command_line = MALLOC(size);
        if (!command_line)
                return 0;
 
        /* Launch the script */
-       snprintf(command_line, size, "\"%s\" %s \"%s\" %s",script, type, name, state);
+       snprintf(command_line, size, "\"%s\" %s \"%s\" %s %d",
+                script, type, name, state, prio);
        notify_exec(command_line);
        FREE(command_line);
        return 1;
@@ -174,7 +180,8 @@ notify_instance_exec(vrrp_rt * vrrp, int state)
 
        /* Launch the generic notify script */
        if (gscript && script_open_litteral(gscript)) {
-               notify_script_exec(gscript, "INSTANCE", state, vrrp->iname);
+               notify_script_exec(gscript, "INSTANCE", state, vrrp->iname,
+                                  vrrp->effective_priority);
                ret = 1;
        }
 
@@ -196,7 +203,7 @@ notify_group_exec(vrrp_sgroup * vgroup, int state)
 
        /* Launch the generic notify script */
        if (gscript && script_open_litteral(gscript)) {
-               notify_script_exec(gscript, "GROUP", state, vgroup->gname);
+               notify_script_exec(gscript, "GROUP", state, vgroup->gname, 0);
                ret = 1;
        }
 
index bae878a..5bed78e 100644 (file)
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: vrrp_parser.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_parser.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -129,6 +129,11 @@ vrrp_track_int_handler(vector strvec)
        alloc_value_block(strvec, alloc_vrrp_track);
 }
 static void
+vrrp_track_scr_handler(vector strvec)
+{
+       alloc_value_block(strvec, alloc_vrrp_track_script);
+}
+static void
 vrrp_dont_track_handler(vector strvec)
 {
        vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
@@ -157,14 +162,14 @@ static void
 vrrp_prio_handler(vector strvec)
 {
        vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
-       vrrp->priority = atoi(VECTOR_SLOT(strvec, 1));
+       vrrp->effective_priority = vrrp->base_priority = atoi(VECTOR_SLOT(strvec, 1));
 
-       if (VRRP_IS_BAD_PRIORITY(vrrp->priority)) {
+       if (VRRP_IS_BAD_PRIORITY(vrrp->base_priority)) {
                syslog(LOG_INFO, "VRRP Error : Priority not valid !\n");
                syslog(LOG_INFO,
                       "             must be between 1 & 255. reconfigure !\n");
                syslog(LOG_INFO, "             Using default value : 100\n");
-               vrrp->priority = 100;
+               vrrp->effective_priority = vrrp->base_priority = 100;
        }
 }
 static void
@@ -243,6 +248,13 @@ vrrp_notify_fault_handler(vector strvec)
        vrrp->notify_exec = 1;
 }
 static void
+vrrp_notify_stop_handler(vector strvec)
+{
+       vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
+       vrrp->script_stop = set_value(strvec);
+       vrrp->notify_exec = 1;
+}
+static void
 vrrp_notify_handler(vector strvec)
 {
        vrrp_rt *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp);
@@ -338,6 +350,29 @@ vrrp_vroutes_handler(vector strvec)
 {
        alloc_value_block(strvec, alloc_vrrp_vroute);
 }
+static void
+vrrp_script_handler(vector strvec)
+{
+       alloc_vrrp_script(VECTOR_SLOT(strvec, 1));
+}
+static void
+vrrp_vscript_script_handler(vector strvec)
+{
+       vrrp_script *vscript = LIST_TAIL_DATA(vrrp_data->vrrp_script);
+       vscript->script = set_value(strvec);
+}
+static void
+vrrp_vscript_interval_handler(vector strvec)
+{
+       vrrp_script *vscript = LIST_TAIL_DATA(vrrp_data->vrrp_script);
+       vscript->interval = atoi(VECTOR_SLOT(strvec, 1)) * TIMER_HZ;
+}
+static void
+vrrp_vscript_weight_handler(vector strvec)
+{
+       vrrp_script *vscript = LIST_TAIL_DATA(vrrp_data->vrrp_script);
+       vscript->weight = atoi(VECTOR_SLOT(strvec, 1));
+}
 
 vector
 vrrp_init_keywords(void)
@@ -362,6 +397,7 @@ vrrp_init_keywords(void)
        install_keyword("interface", &vrrp_int_handler);
        install_keyword("dont_track_primary", &vrrp_dont_track_handler);
        install_keyword("track_interface", &vrrp_track_int_handler);
+       install_keyword("track_script", &vrrp_track_scr_handler);
        install_keyword("mcast_src_ip", &vrrp_mcastip_handler);
        install_keyword("virtual_router_id", &vrrp_vrid_handler);
        install_keyword("priority", &vrrp_prio_handler);
@@ -376,6 +412,7 @@ vrrp_init_keywords(void)
        install_keyword("notify_backup", &vrrp_notify_backup_handler);
        install_keyword("notify_master", &vrrp_notify_master_handler);
        install_keyword("notify_fault", &vrrp_notify_fault_handler);
+       install_keyword("notify_stop", &vrrp_notify_stop_handler);
        install_keyword("notify", &vrrp_notify_handler);
        install_keyword("smtp_alert", &vrrp_smtp_handler);
        install_keyword("lvs_sync_daemon_interface", &vrrp_lvs_syncd_handler);
@@ -385,6 +422,10 @@ vrrp_init_keywords(void)
        install_keyword("auth_type", &vrrp_auth_type_handler);
        install_keyword("auth_pass", &vrrp_auth_pass_handler);
        install_sublevel_end();
+       install_keyword_root("vrrp_script", &vrrp_script_handler);
+       install_keyword("script", &vrrp_vscript_script_handler);
+       install_keyword("interval", &vrrp_vscript_interval_handler);
+       install_keyword("weight", &vrrp_vscript_weight_handler);
 
        return keywords;
 }
index f1bbe09..0e9a0ee 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Sheduling framework for vrrp code.
  *
- * Version:     $Id: vrrp_scheduler.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_scheduler.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -33,6 +33,7 @@
 #include "vrrp_index.h"
 #include "ipvswrapper.h"
 #include "memory.h"
+#include "notify.h"
 #include "list.h"
 #include "main.h"
 #include "smtp.h"
@@ -70,6 +71,11 @@ static void vrrp_goto_master(vrrp_rt *);
 static void vrrp_master(vrrp_rt *);
 static void vrrp_fault(vrrp_rt *);
 
+static int vrrp_update_priority(thread * thread_obj);
+static int vrrp_script_child_timeout_thread(thread * thread_obj);
+static int vrrp_script_child_thread(thread * thread_obj);
+static int vrrp_script_thread(thread * thread_obj);
+
 struct {
        void (*read) (vrrp_rt *, char *, int);
        void (*read_to) (vrrp_rt *);
@@ -180,7 +186,49 @@ vrrp_init_state(list l)
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                vrrp = ELEMENT_DATA(e);
 
-               if (vrrp->priority == VRRP_PRIO_OWNER ||
+               /* In case of VRRP SYNC, we have to carefully check that we are
+                * not running floating priorities on any VRRP instance.
+                */
+               if (vrrp->sync) {
+                       element e;
+                       tracked_sc *sc;
+                       tracked_if *tip;
+                       int warning = 0;
+
+                       if (!LIST_ISEMPTY(vrrp->track_ifp)) {
+                               for (e = LIST_HEAD(vrrp->track_ifp); e; ELEMENT_NEXT(e)) {
+                                       tip = ELEMENT_DATA(e);
+                                       if (tip->weight) {
+                                               tip->weight = 0;
+                                               warning++;
+                                       }
+                               }
+                       }
+
+                       if (!LIST_ISEMPTY(vrrp->track_script)) {
+                               for (e = LIST_HEAD(vrrp->track_script); e;
+                                    ELEMENT_NEXT(e)) {
+                                       sc = ELEMENT_DATA(e);
+                                       if (sc->weight) {
+                                               sc->weight = 0;
+                                               sc->scr->inuse--;
+                                               warning++;
+                                       }
+                               }
+                       }
+
+                       if (warning > 0) {
+                               syslog(LOG_INFO, "VRRP_Instance(%s) : ignoring "
+                                                "track weights due to SYNC group",
+                                      vrrp->iname);
+                       }
+               } else {
+                       /* Register new priority update thread */
+                       thread_add_timer(master, vrrp_update_priority,
+                                        vrrp, vrrp->adver_int);
+               }
+
+               if (vrrp->base_priority == VRRP_PRIO_OWNER ||
                    vrrp->wantstate == VRRP_STATE_MAST) {
 #ifdef _HAVE_IPVS_SYNCD_
                        /* Check if sync daemon handling is needed */
@@ -233,6 +281,28 @@ vrrp_init_sands(list l)
        }
 }
 
+/* if run after vrrp_init_state(), it will be able to detect scripts that
+ * have been disabled because of a sync group and will avoid to start them.
+ */
+static void
+vrrp_init_script(list l)
+{
+       vrrp_script *vscript;
+       element e;
+
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               vscript = ELEMENT_DATA(e);
+               if (vscript->inuse == 0)
+                       vscript->result = VRRP_SCRIPT_STATUS_DISABLED;
+
+               if (vscript->result == VRRP_SCRIPT_STATUS_INIT) {
+                       vscript->result = VRRP_SCRIPT_STATUS_NONE;
+                       thread_add_timer(master, vrrp_script_thread,
+                                        vscript, vscript->interval);
+               }
+       }
+}
+
 /* Timer functions */
 static TIMEVAL
 vrrp_compute_timer(const int fd)
@@ -307,6 +377,10 @@ vrrp_register_workers(list l)
        /* Init VRRP instances sands */
        vrrp_init_sands(vrrp_data->vrrp);
 
+       /* Init VRRP tracking scripts */
+       if (!LIST_ISEMPTY(vrrp_data->vrrp_script))
+               vrrp_init_script(vrrp_data->vrrp_script);
+
        /* Register VRRP workers threads */
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
                sock_obj = ELEMENT_DATA(e);
@@ -553,12 +627,14 @@ vrrp_leave_fault(vrrp_rt * vrrp, char *buffer, int len)
                                       vrrp->iname);
                                vrrp->state = VRRP_STATE_BACK;
                                vrrp_smtp_notifier(vrrp);
+                               notify_instance_exec(vrrp, VRRP_STATE_BACK);
                        }
                } else {
                        syslog(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE",
                               vrrp->iname);
                        vrrp->state = VRRP_STATE_BACK;
                        vrrp_smtp_notifier(vrrp);
+                       notify_instance_exec(vrrp, VRRP_STATE_BACK);
                }
        }
 }
@@ -598,6 +674,45 @@ vrrp_gratuitous_arp_thread(thread * thread_obj)
        return 0;
 }
 
+/* Update VRRP effective priority based on multiple checkers.
+ * This is a thread which is executed every adver_int.
+ */
+static int
+vrrp_update_priority(thread * thread_obj)
+{
+       vrrp_rt *vrrp = THREAD_ARG(thread_obj);
+       int prio_offset, new_prio;
+
+       /* compute prio_offset right here */
+       prio_offset = 0;
+
+       /* Now we will sum the weights of all interfaces which are tracked. */
+       if (!vrrp->sync && !LIST_ISEMPTY(vrrp->track_ifp))
+                prio_offset += vrrp_tracked_weight(vrrp->track_ifp);
+
+       /* Now we will sum the weights of all scripts which are tracked. */
+       if (!vrrp->sync && !LIST_ISEMPTY(vrrp->track_script))
+               prio_offset += vrrp_script_weight(vrrp->track_script);
+
+       if (vrrp->base_priority == VRRP_PRIO_OWNER) {
+               /* we will not run a PRIO_OWNER into a non-PRIO_OWNER */
+               vrrp->effective_priority = VRRP_PRIO_OWNER;
+       } else {
+               /* WARNING! we must compute new_prio on a signed int in order
+                  to detect overflows and avoid wrapping. */
+               new_prio = vrrp->base_priority + prio_offset;
+               if (new_prio < 1)
+                       new_prio = 1;
+               else if (new_prio > 254)
+                       new_prio = 254;
+               vrrp->effective_priority = new_prio;
+       }
+
+       /* Register next priority update thread */
+       thread_add_timer(master, vrrp_update_priority, vrrp, vrrp->adver_int);
+       return 0;
+}
+
 static void
 vrrp_master(vrrp_rt * vrrp)
 {
@@ -787,3 +902,115 @@ vrrp_read_dispatcher_thread(thread * thread_obj)
 
        return 0;
 }
+
+/* Script tracking threads */
+static int
+vrrp_script_thread(thread * thread_obj)
+{
+       vrrp_script *vscript = THREAD_ARG(thread_obj);
+       int status;
+       pid_t pid;
+
+       /* Register next timer tracker */
+       thread_add_timer(thread_obj->master, vrrp_script_thread, vscript,
+                        vscript->interval);
+
+       /* Daemonization to not degrade our scheduling timer */
+       pid = fork();
+
+       /* In case of fork is error. */
+       if (pid < 0) {
+               syslog(LOG_INFO, "Failed fork process");
+               return -1;
+       }
+
+       /* In case of this is parent process */
+       if (pid) {
+               long timeout;
+               timeout = vscript->interval;
+               thread_add_child(thread_obj->master, vrrp_script_child_thread,
+                                vscript, pid, timeout);
+               return 0;
+       }
+
+       /* Child part */
+       closeall(0);
+       open("/dev/null", O_RDWR);
+       dup(0);
+       dup(0);
+
+       /* Also need to reset the signal state */
+       {
+               sigset_t empty_set;
+               sigemptyset(&empty_set);
+               sigprocmask(SIG_SETMASK, &empty_set, NULL);
+
+               signal(SIGHUP, SIG_DFL);
+               signal(SIGINT, SIG_DFL);
+               signal(SIGTERM, SIG_DFL);
+               signal(SIGKILL, SIG_DFL);
+       }
+
+       status = system_call(vscript->script);
+
+       if (status < 0 || !WIFEXITED(status))
+               status = 0; /* Script errors aren't server errors */
+       else
+               status = WEXITSTATUS(status);
+
+       exit(status);
+}
+
+static int
+vrrp_script_child_thread(thread * thread_obj)
+{
+       int wait_status;
+       vrrp_script *vscript = THREAD_ARG(thread_obj);
+
+       if (thread_obj->type == THREAD_CHILD_TIMEOUT) {
+               pid_t pid;
+
+               pid = THREAD_CHILD_PID(thread_obj);
+
+               /* The child hasn't responded. Kill it off. */
+               vscript->result = VRRP_SCRIPT_STATUS_NONE;
+               kill(pid, SIGTERM);
+               thread_add_child(thread_obj->master, vrrp_script_child_timeout_thread,
+                                vscript, pid, 2);
+               return 0;
+       }
+
+       wait_status = THREAD_CHILD_STATUS(thread_obj);
+
+       if (WIFEXITED(wait_status)) {
+               int status;
+               status = WEXITSTATUS(wait_status);
+               vscript->result = (status == 0) ?  VRRP_SCRIPT_STATUS_GOOD :
+                                                  VRRP_SCRIPT_STATUS_NONE;
+       }
+
+       return 0;
+}
+
+static int
+vrrp_script_child_timeout_thread(thread * thread_obj)
+{
+       pid_t pid;
+
+       if (thread_obj->type != THREAD_CHILD_TIMEOUT)
+               return 0;
+
+       /* OK, it still hasn't exited. Now really kill it off. */
+       pid = THREAD_CHILD_PID(thread_obj);
+       if (kill(pid, SIGKILL) < 0) {
+               /* Its possible it finished while we're handing this */
+               if (errno != ESRCH)
+                       DBG("kill error: %s", strerror(errno));
+               return 0;
+       }
+
+       syslog(LOG_WARNING, "Process [%d] didn't respond to SIGTERM", pid);
+       waitpid(pid, NULL, 0);
+
+       return 0;
+}
index 7c44316..53882cc 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        VRRP synchronization framework.
  *
- * Version:     $Id: vrrp_sync.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_sync.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -36,7 +36,8 @@ vrrp_init_instance_sands(vrrp_rt * vrrp)
 
        if (vrrp->state == VRRP_STATE_MAST        ||
            vrrp->state == VRRP_STATE_GOTO_MASTER ||
-           vrrp->state == VRRP_STATE_GOTO_FAULT) {
+           vrrp->state == VRRP_STATE_GOTO_FAULT  ||
+           vrrp->wantstate == VRRP_STATE_GOTO_MASTER) {
                vrrp->sands.tv_sec = time_now.tv_sec + vrrp->adver_int / TIMER_HZ;
                vrrp->sands.tv_usec = time_now.tv_usec;
                return;
@@ -160,7 +161,7 @@ vrrp_sync_master_election(vrrp_rt * vrrp)
                        syslog(LOG_INFO,
                               "VRRP_Instance(%s) forcing a new MASTER election",
                               isync->iname);
-                       vrrp_send_adv(isync, isync->priority);
+                       vrrp_send_adv(isync, isync->effective_priority);
                }
        }
 }
index 18578b9..e1c0d0f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Interface tracking framework.
  *
- * Version:     $Id: vrrp_track.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vrrp_track.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
 void
 dump_track(void *track_data_obj)
 {
-       interface *ifp = track_data_obj;
-       syslog(LOG_INFO, "     %s", IF_NAME(ifp));
+       tracked_if *tip = track_data_obj;
+       syslog(LOG_INFO, "     %s weight %d", IF_NAME(tip->ifp), tip->weight);
 }
 void
 alloc_track(list track_list, vector strvec)
 {
        interface *ifp = NULL;
+       tracked_if *tip = NULL;
+       int weight = 0;
        char *tracked = VECTOR_SLOT(strvec, 0);
 
        ifp = if_get_by_ifname(tracked);
@@ -49,19 +51,95 @@ alloc_track(list track_list, vector strvec)
                return;
        }
 
-       list_add(track_list, ifp);
+       if (VECTOR_SIZE(strvec) >= 3 &&
+           !strcmp(VECTOR_SLOT(strvec, 1), "weight")) {
+               weight = atoi(VECTOR_SLOT(strvec, 2));
+               if (weight < -254 || weight > 254) {
+                       syslog(LOG_INFO, "     %s: weight must be between "
+                                        "[-254..254] inclusive. Ignoring...", tracked);
+                       weight = 0;
+               }
+       }
+
+       tip         = (tracked_if *) MALLOC(sizeof (tracked_if));
+       tip->ifp    = ifp;
+       tip->weight = weight;
+
+       list_add(track_list, tip);
+}
+
+static vrrp_script *
+find_script_by_name(char *name)
+{
+       element e;
+       vrrp_script *scr;
+
+       if (LIST_ISEMPTY(vrrp_data->vrrp_script))
+               return NULL;
+
+       for (e = LIST_HEAD(vrrp_data->vrrp_script); e; ELEMENT_NEXT(e)) {
+               scr = ELEMENT_DATA(e);
+               if (!strcmp(scr->sname, name))
+                       return scr;
+       }
+       return NULL;
+}
+
+/* Track script dump */
+void
+dump_track_script(void *track_data_obj)
+{
+       tracked_sc *tsc = track_data_obj;
+       syslog(LOG_INFO, "     %s weight %d", tsc->scr->sname, tsc->weight);
+}
+void
+alloc_track_script(list track_list, vector strvec)
+{
+       vrrp_script *vsc = NULL;
+       tracked_sc *tsc = NULL;
+       int weight = 0;
+       char *tracked = VECTOR_SLOT(strvec, 0);
+
+       vsc = find_script_by_name(tracked);
+
+       /* Ignoring if no interface found */
+       if (!vsc) {
+               syslog(LOG_INFO, "     %s no match, ignoring...", tracked);
+               return;
+       }
+
+       /* default weight */
+       weight = vsc->weight;
+
+       if (VECTOR_SIZE(strvec) >= 3 &&
+           !strcmp(VECTOR_SLOT(strvec, 1), "weight")) {
+               weight = atoi(VECTOR_SLOT(strvec, 2));
+               if (weight < -254 || weight > 254) {
+                       weight = vsc->weight;
+                       syslog(LOG_INFO, "     %s: weight must be between [-254..254]"
+                                        " inclusive, ignoring...",
+                              tracked);
+               }
+       }
+
+       tsc         = (tracked_sc *) MALLOC(sizeof (tracked_sc));
+       tsc->scr    = vsc;
+       tsc->weight = weight;
+       if (weight > 0)
+               vsc->inuse++;
+       list_add(track_list, tsc);
 }
 
-/* Test if all tracked interfaces are UP */
+/* Test if all tracked interfaces are either UP or weight-tracked */
 int
 vrrp_tracked_up(list l)
 {
        element e;
-       interface *ifp;
+       tracked_if *tip;
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
-               ifp = ELEMENT_DATA(e);
-               if (!IF_ISUP(ifp))
+               tip = ELEMENT_DATA(e);
+               if (!tip->weight && !IF_ISUP(tip->ifp))
                        return 0;
        }
 
@@ -73,12 +151,66 @@ void
 vrrp_log_tracked_down(list l)
 {
        element e;
-       interface *ifp;
+       tracked_if *tip;
 
        for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
-               ifp = ELEMENT_DATA(e);
-               if (!IF_ISUP(ifp))
+               tip = ELEMENT_DATA(e);
+               if (!IF_ISUP(tip->ifp))
                        syslog(LOG_INFO, "Kernel is reporting: interface %s DOWN",
-                              IF_NAME(ifp));
+                              IF_NAME(tip->ifp));
+       }
+}
+
+/* Returns total weights of all tracked interfaces :
+ * - a positive interface weight adds to the global weight when the
+ *   interface is UP.
+ * - a negative interface weight subtracts from the global weight when the
+ *   interface is DOWN.
+ *
+ */
+int
+vrrp_tracked_weight(list l)
+{
+       element e;
+       tracked_if *tip;
+       int weight = 0;
+
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               tip = ELEMENT_DATA(e);
+               if (IF_ISUP(tip->ifp)) {
+                       if (tip->weight > 0)
+                               weight += tip->weight;
+               } else {
+                       if (tip->weight < 0)
+                               weight += tip->weight;
+               }
        }
+
+       return weight;
+}
+
+/* Returns total weights of all tracked scripts :
+ * - a positive weight adds to the global weight when the result is OK
+ * - a negative weight subtracts from the global weight when the result is bad
+ *
+ */
+int
+vrrp_script_weight(list l)
+{
+       element e;
+       tracked_sc *tsc;
+       int weight = 0;
+
+       for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
+               tsc = ELEMENT_DATA(e);
+               if (tsc->scr->result == VRRP_SCRIPT_STATUS_GOOD) {
+                       if (tsc->weight > 0)
+                               weight += tsc->weight;
+               } else if (tsc->scr->result == VRRP_SCRIPT_STATUS_NONE) {
+                       if (tsc->weight < 0)
+                               weight += tsc->weight;
+               }
+       }
+
+       return weight;
 }
index b18076f..cde1757 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        HTML stream parser utility functions.
  *
- * Version:     $Id: html.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: html.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *
index 0af5c60..8692e60 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        parser.c include file.
  *
- * Version:     $Id: html.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: html.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *
index e9b8ff1..95f0ed3 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        List structure manipulation.
  *  
- * Version:     $Id: list.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: list.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 4aa110d..befb77c 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        list.c include file.
  *  
- * Version:     $Id: list.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: list.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index da90e06..3a6cb19 100644 (file)
@@ -6,7 +6,7 @@
  * Part:        Memory management framework. This framework is used to
  *              find any memory leak.
  *
- * Version:     $Id: memory.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: memory.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 43e6f6c..d49a9a7 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        memory.c include file.
  *
- * Version:     $Id: memory.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: memory.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Authors:     Alexandre Cassen, <acassen@linux-vs.org>
  *              Jan Holmberg, <jan@artech.net>
index 9456f1d..47d8dce 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        Forked system call to launch an extra script.
  *
- * Version:     $Id: notify.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: notify.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 5e1d8dd..5d9fd0f 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        notify.c include file.
  *
- * Version:     $Id: notify.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: notify.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 1095bd4..dbec8f4 100644 (file)
@@ -7,7 +7,7 @@
  *              data structure representation the conf file representing
  *              the loadbalanced server pool.
  *  
- * Version:     $Id: parser.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: parser.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index 7bb6327..a649ee2 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        cfreader.c include file.
  *  
- * Version:     $Id: parser.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: parser.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 6454f54..777dead 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 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: scheduler.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
@@ -486,7 +486,7 @@ thread_compute_timer(thread_master * m, TIMEVAL * timer_wait)
 thread *
 thread_fetch(thread_master * m, thread * fetch)
 {
-       int ret;
+       int ret, old_errno;
        thread *thread_obj;
        fd_set readfd;
        fd_set writefd;
@@ -576,6 +576,9 @@ retry:      /* When thread can't fetch try to find next thread again. */
                sigprocmask(SIG_SETMASK, &saveset, NULL);
        }
 
+       /* we have to save errno here because the next syscalls will set it */
+       old_errno = errno;
+
        /*
         * When we receive a signal, we only add it to the signal_mask. This
         * is so that we can run our handler functions in a safe place and
@@ -588,9 +591,9 @@ retry:      /* When thread can't fetch try to find next thread again. */
        set_time_now();
 
        if (ret < 0) {
-               if (errno != EINTR) {
+               if (old_errno != EINTR) {
                        /* Real error. */
-                       DBG("select error: %s", strerror(errno));
+                       DBG("select error: %s", strerror(old_errno));
                        assert(0);
                } else {
                        /*
index dbe27d6..d68e2bd 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        scheduler.c include file.
  *
- * Version:     $Id: scheduler.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: scheduler.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 650fd6e..7229302 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Signals framework.
  *  
- * Version:     $Id: signals.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: signals.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Kevin Lindsay, <kevinl@netnation.com>
  *              Alexandre Cassen, <acassen@linux-vs.org>
index c8bd115..5c7356e 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        signals.c include file.
  *  
- * Version:     $Id: signals.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: signals.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Kevin Lindsay, <kevinl@netnation.com>
  *              Alexandre Cassen, <acassen@linux-vs.org>
index 31c9a20..aea2cda 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Timer manipulations.
  *  
- * Version:     $Id: timer.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: timer.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
@@ -24,6 +24,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <errno.h>
 #include "timer.h"
 
 /* time_now holds current time */
@@ -97,10 +98,12 @@ TIMEVAL
 timer_now(void)
 {
        TIMEVAL curr_time;
+       int old_errno = errno;
 
        /* init timer */
        TIMER_RESET(curr_time);
        gettimeofday(&curr_time, NULL);
+       errno = old_errno;
 
        return curr_time;
 }
@@ -109,9 +112,12 @@ timer_now(void)
 TIMEVAL
 set_time_now(void)
 {
+       int old_errno = errno;
+
        /* init timer */
        TIMER_RESET(time_now);
        gettimeofday(&time_now, NULL);
+       errno = old_errno;
 
        return time_now;
 }
index ad7f19c..1a94004 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        timer.c include file.
  *  
- * Version:     $Id: timer.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: timer.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 504128a..1190fe9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        General program utils.
  *
- * Version:     $Id: utils.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: utils.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 83f6703..5da5c43 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Part:        utils.h include file.
  *
- * Version:     $Id: utils.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: utils.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *
index 5b50912..2d8c4b8 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        Vector structure manipulation.
  *  
- * Version:     $Id: vector.c,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vector.c,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  * 
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *              
index b6f7865..17d5daa 100644 (file)
@@ -5,7 +5,7 @@
  * 
  * Part:        vector.c include file.
  *  
- * Version:     $Id: vector.h,v 1.1.12 2006/03/09 01:22:13 acassen Exp $
+ * Version:     $Id: vector.h,v 1.1.13 2006/10/11 05:22:13 acassen Exp $
  *
  * Author:      Alexandre Cassen, <acassen@linux-vs.org>
  *