mirror of
https://github.com/valkey-io/valkey.git
synced 2026-05-06 05:26:42 -04:00
Set errno on EOF in syncRead and propagate it in logs (#3580)
When read() returns 0 (EOF/connection closed) in syncRead(), errno is not set by POSIX, so it retains a stale value (typically 0). This causes callers using connGetLastError() to log strerror(0) which is the misleading string "Success". Set errno = ECONNRESET on EOF in syncRead(), matching the existing pattern used for the timeout case (errno = ETIMEDOUT). Also set conn->last_errno = errno in connSocketSyncWrite, connSocketSyncRead, and connSocketSyncReadLine wrappers, matching the pattern used by their async counterparts connSocketWrite and connSocketRead. After this fix, replica logs will show: "I/O error reading bulk count from PRIMARY: Connection reset by peer" instead of the misleading: "I/O error reading bulk count from PRIMARY: Success" --------- Signed-off-by: Abhishek Mathur <matshek@amazon.com> Signed-off-by: djk1027 <djk9510271@gmail.com> Co-authored-by: Abhishek Mathur <matshek@amazon.com> Co-authored-by: Daejun Kim <djk9510271@gmail.com> Co-authored-by: Madelyn Olson <madelyneolson@gmail.com>
This commit is contained in:
+15
-3
@@ -391,15 +391,27 @@ static int connSocketBlockingConnect(connection *conn, const char *addr, int por
|
||||
*/
|
||||
|
||||
static ssize_t connSocketSyncWrite(connection *conn, char *ptr, ssize_t size, long long timeout) {
|
||||
return syncWrite(conn->fd, ptr, size, timeout);
|
||||
ssize_t ret = syncWrite(conn->fd, ptr, size, timeout);
|
||||
if (ret == -1) {
|
||||
conn->last_errno = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t connSocketSyncRead(connection *conn, char *ptr, ssize_t size, long long timeout) {
|
||||
return syncRead(conn->fd, ptr, size, timeout);
|
||||
ssize_t ret = syncRead(conn->fd, ptr, size, timeout);
|
||||
if (ret == -1) {
|
||||
conn->last_errno = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t connSocketSyncReadLine(connection *conn, char *ptr, ssize_t size, long long timeout) {
|
||||
return syncReadLine(conn->fd, ptr, size, timeout);
|
||||
ssize_t ret = syncReadLine(conn->fd, ptr, size, timeout);
|
||||
if (ret == -1) {
|
||||
conn->last_errno = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int connSocketGetType(void) {
|
||||
|
||||
+4
-1
@@ -94,7 +94,10 @@ ssize_t syncRead(int fd, char *ptr, ssize_t size, long long timeout) {
|
||||
/* Optimistically try to read before checking if the file descriptor
|
||||
* is actually readable. At worst we get EAGAIN. */
|
||||
nread = read(fd, ptr, size);
|
||||
if (nread == 0) return -1; /* short read. */
|
||||
if (nread == 0) {
|
||||
errno = ECONNRESET;
|
||||
return -1;
|
||||
}
|
||||
if (nread == -1) {
|
||||
if (errno != EAGAIN) return -1;
|
||||
} else {
|
||||
|
||||
@@ -1775,6 +1775,9 @@ static ssize_t connTLSSyncWrite(connection *conn_, char *ptr, ssize_t size, long
|
||||
unsetBlockingTimeout(conn);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
conn->c.last_errno = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1790,6 +1793,9 @@ static ssize_t connTLSSyncRead(connection *conn_, char *ptr, ssize_t size, long
|
||||
unsetBlockingTimeout(conn);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
conn->c.last_errno = errno;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1827,6 +1833,9 @@ exit:
|
||||
if (!blocking) {
|
||||
unsetBlockingTimeout(conn);
|
||||
}
|
||||
if (nread < 0) {
|
||||
conn->c.last_errno = errno;
|
||||
}
|
||||
return nread;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user