On Tue, 4 Aug 2009 14:00:01 +1000, Simon Horman wrote:
> On Tue, May 26, 2009 at 05:03:12PM +0200, Hannes Eder wrote:
> > 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.
> 
> Hi Hannes,
> 
> sorry for taking an extra long time to notice this one.
> The change seems reasonable to me, and I'm happy to commit it
> (assuming that it still applies). But I am wondering if
> it would be better to add this to ipvsadm. What do you think?

Hi Simon,

What this patch in essence does is comparing:

  - a ldirectord config file (how it should be), against

  - ipvsadm output (how it is).

Lots of the code needed for that is already in ldirectord (parsing
config files and parsing ipvsadm's output).  Implementing this in
ipvsadm would require ipvsadm to parse ldirectord config files.  I do
not think this is such a good idea.  IMHO the best place for this is
ldirectord.

> > The output mimics format of NetScaler "show" commands.

I changed my mind on that.  I think it is better to use the ldirectord
terminology instead of the NetScaler terminology, this makes the it
fit better.

I'll send a new patch.

Cheers,
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/

Reply via email to