On Thu, Nov 29, 2007 at 08:41:27AM -0600, Aaron Linnen wrote:
> I have a service with a custom protocol that I'm load balancing and I
> didn't find an easy way to get that going with ldirectord. I came up
> with a quick modification that enabled what I needed, but would
> appreciate comments or, ideally including similar functionality in
> future releases.
>
> It's a new service type called simpletcp, and is configured like so:
> virtual = 192.168.44.3:10301
> protocol = tcp
> scheduler = wlc
> real = 192.168.45.4:10301 gate 100
> real = 192.168.45.5:10301 gate 100
> service = simpletcp
> request = "command\narg\n.\n"
> receive = "^\+OK"
>
> The check simply sends the request string down the connection and tests
> against the receive regex. My perl-foo is weak these days, so I'm sure
> there are some easy improvements that could be made.
Hi Arron,
thanks for your patch. This idea looks like a good one to me and
I'm quite happy to push it into the next release (or the one after that,
as the next release is close to going out the door).
A few things:
* How well have you tested this? Its unlikely to break anything except
itself, but its good to get an idea anyway.
* Can you add something to the documentation at the top of ldirectord?
Perhaps doding this as a second patch would work well.
* Your patch seemed to replace all tabs with spaces so it didn't apply.
I manually fixed this up and the fixed version is below.
* If at all possible could you provide a sign-off line as described
in section 5 of http://linux.yyz.us/patch-format.html
Thats basically to say this is your work and you are ok with
it going into a GPL project.
--
Horms
Date: Thu, 29 Nov 2007 08:41:27 -0600
From: Aaron Linnen <aaron@xxxxxxxxxxxxxx>
To: "LinuxVirtualServer.org users mailing list."
<lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: [lvs-users] ldirectord SimpleTCP service check [PATCH]
I have a service with a custom protocol that I'm load balancing and I
didn't find an easy way to get that going with ldirectord. I came up
with a quick modification that enabled what I needed, but would
appreciate comments or, ideally including similar functionality in
future releases.
It's a new service type called simpletcp, and is configured like so:
virtual = 192.168.44.3:10301
protocol = tcp
scheduler = wlc
real = 192.168.45.4:10301 gate 100
real = 192.168.45.5:10301 gate 100
service = simpletcp
request = "command\narg\n.\n"
receive = "^\+OK"
The check simply sends the request string down the connection and tests
against the receive regex. My perl-foo is weak these days, so I'm sure
there are some easy improvements that could be made.
Aaron
Index: heartbeat/ldirectord/ldirectord.in
===================================================================
--- heartbeat.orig/ldirectord/ldirectord.in 2007-11-30 16:17:41.000000000
+0900
+++ heartbeat/ldirectord/ldirectord.in 2007-11-30 16:26:34.000000000 +0900
@@ -1225,7 +1225,8 @@ sub read_config
$1 eq "radius"||
$1 eq "pgsql" ||
$1 eq "sip" ||
- $1 eq "smtp")
+ $1 eq "smtp" ||
+ $1 eq "simpletcp")
or &config_error($line,
"service must " .
"be dns, ftp, " .
@@ -2223,6 +2224,8 @@ sub ld_main
$$r{num_connects} = 0 if
(check_pgsql($v, $r) == $SERVICE_UP);
} elsif ($$v{service} eq "oracle") {
$$r{num_connects} = 0 if
(check_oracle($v, $r) == $SERVICE_UP);
+ } elsif ($$v{service} eq "simpletcp") {
+ $$r{num_connects} = 0 if
(check_simpletcp($v, $r) == $SERVICE_UP);
} else {
$$r{num_connects} = 0 if
(check_none($v, $r) == $SERVICE_UP);
}
@@ -2911,6 +2914,73 @@ sub check_sip
}
+sub check_simpletcp
+{
+ my ($v, $r) = @_;
+ my $d_port = ld_checkport($v, $r);
+
+ &ld_debug(2, "Checking simpletcp server=$$r{server} port=$d_port");
+
+ eval {
+ use Socket;
+
+ local $SIG{'__DIE__'} = "DEFAULT";
+ local $SIG{'ALRM'} = sub { die "Timeout Alarm" };
+ &ld_debug(4, "Timeout is $$v{checktimeout}");
+ alarm $$v{negotiatetimeout};
+
+ my $sock = &ld_open_socket($$r{server}, $d_port,
+ $$v{protocol});
+ unless ($sock) {
+ alarm 0;
+ die("Socket Connect Failed");
+ }
+
+ my $s_sockaddr = getsockname($sock);
+ my ($s_port, $s_addr) = sockaddr_in($s_sockaddr);
+ my $s_addr_str = inet_ntoa($s_addr);
+
+ &ld_debug(3, "Connected from $s_addr_str:$s_port to " .
+ $$r{server} . ":$d_port");
+
+ select $sock;
+ $|=1;
+ select STDOUT;
+
+ my $request = $$r{request};
+ $request =~ s/\\n/\n/g ;
+
+ &ld_debug(2, "Checking simpletcp server=$$r{server} port=$d_port
request:\n$request");
+ print $sock $request;
+
+ my $ok;
+ my $reply;
+ while (<$sock>) {
+ &ld_debug(2, "Checking simpletcp server=$$r{server}
port=$d_port receive=" . $$r{receive} ." got: $_\n");
+ if ( $_ =~ /$$r{receive}/ ) {
+ $ok = 1;
+ last;
+ }
+ }
+ alarm 0; # Cancel the alarm
+ close($sock);
+
+ if (!defined $ok) {
+ die "No OK\n";
+ }
+ };
+
+ if ($@) {
+ &service_set($v, $r, "down");
+ &ld_debug(3, "Deactivated service $$r{server}:$$r{port}: $@");
+ return $SERVICE_DOWN;
+ } else {
+ &service_set($v, $r, "up");
+ &ld_debug(3, "Activated service $$r{server}:$$r{port}");
+ return $SERVICE_UP;
+ }
+}
+
sub check_ftp
{
require Net::FTP;
|