LVS
lvs-users
Google
 
Web LinuxVirtualServer.org

Re: LDIRECTORD: Add external checktype

To: "LinuxVirtualServer.org users mailing list." <lvs-users@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re: LDIRECTORD: Add external checktype
From: "J.Libak@xxxxxxxxxx" <J.Libak@xxxxxxxxxx>
Date: Tue, 24 Apr 2007 18:39:42 +0200
I wrote this patch a while ago, but don't use it at the moment.

Roberto Nibali wrote:
>> Cc: Roberto Nibali <ratz@xxxxxxxxxxxx>
>> Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
>>
>> Index: heartbeat/ldirectord/ldirectord.in
>> ===================================================================
>> --- heartbeat.orig/ldirectord/ldirectord.in  2007-04-24 18:17:05.000000000 
>> +0900
>> +++ heartbeat/ldirectord/ldirectord.in       2007-04-24 18:17:16.000000000 
>> +0900
>> @@ -286,7 +286,7 @@ checktimeout, negotiatetimeout, checkcou
>>  emailalertfreq and quiescent options listed above may also appear inside a
>>  virtual section, in which case the global setting is overridden.
>>  
>> -B<checktype => B<connect>|B<negotiate>|B<off>|B<on>|B<ping>|I<N>
>> +B<checktype => B<connect>|B<external>|B<negotiate>|B<off>|B<on>|B<ping>|I<N>
>>  
>>  Type of check to perform. Negotiate sends a request and matches a receive
>>  string. Connect only attemts to make a TCP/IP connection, thus the
>> @@ -351,6 +351,14 @@ Number of port to monitor. Sometimes che
>>  
>>  Default: port specified for each real server
>>  
>> +B<externalpath = ">I<path to script>B<">
>> +
>> +This setting is taken into account if checktype is external - by external
>> +script. Enter path of the script into double quotes. Script should return
>> +0 if everything is ok, or something else if it isn't. 4 parameters are 
>> passed
>> +to the script - virtual server ip/firewall mark, virtual server port,
>> +real server ip, real server port.
>> +
> 
> Do we need a warning here, that all the calling of external scripts can
> be dangerous security-wise and hazardous runtime-wise? I've just been
> burnt a couple of times when I provided such functionality to former
> customers, who then at free will started creating script monstrosities.
> 

Add a warning to description that it should be used only as the last option.

>>  B<request = ">I<uri to requested object>B<">
>>  
>>  This object will be requested each checkinterval seconds on each real
>> @@ -1021,6 +1029,7 @@ sub read_config
>>                      }
>>                      $vsrv{real} = \@rsrv;
>>                      $vsrv{scheduler} = "wrr";
>> +                    $vsrv{externalpath} = "/bin/true";
>>                      $vsrv{request} = "/";
>>                      $vsrv{receive} = "";
>>                      $vsrv{login} = "";
>> @@ -1062,11 +1071,19 @@ sub read_config
>>                                      if ($1 =~ /(\d+)/ && $1>=0) {
>>                                              $vsrv{num_connects} = $1;
>>                                              $vsrv{checktype} = "combined";
>> -                                    } elsif ( $1 =~ /(\w+)/ && ($1 eq 
>> "connect" || $1 eq "negotiate" || $1 eq "ping" || $1 eq "off" || $1 eq "on") 
>> ) {
>> +                                    } elsif ( $1 =~ /(\w+)/ &&
>> +                                              ($1 eq "connect"      ||
>> +                                               $1 eq "negotiate"    ||
>> +                                               $1 eq "ping"         ||
>> +                                               $1 eq "off"          ||
>> +                                               $1 eq "on"           ||
>> +                                               $1 eq "external") ) {
>>                                              $vsrv{checktype} = $1;
>>                                      } else {
>>                                              &config_error($line, "checktype 
>> must be connect, negotiate, ping, off, on or a positive number");
>> -                                    }
>> +                                    } elsif ($rcmd =~ 
>> /^externalpath\s*=\s*(.*)/){
>> +                                    $1 =~ /(.+)/ or &config_error($line, 
>> "invalid external script");
>> +                                    $vsrv{externalpath} = $1;
>>                              } elsif ($rcmd =~ /^checktimeout\s*=\s*(.*)/){
>>                                          $1 =~ /(\d+)/ && $1 or 
>> &config_error($line, "invalid check timeout");
>>                                          $vsrv{checktimeout} = $1;
>> @@ -2102,6 +2119,9 @@ sub ld_main
>>                              } 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 "external") {
>> +                                            &ld_debug(2, "Checking 
>> external: real server=$real_id (virtual=$virtual_id)");
>> +                                    check_external($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") {
>> @@ -2570,6 +2590,40 @@ sub check_connect
>>  }
>>  
>>  
>> +sub check_external {
>> +    my ($v, $r) = @_;
>> +    my $result;
>> +    my $v_server;
>> +
>> +    eval {
>> +            local $SIG{'__DIE__'} = "DEFAULT";
>> +            local $SIG{'ALRM'} = sub { die "Timeout Alarm" };
>> +            &ld_debug(4, "Timeout is $$v{checktimeout}");
>> +            alarm $$v{checktimeout};
>> +            if (defined $$v{server}) {
>> +                    $v_server = $$v{server};
>> +            } else {
>> +                    $v_server = $$v{fwm};
>> +            }
>> +            $result = system("$$v{externalpath} $v_server " .
>> +                             "$$v{port} $$r{server} $$r{port}");
>> +            alarm 0;
>> +            $result >>= 8;
>> +    };
>> +    if ($@ or $result != 0) {
>> +            &service_set($v, $r, "down");
>> +            &ld_debug(3, "Deactivated service $$r{server}:$$r{port}: "
>> +                      "$@ after calling $$v{externalpath} with result "
>> +                      "$result");
>> +            return 0;
>> +    } else {
>> +            &service_set($v, $r, "up");
>> +            &ld_debug(3, "Activated service $$r{server}:$$r{port}");
>> +            return 1;
>> +    }
>> +}
>> +
>> +
>>  sub check_sip
>>  {
>>      my ($v, $r) = @_;
>>
> 
> I seem to be confused a bit at times: so in this checktype the return
> value of the function is 1 for non-failed health check and activated
> service and 0 otherwise? How about introducing enums {SERVICE_UP,
> SERVICE_DOWN} for legibility?
> 

Return value of the function is irrelevant, as we only call
check_external($v, $r); and don't do anything with the return value.
Service is activated/deactivated by the &service_set($v, $r, "up"); call.

Jaro

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