Fix bug in RecvMMsgDispatcher.

Fixed a bug introduced in the following commit:
https://github.com/google/gvisor/commit/979d6e7d77b17e94defc29515180cc75d3560383

The commit introduced a bug which causes the recvmmsg dispatcher to never exit
as BlockingPoll is now called with two fds and poll will not return an error
anymore if one of the FD is closed. We need to explicitly check the events for
each FD to determine if the sentry FD is closed.

ReadV dispatcher does not have the same issue as Readv does not rely on sk_err
field of the underlying socket to determine if the socket is in an error
state. Recvmmsg OTOH seems to get confused and always returns EAGAIN if poll()
is called which queries the sk_err field and clears it.

PiperOrigin-RevId: 396676135
This commit is contained in:
Bhasker Hariharan
2021-09-14 14:09:09 -07:00
committed by gVisor bot
parent 5593b8a7e6
commit 603f473ada
3 changed files with 17 additions and 3 deletions
+1 -1
View File
@@ -27,7 +27,7 @@ TEXT ·BlockingPoll(SB),NOSPLIT,$0-40
MOVQ $0x0, R10 // sigmask parameter which isn't used here
MOVQ $0x10f, AX // SYS_PPOLL
SYSCALL
CMPQ AX, $0xfffffffffffff001
CMPQ AX, $0xfffffffffffff002
JLS ok
MOVQ $-1, n+24(FP)
NEGQ AX
+1 -1
View File
@@ -27,7 +27,7 @@ TEXT ·BlockingPoll(SB),NOSPLIT,$0-40
MOVD $0x0, R3 // sigmask parameter which isn't used here
MOVD $0x49, R8 // SYS_PPOLL
SVC
CMP $0xfffffffffffff001, R0
CMP $0xfffffffffffff002, R0
BLS ok
MOVD $-1, R1
MOVD R1, n+24(FP)
+15 -1
View File
@@ -181,7 +181,9 @@ func BlockingReadvUntilStopped(efd int, fd int, iovecs []unix.Iovec) (int, tcpip
if e == 0 {
return int(n), nil
}
if e != 0 && e != unix.EWOULDBLOCK {
return 0, TranslateErrno(e)
}
stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN)
if stopped {
return -1, nil
@@ -204,6 +206,10 @@ func BlockingRecvMMsgUntilStopped(efd int, fd int, msgHdrs []MMsgHdr) (int, tcpi
return int(n), nil
}
if e != 0 && e != unix.EWOULDBLOCK {
return 0, TranslateErrno(e)
}
stopped, e := BlockingPollUntilStopped(efd, fd, unix.POLLIN)
if stopped {
return -1, nil
@@ -228,5 +234,13 @@ func BlockingPollUntilStopped(efd int, fd int, events int16) (bool, unix.Errno)
},
}
_, errno := BlockingPoll(&pevents[0], len(pevents), nil)
if errno != 0 {
return pevents[0].Revents&unix.POLLIN != 0, errno
}
if pevents[1].Revents&unix.POLLHUP != 0 || pevents[1].Revents&unix.POLLERR != 0 {
errno = unix.ECONNRESET
}
return pevents[0].Revents&unix.POLLIN != 0, errno
}