--- ipvs-0.9.1/contrib/ldirectord/ldirectord.orig Thu Jan 4 12:26:25 2001 +++ ipvs-0.9.1/contrib/ldirectord/ldirectord Thu May 10 12:18:12 2001 @@ -1,7 +1,7 @@ #!/usr/bin/perl # # Linux Director Daemon - run "perldoc ldirectord" for details -# $Id: ldirectord.diff,v 1.5 2001/06/13 15:05:11 raf Exp $ +# $Id: ldirectord.diff,v 1.5 2001/06/13 15:05:11 raf Exp $ # © 2000, Jacob Rief # This is GPL software. You should own a few hundred copies # of the GPL by now. if not, get one at http://www.fsf.org @@ -45,7 +45,7 @@ This is the name for the configuration as specified in the file BI -B<-d> Don't start as daemon. Useful for debugging. +B<-d> Don't start as daemon. Useful for debugging. #' B<-h> Help. Print user manual of ldirectord. @@ -82,6 +82,16 @@ is 5 seconds. If defined in virtual server section then the global value is overridden. +BI + +Not used. + +BI + +Defines the number of seconds to wait for TCP/IP timeouts. Default is +defined by the operating system. If defined in virtual server section +then the global value is overridden. + BI Defines the number of second between server checks. Default is 10 seconds. @@ -93,6 +103,13 @@ file changed on disk, the configuration is automatically reloaded. Default is no. +BIB<"> + +If this directive is defined, B automatically send a mail +to the given address whenever a real server has its status changed. +If defined in virtual server section then the global value is +overridden. + BIB<"> If this directive is defined, B automatically calls @@ -258,7 +275,9 @@ $RUNPID="/var/run/ldirectord"; $AUTOCHECK="no"; $CALLBACK; +$ADMIN; $FOREGROUND; +$RETRIES=3; @VIRTUAL; @OLDVIRTUAL; @REAL; @@ -267,6 +286,7 @@ $checksum; $stattime; $initializing; +$START_PHASE=1; use Getopt::Std; use English; @@ -434,9 +454,9 @@ $LD_TERM_CALLED = 1; ld_cmd_children("stop", %LD_INSTANCE); - &ld_rm_file("$RUNPID.$CFGNAME.pid"); ld_stop(); &ld_log("Linux Director Daemon terminated on signal: $signal"); + &ld_rm_file("$RUNPID.$CFGNAME.pid"); &ld_exit(0, "Linux Director Daemon terminated on signal: $signal"); } @@ -483,6 +503,7 @@ { undef @VIRTUAL; undef $CALLBACK; + undef $ADMIN; undef $FOREGROUND; undef $checksum; $stattime = 0; @@ -633,6 +654,9 @@ ($tmp =~ /(\d+\.\d+\.\d+\.\d+:\d+)/ || $tmp =~ /(\d+\.\d+\.\d+\.\d+)/) && $1 or config_error($line, "invalid address for fallback server"); $vsrv{fallback} = $tmp + } elsif ($rcmd =~ /^admin\s*=\s*\"(.*)\"/) { + $1 =~ /(.+)/ or config_error($line, "invalid admin string"); + $vsrv{admin} = $1; } else { config_error($line, "Unknown command $_"); } @@ -651,6 +675,9 @@ } elsif ($_ =~ /^checkinterval\s*=\s*(.*)/) { $1 =~ /(\d+)/ && $1 or config_error($line, "invalid checkinterval value"); $CHECKINTERVAL = $1; + } elsif ($_ =~ /^retry\s*=\s*(.*)/) { + $1 =~ /(\d+)/ && $1 or config_error($line, "invalid retry value"); + $RETRIES = $1; } elsif ($_ =~ /^fallback\s*=\s*(.*)/) { my $tmp = $1; ($tmp =~ /(\d+\.\d+\.\d+\.\d+:\d+)/ || $tmp =~ /(\d+\.\d+\.\d+\.\d+)/) && $1 @@ -662,6 +689,9 @@ $AUTOCHECK = $1; } elsif ($_ =~ /^callback\s*=\s*\"(.*)\"/) { $CALLBACK = $1; + } elsif ($_ =~ /^admin\s*=\s*\"(.*)\"/) { + (length($1) > 0) or config_error($line, "undefined admin mail address"); + $ADMIN = $1; } elsif ($_ =~ /^logfile\s*=\s*\"(.*)\"/) { my $tmpLDIRLOG = $LDIRLOG; $LDIRLOG = $1; @@ -1017,6 +1047,7 @@ } check_cfgfile(); sleep $CHECKINTERVAL; + undef $START_PHASE; } } @@ -1053,18 +1084,27 @@ { use LWP::UserAgent; my ($v, $r) = @_; - my $ua = new LWP::UserAgent; + mu ($ua, $req, $res, $recstr, $retr); + $retr = $RETRIES; +_re_http_: + $retr -- ; + $ua = new LWP::UserAgent; $ua->agent("LinuxDirector/0.1".$ua->agent); $ua->timeout($$v{negotiatetimeout}); - my $req = new HTTP::Request(GET=>"$$r{url}"); - my $res = $ua->request($req); - my $recstr = $$r{receive}; + $req = new HTTP::Request(GET=>"$$r{url}"); + $res = $ua->request($req); + $recstr = $$r{receive}; if ($res->is_success && (!($recstr =~ /.+/) || $res->content =~ /$recstr/)) { service_set($v, $r, "up"); return 1; } else { + if( $retr != 0 ) { + sleep(1); + goto _re_http_; + } else { service_set($v, $r, "down"); return 0; + } } } @@ -1127,15 +1167,23 @@ use Net::FTP; my ($v, $r) = @_; my $ftp; + my $retr = $RETRIES; local *READ_FH; local *WRITE_FH; pipe(\*READ_FH, \*WRITE_FH); select(\*WRITE_FH); $| = 1; select(STDERR); +_re_ftp_: + $retr --; unless ($ftp = Net::FTP->new("$$r{server}:$$r{port}", Timeout=>$$v{negotiatetimeout})) { + if ($retr != 0) { + sleep(1); + goto _re_ftp_; + } else { service_set($v, $r, "down"); return 0; + } } $ftp->login($$v{login}, $$v{passwd}); $ftp->cwd("/"); @@ -1168,6 +1216,24 @@ } +# alert_admin +# Send a mail notification when a real server status changed +sub alert_admin { + use Mail::Send; + use Socket; + my ($server, $port, $state, $admin) = @_; + my ($msg, $fh); + $msg = new Mail::Send; + # use global ADMIN def if admin for virtual is undef. + $admin = $ADMIN unless defined ($admin); + &ld_debug(4, "sending mail to $admin"); + $msg->to($admin); + my $hrserver = gethostbyaddr(inet_aton($server),AF_INET); + $msg->subject("[LDIRECTORD] $hrserver\[$server]:$port $state"); + $fh = $msg->open; + print $fh "Service on host $hrserver\[$server], port $port is $state."; + $fh->close; +} # service_set # Used to bring up and down real servers. # This is the function you should call if you want to bring a real server up or down. @@ -1210,10 +1276,12 @@ $$r{status}=0; _service_up($v, $r); &ld_debug(2, "Enabling server=$$r{server}"); + &alert_admin($$r{server},$$r{port},up,$$v{admin}) if (defined $ADMIN and ! $START_PHASE); } elsif ($state=~/down/i) { $$r{status}=1; _service_down($v, $r); &ld_debug(2, "Disabling server=$$r{server}"); + &alert_admin($$r{server},$$r{port},down,$$v{admin}) if (defined $ADMIN); } } } @@ -1238,7 +1306,8 @@ &system_wrapper("$IPVSADM -a $$v{proto} " . &get_virtual($v) . " -R $$r{server}:$$r{port} $$r{forw} $$r{wght}"); $$r{status} = 1; $$v{status}++; - &ld_log("Adding real server: $$r{server}:$$r{port} ($$v{status} x " . &get_virtual($v) . ")"); + my $hrserver = gethostbyaddr(inet_aton($$r{server}),AF_INET); + &ld_log("Adding real server: $hrserver\[$$r{server}]:$$r{port} ($$v{status} x " . &get_virtual($v) . ")"); &fallback_off($v); } } @@ -1262,7 +1331,8 @@ &system_wrapper("$IPVSADM -d $$v{proto} " . &get_virtual($v) . " -R $$r{server}:$$r{port}"); $$r{status} = 0; $$v{status}--; - &ld_log("Removing real server: $$r{server}:$$r{port} ($$v{status} x " . &get_virtual($v) . ")"); + my $hrserver = gethostbyaddr(inet_aton($$r{server}),AF_INET); + &ld_log("Removing real server: $hrserver\[$$r{server}]:$$r{port} ($$v{status} x " . &get_virtual($v) . ")"); &fallback_on($v); } }