On Nov 28, 2007 1:56 AM, Ryan Castellucci <ryan.castellucci@xxxxxxxxx> wrote:
> The attached patch modifies ldirectord to fork a process for each
Or not attached. Apparently the mailing list ate it.
===== CUT =====
--- /usr/sbin/ldirectord 2006-11-30 03:45:49.000000000 +0000
+++ /usr/local/sbin/ldirectord-fork 2007-11-28 09:26:20.000000000 +0000
@@ -444,6 +444,8 @@
@OLDEMAILSTATUS
$CRLF
+
+ %CHILDREN_PID
);
# default values
@@ -471,7 +473,7 @@
#use Time::HiRes qw( gettimeofday tv_interval );
use Socket;
use Sys::Hostname;
-use POSIX qw(setsid);
+use POSIX qw(setsid :sys_wait_h);
use Sys::Syslog qw(:DEFAULT setlogsock);
# command line options
@@ -762,6 +764,10 @@
%LD_INSTANCE = %OLD_INSTANCE;
}
undef @OLDVIRTUAL;
+ foreach my $vid (keys %CHILDREN_PID) {
+ &ld_log("Killing child $vid (PID=$CHILDREN_PID{$vid})");
+ kill 15, $CHILDREN_PID{$vid};
+ }
}
@@ -1778,89 +1784,128 @@
{
# Main failover checking code
while (1) {
- my @real_checked;
foreach my $v (@VIRTUAL) {
- my $real = $$v{real};
my $virtual_id = get_virtual_id_str($v);
-
- REAL: foreach my $r (@$real) {
- my $real_id = get_real_id_str($r, $v);
- foreach my $tmp_id (@real_checked) {
- if($real_id eq $tmp_id) {
- &ld_debug(3, "Already
checked: real server=$real_id (virtual=$virtual_id)");
- next REAL;
- }
- }
- if ($$v{checktype} eq "negotiate" ||
$$r{num_connects}>=$$v{num_connects}) {
- &ld_debug(2, "Checking
negotiate: real server=$real_id (virtual=$virtual_id)");
- if ($$v{service} eq "http" ||
$$v{service} eq "https") {
- $$r{num_connects} = 0
if (check_http($v, $r));
- # my $req = new
HTTP::Request(GET=>"$$r{url}");
- # $ua->register($req,
\&http_received);
- } elsif ($$v{service} eq "pop") {
- $$r{num_connects} = 0
if (check_pop($v, $r));
- } elsif ($$v{service} eq "pops") {
- $$r{num_connects} = 0
if (check_pops($v, $r));
- } elsif ($$v{service} eq "imap") {
- $$r{num_connects} = 0
if (check_imap($v, $r));
- } elsif ($$v{service} eq "imaps") {
- $$r{num_connects} = 0
if (check_imaps($v, $r));
- } elsif ($$v{service} eq "smtp") {
- $$r{num_connects} = 0
if (check_smtp($v, $r));
- } elsif ($$v{service} eq "ftp") {
- $$r{num_connects} = 0
if (check_ftp($v, $r));
- } elsif ($$v{service} eq "ldap") {
- $$r{num_connects} = 0
if (check_ldap($v, $r));
- } elsif ($$v{service} eq "nntp") {
- $$r{num_connects} = 0
if (check_nntp($v, $r));
- } elsif ($$v{service} eq "dns") {
- $$r{num_connects} = 0
if (check_dns($v, $r));
- } elsif ($$v{service} eq "sip") {
- $$r{num_connects} = 0
if (check_sip($v, $r));
- } elsif ($$v{service} eq "mysql") {
- $$r{num_connects} = 0
if (check_mysql($v, $r));
- } elsif ($$v{service} eq "pgsql") {
- $$r{num_connects} = 0
if (check_pgsql($v, $r));
- } else {
- $$r{num_connects} = 0
if (check_none($v, $r));
- }
- } elsif ($$v{checktype} eq "connect") {
- if ($$v{protocol} ne "udp") {
- &ld_debug(2, "Checking
connect: real server=$real_id (virtual=$virtual_id)");
- check_connect($v, $r);
- }
- else {
- &ld_debug(2, "Checking
connect (ping): real server=$real_id (virtual=$virtual_id)");
- check_ping($v, $r);
- }
- } elsif ($$v{checktype} eq "ping") {
- &ld_debug(2, "Checking ping:
real server=$real_id (virtual=$virtual_id)");
- check_ping($v, $r);
- } elsif ($$v{checktype} eq "off") {
- &ld_debug(2, "Checking off: No
real or fallback servers to be added\n");
- } elsif ($$v{checktype} eq "on") {
- &ld_debug(2, "Checking on:
Real servers are added without any checks\n");
- &service_set($v, $r, "up");
- } elsif ($$v{checktype} eq "combined") {
- &ld_debug(2, "Checking
combined-connect: real server=$real_id (virtual=$virtual_id)");
- if (check_connect($v, $r)) {
- $$r{num_connects}++;
- } else {
- $$r{num_connects} = 999999;
- }
+ if (!exists($CHILDREN_PID{$virtual_id})) {
+ &ld_log("Child not running for
$virtual_id, spawning");
+ my $pid = fork;
+ if (!defined($pid)) {
+ &ld_log("fork failed");
+ } elsif ($pid == 0) {
+ real_child($v);
+ } else {
+
$CHILDREN_PID{get_virtual_id_str($v)} = $pid;
+ &ld_log("Spawned child
$virtual_id PID=$pid");
}
- push(@real_checked, $real_id);
+ } elsif
(waitpid($CHILDREN_PID{get_virtual_id_str($v)}, WNOHANG)) {
+ delete $CHILDREN_PID{get_virtual_id_str($v)};
}
# $ua->wait($$v{checktimeout});
}
if (!check_cfgfile()) {
- sleep $CHECKINTERVAL;
+ #sleep $CHECKINTERVAL;
+ sleep 1;
}
ld_emailalert_resend();
}
}
+sub real_child
+{
+ my $v = shift;
+
+ # Just exit on signals
+ $SIG{'INT'} = undef;
+ $SIG{'QUIT'} = undef;
+ $SIG{'ILL'} = undef;
+ $SIG{'ABRT'} = undef;
+ $SIG{'FPE'} = undef;
+ $SIG{'SEGV'} = undef;
+ $SIG{'TERM'} = undef;
+ $SIG{'BUS'} = undef;
+ $SIG{'SYS'} = undef;
+ $SIG{'XCPU'} = undef;
+ $SIG{'XFSZ'} = undef;
+ $SIG{'IOT'} = undef;
+ $SIG{'ENT'} = undef;
+ $SIG{'PIPE'} = "IGNORE";
+ $SIG{'HUP'} = sub { exit 1 };
+
+
+ my $real = $$v{real};
+ my $virtual_id = get_virtual_id_str($v);
+ $0 = $virtual_id;
+ foreach my $r (@$real) {
+ service_set($v, $r, "down", "force");
+ }
+ while (1) {
+ foreach my $r (@$real) {
+ my $real_id = get_real_id_str($r, $v);
+ $0 = "$virtual_id checking $$r{server}";
+ if ($$v{checktype} eq "negotiate" ||
$$r{num_connects}>=$$v{num_connects}) {
+ &ld_debug(2, "Checking negotiate: real
server=$real_id (virtual=$virtual_id)");
+ if ($$v{service} eq "http" ||
$$v{service} eq "https") {
+ $$r{num_connects} = 0 if
(check_http($v, $r));
+ # my $req = new
HTTP::Request(GET=>"$$r{url}");
+ # $ua->register($req, \&http_received);
+ } elsif ($$v{service} eq "pop") {
+ $$r{num_connects} = 0 if
(check_pop($v, $r));
+ } elsif ($$v{service} eq "pops") {
+ $$r{num_connects} = 0 if
(check_pops($v, $r));
+ } elsif ($$v{service} eq "imap") {
+ $$r{num_connects} = 0 if
(check_imap($v, $r));
+ } elsif ($$v{service} eq "imaps") {
+ $$r{num_connects} = 0 if
(check_imaps($v, $r));
+ } elsif ($$v{service} eq "smtp") {
+ $$r{num_connects} = 0 if
(check_smtp($v, $r));
+ } elsif ($$v{service} eq "ftp") {
+ $$r{num_connects} = 0 if
(check_ftp($v, $r));
+ } elsif ($$v{service} eq "ldap") {
+ $$r{num_connects} = 0 if
(check_ldap($v, $r));
+ } elsif ($$v{service} eq "nntp") {
+ $$r{num_connects} = 0 if
(check_nntp($v, $r));
+ } elsif ($$v{service} eq "dns") {
+ $$r{num_connects} = 0 if
(check_dns($v, $r));
+ } elsif ($$v{service} eq "sip") {
+ $$r{num_connects} = 0 if
(check_sip($v, $r));
+ } elsif ($$v{service} eq "mysql") {
+ $$r{num_connects} = 0 if
(check_mysql($v, $r));
+ } elsif ($$v{service} eq "pgsql") {
+ $$r{num_connects} = 0 if
(check_pgsql($v, $r));
+ } else {
+ $$r{num_connects} = 0 if
(check_none($v, $r));
+ }
+ } elsif ($$v{checktype} eq "connect") {
+ if ($$v{protocol} ne "udp") {
+ &ld_debug(2, "Checking
connect: real server=$real_id (virtual=$virtual_id)");
+ check_connect($v, $r);
+ }
+ else {
+ &ld_debug(2, "Checking connect
(ping): real server=$real_id (virtual=$virtual_id)");
+ check_ping($v, $r);
+ }
+ } elsif ($$v{checktype} eq "ping") {
+ &ld_debug(2, "Checking ping: real
server=$real_id (virtual=$virtual_id)");
+ check_ping($v, $r);
+ } elsif ($$v{checktype} eq "off") {
+ &ld_debug(2, "Checking off: No real or
fallback servers to be added\n");
+ } elsif ($$v{checktype} eq "on") {
+ &ld_debug(2, "Checking on: Real
servers are added without any checks\n");
+ &service_set($v, $r, "up");
+ } elsif ($$v{checktype} eq "combined") {
+ &ld_debug(2, "Checking
combined-connect: real server=$real_id (virtual=$virtual_id)");
+ if (check_connect($v, $r)) {
+ $$r{num_connects}++;
+ } else {
+ $$r{num_connects} = 999999;
+ }
+ }
+ }
+ $0 = $virtual_id;
+ sleep $CHECKINTERVAL;
+ }
+}
sub check_http
{
===== CUT =====
--
Ryan Castellucci http://ryanc.org/
|