Match the output of `ipvsadm -L -n` against a given ldirectord
configuration file to produce a verbose status sub-command output, to
see which virtual and which real servers are up or down, plus some
additional information.
---
The output mimics format of NetScaler "show" commands.
Comments?
Best,
Hannes
diff -r 15160b7b2a93 ldirectord/ldirectord.in
--- a/ldirectord/ldirectord.in Tue May 26 13:55:29 2009 +0200
+++ b/ldirectord/ldirectord.in Tue May 26 15:57:00 2009 +0200
@@ -999,6 +999,8 @@
print STDERR "ldirectord for $CONFIG is running with
pid: $oldpid\n";
ld_cmd_children("status", %LD_INSTANCE);
ld_log("ldirectord for $CONFIG is running with pid:
$oldpid");
+ ld_setup();
+ ld_show_status();
ld_log("Exiting from ldirectord $CMD");
ld_exit(0, "Exiting from ldirectord $CMD");
}
@@ -1019,6 +1021,8 @@
$status = 3;
}
print "ldirectord is stopped for $CONFIG\n";
+ ld_setup();
+ ld_show_status();
ld_exit($status, "Exiting from ldirectord $CMD");
} else {
ld_log("ldirectord is stopped for $CONFIG");
@@ -4966,3 +4970,138 @@
{
return ld_find_cmd_path($_[0], $ENV{'PATH'}, $_[1]);
}
+
+# mode_disp_str
+# helper for ld_show_status
+sub mode_disp_str
+{
+ my ($mode) = (@_);
+ my %map = (
+ gate => "DSR",
+ masq => "NAT",
+ ipip => "TUN"
+ );
+ return exists($map{$mode}) ? "$map{$mode} ($mode)" : "? ($mode)";
+}
+
+# scheduler_disp_str
+# helper for ld_show_status
+sub scheduler_disp_str
+{
+ my ($scheduler) = (@_);
+
+ # stolen from the ipvsadm-1.2.0 manpage
+ my %scheduler_disp_strs = (
+ rr => "Robin Robin",
+ wrr => "Weighted Round Robin",
+ lc => "Least-Connection",
+ wlc => "Weighted Least-Connection",
+ lblc => "Locality-Based Least-Connection",
+ lblcr => "Locality-Based Least-Connection with Replication",
+ dh => "Destination Hashing",
+ sh => "Source Hashing",
+ sed => "Shortest Expected Delay",
+ nq => "Never Queue"
+ );
+
+ my $scheduler_name = $scheduler_disp_strs{$scheduler};
+ $scheduler_name = "?" if (!defined($scheduler_name));
+ $scheduler_name =~ tr/ -//d;
+ return uc($scheduler_name) . " ($scheduler)";
+}
+
+# ld_show_status
+# Write a verbose status to STDOUT. It does so by matching the output of
+# ipvsadm against the given config file. No IPC to the running ldirectord
+# daemon is performed.
+#
+# pre: read_config() and ld_setup() have been called.
+# return: none
+sub ld_show_status
+{
+ # read and parse `ipvsadm -L -n`
+ my $ipvs = &ld_read_ipvsadm();
+
+ print "\n";
+
+ foreach my $cv (@VIRTUAL) {
+ my $real_service = &get_virtual($cv) . " " . $cv->{protocol};
+ my $crs = $cv->{real};
+ my $irs = $ipvs->{$real_service}->{real};
+ my $fb = fallback_find($cv);
+ my $real_str;
+ my $r;
+
+ my $state = exists($ipvs->{$real_service}) ? "UP" : "DOWN";
+ print "\t", get_virtual($cv), " - ", uc($$cv{protocol}), "\n";
+ print "\tState: ", $state, "\n";
+
+ my $eff_state = "DOWN";
+ for $r (values %$irs) {
+ if ($$r{weight} > 0) {
+ $eff_state = "UP";
+ last;
+ }
+ }
+
+ if ($eff_state eq "DOWN" and defined($fb)) {
+ $real_str = "$$fb{server}:$$fb{port}";
+ if (defined($$irs{$real_str})
+ and $$irs{$real_str}->{weight} > 0) {
+ $eff_state = "FALLBACK";
+ }
+ }
+
+ print "\tEffective State: ", $eff_state, "\n";
+ print "\tMethod: ", scheduler_disp_str($$cv{scheduler}), "\n";
+ print "\tConfig Options:\n";
+ for my $key (sort keys %$cv) {
+ next if ($key =~
m/^(server|port|protocol|real|flags|proto|fallback|scheduler)$/m);
+ my $value = $$cv{$key};
+ next if (!defined($value) or $value eq "");
+ print "\t\t$key: $value\n";
+ }
+ print "\n";
+
+ my $r_nr = 1;
+
+ # list fallback
+ if (defined($fb)) {
+ $state = "FALLBACK";
+ print $r_nr, ")\t", $$fb{server}, ":", $$fb{port},
+ " - ", uc($$cv{protocol}),
+ " Mode: ", mode_disp_str($$fb{forward}),
+ " State: ", $state,
+ "\tWeight: ", $$fb{weight}, "\n";
+ $r_nr++;
+ delete($$irs{"$$fb{server}:$$fb{port}"});
+ }
+
+ # list real servers which are in the config (up or down)
+ for $r (@$crs) {
+ $real_str = "$$r{server}:$$r{port}";
+ $state = (!defined($$irs{$real_str})
+ or $$irs{$real_str}->{weight} == 0) ? "DOWN"
: "UP";
+ print $r_nr, ")\t", $$r{server}, ":" , $$r{port},
+ " - ", uc($$cv{protocol}),
+ " Mode: ", mode_disp_str($$r{forward}),
+ " State: ", $state,
+ "\tWeight: ", $$r{weight}, "\n";
+ $r_nr++;
+ delete($$irs{$real_str});
+ }
+
+ # list real servers which are up but NOT in the config
+ $state = "UP (NOT IN CFG)";
+ while (($real_str, $r) = each %$irs) {
+ print $r_nr, ")\t", $real_str,
+ " - ", uc($$cv{protocol}),
+ " Mode: ", mode_disp_str($$r{forward}),
+ " State: ", $state,
+ "\tWeight: ", $$r{weight}, "\n";
+ $r_nr++;
+ }
+
+ print "\n";
+ }
+}
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/