2.2.3 winbindd and signal processing

Michael Steffens michael_steffens at hp.com
Tue Jan 29 09:59:03 GMT 2002


Hi,

in current CVS 2.2.3 winbindd versions there is a problem
with signal processing. As the signal handlers are all
being registered with SA_RESTART by CatchSignal(), signals
sent to winbindd will not make its call to select() return.

On Linux this seems to work, anyway (maybe SA_RESTART is
ignored there?), but not so on HP-UX. And maybe also not
on other Unices?

So for shutting down winbindd cleanly one has to signal first,
and then trigger the actual termination with a failing request,
for example via wbinfo. :-)

Why not using the sys_select mechanism used everywhere else
in Samba also for winbindd? Unfortunately, the sys_select()
function does not replace the original completely, as it
omits writefds and errorfds parameters. And writefds is
required by winbindd...

Attached is a patch which extends sys_select() and
sys_select_intr() to accept all arguments select() does,
and adjusts all callers to pass NULL for writefds and
errorfds. In winbindd.c select() is replaced by sys_select().

This seems to run properly, here. What do you think about it?

Cheers!
Michael
-------------- next part --------------
diff -ur orig/samba/source/client/client.c samba/source/client/client.c
--- orig/samba/source/client/client.c	Tue Jan 29 14:29:13 2002
+++ samba/source/client/client.c	Tue Jan 29 14:48:47 2002
@@ -2083,7 +2083,7 @@
 
 	timeout.tv_sec = 0;
 	timeout.tv_usec = 0;
-	sys_select_intr(cli->fd+1,&fds,&timeout);
+	sys_select_intr(cli->fd+1,&fds,NULL,NULL,&timeout);
       		
 	/* We deliberately use receive_smb instead of
 	   client_receive_smb as we want to receive
diff -ur orig/samba/source/include/proto.h samba/source/include/proto.h
--- orig/samba/source/include/proto.h	Tue Jan 29 14:29:14 2002
+++ samba/source/include/proto.h	Tue Jan 29 15:07:16 2002
@@ -156,8 +156,8 @@
 /*The following definitions come from  lib/select.c  */
 
 void sys_select_signal(void);
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval);
-int sys_select_intr(int maxfd, fd_set *fds,struct timeval *tval);
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval);
 
 /*The following definitions come from  lib/signal.c  */
 
diff -ur orig/samba/source/lib/readline.c samba/source/lib/readline.c
--- orig/samba/source/lib/readline.c	Tue Jan 29 14:29:14 2002
+++ samba/source/lib/readline.c	Tue Jan 29 14:56:09 2002
@@ -67,7 +67,7 @@
 			FD_ZERO(&fds);
 			FD_SET(fd,&fds);
 	
