LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: [lvs-users] RFC: Forking ldirecterd [PATCH]

To: lvs-users@xxxxxxxxxxxxxxxxxxxxxx
Subject: Re: [lvs-users] RFC: Forking ldirecterd [PATCH]
From: "Ryan Castellucci" <ryan.castellucci@xxxxxxxxx>
Date: Wed, 28 Nov 2007 02:18:43 -0800
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/


<Prev in Thread] Current Thread [Next in Thread>