Commit c4a10ad5 authored by Jacek Kalwas's avatar Jacek Kalwas Committed by Tomasz Zawadzki
Browse files

sock: reorder err checks in spdk_sock_posix_fd_connect



Lack of POLLOUT indicates an error but there is no hint about potential
reason hence reorder checks to to have SO_ERROR check first.

Note this is not clearly described as allowed by connect() man page.

       EINPROGRESS
              The socket is nonblocking and the connection cannot be
              completed immediately.  (UNIX domain sockets failed with
              EAGAIN instead.)  It is possible to select(2) or poll(2)
              for completion by selecting the socket for writing.  After
              select(2) indicates writability, use getsockopt(2) to read
              the SO_ERROR option at level SOL_SOCKET to determine
              whether connect() completed successfully (SO_ERROR is zero)
              or unsuccessfully (SO_ERROR is one of the usual error codes
              listed here, explaining the reason for the failure).

However, it is experimentally proven that in case of target being
unreachable only POLLERR event can be returned and with SO_ERROR check
we get 113 (EHOSTUNREACH) as a valuable hint.

Change-Id: I1a59af52415dc34efa819007d56738a149d9df0c
Signed-off-by: default avatarJacek Kalwas <jacek.kalwas@nutanix.com>
Reviewed-on: https://review.spdk.io/c/spdk/spdk/+/25953


Reviewed-by: default avatarTomasz Zawadzki <tomasz@tzawadzki.com>
Community-CI: Mellanox Build Bot
Reviewed-by: default avatarBen Walker <ben@nvidia.com>
Community-CI: Broadcom CI <spdk-ci.pdl@broadcom.com>
Tested-by: default avatarSPDK Automated Test System <spdkbot@gmail.com>
Reviewed-by: default avatarAleksey Marchuk <alexeymar@nvidia.com>
parent b62dbc01
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -523,13 +523,6 @@ spdk_sock_posix_fd_connect(int fd, struct addrinfo *res, struct spdk_sock_opts *
		return -1;
	}

	if (!(pfd.revents & POLLOUT)) {
		SPDK_ERRLOG("poll() returned %d event(s) %s%s%sbut not POLLOUT\n", rc,
			    pfd.revents & POLLERR ? "POLLERR, " : "", pfd.revents & POLLHUP ? "POLLHUP, " : "",
			    pfd.revents & POLLNVAL ? "POLLNVAL, " : "");
		return -1;
	}

	rc = getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &len);
	if (rc != 0) {
		SPDK_ERRLOG("getsockopt() failed, errno = %d\n", errno);
@@ -541,6 +534,13 @@ spdk_sock_posix_fd_connect(int fd, struct addrinfo *res, struct spdk_sock_opts *
		return 1;
	}

	if (!(pfd.revents & POLLOUT)) {
		SPDK_ERRLOG("poll() returned %d event(s) %s%s%sbut not POLLOUT\n", rc,
			    pfd.revents & POLLERR ? "POLLERR, " : "", pfd.revents & POLLHUP ? "POLLHUP, " : "",
			    pfd.revents & POLLNVAL ? "POLLNVAL, " : "");
		return -1;
	}

	if (spdk_fd_clear_nonblock(fd)) {
		return -1;
	}