* 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.

Thanks to Tuomo Soini for pointing me in this direction

Signed-off-by: Simon Horman <[EMAIL PROTECTED]>
Index: heartbeat/ldirectord/ldirectord.in
===================================================================
--- heartbeat.orig/ldirectord/ldirectord.in     2007-07-03 19:01:52.000000000 
+0900
+++ heartbeat/ldirectord/ldirectord.in  2007-07-03 19:04:11.000000000 +0900
@@ -1168,7 +1168,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, 
@@ -1421,16 +1413,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");
 }
 
 
@@ -1640,17 +1636,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")
@@ -1661,7 +1662,8 @@ sub parse_fallback
           $fwd="gate"
         }
 
-       return({"server"=>$ip_port, "forward"=>$fwd});
+       return({"server"=>$server, "port"=>$port, "forward"=>$fwd,
+               "weight"=>1});
 }
 
 
@@ -3211,7 +3213,7 @@ sub fallback_off
                return;
        }
 
-       &_remove_service($v, $fallback->{server},
+       &_remove_service($v, $fallback->{server} . ":" .  $fallback->{port},
                        get_forward_flag($fallback->{forward}),
                                "fallback");
 }
@@ -3231,11 +3233,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;
 }
 
 

-- 

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

_______________________________________________________
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