s3: Mark sockets in error state writable
authorVolker Lendecke <vl@samba.org>
Tue, 31 May 2011 11:24:22 +0000 (13:24 +0200)
committerVolker Lendecke <vlendec@samba.org>
Tue, 31 May 2011 18:59:10 +0000 (20:59 +0200)
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 <vlendec@samba.org>
Autobuild-Date: Tue May 31 20:59:10 CEST 2011 on sn-devel-104

source3/lib/events.c

index 9ff14880ecdbeefa968097086e22f2d6b6c51d85..499d92edd2c5a9b88fa572f6db6d860b7744f081 100644 (file)
@@ -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;