LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: [lvs-users] serious problem experienced with ldirectord 1.77.2.6?

To: Struan Bartlett <struan@xxxxxxxxxxxxx>
Subject: Re: [lvs-users] serious problem experienced with ldirectord 1.77.2.6?
Cc: lvs-users@xxxxxxxxxxxxxxxxxxxxxx
From: Horms <horms@xxxxxxxxxxxx>
Date: Thu, 5 Jul 2007 14:25:25 +0900
On Mon, Oct 10, 2005 at 10:21:05AM +0100, Struan Bartlett wrote:
> Hi -
> 
> I'm new to this list but I hope you'll forgive me getting right to the
> point.
> 
> Our organisation is testing a new version of ldirectord - version 1.77.2.6
> from Debian package 1.2.3-9sarge3 - and have encountered a serious problem
> that shows different behaviour to the previous version we used (1.26) and,
> unlike that previous version, seems to prevent it from working properly.
> 
> Here is our ldirectord.cf:
> 
> checktimeout=60
> checkinterval=15
> fallback=127.0.0.1
> 
> virtual=217.204.41.132:80
>         scheduler=wlc
>         real=192.168.2.32:80 masq 1024
>         real=192.168.2.52:80 masq 1024
>         real=192.168.2.62:80 masq 1024
>         real=192.168.2.72:80 masq 1024
>         service=http
>         request="/cgi/NewsNow/Status/"
>         receive="ldirectord-ok-string"
>         protocol=tcp
> 
> Now observe the results on startup:
> 
> # /etc/init.d/ldirectord start
> Starting ldirectord
> 
> # ipvsadm -Ln
> IP Virtual Server version 1.0.10 (size=4096)
> Prot LocalAddress:Port Scheduler Flags
>   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
> TCP  217.204.41.132:80 wlc
>   -> 192.168.2.62:80              Masq    1024   0          0
>   -> 192.168.2.72:80              Masq    1024   0          0
>   -> 192.168.2.52:80              Masq    1024   0          0
>   -> 192.168.2.32:80              Masq    1024   0          0
>   -> 127.0.0.1:80                 Local   1      0          0
> 
> As I hope you see, the failover server weight has not been switched to
> zero, which appears to continue to allow some traffic to reach the
> failover servers. I understand this is incorrect.
> 
> Please could you advise: is this a known bug, an unknown bug, or an error
> in our configuration of ldirectord?
> 
> Kind regards,
> 
> Struan Bartlett
> 
> P.S. For your information, the situation is not the same after a reload:
> 
> # /etc/init.d/ldirectord reload
> 
> # ipvsadm -Ln
> IP Virtual Server version 1.0.10 (size=4096)
> Prot LocalAddress:Port Scheduler Flags
>   -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
> TCP  217.204.41.132:80 wlc
>   -> 192.168.2.62:80              Masq    1024   0          0
>   -> 192.168.2.72:80              Masq    1024   0          0
>   -> 192.168.2.52:80              Masq    1024   0          0
>   -> 192.168.2.32:80              Masq    1024   0          0

Hi Struan,

Sorry for letting your bug report fester in my inbox for such a long
time. I've been doing a bit of a blitz on ldirectord bugs over the past
few days, and I found that inadvertantly I had a fix for this problem -
which is still present in the latest version of ldirectord. I'm not sure
if the patch below applied against 1.77.2.6, and it is rather long.
But here is is, just for the record.

-- 
Horms
  H: http://www.vergenet.net/~horms/
  W: http://www.valinux.co.jp/en/


Subject: [LDIRECTORD] Tidy up fallback

* Use the same parsing sequence for per-virtual and global fallback
* Cope with the fallback not having a port specified by using
  the port of the virtual service
* Split the server feild up into server (ip) and port, and also
  add a weight feild so that when its passed to get_real_id_str()
  it has the relevant feilds that would be in a real server,
  otherwise get_real_id_str() tries to access non-existent values.

This patch solves a bug discovered by Struan Bartlett whereby
the failack server will not be removed as expected if it doesn't
have a port specified.

