From 5f6f71956460d6840c1433b59e20555268b622ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 31 May 2011 13:24:22 +0200 Subject: [PATCH] s3: Mark sockets in error state writable Without this patch, when a socket only has a write event pending, we will never detect an error condition. I've seen winbind doing 12:19:13.659964 gettimeofday({1306837153, 659984}, NULL) = 0 <0.000016> 12:19:13.660109 poll([{fd=35, events=POLLOUT}, {fd=32, events=POLLIN|POLLHUP}], 2, 9996) = 1 ([{fd=35, revents=POLLERR|POLLHUP}]) <0.000015> 12:19:13.660253 gettimeofday({1306837153, 660269}, NULL) = 0 <0.000013> 12:19:13.660298 poll([{fd=35, events=POLLOUT}, {fd=32, events=POLLIN|POLLHUP}], 2, 9996) = 1 ([{fd=35, revents=POLLERR|POLLHUP}]) <0.000015> for a while when trying to connect to a DC when the socket had died already. Volker Autobuild-User: Volker Lendecke Autobuild-Date: Tue May 31 20:59:10 CEST 2011 on sn-devel-104 --- source3/lib/events.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/source3/lib/events.c b/source3/lib/events.c index 9ff14880ecd..499d92edd2c 100644 --- a/source3/lib/events.c +++ b/source3/lib/events.c @@ -260,6 +260,29 @@ bool run_events_poll(struct tevent_context *ev, int pollrtn, if (pfd->revents & (POLLIN|POLLHUP|POLLERR)) { flags |= EVENT_FD_READ; + + if ((fde->flags & EVENT_FD_READ) == 0) { + /* + * This one is a bit subtle. If a socket is + * not being asked for readability and dies + * with POLLHUP|POLLERR, then the write + * handler must be activated to detect the + * dead socket with a failed write(2) + * call. The error I've seen is winbind + * spinning in poll trying to send something + * to a DC on a dead socket. poll gave + * POLLHUP|POLLERR, but because winbind at + * this moment only had asked for socket + * writability, it spun. + * + * We can't activate EVENT_FD_WRITE though + * whenever we have an error condition via + * POLLHUP|POLLERR, because at least smbd + * monitors EVENT_FD_WRITE in its callback, + * doing nothing. + */ + flags |= EVENT_FD_WRITE; + } } if (pfd->revents & POLLOUT) { flags |= EVENT_FD_WRITE; -- 2.11.4.GIT