This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[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: Tue, 9 Apr 2013 17:08:49 +0530
- Subject: [PATCH v2][BZ #15339] Avoid returning EAI_SYSTEM when there's a network error
- References: <20130325125824 dot GA11387 at altlinux dot org> <CAAHN_R1OWczQtSFVHK3DVdqBg4+qKivxMoN_6gjfxxGiyzYO8A at mail dot gmail dot com> <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>
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;