Thanks also to Tuomo Soini for pointing me in this direction

Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
Index: heartbeat/ldirectord/ldirectord.in
===================================================================
--- heartbeat.orig/ldirectord/ldirectord.in     2007-07-05 14:21:42.000000000 
+0900
+++ heartbeat/ldirectord/ldirectord.in  2007-07-05 14:21:42.000000000 +0900
@@ -1173,7 +1173,9 @@ sub read_config
                                        $vsrv{virtualhost} = $1;
                                } elsif ($rcmd =~ /^fallback\s*=\s*(.*)/) {    
# Allow specification of a virtual-specific fallback host
                                        $fallback_line=$line;
-                                       $vsrv{fallback}=parse_fallback($line, 
$1);
+                                       $vsrv{fallback} =
+                                               parse_fallback($line, $1,
+                                                              \%vsrv);
                                 } elsif ($rcmd =~ /^quiescent\s*=\s*(.*)/) {
                                         ($1 eq "yes" || $1 eq "no")
                                                 or &config_error($line, 
"quiescent must be 'yes' or 'no'");
@@ -1240,21 +1242,11 @@ sub read_config
                                        "invalid check count value");
                        $CHECKCOUNT = $1;
                } elsif ($linedata  =~ /^fallback\s*=\s*(.*)/) {
-                        my $tcp = &ld_gethostservbyname($1, "tcp");
-                       my $udp = &ld_gethostservbyname($1, "udp");
-                        my $tcp_fb;
-                        my $udp_fb;
-                       if(!defined($tcp) and !defined($udp)){
-                           &config_error($line, 
-                               "invalid address for fallback server");
-                       }
-                        if(defined($tcp)) {
-                               $tcp_fb=&parse_fallback($line, $tcp);
-                        }
-                        if(defined($udp)) {
-                               $udp_fb=&parse_fallback($line, $udp);
-                        }
-                       $FALLBACK = { "tcp" => $tcp_fb, "udp" => $udp_fb };
+                       my $tcp = parse_fallback($line, $1, undef);
+                       my $udp = parse_fallback($line, $1, undef);
+                        &_ld_read_config_fallback_resolve($line, "tcp", $tcp);
+                       &_ld_read_config_fallback_resolve($line, "udp", $udp);
+                       $FALLBACK = { "tcp" => $tcp, "udp" => $udp };
                } elsif ($linedata  =~ /^autoreload\s*=\s*(.*)/) {
                        ($1 eq "yes" || $1 eq "no")
                            or &config_error($line, 
@@ -1477,16 +1469,20 @@ sub _ld_read_config_fallback_resolve
 {
        my($line, $protocol, $fallback)=(@_);
 
-        my $ip_port;
-
         unless($fallback) {
                 return;
         }
 
-       $fallback->{server}=&ld_gethostservbyname(
-                $fallback->{server}, $protocol) 
-               or &config_error($line, 
-                       "invalid address for fallback server");
+       $fallback->{server} = &ld_gethostbyname($fallback->{server}) or
+               &config_error($line, "invalid address for fallback server: " .
+                             $fallback->{server});
+
+        unless($fallback->{"port"}) {
+                return;
+        }
+
+       $fallback->{port} = &ld_getservbyname($fallback->{port}, $protocol) or
+               &config_error($line, "invalid port for fallback server");
 }
 
 
@@ -1696,17 +1692,22 @@ sub add_real_server
 
 sub parse_fallback
 {
-       my ($line, $fallback) = (@_);
+       my ($line, $fallback, $vsrv) = (@_);
 
-       my $ip_port;
+       my $server;
+       my $port;
        my $fwd;
 
-        $fallback =~ /^\s*(\S+)(\s+(\S+))?\s*/ or
+        $fallback =~ /^\s*([^:         ]+)(:(\S+))?(\s+(\S+))?\s*/ or
                   &config_error($line, "invalid fallback server: $fallback");
 
-        $ip_port=$1;
-        $fwd=$3;
+        $server=$1;
+        $port=$3;
+        $fwd=$5;
 
+       if (not defined($port) and defined($vsrv)) {
+               $port = $vsrv->{"port"};
+       }
 
         if($fwd) {
                 ($fwd eq "gate" || $fwd eq "masq" || $fwd eq "ipip")
@@ -1717,7 +1718,8 @@ sub parse_fallback
           $fwd="gate"
         }
 
-       return({"server"=>$ip_port, "forward"=>$fwd});
+       return({"server"=>$server, "port"=>$port, "forward"=>$fwd,
+               "weight"=>1});
 }
 
 
@@ -1999,7 +2001,7 @@ sub ld_start
                my $fallback = fallback_find($nv);
 
                if (defined($fallback)) {
-                       delete($or->{$fallback->{server}});
+                       delete($or->{"$fallback->{server}:$fallback->{port}"});
                }
 
                for $nr (@$nreal) {
@@ -3251,7 +3253,7 @@ sub fallback_on
                return;
        }
 
-       &_restore_service($v, $fallback->{server}, 
+       &_restore_service($v, $fallback->{server} . ":" . $fallback->{port},
                        get_forward_flag($fallback->{forward}), 
                                "1", "fallback");
 }
@@ -3274,7 +3276,7 @@ sub fallback_off
                return;
        }
 
-       &_remove_service($v, $fallback->{server},
+       &_remove_service($v, $fallback->{server} . ":" .  $fallback->{port},
                        get_forward_flag($fallback->{forward}),
                                "fallback");
 }
@@ -3294,11 +3296,20 @@ sub fallback_find
 
        if( defined $virtual->{"fallback"} ) {
                return($virtual->{"fallback"});
-       } elsif ( defined($FALLBACK) ) {
-               return($FALLBACK->{$virtual->{"protocol"}});
+       } elsif ( not defined($FALLBACK) ) {
+               return undef;
        }
 
-       return undef;
+       # If the global fallback has a port, it can be used as is
+       if (defined($FALLBACK->{$virtual->{"protocol"}}->{"port"})) {
+               return $FALLBACK->{$virtual->{"protocol"}};
+       }
+
+       # Else create an anonymous fallback
+       my %anon_fallback = %{$FALLBACK->{$virtual->{"protocol"}}};
+       $anon_fallback{"port"} = $virtual->{"port"};
+
+       return \%anon_fallback;
 }
 
 


<Prev in Thread] Current Thread [Next in Thread>
  • Re: [lvs-users] serious problem experienced with ldirectord 1.77.2.6?, Horms <=