diff --git a/ctdb/config/functions b/ctdb/config/functions index 531f85937db..06751547395 100644 --- a/ctdb/config/functions +++ b/ctdb/config/functions @@ -447,13 +447,14 @@ add_ip_to_iface() local _iface=$1 local _ip=$2 local _maskbits=$3 + local _readd_base="$CTDB_BASE/state/interface_modify.$_iface.readd.d" local _lockfile="$CTDB_BASE/state/interface_modify.$_iface.flock" test -f $_lockfile || { touch $_lockfile } - flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh add "$_iface" "$_ip" "$_maskbits" + flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh add "$_iface" "$_ip" "$_maskbits" "$_readd_base" return $? } @@ -462,13 +463,31 @@ delete_ip_from_iface() local _iface=$1 local _ip=$2 local _maskbits=$3 + local _readd_base="$CTDB_BASE/state/interface_modify.$_iface.readd.d" local _lockfile="$CTDB_BASE/state/interface_modify.$_iface.flock" test -f $_lockfile || { touch $_lockfile } - flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh delete "$_iface" "$_ip" "$_maskbits" + flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh delete "$_iface" "$_ip" "$_maskbits" "$_readd_base" + return $? +} + +setup_iface_ip_readd_script() +{ + local _iface=$1 + local _ip=$2 + local _maskbits=$3 + local _readd_script=$4 + local _readd_base="$CTDB_BASE/state/interface_modify.$_iface.readd.d" + local _lockfile="$CTDB_BASE/state/interface_modify.$_iface.flock" + + test -f $_lockfile || { + touch $_lockfile + } + + flock --timeout 30 $_lockfile $CTDB_BASE/interface_modify.sh readd_script "$_iface" "$_ip" "$_maskbits" "$_readd_base" "$_readd_script" return $? } diff --git a/ctdb/config/interface_modify.sh b/ctdb/config/interface_modify.sh index 2835d18faff..738530b4e9e 100755 --- a/ctdb/config/interface_modify.sh +++ b/ctdb/config/interface_modify.sh @@ -5,12 +5,16 @@ OP=$1 IFACE=$2 IP=$3 MASKBITS=$4 +READD_BASE=$5 +READD_SCRIPT=$6 add_ip_to_iface() { local _iface=$1 local _ip=$2 local _maskbits=$3 + local _readd_base=$4 + local _script_dir="$_readd_base/$_ip.$_maskbits" # we make sure the interface is up first /sbin/ip link set $_iface up || { @@ -22,6 +26,13 @@ add_ip_to_iface() return 1; } + mkdir -p $_script_dir || { + echo "Failed to mkdir -p $_script_dir" + return 1; + } + + rm -f $_script_dir/* + return 0; } @@ -30,6 +41,8 @@ delete_ip_from_iface() local _iface=$1 local _ip=$2 local _maskbits=$3 + local _readd_base=$4 + local _script_dir="$_readd_base/$_ip.$_maskbits" # the ip tool will delete all secondary IPs if this is the primary. To work around # this _very_ annoying behaviour we have to keep a record of the secondaries and re-add @@ -49,8 +62,27 @@ delete_ip_from_iface() echo "re-adding secondary address $_i to dev $_iface" /sbin/ip addr add $_i brd + dev $_iface || _failed=1 fi + local _s_ip=`echo "$_i" | cut -d '/' -f1` + local _s_maskbits=`echo "$_i" | cut -d '/' -f2` + local _s_script_dir="$_readd_base/$_s_ip.$_s_maskbits" + + local _s_script="" + for _s_script in $_s_script_dir/*; do + $_s_script "$_iface" "$_s_ip" "$_s_maskbits" || { + ret=$? + echo "$_s_script '$_iface' '$_s_ip' '$_s_maskbits' - failed - $ret" + _failed=1 + } + echo "call $_s_script '$_iface' '$_s_ip' '$_s_maskbits'" + done + done } + + test -d $_script_dir && { + rm -f $_script_dir/* + } + [ $_failed = 0 ] || { echo "Failed to del $_ip on dev $_iface" return 1; @@ -58,13 +90,47 @@ delete_ip_from_iface() return 0; } +setup_iface_ip_readd_script() +{ + local _iface=$1 + local _ip=$2 + local _maskbits=$3 + local _readd_base=$4 + local _readd_script=$5 + local _script_dir="$_readd_base/$_ip.$_maskbits" + + test -x "$_readd_script" || { + echo "Script '$_readd_script' isn't executable" + return 1; + } + + local _readd_basename=`basename $_readd_script` + local _readd_final="$_script_dir/$_readd_basename" + + mkdir -p $_script_dir || { + echo "Failed to mkdir -p $_script_dir" + return 1; + } + + cp -a $_readd_script $_readd_final || { + echo "Failed to - cp -a $_readd_script $_readd_final" + return 1; + } + + return 0 +} + case "$OP" in add) - add_ip_to_iface $IFACE $IP $MASKBITS + add_ip_to_iface $IFACE $IP $MASKBITS $READD_BASE exit $? ;; delete) - delete_ip_from_iface $IFACE $IP $MASKBITS + delete_ip_from_iface $IFACE $IP $MASKBITS $READD_BASE + exit $? + ;; + readd_script) + setup_iface_ip_readd_script $IFACE $IP $MASKBITS $READD_BASE $READD_SCRIPT exit $? ;; esac