socket: preserve real errno when socket/bind calls fail

When reporting socket/bind failures we want to ensure any fatal error
reported is as accurate as possible. We'll prefer reporting a bind()
errno over a socket() errno, because if socket() works but bind() fails
that is a more significant event.

Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2018-07-24 15:12:15 +01:00
parent 55ce656463
commit f56eb726b1
1 changed files with 11 additions and 12 deletions

View File

@ -310,8 +310,8 @@ int virNetSocketNewListenTCP(const char *nodename,
struct addrinfo hints; struct addrinfo hints;
int fd = -1; int fd = -1;
size_t i; size_t i;
bool addrInUse = false; int socketErrno = 0;
bool familyNotSupported = false; int bindErrno = 0;
virSocketAddr tmp_addr; virSocketAddr tmp_addr;
*retsocks = NULL; *retsocks = NULL;
@ -351,7 +351,7 @@ int virNetSocketNewListenTCP(const char *nodename,
if ((fd = socket(runp->ai_family, runp->ai_socktype, if ((fd = socket(runp->ai_family, runp->ai_socktype,
runp->ai_protocol)) < 0) { runp->ai_protocol)) < 0) {
if (errno == EAFNOSUPPORT) { if (errno == EAFNOSUPPORT) {
familyNotSupported = true; socketErrno = errno;
runp = runp->ai_next; runp = runp->ai_next;
continue; continue;
} }
@ -386,7 +386,7 @@ int virNetSocketNewListenTCP(const char *nodename,
virReportSystemError(errno, "%s", _("Unable to bind to port")); virReportSystemError(errno, "%s", _("Unable to bind to port"));
goto error; goto error;
} }
addrInUse = true; bindErrno = errno;
VIR_FORCE_CLOSE(fd); VIR_FORCE_CLOSE(fd);
runp = runp->ai_next; runp = runp->ai_next;
continue; continue;
@ -409,14 +409,13 @@ int virNetSocketNewListenTCP(const char *nodename,
fd = -1; fd = -1;
} }
if (nsocks == 0 && familyNotSupported) { if (nsocks == 0) {
virReportSystemError(EAFNOSUPPORT, "%s", _("Unable to bind to port")); if (bindErrno)
goto error; virReportSystemError(bindErrno, "%s", _("Unable to bind to port"));
} else if (socketErrno)
virReportSystemError(socketErrno, "%s", _("Unable to create socket"));
if (nsocks == 0 && else
addrInUse) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No addresses to bind to"));
virReportSystemError(EADDRINUSE, "%s", _("Unable to bind to port"));
goto error; goto error;
} }