Files
packages/net/keepalived/files/keepalived.init
Ben Kelly 0b16c2ada2 keepalived: Fix ordering of config sections
keepalived seems to be rather particular about which config parameters
come before others.

When defining a virtual IP address, keepalived will check to see if the
vrrp instance is associated with a valid interface. Previously, the
interface parameter was declared after the virtual IP address which
caused an error when keepalived tried to run this check. Keepalived
tries to fall back to checking if 'eth0' exists.

The fix is to re-order the config stanzas so that the interface
parameter comes before the virtual IP address definitions.

Signed-off-by: Ben Kelly <ben@benjii.net>
Signed-off-by: Alexandru Ardelean <ardeleanalex@gmail.com>
2016-12-31 12:37:14 +02:00

394 lines
9.5 KiB
Bash

#!/bin/sh /etc/rc.common
# Copyright (C) 2007-2015 OpenWrt.org
START=70
STOP=01
USE_PROCD=1
KEEPALIVED_CONF=/tmp/keepalived.conf
INDENT_1=\\t
INDENT_2=$INDENT_1$INDENT_1
config_section_open() {
local tag=$1
local name=$2
printf "$tag" >> $KEEPALIVED_CONF
[ -n "$name" ] && printf " $name" >> $KEEPALIVED_CONF
printf " {\n" >> $KEEPALIVED_CONF
}
config_section_close() {
printf "}\n\n" >> $KEEPALIVED_CONF
}
config_foreach_wrapper() {
local section=$1
local function=$1
# Convention is that 'function' and 'section' are the same
config_foreach $function $section
}
print_elems_indent() {
local config=$1
shift
local indent=$1
shift
[ -z "$indent" ] && indent="$INDENT_1"
for opt in $*; do
local $opt
local no_val=0
if [ ${opt:0:7} == "no_val_" ]; then
opt=${opt:7}
no_val=1
fi
config_get $opt $config $opt
eval optval=\$$opt
[ -z "$optval" ] && continue
printf "$indent$opt" >> $KEEPALIVED_CONF
[ "$no_val" == "0" ] && printf " $optval" >> $KEEPALIVED_CONF
printf "\n" >> $KEEPALIVED_CONF
done
unset optval
}
print_list_indent() {
local lst=$1
local indent=$2
local lst_elems
[ -z "$indent" ] && indent=$INDENT_1
eval lst_elems=\$$lst
[ -z "$lst_elems" ] && return 0
printf "$indent$lst {\n" >> $KEEPALIVED_CONF
for e in $lst_elems; do
[ -n "$eval_item_func" ]
printf "$indent$INDENT_1$e\n" >> $KEEPALIVED_CONF
done
printf "$indent}\n" >> $KEEPALIVED_CONF
}
global_defs() {
local linkbeat_use_polling notification_email
config_get alt_config_file $1 alt_config_file
[ -z "$alt_config_file" ] || return 0
config_get_bool linkbeat_use_polling $1 linkbeat_use_polling 0
[ $linkbeat_use_polling -gt 0 ] && printf "linkbeat_use_polling\n\n" >> $KEEPALIVED_CONF
config_get notification_email $1 notification_email
print_list_indent notification_email
print_elems_indent $1 $INDENT_1 notification_email_from smtp_server smtp_connect_timeout \
router_id vrrp_mcast_group4 vrrp_mcast_group6
}
print_ipaddress_indent() {
local section=$1
local curr_ipaddr=$2
local indent=$3
local address device scope name
config_get name $section name
[ "$name" != "$curr_ipaddr" ] && return 0
config_get address $section address
config_get device $section device
config_get scope $section scope
# Default indent
[ -z "$indent" ] && indent=$INDENT_1
# If no address or device exit
[ -z "$address" -o -z "$device" ] && return 0
# Add IP address/netmask and device
printf "$indent$address dev $device" >> $KEEPALIVED_CONF
# Add scope
[ -n "$scope" ] && printf " scope $scope" >> $KEEPALIVED_CONF
printf "\n" >> $KEEPALIVED_CONF
}
static_ipaddress() {
local address
config_get address "$1" address
for a in $address; do
config_foreach print_ipaddress_indent ipaddress $a
done
}
print_route_indent() {
local section=$1
local curr_route=$2
local indent=$3
local name blackhole address src_addr gateway device scope table
config_get name $section name
[ "$name" != "$curr_route" ] && return 0
config_get_bool blackhole $section blackhole 0
config_get address $section address
config_get src_addr $section src_addr
config_get gateway $section gateway
config_get device $section device
config_get table $section table
# If no address exit
[ -z "$address" ] && return 0
# Default indent
[ -z "$indent" ] && indent=$INDENT_1
[ $blackhole -gt 0 ] && {
printf "${indent}blackhole $address\n" >> $KEEPALIVED_CONF
return 0
}
# Add src addr or address
if [ -n "$src_addr" ]; then
printf "${indent}src $src_addr $address" >> $KEEPALIVED_CONF
else
[ -z "$device" ] && return 0
printf "$indent$address" >> $KEEPALIVED_CONF
fi
# Add route/gateway
[ -n "$gateway" ] && printf " via $gateway" >> $KEEPALIVED_CONF
# Add device
printf " dev $device" >> $KEEPALIVED_CONF
# Add scope
[ -n "$scope" ] && printf " scope $scope" >> $KEEPALIVED_CONF
# Add table
[ -n "$table" ] && printf " table $table" >> $KEEPALIVED_CONF
printf "\n" >> $KEEPALIVED_CONF
}
print_track_elem_indent() {
local section=$1
local curr_track_elem=$2
local indent=$3
local script name value
config_get name $section name
[ "$name" != "$curr_track_elem" ] && return 0
config_get value $section value
config_get weight $section weight
[ -z "$value" ] && return 0
printf "$indent$value" >> $KEEPALIVED_CONF
[ -n "$weight" ] && printf " weight $weight" >> $KEEPALIVED_CONF
printf "\n" >> $KEEPALIVED_CONF
}
static_routes() {
local route
config_get route "$1" route
for r in $route; do
config_foreach print_route_indent route $r
done
}
# Count 'vrrp_instance' with the given name ; called by vrrp_instance_check()
vrrp_instance_name_count() {
local name
config_get name $1 name
[ "$name" == "$2" ] && count=$((count + 1))
}
# Check if there's a 'vrrp_instance' section with the given name
vrrp_instance_check() {
local count=0
local name=$1
config_foreach vrrp_instance_name_count vrrp_instance $name
[ $count -gt 0 ] && return 0 || return 1
}
vrrp_sync_group() {
local group name
local valid_group
# No name for group, exit
config_get name $1 name
[ -z "$name" ] && return 0
# No members for group, exit
config_get group $1 group
[ -z "$group" ] && return 0
# Check if we have 'vrrp_instance's defined for
# each member and remove names with not vrrp_instance defined
for m in $group; do
vrrp_instance_check $m && valid_group="$valid_group $m"
done
[ -z "$valid_group" ] && return 0
config_section_open "vrrp_sync_group" "$name"
group="$valid_group"
print_list_indent group
print_elems_indent $1 $INDENT_1 notify_backup notify_master notify_fault \
notify no_val_smtp_alert no_val_global_tracking
config_section_close
}
vrrp_instance() {
local name auth_type auth_pass
config_get name $1 name
[ -z "$name" ] && return 0
config_section_open "vrrp_instance" "$name"
config_get auth_type $1 auth_type
config_get auth_pass $1 auth_pass
[ -n "$auth_type" -a -n "$auth_pass" ] && {
printf "${INDENT_1}authentication {\n" >> $KEEPALIVED_CONF
printf "${INDENT_2}auth_type $auth_type\n" >> $KEEPALIVED_CONF
printf "${INDENT_2}auth_pass $auth_pass\n" >> $KEEPALIVED_CONF
printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
}
print_elems_indent $1 $INDENT_1 use_vmac state interface \
mcast_src_ip unicast_src_ip virtual_router_id version priority \
advert_int preempt_delay debug notify_backup \
notify_master notify_fault notify_stop notify \
lvs_sync_daemon_interface garp_master_delay garp_master_refresh \
garp_master_repeat garp_master_refresh_repeat \
no_val_vmac_xmit_base no_val_native_ipv6 no_val_accept \
no_val_dont_track_primary no_val_smtp_alert no_val_nopreempt
# Handle virtual_ipaddress & virtual_ipaddress_excluded lists
for opt in virtual_ipaddress virtual_ipaddress_excluded; do
config_get $opt $1 $opt
eval optval=\$$opt
[ -z "$optval" ] && continue
printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
for a in $optval; do
config_foreach print_ipaddress_indent ipaddress $a $INDENT_2
done
printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
done
# Handle virtual_routes
for opt in virtual_routes; do
config_get $opt $1 $opt
eval optval=\$$opt
[ -z "$optval" ] && continue
printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
for r in $optval; do
config_foreach print_route_indent route $r $INDENT_2
done
printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
done
# Handle track_interface & track_script lists
for opt in track_interface track_script; do
config_get $opt $1 $opt
eval optval=\$$opt
[ -z "$optval" ] && continue
printf "$INDENT_1$opt {\n" >> $KEEPALIVED_CONF
for t in $optval; do
printf "$INDENT_2$optval\n" >> $KEEPALIVED_CONF
done
printf "$INDENT_1}\n" >> $KEEPALIVED_CONF
done
# Handle simple lists of strings (with no spaces in between)
for opt in unicast_peer; do
config_get $opt $1 $opt
print_list_indent $opt
done
unset optval
config_section_close
}
vrrp_script() {
local name
config_get name $1 name
[ -z "$name" ] && return 0
config_section_open "vrrp_script" "$name"
print_elems_indent $1 $INDENT_1 script interval weight fall rise
config_section_close
}
process_config() {
local alt_config_file
rm -f $KEEPALIVED_CONF
# First line
printf "! Configuration File for keepalived (autogenerated via init script)\n\n" > $KEEPALIVED_CONF
[ -f /etc/config/keepalived ] || return 0
config_load 'keepalived'
config_section_open "global_defs"
config_foreach_wrapper global_defs
config_section_close
# If "alt_config_file" specified, use that instead
[ -n "$alt_config_file" ] && [ -f "$alt_config_file" ] && {
rm -f $KEEPALIVED_CONF
# Symlink "alt_config_file" since it's a bit easier and safer
ln -s $alt_config_file $KEEPALIVED_CONF
return 0
}
config_section_open "static_ipaddress"
config_foreach_wrapper static_ipaddress
config_section_close
config_section_open "static_routes"
config_foreach_wrapper static_routes
config_section_close
config_foreach_wrapper vrrp_script
config_foreach_wrapper vrrp_sync_group
config_foreach_wrapper vrrp_instance
return 0
}
service_running() {
pgrep -x /usr/sbin/keepalived &> /dev/null
}
reload_service() {
running && {
process_config
# SIGHUP is used by keepalived to do init.d reload
# Get the oldest process (assumption is that it's the parent process)
PID=$(pgrep -o /usr/sbin/keepalived)
kill -SIGHUP $PID
return 0
}
return 1
}
start_service() {
procd_open_instance
procd_set_param command /usr/sbin/keepalived
procd_append_param command -n # don't daemonize, procd will handle that for us
procd_append_param command -f "$KEEPALIVED_CONF"
process_config
# set auto respawn behavior
procd_set_param respawn
procd_close_instance
}