s3: Fix starving the echo responder
authorVolker Lendecke <vl@samba.org>
Tue, 8 Jun 2010 12:33:05 +0000 (14:33 +0200)
committerVolker Lendecke <vl@samba.org>
Fri, 11 Jun 2010 08:40:11 +0000 (10:40 +0200)
When both the echo responder and the 445 socket want to send stuff to the
worker smbd, the select loop is not fair. It always chooses the smaller file
descriptor to work on. This can mean that on a busy system the echo responder
never gets around to feed its stuff to the parent.

This fix chooses the async echo responder socket when both the 445 and the echo
responder socket are readable.

Yes, it is a very hackish fix which is required *now* I think. The proper fix
would be to either assign priorities to fd's in tevent, or the from my point of
view better fix would be to make tevent kindof round-robin.

Round-robin would mean that whenever a fd has been dealt with, it is taken off
the list of interested sockets, and only if no other socket is active, all of
the ones waiting are put back. This is a bit like EPOLL_ONESHOT, which I would
like to use for this in the epoll case. Although, I need to do some research if
maybe epoll already guarantees round-robin, I did not find anything in the docs
yet.

Volker

source3/smbd/process.c

index e13d6fda1fff04dcbc8bc2587062513314365c82..57d91493bd024c38eb5a54edd2acaeea46666f5f 100644 (file)
@@ -879,6 +879,17 @@ static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *
                errno = sav;
        }
 
+        if ((conn->smb1.echo_handler.trusted_fd != -1)
+           && FD_ISSET(smbd_server_fd(), &r_fds)
+           && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
+               /*
+                * Prefer to read pending requests from the echo handler. To
+                * quote Jeremy (da70f8ab1): This is a hack of monstrous
+                * proportions...
+                */
+               FD_CLR(smbd_server_fd(), &r_fds);
+        }
+
        if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
                return NT_STATUS_RETRY;
        }