Bug 14078

Summary: pinger function in nanny.c in the piranha package
Product: [Retired] Red Hat High Availability Server Reporter: Jeremy Rumpf <jrumpf>
Component: piranhaAssignee: Phil Copeland <copeland>
Status: CLOSED ERRATA QA Contact: Phil Copeland <copeland>
Severity: medium Docs Contact:
Priority: medium    
Version: 1.0CC: jrumpf
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2000-07-18 15:43:14 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Red Hat Bugzilla 2000-07-16 19:03:14 UTC
I tried to get this on the piranha mailing list but couldn't get a response
from the server. I figured this would be the best alternative.

I'm posting this using the piranha source from the
piranha-0.4.16-2.src.rpm.

If you setup pulse in the lvs.cf file with a send statement and no expect
statement, example


virtual egovnetwww1 {
        address = XXX.XXX.XXX.XXX eth1:1
                                #external addy of
                                #the vserver
 
        active = 1
        load_monitor = rup
                                #Use rstatd to
                                #determine the load
 
        timeout = 20
                                #Seconds before
                                #a server is considered
                                #dead
 
        reentry = 40
                                #Seconds we wait when
                                #a server comes back
                                #online
 
        port = 80
                                #External/internal
                                #listening port
 
        protocol = tcp
                                #self explanitory
 
        scheduler = wlc
                                #Weighted least connection
 
         send = "\n"
        #expect = ""
                                #These are the test strings
                                #to be sent and recieved
                                #to determine if the
                                #service is alive
                                #These will default for http
		 
        persistent = 180
                                #Maintain a persistent
                                #connections for 180 seconds
 
        pmask = 255.255.255.255
 
                                #Actual physical server
                                #definitions follow        

etc, etc....

The pinger function will fail waiting for the expect string even though it
is not required.  This causes the removal of the server from the virtual
server. A simple fix is in order (though I am in now way an expert).

The original around line 340 of the nanny.c file is as follows:

    340        if (i) {
    341         if (expect_str) {
    342             read_len = strlen(expect_str);
    343             if (read_len >= sizeof(read_buf))
    344                 read_len = sizeof(read_buf) - 1;
    345
    346                 i = (int) read(connectSock, read_buf, read_len);
    347
    348             if (i >= 0) {
    349                 read_buf[i] = 0;
    350
    351                 if (flags & NANNY_FLAG_VERBOSE) {
    352                     piranha_log(flags,
    353                         (char *) "read expected len=%d,
text=\"%s\"",
    354                         strlen(expect_str), expect_str);
    355                     piranha_log(flags, (char *) "read got len=%d,
text=%s",
    356                         strlen(read_buf), read_buf);
    357           }
    358
    359                  if ((read_len == 1) && (*expect_str == '*')) {
    360                      read_buf[0] = '*';
    361                      read_buf[1] = 0;
    362                      i = 1;
    363                  } /* Wildcard */
    364
    365                  if (i >= read_len) {
    366                      if (strncmp((const char *) expect_str,
    367                                 (const char *) read_buf, read_len))
    368                         return_status = 1;
    369                 }
    370                 else
    371                     return_status = 1;
    372             }
    373             else
    374                 return_status = 1;
    375         }
    376     }
    377
    378         close(connectSock);
    379
    380         if (!i) {
    381         piranha_log(flags, (char *) "read from %s:%d timed out",
    382             inet_ntoa(*whereto), port);
    383             return_status = 1;
    384     }
    385
    386     return return_status;
    387 }                                           


Changed to:


    340         if (i) {
    341         if (expect_str) {
    342             read_len = strlen(expect_str);
    343             if (read_len >= sizeof(read_buf))
    344                 read_len = sizeof(read_buf) - 1;
    345
    346                 i = (int) read(connectSock, read_buf, read_len);
    347
    348             if (i >= 0) {
    349                 read_buf[i] = 0;
    350
    351                 if (flags & NANNY_FLAG_VERBOSE) {
    352                     piranha_log(flags,
    353                         (char *) "read expected len=%d,
text=\"%s\"",
    354                         strlen(expect_str), expect_str);
    355                     piranha_log(flags, (char *) "read got len=%d,
text=%s",
    356                         strlen(read_buf), read_buf);
    357                 }
    358
    359                  if ((read_len == 1) && (*expect_str == '*')) {
    360                      read_buf[0] = '*';
    361                      read_buf[1] = 0;
    362                      i = 1;
    363                  } /* Wildcard */
    364
    365                  if (i >= read_len) {
    366                      if (strncmp((const char *) expect_str,
    367                                 (const char *) read_buf, read_len))
    368                         return_status = 1;
    369                 }
    370                 else
    371                     return_status = 1;
    372             }
    373             else
    374                 return_status = 1;
    375         }
    376
    377
    378         if (!i) {
    379         piranha_log(flags, (char *) "read from %s:%d timed out",
    380             inet_ntoa(*whereto), port);
    381             return_status = 1;
    382       }
    383     }
    384
    385         close(connectSock);
    386     return return_status;
    387 }                          


Just put the test for the read time out within exect_string stanza and
place the close command before the return. It seems, it still waits for the
poll timeout but ignores everything since expect_str is NULL. 

I came across this trying to cluster some nonstandard servers (ie banner
servers) where the default HTTP request didn't apply. When trying to
override the default http send and expect strings manually in the lvs.cf
file nanny still reported read timeouts when the send was specified without
the expect. 

Hope this helps.....

jrumpf

Comment 1 Red Hat Bugzilla 2000-07-18 15:43:12 UTC
This problem has been found and new RPMs will be posted shortly
Thanks!

Comment 2 Red Hat Bugzilla 2000-07-25 16:24:16 UTC
This has been fixed and will be posted shortly. When the updated RPMs are
released, you will be able to download them from
http://people.redhat.com/kbarrett/HA/ , and they will be announced on
piranha-list.



Comment 3 Red Hat Bugzilla 2000-07-28 21:29:36 UTC
New RPMs have been posted. 0.4.16-3