This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[ping2][PATCH v2][BZ #15339] Avoid returning EAI_SYSTEM when there's a network error
- From: Siddhesh Poyarekar <siddhesh at redhat dot com>
- To: libc-alpha at sourceware dot org
- Date: Mon, 22 Apr 2013 10:32:26 +0530
- Subject: [ping2][PATCH v2][BZ #15339] Avoid returning EAI_SYSTEM when there's a network error
- References: <20130401171156 dot GB9522 at altlinux dot org> <CAAHN_R1yThAuKHrr4cePcmrVo_=vHLf9257OGFsE6v3Oc36s4Q at mail dot gmail dot com> <20130402134937 dot GB3211 at altlinux dot org> <20130408033614 dot GA20503 at altlinux dot org> <20130408052713 dot GB32556 at spoyarek dot pnq dot redhat dot com> <20130408055825 dot GA21873 at altlinux dot org> <20130408063238 dot GG32556 at spoyarek dot pnq dot redhat dot com> <20130408174239 dot GA26714 at altlinux dot org> <20130409113848 dot GL15689 at spoyarek dot pnq dot redhat dot com> <20130415120657 dot GG14422 at spoyarek dot pnq dot redhat dot com>
Ping!
On Mon, Apr 15, 2013 at 05:36:58PM +0530, Siddhesh Poyarekar wrote:
> Ping. I'm looking for an additional review of this code since it's a
> bit tricky and I want to be sure I'm not leaving any open gaps.
>
> Thanks,
> Siddhesh
>
> On Tue, Apr 09, 2013 at 05:08:49PM +0530, Siddhesh Poyarekar wrote:
> > On Mon, Apr 08, 2013 at 09:42:39PM +0400, Dmitry V. Levin wrote:
> > > The configuration is essentially a bare chroot without additional
> > > configuration, the kernel is 3.8.6. send_dg doesn't call sendmmsg because
> > > of buf2 == NULL.
> >
> > Aha, so it's AF_INET and not AF_UNSPEC like your original reproducer
> > suggested. Here's an updated patch for 15339. The major difference
> > here is that I had incorrectly concluded that NSS_STATUS_UNAVAIL
> > equals to an internal failure. It's only an internal failure if none
> > of the services were usable and in that case too, only when the
> > failure was due to something other than not being able to find the nss
> > module. The latter case is implied if NSS_STATUS_UNAVAIL is returned
> > as is along with h_errno as NO_RECOVERY.
> >
> > Siddhesh
> >
> > [BZ #15339]
> > * nss/getXXbyYY_r.c (REENTRANT_NAME): Set NETDB_INTERNAL only
> > when no services were used.
> > * sysdeps/posix/getaddrinfo.c (gaih_inet): Set h_errno.
> > Return EAI_SYSTEM if h_errno is NETDB_INTERNAL.
> >
> > diff --git a/nss/getXXbyYY_r.c b/nss/getXXbyYY_r.c
> > index 1067744..9e4d110 100644
> > --- a/nss/getXXbyYY_r.c
> > +++ b/nss/getXXbyYY_r.c
> > @@ -284,11 +284,11 @@ done:
> > #endif
> > *result = status == NSS_STATUS_SUCCESS ? resbuf : NULL;
> > #ifdef NEED_H_ERRNO
> > - if (status == NSS_STATUS_UNAVAIL)
> > - /* Either we failed to lookup the functions or the functions themselves
> > - had a system error. Set NETDB_INTERNAL here to let the caller know
> > - that the errno may have the real reason for failure. */
> > - *h_errnop = NETDB_INTERNAL;
> > + if (status == NSS_STATUS_UNAVAIL && !any_service && errno != ENOENT)
> > + /* This happens when we weren't able to use a service for reasons other
> > + than the module not being found. In such a case, we'd want to tell the
> > + caller that errno has the real reason for failure. */
> > + *h_errnop = NETDB_INTERNAL;
> > else if (status != NSS_STATUS_SUCCESS && !any_service)
> > /* We were not able to use any service. */
> > *h_errnop = NO_RECOVERY;
> > diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
> > index 2309281..2928537 100644
> > --- a/sysdeps/posix/getaddrinfo.c
> > +++ b/sysdeps/posix/getaddrinfo.c
> > @@ -1035,7 +1035,14 @@ gaih_inet (const char *name, const struct gaih_service *service,
> > }
> > }
> > else
> > - status = NSS_STATUS_UNAVAIL;
> > + {
> > + status = NSS_STATUS_UNAVAIL;
> > + /* Could not load any of the lookup functions. Indicate
> > + an internal error if the file was found but some other
> > + error led to the failure. */
> > + if (errno != ENOENT)
> > + __set_h_errno (NETDB_INTERNAL);
> > + }
> > }
> >
> > if (nss_next_action (nip, status) == NSS_ACTION_RETURN)
> > @@ -1049,7 +1056,7 @@ gaih_inet (const char *name, const struct gaih_service *service,
> >
> > _res.options |= old_res_options & RES_USE_INET6;
> >
> > - if (status == NSS_STATUS_UNAVAIL)
> > + if (h_errno == NETDB_INTERNAL)
> > {
> > result = GAIH_OKIFUNSPEC | -EAI_SYSTEM;
> > goto free_and_return;