BUG/MEDIUM: fd: HUP is an error only when write is active

William reported that since commit 6b3089856f ("MEDIUM: fd: do not use
the FD_POLL_* flags in the pollers anymore") the master's CLI often
fails to access sub-processes. There are two causes to this. One is
that we did report FD_POLL_ERR on an FD as soon as FD_EV_SHUT_W was
seen, which is automatically inherited from POLLHUP. And since we do
not store the current shutdown state of an FD we can't know if the
poller reports a sudden close resulting from an error or just a
byproduct of a previous shutdown(WR) followed by a read0. The current
patch addresses this by only considering this when the FD was active,
since a shutdown FD is not active. The second issue is that *somewhere*
down the chain, channel data are ignored if an error is reported on a
channel. This results in content truncation, but this cause was not
figured yet.

No backport is needed.
This commit is contained in:
Willy Tarreau 2019-10-01 11:46:40 +02:00
parent 93e548ea26
commit 2aaeee34da

View File

@ -333,10 +333,13 @@ static inline void fd_update_events(int fd, unsigned char evts)
((evts & FD_EV_READY_R) ? FD_POLL_IN : 0) | ((evts & FD_EV_READY_R) ? FD_POLL_IN : 0) |
((evts & FD_EV_READY_W) ? FD_POLL_OUT : 0) | ((evts & FD_EV_READY_W) ? FD_POLL_OUT : 0) |
((evts & FD_EV_SHUT_R) ? FD_POLL_HUP : 0) | ((evts & FD_EV_SHUT_R) ? FD_POLL_HUP : 0) |
((evts & FD_EV_SHUT_W) ? FD_POLL_ERR : 0) |
((evts & FD_EV_ERR_R) ? FD_POLL_ERR : 0) | ((evts & FD_EV_ERR_R) ? FD_POLL_ERR : 0) |
((evts & FD_EV_ERR_W) ? FD_POLL_ERR : 0); ((evts & FD_EV_ERR_W) ? FD_POLL_ERR : 0);
/* SHUTW reported while FD was active for writes is an error */
if ((fdtab[fd].ev & FD_EV_ACTIVE_W) && (evts & FD_EV_SHUT_W))
new_flags |= FD_POLL_ERR;
old = fdtab[fd].ev; old = fdtab[fd].ev;
new = (old & FD_POLL_STICKY) | new_flags; new = (old & FD_POLL_STICKY) | new_flags;