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