--- ldirectord.orig Fri Jul 12 00:35:32 2002 +++ ldirectord Fri Jul 12 01:44:09 2002 @@ -145,6 +145,24 @@ for details. +B[B|B] + +If I, then when real or failback servers are determined +to be down, they are not actually removed from the kernel's LVS +table. Rather, their weight is set to zero which means that no +new connections will be accepted. This has the side effect, +that if the real server has persistent connections, new connections +from any existing clients will continue to be routed to the real +server, until the persistant timeout can expire. See +L for more information on persistant connections. + +If I, then the real or failback servers will be removed +from the kernel's LVS table. The default is I. + +This directive may also appear within a virtual server, in which +case it will overide the global fallback server, if set. + + =head2 Section virtual The following commands must follow a B entry and must be indented @@ -270,6 +288,7 @@ $NEGOTIATETIMEOUT $RUNPID $CHECKTIMEOUT + $QUIESCENT $CALLBACK $CFGNAME @@ -301,6 +320,7 @@ $LD_TERM_CALLED = 0; $NEGOTIATETIMEOUT = 0; $RUNPID = "/var/run/ldirectord"; +$QUIESCENT = "yes"; use Getopt::Std; @@ -585,7 +605,6 @@ $vsrv{negotiatetimeout} = 0; $vsrv{num_connects} = 0; push(@VIRTUAL, \%vsrv); - #flim while() { $line++; $_ =~ s/\t/ /g; @@ -680,6 +699,10 @@ } elsif ($rcmd =~ /^fallback\s*=\s*(.*)/) { # Allow specification of a virtual-specific fallback host $fallback_line=$line; $vsrv{fallback}=parse_fallback($line, $1); + } elsif ($rcmd =~ /^quiescent\s*=\s*(.*)/) { + ($1 eq "yes" || $1 eq "no") + or &config_error($line, "quiescent must be 'yes' or 'no'"); + $vsrv{quiescent} = $1; } else { &config_error($line, "Unknown command $_"); } @@ -745,6 +768,10 @@ $LD_INSTANCE{$1} = 1; } elsif ($_ =~ /^supervised/) { $SUPERVISED = 1; + } elsif ($_ =~ /^quiescent\s*=\s*(.*)/) { + ($1 eq "yes" || $1 eq "no") + or &config_error($line, "quiescent must be 'yes' or 'no'"); + $QUIESCENT = $1; } else { if ($_ =~ /^timeout\s*=\s*(.*)/) { &config_error($line, "timeout directive deprciated in favour of checktimeout, negotiatetimeout or connecttimeout"); @@ -1712,15 +1739,16 @@ } -# _quiescent_service -# Make a real server quiescent +# _remove_service +# Remove a real server by either making it quiescent or deleteing it # Should be called by _service_down or fallback_off # I.e. If you want to change the state of a real server call set_service. # If you call this function directly then ldirectord will lose track # of the state of real servers. -# If the real server exists (which it should) make it quiescent. If it -# doesn't exist, just leave it as it will be added by the _service_up code -# as appropriate. +# If the real server exists (which it should) make it quiescent or +# delete it, depending on the global and per virtual service quiecent flag. +# If it # doesn't exist, just leave it as it will be added by the +# _service_up code as appropriate. # pre: v: reference to virtual service to with the real server belongs # rservice: service to restore. Of the form server:port for a tcp or # udp service. Of the form fwmark for a fwm service. @@ -1731,7 +1759,7 @@ # if it is inactive # return: none -sub _quiescent_service { +sub _remove_service { my ($v, $rservice, $rforw, $tag) = (@_); my $oldsrv; @@ -1749,12 +1777,19 @@ if(defined($ov)){ $or=$ov->{"real"}->{$rservice}; } - if(defined($or)){ - unless($or->{"weight"} eq 0 and - $or->{"forward"} eq $rforw){ - &system_wrapper("$IPVSADM -e $ipvsadm_args $rforw -w 0"); - &ld_log("Quiescent $log_args"); - } + + if(!defined($or) or ($or->{"weight"} eq 0 and + $or->{"forward"} eq $rforw)){ + return; + } + + if(($$v{quiescent} and $$v{quiescent} eq "no") + or (!defined($$v{quiescent}) and $QUIESCENT eq "no")){ + &system_wrapper("$IPVSADM -d $ipvsadm_args"); + &ld_log("Deleted $log_args"); + } else { + &system_wrapper("$IPVSADM -e $ipvsadm_args $rforw -w 0"); + &ld_log("Quiescent $log_args"); } } @@ -1858,7 +1893,7 @@ my ($v, $r) = @_; if ($$r{status}==1) { - &_quiescent_service($v, $r->{server} . ":" . $r->{port}, + &_remove_service($v, $r->{server} . ":" . $r->{port}, $r->{forw}, "real"); $$r{status} = 0; $$v{status}--; @@ -1898,7 +1933,7 @@ my $fallback=&fallback_find($v); if (defined $fallback and $$v{status}==1) { - _quiescent_service($v, $fallback->{server}, + _remove_service($v, $fallback->{server}, get_forward_flag($fallback->{forward}), "fallback"); }