LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

[lvs-users] Patches for ldirectord

To: lvs-users@xxxxxxxxxxxxxxxxxxxxxx
Subject: [lvs-users] Patches for ldirectord
From: "Sean E. Millichamp" <sean@xxxxxxxxxxx>
Date: Tue, 21 Apr 2009 13:51:41 -0400
I have some relatively minor patches for ldirectord to address some issues we had in our environment. The patches are attached to this email. All are developed against the mercurial checkout at http://hg.linux-ha.org/dev/

They are relatively independent in concept, but I developed them cumulatively, so if they weren't all applied in order I would expect some issues.

ldirectord-01-cleanup-forked-children.patch:

I observed that when ldirectord exits while using fork=yes the children forked to perform the checks are not killed or otherwise cleaned up and continue running. This patch sends the children SIGTERM when ldirectord exits.

ldirectord-02-dont-disable-realservers-in-forking.patch:

When using fork=no there is a sanity check on the state of the LVS pools, and ldirectord modifies them as necessary. If there are realservers already present in existing pools ldirectord doesn't disable them until checks can complete. However, when using fork=yes this same sanity check is performed, but all realservers are set down until one check passes successfully. This patch fixes this behavior so that the realservers are not set down initially when fork=yes

ldirectord-03-prefix-forked-processes-with-ldirectord.patch:

It is very nice how ldirectord changes the process name of the forked children to be more informative, but it makes it difficult to easily grep for all ldirectord related processes and non-obvious for people less familiar with ldirectord what those processes are. This patch just prefixes the names of the forked children with "ldirectord", otherwise keeping the current names.

ldirectord-04-add-cleanstop-option.patch:

We would like the ability to stop ldirectord without it clearing out our pools. The new "cleanstop" option allows global or per virtual service ability to disable this cleanup. The default remains to perform the cleanup.

ldirectord-05-add-per-virtual-service-checkinterval.patch:

The current checkinterval option is global only. However, when using fork=yes it is possible and sensible to want to adjust the checkinterval on a per-service basis. This patch allows you to do that, expands on the documentation for the option, and warns you if you try to set checkinterval in a virtual service definition when fork=no.

Feedback welcome.

Thanks!

Sean

# HG changeset patch
# User Sean E. Millichamp <sean@xxxxxxxxxxx>
# Date 1240245735 14400
# Node ID fc85771e74ef8bfac92fcac4e81e5c11e8ba3ba9
# Parent  ec7c07e55310e073f2f37025b9cd6f602470d534
Cleanup children from fork mode when exiting ldirectord