-			if (sys_select_intr(fd+1,&fds,&timeout) == 1) {
+			if (sys_select_intr(fd+1,&fds,NULL,NULL,&timeout) == 1) {
 				ret = fgets(line, sizeof(line), stdin);
 				return ret;
 			}
diff -ur orig/samba/source/lib/select.c samba/source/lib/select.c
--- orig/samba/source/lib/select.c	Tue Jan 29 14:29:14 2002
+++ samba/source/lib/select.c	Tue Jan 29 17:55:41 2002
@@ -52,9 +52,10 @@
 it also guuarantees that fds on return only ever contains bits set
 for file descriptors that were readable
 ********************************************************************/
-int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
+int sys_select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
 {
 	int ret, saved_errno;
+	fd_set *readfds2, readfds_buf;
 
 	if (initialised != sys_getpid()) {
 		pipe(select_pipe);
@@ -77,16 +78,25 @@
 	}
 
 	maxfd = MAX(select_pipe[0]+1, maxfd);
-	FD_SET(select_pipe[0], fds);
+	/* If readfds is NULL we need to provide our own set. */
+	if (readfds) {
+		readfds2 = readfds;
+	} else {
+		readfds2 = &readfds_buf;
+		FD_ZERO(readfds2);
+	}
+	FD_SET(select_pipe[0], readfds2);
 	errno = 0;
-	ret = select(maxfd,fds,NULL,NULL,tval);
+	ret = select(maxfd,readfds2,writefds,errorfds,tval);
 
 	if (ret <= 0) {
-		FD_ZERO(fds);
+		FD_ZERO(readfds2);
+		if (writefds) FD_ZERO(writefds);
+		if (errorfds) FD_ZERO(errorfds);
 	}
 
-	if (FD_ISSET(select_pipe[0], fds)) {
-		FD_CLR(select_pipe[0], fds);
+	if (FD_ISSET(select_pipe[0], readfds2)) {
+		FD_CLR(select_pipe[0], readfds2);
 		ret--;
 		if (ret == 0) {
 			ret = -1;
@@ -113,17 +123,24 @@
 similar to sys_select() but catch EINTR and continue
 this is what sys_select() used to do in Samba
 ********************************************************************/
-int sys_select_intr(int maxfd, fd_set *fds,struct timeval *tval)
+int sys_select_intr(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *errorfds, struct timeval *tval)
 {
 	int ret;
-	fd_set fds2;
+	fd_set *readfds2, readfds_buf, *writefds2, writefds_buf, *errorfds2, errorfds_buf;
 
+	readfds2 = (readfds ? &readfds_buf : NULL);
+	writefds2 = (writefds ? &writefds_buf : NULL);
+	errorfds2 = (errorfds ? &errorfds_buf : NULL);
 	do {
-		fds2 = *fds;
-		ret = sys_select(maxfd, &fds2, tval);
+		if (readfds) readfds_buf = *readfds;
+		if (writefds) writefds_buf = *writefds;
+		if (errorfds) errorfds_buf = *errorfds;
+		ret = sys_select(maxfd, readfds2, writefds2, errorfds2, tval);
 	} while (ret == -1 && errno == EINTR);
 
-	*fds = fds2;
+	if (readfds) *readfds = readfds_buf;
+	if (writefds) *writefds = writefds_buf;
+        if (errorfds) *errorfds = errorfds_buf;
 
 	return ret;
 }
diff -ur orig/samba/source/lib/util.c samba/source/lib/util.c
--- orig/samba/source/lib/util.c	Tue Jan 29 14:29:14 2002
+++ samba/source/lib/util.c	Tue Jan 29 14:55:32 2002
@@ -589,7 +589,7 @@
  
 		FD_ZERO(&fds);
 		errno = 0;
-		sys_select_intr(0,&fds,&tval);
+		sys_select_intr(0,&fds,NULL,NULL,&tval);
 
 		GetTimeOfDay(&t2);
 		tdiff = TvalDiff(&t1,&t2);
diff -ur orig/samba/source/lib/util_sock.c samba/source/lib/util_sock.c
--- orig/samba/source/lib/util_sock.c	Tue Jan 29 14:29:14 2002
+++ samba/source/lib/util_sock.c	Tue Jan 29 14:57:46 2002
@@ -259,7 +259,7 @@
     FD_ZERO(&fds);
     FD_SET(fd,&fds);
       
-    selrtn = sys_select_intr(fd+1,&fds,&timeout);
+    selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
 
     /* Check if error */
     if(selrtn == -1) {
@@ -363,7 +363,7 @@
     FD_ZERO(&fds);
     FD_SET(fd,&fds);
       
-    selrtn = sys_select_intr(fd+1,&fds,&timeout);
+    selrtn = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout);
 
     if(selrtn <= 0)
       return selrtn;
diff -ur orig/samba/source/libsmb/nmblib.c samba/source/libsmb/nmblib.c
--- orig/samba/source/libsmb/nmblib.c	Tue Jan 29 14:29:14 2002
+++ samba/source/libsmb/nmblib.c	Tue Jan 29 14:58:40 2002
@@ -955,7 +955,7 @@
 	timeout.tv_sec = t/1000;
 	timeout.tv_usec = 1000*(t%1000);
 
-	if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) {
+	if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) {
 		/* errno should be EBADF or EINVAL. */
 		DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno));
 		return NULL;
diff -ur orig/samba/source/nmbd/nmbd_packets.c samba/source/nmbd/nmbd_packets.c
--- orig/samba/source/nmbd/nmbd_packets.c	Tue Jan 29 14:29:14 2002
+++ samba/source/nmbd/nmbd_packets.c	Tue Jan 29 14:59:27 2002
@@ -1818,7 +1818,7 @@
 
   BlockSignals(False, SIGTERM);
 
-  selrtn = sys_select(FD_SETSIZE,&fds,&timeout);
+  selrtn = sys_select(FD_SETSIZE,&fds,NULL,NULL,&timeout);
 
   /* We can only take signals when we are in the select - block them again here. */
 
diff -ur orig/samba/source/nsswitch/winbindd.c samba/source/nsswitch/winbindd.c
--- orig/samba/source/nsswitch/winbindd.c	Tue Jan 22 12:44:33 2002
+++ samba/source/nsswitch/winbindd.c	Tue Jan 29 17:52:36 2002
@@ -172,6 +172,7 @@
 static void termination_handler(int signum)
 {
 	do_sigterm = True;
+	sys_select_signal();
 }
 
 static BOOL do_sigusr1;
@@ -179,6 +180,7 @@
 static void sigusr1_handler(int signum)
 {
 	do_sigusr1 = True;
+	sys_select_signal();
 }
 
 static BOOL do_sighup;
@@ -186,6 +188,7 @@
 static void sighup_handler(int signum)
 {
 	do_sighup = True;
+	sys_select_signal();
 }
 
 /* Create winbindd socket */
@@ -639,7 +642,7 @@
 
 		/* Call select */
         
-		selret = select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
+		selret = sys_select(maxfd + 1, &r_fds, &w_fds, NULL, &timeout);
 
 		if (selret == 0)
 			continue;
diff -ur orig/samba/source/smbd/oplock.c samba/source/smbd/oplock.c
--- orig/samba/source/smbd/oplock.c	Tue Jan 29 14:29:20 2002
+++ samba/source/smbd/oplock.c	Tue Jan 29 15:00:45 2002
@@ -94,7 +94,7 @@
 		to.tv_sec = timeout / 1000;
 		to.tv_usec = (timeout % 1000) * 1000;
 
-		selrtn = sys_select(maxfd+1,fds,&to);
+		selrtn = sys_select(maxfd+1,fds,NULL,NULL,&to);
 
 		if (selrtn == -1 && errno == EINTR) {
 			/* could be a kernel oplock interrupt */
diff -ur orig/samba/source/smbd/process.c samba/source/smbd/process.c
--- orig/samba/source/smbd/process.c	Tue Jan 29 14:29:20 2002
+++ samba/source/smbd/process.c	Tue Jan 29 15:01:43 2002
@@ -197,7 +197,7 @@
 	to.tv_sec = timeout / 1000;
 	to.tv_usec = (timeout % 1000) * 1000;
 
-	selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,timeout>0?&to:NULL);
+	selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,timeout>0?&to:NULL);
 
 	/* if we get EINTR then maybe we have received an oplock
 	   signal - treat this as select returning 1. This is ugly, but
diff -ur orig/samba/source/smbd/server.c samba/source/smbd/server.c
--- orig/samba/source/smbd/server.c	Tue Jan 29 14:29:20 2002
+++ samba/source/smbd/server.c	Tue Jan 29 15:02:24 2002
@@ -209,7 +209,7 @@
 		memcpy((char *)&lfds, (char *)&listen_set, 
 		       sizeof(listen_set));
 		
-		num = sys_select(FD_SETSIZE,&lfds,NULL);
+		num = sys_select(FD_SETSIZE,&lfds,NULL,NULL,NULL);
 		
 		if (num == -1 && errno == EINTR) {
 			extern VOLATILE sig_atomic_t reload_after_sighup;
diff -ur orig/samba/source/utils/smbfilter.c samba/source/utils/smbfilter.c
--- orig/samba/source/utils/smbfilter.c	Tue Jan 29 14:29:20 2002
+++ samba/source/utils/smbfilter.c	Tue Jan 29 15:03:36 2002
@@ -118,7 +118,7 @@
 		if (s != -1) FD_SET(s, &fds);
 		if (c != -1) FD_SET(c, &fds);
 
-		num = sys_select_intr(MAX(s+1, c+1),&fds,NULL);
+		num = sys_select_intr(MAX(s+1, c+1),&fds,NULL,NULL,NULL);
 		if (num <= 0) continue;
 		
 		if (c != -1 && FD_ISSET(c, &fds)) {
@@ -182,7 +182,7 @@
 		FD_ZERO(&fds);
 		FD_SET(s, &fds);
 
-		num = sys_select_intr(s+1,&fds,NULL);
+		num = sys_select_intr(s+1,&fds,NULL,NULL,NULL);
 		if (num > 0) {
 			c = accept(s, &addr, &in_addrlen);
 			if (c != -1) {


More information about the samba-technical mailing list