summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2008-05-13 17:18:26 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2008-05-13 17:18:26 -0700
commitdf8f66b210c463238bfaf9c97af500f941ec6ac7 (patch)
tree01ce2462fbfd5a104b7a82c7f0d165d70b5e6b19 /scripts
parent2e368aaca62ca05330d613500772fe8d6aa11032 (diff)
parent6c47fa4846c453964709c02891adb4e582e4cf93 (diff)
downloadvyatta-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-xscripts/keepalived/vyatta-keepalived.pl190
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;
}