[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.bin>
More information about the pgpool-general
mailing list