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

martin.quevedo at temiandu.com martin.quevedo at temiandu.com
Tue Oct 12 09:07:00 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 ?

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



More information about the pgpool-general mailing list