diff options
author | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-05-13 17:18:26 -0700 |
---|---|---|
committer | Stephen Hemminger <stephen.hemminger@vyatta.com> | 2008-05-13 17:18:26 -0700 |
commit | df8f66b210c463238bfaf9c97af500f941ec6ac7 (patch) | |
tree | 01ce2462fbfd5a104b7a82c7f0d165d70b5e6b19 /scripts | |
parent | 2e368aaca62ca05330d613500772fe8d6aa11032 (diff) | |
parent | 6c47fa4846c453964709c02891adb4e582e4cf93 (diff) | |
download | vyatta-cfg-system-df8f66b210c463238bfaf9c97af500f941ec6ac7.tar.gz vyatta-cfg-system-df8f66b210c463238bfaf9c97af500f941ec6ac7.zip |
Merge branch 'hollywood' of suva.vyatta.com:/git/vyatta-cfg-system into hollywood
Diffstat (limited to 'scripts')
-rwxr-xr-x | scripts/keepalived/vyatta-keepalived.pl | 190 |
1 files changed, 175 insertions, 15 deletions
diff --git a/scripts/keepalived/vyatta-keepalived.pl b/scripts/keepalived/vyatta-keepalived.pl index 55d53715..7389534b 100755 --- a/scripts/keepalived/vyatta-keepalived.pl +++ b/scripts/keepalived/vyatta-keepalived.pl @@ -31,8 +31,39 @@ use Getopt::Long; use strict; use warnings; +my $changes_file = '/var/log/vrrpd/changes'; +my $conf_file = VyattaKeepalived::get_conf_file(); + my %HoA_sync_groups; +sub vrrp_get_init_state { + my ($intf, $group, $vips, $preempt) = @_; + + my $init_state; + if (VyattaKeepalived::is_running()) { + my @state_files = VyattaKeepalived::get_state_files($intf, $group); + if (scalar(@state_files) > 0) { + my ($start_time, $f_intf, $f_group, $state, $ltime) = + VyattaKeepalived::vrrp_state_parse($state_files[0]); + if ($state eq "master") { + $init_state = 'MASTER'; + } else { + $init_state = 'BACKUP'; + } + return $init_state; + } + # fall through to logic below + } + + if ($preempt eq "false") { + $init_state = 'BACKUP'; + } else { + $init_state = 'MASTER'; + } + + return $init_state; +} + sub keepalived_get_values { my ($intf, $path) = @_; @@ -86,7 +117,7 @@ sub keepalived_get_values { } } - $config->setLevel("$path vrrp vrrp-group $group run-transition-scripts"); + $config->setLevel("$path vrrp vrrp-group $group run-transition-scripts"); my $run_backup_script = $config->returnValue("backup"); if(!defined $run_backup_script){ $run_backup_script = "null"; @@ -100,13 +131,9 @@ sub keepalived_get_values { $run_master_script = "null"; } - $output .= "vrrp_instance $vrrp_instance \{\n"; - if ($preempt eq "false") { - $output .= "\tstate BACKUP\n"; - } else { - $output .= "\tstate MASTER\n"; - } + my $init_state = vrrp_get_init_state($intf, $group, $vips[0], $preempt); + $output .= "\tstate $init_state\n"; $output .= "\tinterface $intf\n"; $output .= "\tvirtual_router_id $group\n"; $output .= "\tpriority $priority\n"; @@ -151,9 +178,130 @@ sub vrrp_get_sync_groups { return $output; } +sub vrrp_read_changes { + my @lines = (); + open(my $FILE, "<", $changes_file) or die "Error: read $!"; + @lines = <$FILE>; + close($FILE); + chomp @lines; + return @lines; +} + +sub vrrp_save_changes { + my @list = @_; + + my $num_changes = scalar(@list); + VyattaKeepalived::vrrp_log("saving changes file $num_changes"); + open(my $FILE, ">", $changes_file) or die "Error: write $!"; + print $FILE join("\n", @list), "\n"; + close($FILE); +} + +sub vrrp_find_changes { + + my @list = (); + my $config = new VyattaConfig; + my $vrrp_instances = 0; + + $config->setLevel("interfaces ethernet"); + my @eths = $config->listNodes(); + foreach my $eth (@eths) { + my $path = "interfaces ethernet $eth"; + $config->setLevel($path); + if ($config->exists("vrrp")) { + my %vrrp_status_hash = $config->listNodeStatus("vrrp"); + my ($vrrp, $vrrp_status) = each(%vrrp_status_hash); + if ($vrrp_status ne "static") { + push @list, $eth; + VyattaKeepalived::vrrp_log("$vrrp_status found $eth"); + } + } + if ($config->exists("vif")) { + my $path = "interfaces ethernet $eth vif"; + $config->setLevel($path); + my @vifs = $config->listNodes(); + foreach my $vif (@vifs) { + my $vif_intf = $eth . "." . $vif; + my $vif_path = "$path $vif"; + $config->setLevel($vif_path); + if ($config->exists("vrrp")) { + my %vrrp_status_hash = $config->listNodeStatus("vrrp"); + my ($vrrp, $vrrp_status) = each(%vrrp_status_hash); + if ($vrrp_status ne "static") { + push @list, "$eth.$vif"; + VyattaKeepalived::vrrp_log("$vrrp_status found $eth.$vif"); + } + } + } + } + } + + # + # Now look for deleted from the origin tree + # + $config->setLevel("interfaces ethernet"); + @eths = $config->listOrigNodes(); + foreach my $eth (@eths) { + my $path = "interfaces ethernet $eth"; + $config->setLevel($path); + if ($config->isDeleted("vrrp")) { + push @list, $eth; + VyattaKeepalived::vrrp_log("Delete found $eth"); + } + $config->setLevel("$path vif"); + my @vifs = $config->listOrigNodes(); + foreach my $vif (@vifs) { + my $vif_intf = $eth . "." . $vif; + my $vif_path = "$path vif $vif"; + $config->setLevel($vif_path); + if ($config->isDeleted("vrrp")) { + push @list, "$eth.$vif"; + VyattaKeepalived::vrrp_log("Delete found $eth.$vif"); + } + } + } + + my $num = scalar(@list); + VyattaKeepalived::vrrp_log("Start transation: $num changes"); + if ($num) { + vrrp_save_changes(@list); + } + return $num; +} + +sub remove_from_changes { + my $intf = shift; + + my @lines = vrrp_read_changes(); + if (scalar(@lines) < 1) { + # + # we shouldn't get to this point, but try to handle it if we do + # + system("rm -f $changes_file"); + return 0; + } + my @new_lines = (); + foreach my $line (@lines) { + if ($line =~ /$intf$/) { + VyattaKeepalived::vrrp_log("remove_from_changes [$line]"); + } else { + push @new_lines, $line; + } + } + + my $num_changes = scalar(@new_lines); + if ($num_changes > 0) { + vrrp_save_changes(@new_lines); + } else { + system("rm -f $changes_file"); + } + return $num_changes; +} + sub vrrp_update_config { - my $output; + my ($intf) = @_; + my $output = ''; my $config = new VyattaConfig; $config->setLevel("interfaces ethernet"); @@ -190,16 +338,14 @@ sub vrrp_update_config { } } } - + if ($vrrp_instances > 0) { my $sync_groups = vrrp_get_sync_groups(); if (defined $sync_groups && $sync_groups ne "") { $output = $sync_groups . $output; } - my $conf_file = VyattaKeepalived::get_conf_file(); keepalived_write_file($conf_file, $output); - VyattaKeepalived::restart_daemon($conf_file); - } + } return $vrrp_instances; } @@ -227,8 +373,22 @@ if (! defined $action) { } if ($action eq "update") { - my $vrrp_instances = vrrp_update_config(); - VyattaKeepalived::vrrp_log("vrrp update $vrrp_intf $vrrp_instances"); + VyattaKeepalived::vrrp_log("vrrp update $vrrp_intf"); + if ( ! -e $changes_file) { + my $num_changes = vrrp_find_changes(); + if ($num_changes == 0) { + # + # Shouldn't happen, but ... + # + VyattaKeepalived::vrrp_log("unexpected 0 changes"); + } + } + my $vrrp_instances = vrrp_update_config($vrrp_intf); + my $more_changes = remove_from_changes($vrrp_intf); + VyattaKeepalived::vrrp_log(" instances $vrrp_instances, $more_changes"); + if ($vrrp_instances > 0 and $more_changes == 0) { + VyattaKeepalived::restart_daemon($conf_file); + } if ($vrrp_instances == 0) { VyattaKeepalived::stop_daemon(); } @@ -239,9 +399,9 @@ if ($action eq "delete") { print "must include interface & group"; exit 1; } + VyattaKeepalived::vrrp_log("vrrp delete $vrrp_intf $vrrp_group"); my $state_file = VyattaKeepalived::get_state_file($vrrp_intf, $vrrp_group); system("rm -f $state_file"); - VyattaKeepalived::vrrp_log("vrrp delete $vrrp_intf $vrrp_group"); exit 0; } |