[pgpool-general: 7766] Re: problem connecting to backend

Tatsuo Ishii ishii at sraoss.co.jp
Tue Oct 12 09:42:52 JST 2021


> Dear Tatsuo,
> 
> I was able to narrow it down
> errno = 0 in file src/utils/psprintf.c is causing my problem
> 
> size_t
> pvsnprintf(char *buf, size_t len, const char *fmt, va_list args)
> {
>         int                     nprinted;
> 
>         Assert(len > 0);
>         //errno = 0;
> 
> Shouldn't you save errno in that function and restore it on return instead
> of setting it to zero ?

Good catch! You are absolutely right. Can you please review attached patch?

> Regards,
> Martin 
> 
> 
> 
> -----Original Message-----
> From: Tatsuo Ishii <ishii at sraoss.co.jp> 
> Sent: Monday, October 11, 2021 1:27 AM
> To: martin.quevedo at temiandu.com
> Cc: pgpool-general at pgpool.net
> Subject: Re: [pgpool-general: 7756] problem connecting to backend
> 
> Hi Martin,
> 
>> Hello all,
>> 
>> 
>> 
>> I was experiencing problems connecting to my PG backends
>> 
>> I started debugging and I found, in 
>> *src/protocol/pool_connection_pool.c*,
>> the following
>> 
>> 
>> 
>> In function *connect_with_timeout*, after *if (connect(fd, 
>> walk->ai_addr,
>> walk->ai_addrlen) < 0)*
>> 
>> The errno variable was quickly set to zero
>> 
>> I was getting the value *EINPROGRESS*, but by the time the following 
>> code was executed,
>> 
>> 
>> 
>> *if ((errno != EINPROGRESS) && (errno != EALREADY))*
>> 
>> *                        {.}*
>> 
>> 
>> 
>> *errno* was already zero
>> 
>> 
>> 
>> So, I assigned *errno* to a *int error* variable and used that one 
>> instead of *errno*, which solved the problem
>> 
>> 
>> 
>> Any ideas why *errno* can change to zero between the connect() call 
>> and the *if ((errno != EINPROGRESS) && (errno != EALREADY))* line?
> 
> One possibility is an interruption by a signal. When a signal arrives to the
> pgpool process, a signal handler is called. If the signal handler resets
> errno inside, you will see the errno is set to 0.  I though all signal
> handlers save the errno before processing the code in the signal handler,
> but I found questionable signal handler:
> 
> static RETSIGTYPE die(int sig) in src/protocol/child.c.
> 
> saving errno is executed *after* POOL_SETMASK(&BlockSig) is called.
> POOL_SETMASK(&BlockSig) calls system calls inside, the errno could be set to
> 0. This is clealry wrong.  If my theory is correct, attached patch should
> fix the problem. Can you please try it out?
> 
>>                 if (connect(fd, walk->ai_addr, walk->ai_addrlen) < 0)
>> 
>>                 {
>> 
>>                         int errno2 = errno;
>> 
>>                         if (errno2 == EISCONN)
> 
> Unfortunately this will not fix the problem because of possible window.
> What if errno is set before this?
> 
>>                         int errno2 = errno;
> --
> Tatsuo Ishii
> SRA OSS, Inc. Japan
> English: http://www.sraoss.co.jp/index_en.php
> Japanese:http://www.sraoss.co.jp
> 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: fix_smash_errno.diff
Type: text/x-patch
Size: 1796 bytes
Desc: not available
URL: <http://www.pgpool.net/pipermail/pgpool-general/attachments/20211012/8cb30232/attachment-0001.bin>


More information about the pgpool-general mailing list