diff -r ec7c07e55310 -r fc85771e74ef ldirectord/ldirectord.in
--- a/ldirectord/ldirectord.in  Fri Apr 10 18:14:02 2009 +0200
+++ b/ldirectord/ldirectord.in  Mon Apr 20 12:42:15 2009 -0400
@@ -2298,6 +2298,14 @@ sub ld_cmd_children
 
 sub ld_stop
 {
+       # Kill children
+       if ($FORKING eq 'yes') {
+               foreach my $virtual_id (keys (%FORK_CHILDREN)) {
+                       my $pid = $FORK_CHILDREN{$virtual_id};
+                       ld_log("Killing child $virtual_id PID=$pid");
+                       kill 15, $pid;
+               }
+       }
        foreach my $v (@VIRTUAL) {
                my $real = $$v{real};
                foreach my $r (@$real) {
# HG changeset patch
# User Sean E. Millichamp <sean@xxxxxxxxxxx>
# Date 1240261618 14400
# Node ID 7ce7e00a71922441054db55f73efebaba7b35fe9
# Parent  fc85771e74ef8bfac92fcac4e81e5c11e8ba3ba9
Don't initially weight existing realservers to 0 when using forking mode

diff -r fc85771e74ef -r 7ce7e00a7192 ldirectord/ldirectord.in
--- a/ldirectord/ldirectord.in  Mon Apr 20 12:42:15 2009 -0400
+++ b/ldirectord/ldirectord.in  Mon Apr 20 17:06:58 2009 -0400
@@ -2404,9 +2404,6 @@ sub run_child
         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 => 1});
-        }
         while (1) {
                 foreach my $r (@$real) {
                         $0 = "$virtual_id checking $$r{server}";
# HG changeset patch
# User Sean E. Millichamp <sean@xxxxxxxxxxx>
# Date 1240261845 14400
# Node ID 01076fdd4b52fce922ae21bd0635faeeea634413
# Parent  7ce7e00a71922441054db55f73efebaba7b35fe9
Prefix all forked processes with "ldirectord" for easy locating

diff -r 7ce7e00a7192 -r 01076fdd4b52 ldirectord/ldirectord.in
--- a/ldirectord/ldirectord.in  Mon Apr 20 17:06:58 2009 -0400
+++ b/ldirectord/ldirectord.in  Mon Apr 20 17:10:45 2009 -0400
@@ -2403,13 +2403,13 @@ sub run_child
         
         my $real = $$v{real};
         my $virtual_id = get_virtual_id_str($v);
-        $0 = $virtual_id;
+        $0 = "ldirectord $virtual_id";
         while (1) {
                 foreach my $r (@$real) {
-                        $0 = "$virtual_id checking $$r{server}";
+                        $0 = "ldirectord $virtual_id checking $$r{server}";
                         _check_real($v, $r);
                 }
-                $0 = $virtual_id;
+                $0 = "ldirectord $virtual_id";
                 sleep $CHECKINTERVAL;
                 ld_emailalert_resend();
         }
# HG changeset patch
# User Sean E. Millichamp <sean@xxxxxxxxxxx>
# Date 1240319501 14400
# Node ID 2e5b0e0c30bc587e4b803510c142cb1c4a0350b1
# Parent  01076fdd4b52fce922ae21bd0635faeeea634413
Add "cleanstop" option to make exit-time cleanup of LVS pools configurable

diff -r 01076fdd4b52 -r 2e5b0e0c30bc ldirectord/ldirectord.in
--- a/ldirectord/ldirectord.in  Mon Apr 20 17:10:45 2009 -0400
+++ b/ldirectord/ldirectord.in  Tue Apr 21 09:11:41 2009 -0400
@@ -295,6 +295,21 @@ Default: I<yes>
 Default: I<yes>
 
 
+B<cleanstop = >B<yes>|B<no>
+
+If I<yes>, then when ldirectord exits it will remove all of the virtual
+server pools that it is managing from the kernel's LVS table.
+
+If I<no>, then the virtual server pools it is managing and any real
+or failback servers listed in them at the time ldirectord exits will
+be left as-is.  If you want to be able to stop ldirectord without having
+traffic to your realservers interrupted you will want to set this to I<no>.
+
+If defined in a virtual server section then the global value is overridden.
+
+Default: I<yes>
+
+
 =head2 Section virtual
 
 The following commands must follow a B<virtual> entry and must be indented
@@ -637,6 +652,7 @@ use vars qw(
            $EMAILALERT
            $EMAILALERTFREQ
            $EMAILALERTSTATUS
+           $CLEANSTOP
 
            $CALLBACK
            $CFGNAME
@@ -710,6 +726,7 @@ if (! defined $LDIRECTORD) {
 $EMAILALERT      = "";
 $EMAILALERTFREQ          = 0;
 $EMAILALERTSTATUS = $DAEMON_STATUS_ALL;
+$CLEANSTOP       = "yes"; 
 
 $CRLF = "\x0d\x0a";
 
@@ -1391,6 +1408,10 @@ sub read_config
                                                &config_error($line, "unable to 
open monitorfile $monitorfile: $!");
                                        }
                                        $vsrv{monitorfile} = $monitorfile;
+                                } elsif  ($rcmd =~ /^cleanstop\s*=\s*(.*)/) {
+                                       ($1 eq "yes" || $1 eq "no")
+                                               or &config_error($line, 
"cleanstop must be 'yes' or 'no'");
+                                       $vsrv{cleanstop} = $1;
                                } else {
                                        &config_error($line, "Unknown command 
\"$linedata\"");
                                }
@@ -1505,6 +1526,10 @@ sub read_config
                        $EMAILALERTFREQ = $1;
                } elsif  ($linedata  =~ /^emailalertstatus\s*=\s*(.*)/) {
                        $EMAILALERTSTATUS = &parse_emailalertstatus($line, $1);
+               } elsif  ($linedata  =~ /^cleanstop\s*=\s*(.*)/) {
+                       ($1 eq "yes" || $1 eq "no")
+                           or &config_error($line, "cleanstop must be 'yes' or 
'no'");
+                       $CLEANSTOP = $1;
                } else {
                        if ($linedata  =~ /^timeout\s*=\s*(.*)/) {
                                &config_error($line, 
@@ -2307,6 +2332,8 @@ sub ld_stop
                }
        }
        foreach my $v (@VIRTUAL) {
+               next if ( (! defined($$v{cleanstop}) and $CLEANSTOP eq 'no') or
+                       (defined($$v{cleanstop}) and $$v{cleanstop} eq 'no') );
                my $real = $$v{real};
                foreach my $r (@$real) {
                        if (defined $$r{virtual_status}) {
# HG changeset patch
# User Sean E. Millichamp <sean@xxxxxxxxxxx>
# Date 1240325877 14400
# Node ID a223b9524d594202f952586285a3d6dbbca9292f
# Parent  2e5b0e0c30bc587e4b803510c142cb1c4a0350b1
Add support for per-virtual service checkinterval when fork=yes

diff -r 2e5b0e0c30bc -r a223b9524d59 ldirectord/ldirectord.in
--- a/ldirectord/ldirectord.in  Tue Apr 21 09:11:41 2009 -0400
+++ b/ldirectord/ldirectord.in  Tue Apr 21 10:57:57 2009 -0400
@@ -140,6 +140,16 @@ B<checkinterval = >I<n>
 B<checkinterval = >I<n>
 
 Defines the number of second between server checks.
+
+When fork=no this option defines the amount of time ldirectord sleeps
+between running all of the realserver checks in all virtual service pools.
+
+When fork=yes this option defines the amount of time each forked child
+sleeps per virtual service pool after running all realserver checks for
+that pool.
+
+If set in the virtual server section then the global value is overridden,
+but ONLY if using forking mode (B<fork = >I<yes>).
 
 Default: 10 seconds
 
@@ -1542,6 +1552,18 @@ sub read_config
                }
        }
        close(CFGFILE);
+
+       # Check for sensible use of checkinterval, warn if it is used in a 
virtual
+       # service when fork=no
+       if ($FORKING eq 'no') {
+               foreach my $v (@VIRTUAL) {
+                       if (defined($$v{checkinterval})) {
+                               config_warn(-1, "checkinterval in virtual 
service ".
+                                       get_virtual_id_str($v)." ignored when 
fork=no");
+                       }
+               }
+       }
+
        return(0);
 }
 
@@ -2430,6 +2452,7 @@ sub run_child
         
         my $real = $$v{real};
         my $virtual_id = get_virtual_id_str($v);
+        my $checkinterval = $$v{checkinterval} || $CHECKINTERVAL;
         $0 = "ldirectord $virtual_id";
         while (1) {
                 foreach my $r (@$real) {
@@ -2437,7 +2460,7 @@ sub run_child
                         _check_real($v, $r);
                 }
                 $0 = "ldirectord $virtual_id";
-                sleep $CHECKINTERVAL;
+                sleep $checkinterval;
                 ld_emailalert_resend();
         }
 }
_______________________________________________
Please read the documentation before posting - it's available at:
http://www.linuxvirtualserver.org/

LinuxVirtualServer.org mailing list - lvs-users@xxxxxxxxxxxxxxxxxxxxxx
Send requests to lvs-users-request@xxxxxxxxxxxxxxxxxxxxxx
or go to http://lists.graemef.net/mailman/listinfo/lvs-users
<Prev in Thread] Current Thread [Next in Thread>