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

Martin Quevedo martin.quevedo at temiandu.com
Tue Oct 12 12:21:00 JST 2021


quick question

for this part of your patch

@@ -189,7 +196,10 @@ pvsnprintf(char *buf, size_t len, const char *fmt,
va_list args)
  }

  if (len >= MaxAllocSize / 2)
+ {
+ errno = save_errno;
  return MaxAllocSize;
+ }

  return len * 2;
 }

wouldnt it be better to do it like this?

@@ -189,7 +196,10 @@ pvsnprintf(char *buf, size_t len, const char *fmt,
va_list args)
  }

+ errno = save_errno;
  if (len >= MaxAllocSize / 2)
     return MaxAllocSize;

  return len * 2;
 }

in order to cover both returns ?

El lun, 11 de oct. de 2021 a la(s) 21:42, Tatsuo Ishii (ishii at sraoss.co.jp)
escribió:

> > 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 --------------
An HTML attachment was scrubbed...
URL: <http://www.pgpool.net/pipermail/pgpool-general/attachments/20211012/8a020190/attachment.htm>


More information about the pgpool-general mailing list