ldirectord works for HTTP but Not FTP -- CAUSE ISOLATED

Horms horms at verge.net.au
Tue Jul 18 18:43:02 BST 2006


On Sun, Jul 16, 2006 at 05:49:44PM -0700, Joseph Mack NA3T wrote:
> On Sun, 16 Jul 2006, Robinson, Eric wrote:
> 
> >The root cause is that ipvsadm is misbehaving. Instead of changing the
> >realserver's weight, it is complaining that the destination exists.
> 
> There were a few of us who wanted this behaviour changed, 
> but at the time we were vetoed, but maybe times have 
> changed.
> 
> Hey Horms,
> 
> 	I don't suppose the ipvsadm add/edit patch of yours 
> could be revisited? It seems the current behaviour is 
> causing problems with ldirectord.

Hi Joe,

Eric and I discussed this offline and I have formulated a patch which
seems to be working.  It should apply to 1.131 (the version he is
using), 1.141 (the version in CVS right now), and likely quite a few
other versions. Comments inline. Feedback welcome.

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

--- from-0001/ldirectord
+++ to-work/ldirectord	2006-07-17 22:15:09.000000000 -0400
@@ -1496,6 +1496,44 @@ sub ld_setup
 	}
 }
 
+# ld_read_ipvsadm
+#
+# Net::FTP seems to set the input record separator ($\) to null
+# putting IO into slurp (whole file at a time, rather than line at a time)
+# mode. Net::FTP does this using local $\, which should mean
+# that the change doesn' effect code here, but it does. It also
+# seems to be imposible to turn it off, by say setting $\ back to '\n'
+# Perhaps there is more to this than meets the eye. Perhaps its a perl bug.
+# In any case, this should fix the problem.
+#
+# This should not affect pid or config file parsing as they are called
+# before Net::FTP and as this appears to be a bit of a work around,
+# I'd rather use it in as few places as possible
+#
+# Observed with perl v5.8.8 (Debian's perl 5.8.8-6)
+# -- Horms, 17th July 2005
+sub ld_readline
+{
+	my ($fd, $buf) = (@_);
+	my $line;
+
+	# Uncomment the following line to turn off this work around
+	# return readline($fd);
+
+	$line = shift @$buf;
+	if (defined $line) {
+		return $line . "\n";
+	}
+
+	push @$buf, split /\n/, readline($fd);
+
+	$line = shift @$buf;
+	if (defined $line) {
+		return $line . "\n";
+	}
+
+	return undef;
+}
 
 # ld_read_ipvsadm
 # Parses the output of "ipvsadm -L -n" and puts into a structure of
@@ -1540,28 +1578,35 @@ sub ld_read_ipvsadm
 	my %oldsrv;
 	my $real_service;
 	my $fwd;
+	my $buf = [];
+	my $fh;
+	my $line;
 
 	# read status of current ipvsadm -L -n
-	unless(open(IPVS, "$IPVSADM -L -n |")){
+	unless(open($fh, "$IPVSADM -L -n 2>&1|")){
           &ld_exit(1, "Could not run $IPVSADM -L -n: $!");
         }
-	$_ = <IPVS>; $_ = <IPVS>; $_ = <IPVS>;
 
-	while (<IPVS>) {
-		if ($_ =~ /(\w+)\s+(\d+\.\d+\.\d+\.\d+\:\d+|\d+)\s+(\w+)\s+persistent\s+(\d+)\s+mask\s+(.*)/) {
+	# Skip the first three lines
+	$line = ld_readline($fh, $buf); 
+	$line = ld_readline($fh, $buf); 
+	$line = ld_readline($fh, $buf);
+
+	while ($line = ld_readline($fh, $buf)) {
+		if ($line =~ /(\w+)\s+(\d+\.\d+\.\d+\.\d+\:\d+|\d+)\s+(\w+)\s+persistent\s+(\d+)\s+mask\s+(.*)/) {
 			$real_service = "$2 ".lc($1);
 			$oldsrv{"$real_service"} = {"real"=>{}, "scheduler"=>$3, "persistent"=>$4, "netmask"=>$5};
-		} elsif ($_ =~ /(\w+)\s+(\d+\.\d+\.\d+\.\d+\:\d+|\d+)\s+(\w+)\s+persistent\s+(\d+)/) {
+		} elsif ($line =~ /(\w+)\s+(\d+\.\d+\.\d+\.\d+\:\d+|\d+)\s+(\w+)\s+persistent\s+(\d+)/) {
 			$real_service = "$2 ".lc($1);
 			$oldsrv{"$real_service"} = {"real"=>{}, "scheduler"=>$3, "persistent"=>$4};
-		} elsif ($_ =~ /(\w+)\s+(\d+\.\d+\.\d+\.\d+\:\d+|\d+)\s+(\w+)/) {
+		} elsif ($line =~ /(\w+)\s+(\d+\.\d+\.\d+\.\d+\:\d+|\d+)\s+(\w+)/) {
 			$real_service = "$2 ".lc($1);
 			$oldsrv{"$real_service"} = {"real"=>{}, "scheduler"=>$3};
 		} else {
 			next;
 		}
-		while(<IPVS>) {
-			last unless $_ =~ / ->\s+(\d+\.\d+\.\d+\.\d+\:\d+)\s+(\w+)\s+(\d+)/;
+		while ($line = ld_readline($fh, $buf)) {
+			last unless $line =~ / ->\s+(\d+\.\d+\.\d+\.\d+\:\d+)\s+(\w+)\s+(\d+)/;
 			if ($2 eq "Route") {
 				$fwd = "gate";
 			} elsif ($2 eq "Tunnel") {
@@ -1573,7 +1618,7 @@ sub ld_read_ipvsadm
 		}
 		redo;
 	}
-	close(IPVS);
+	close($fh);
 
         return(\%oldsrv);
 }

Search lvs-users Archives
Limit search to: Subject & Body Subject Author
Sort by: Reverse Sort

More information about the lvs-users mailing list