The branch, v4-0-test has been updated via 5b9d192 s3: nmbd: Ensure the main nmbd process doesn't create zombies. via 7432a08 pthreadpool: Slightly serialize jobs via a163255 s3: lib: Signal handling - ensure smbrun and change password code save and restore existing SIGCHLD handlers. via 1dda86f lib: util: Signal handling - change CatchChild() and CatchChildLeaveStatus() to return the previous handler. from 6642684 s3: smb2cli: query info return length check was reversed.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v4-0-test - Log ----------------------------------------------------------------- commit 5b9d192548eeb1ab87d2490a2437b1f268b10538 Author: Jeremy Allison <j...@samba.org> Date: Tue Sep 23 13:32:37 2014 -0700 s3: nmbd: Ensure the main nmbd process doesn't create zombies. Use the same mechanism as setup for smbd and winbindd. Fixes bug #10830 - nmbd can leave unreaped zombies. https://bugzilla.samba.org/show_bug.cgi?id=10830 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Martin Schwenke <mar...@meltin.net> Autobuild-User(v4-0-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-0-test): Mon Oct 13 23:31:07 CEST 2014 on sn-devel-104 commit 7432a08575a48ed7f6bac5147d650660e991812d Author: Jeremy Allison <j...@samba.org> Date: Mon Aug 25 12:27:54 2014 -0700 pthreadpool: Slightly serialize jobs Using the new msg_source program with 1.500 instances against a single msg_sink I found the msg_source process to spawn two worker threads for synchronously sending the data towards the receiving socket. This should not happen: Per destination node we only create one queue. We strictly only add pthreadpool jobs one after the other, so a single helper thread should be perfectly sufficient. It turned out that under heavy overload the main sending thread was scheduled before the thread that just had finished its send() job. So the helper thread was not able to increment the pool->num_idle variable indicating that we don't have to create a new thread when the new job is added. This patch moves the signalling write under the mutex. This means that indicating readiness via the pipe and the pool->num_idle variable happen both under the same mutex lock and thus are atomic. No superfluous threads anymore. Back port of commit 1c4284c7395f23cefa61a407db74cf5067aee2aa that went into master. https://bugzilla.samba.org/show_bug.cgi?id=10779 Signed-off-by: Volker Lendecke <v...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit a16325505a43b06044520bcc0307a3af10a0a768 Author: Jeremy Allison <j...@samba.org> Date: Tue Sep 23 14:51:18 2014 -0700 s3: lib: Signal handling - ensure smbrun and change password code save and restore existing SIGCHLD handlers. Bug #10831 - SIGCLD Signal handler not correctly reinstalled on old library code use - smbrun etc. https://bugzilla.samba.org/show_bug.cgi?id=10831 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Martin Schwenke <mar...@meltin.net> commit 1dda86f32c9f1ad5c906a85596d062149693235e Author: Jeremy Allison <j...@samba.org> Date: Thu Oct 9 13:41:05 2014 -0700 lib: util: Signal handling - change CatchChild() and CatchChildLeaveStatus() to return the previous handler. Bug #10831 - SIGCLD Signal handler not correctly reinstalled on old library code use - smbrun etc. https://bugzilla.samba.org/show_bug.cgi?id=10831 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Martin Schwenke <mar...@meltin.net> ----------------------------------------------------------------------- Summary of changes: lib/util/samba_util.h | 4 ++-- lib/util/signal.c | 8 ++++---- source3/lib/pthreadpool/pthreadpool.c | 6 +++--- source3/lib/smbrun.c | 18 ++++++++++-------- source3/nmbd/nmbd.c | 3 +++ source3/rpc_server/samr/srv_samr_chgpasswd.c | 9 +++++---- 6 files changed, 27 insertions(+), 21 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index c061721..3c1874f 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -104,12 +104,12 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int); /** Ignore SIGCLD via whatever means is necessary for this OS. **/ -void CatchChild(void); +void (*CatchChild(void))(int); /** Catch SIGCLD but leave the child around so it's status can be reaped. **/ -void CatchChildLeaveStatus(void); +void (*CatchChildLeaveStatus(void))(int); struct sockaddr; diff --git a/lib/util/signal.c b/lib/util/signal.c index ead947e..33a9900 100644 --- a/lib/util/signal.c +++ b/lib/util/signal.c @@ -129,16 +129,16 @@ void (*CatchSignal(int signum,void (*handler)(int )))(int) Ignore SIGCLD via whatever means is necessary for this OS. **/ -void CatchChild(void) +void (*CatchChild(void))(int) { - CatchSignal(SIGCLD, sig_cld); + return CatchSignal(SIGCLD, sig_cld); } /** Catch SIGCLD but leave the child around so it's status can be reaped. **/ -void CatchChildLeaveStatus(void) +void (*CatchChildLeaveStatus(void))(int) { - CatchSignal(SIGCLD, sig_cld_leave_status); + return CatchSignal(SIGCLD, sig_cld_leave_status); } diff --git a/source3/lib/pthreadpool/pthreadpool.c b/source3/lib/pthreadpool/pthreadpool.c index 0430377..fbbb173 100644 --- a/source3/lib/pthreadpool/pthreadpool.c +++ b/source3/lib/pthreadpool/pthreadpool.c @@ -488,14 +488,14 @@ static void *pthreadpool_server(void *arg) job->fn(job->private_data); + res = pthread_mutex_lock(&pool->mutex); + assert(res == 0); + written = write(pool->sig_pipe[1], &job->id, sizeof(int)); free(job); - res = pthread_mutex_lock(&pool->mutex); - assert(res == 0); - if (written != sizeof(int)) { pthreadpool_server_exit(pool); pthread_mutex_unlock(&pool->mutex); diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 0ecdc0d..e33d152 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -69,6 +69,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) pid_t pid; uid_t uid = current_user.ut.uid; gid_t gid = current_user.ut.gid; + void (*saved_handler)(int); /* * Lose any elevated privileges. @@ -90,11 +91,11 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) * SIGCLD signals as it also eats the exit status code. JRA. */ - CatchChildLeaveStatus(); + saved_handler = CatchChildLeaveStatus(); if ((pid=fork()) < 0) { DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) )); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); if (outfd) { close(*outfd); *outfd = -1; @@ -119,7 +120,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) break; } - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); if (wpid != pid) { DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno))); @@ -144,7 +145,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) return status; } - CatchChild(); + (void)CatchChild(); /* we are in the child. we exec /bin/sh to do the work for us. we don't directly exec the command we want because it may be a @@ -233,6 +234,7 @@ int smbrunsecret(const char *cmd, const char *secret) uid_t uid = current_user.ut.uid; gid_t gid = current_user.ut.gid; int ifd[2]; + void (*saved_handler)(int); /* * Lose any elevated privileges. @@ -253,11 +255,11 @@ int smbrunsecret(const char *cmd, const char *secret) * SIGCLD signals as it also eats the exit status code. JRA. */ - CatchChildLeaveStatus(); + saved_handler = CatchChildLeaveStatus(); if ((pid=fork()) < 0) { DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno))); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); return errno; } @@ -289,7 +291,7 @@ int smbrunsecret(const char *cmd, const char *secret) break; } - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); if (wpid != pid) { DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno))); @@ -305,7 +307,7 @@ int smbrunsecret(const char *cmd, const char *secret) return status; } - CatchChild(); + (void)CatchChild(); /* we are in the child. we exec /bin/sh to do the work for us. we don't directly exec the command we want because it may be a diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 4d3e039..c924dd4 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -876,6 +876,9 @@ static bool open_sockets(bool isdaemon, int port) BlockSignals(True, SIGUSR2); #endif + /* Ignore children - no zombies. */ + CatchChild(); + if ( opt_interactive ) { Fork = False; log_stdout = True; diff --git a/source3/rpc_server/samr/srv_samr_chgpasswd.c b/source3/rpc_server/samr/srv_samr_chgpasswd.c index 1c9c33a..684ccee 100644 --- a/source3/rpc_server/samr/srv_samr_chgpasswd.c +++ b/source3/rpc_server/samr/srv_samr_chgpasswd.c @@ -391,6 +391,7 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass, pid_t pid, wpid; int wstat; bool chstat = False; + void (*saved_handler)(int); if (pass == NULL) { DEBUG(0, ("chat_with_program: user doesn't exist in the UNIX password database.\n")); @@ -408,13 +409,13 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass, * SIGCLD signals as it also eats the exit status code. JRA. */ - CatchChildLeaveStatus(); + saved_handler = CatchChildLeaveStatus(); if ((pid = fork()) < 0) { DEBUG(3, ("chat_with_program: Cannot fork() child for password change: %s\n", pass->pw_name)); SAFE_FREE(slavedev); close(master); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); return (False); } @@ -439,14 +440,14 @@ static bool chat_with_program(char *passwordprogram, const struct passwd *pass, if (wpid < 0) { DEBUG(3, ("chat_with_program: The process is no longer waiting!\n\n")); close(master); - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); return (False); } /* * Go back to ignoring children. */ - CatchChild(); + (void)CatchSignal(SIGCLD, saved_handler); close(master); -- Samba Shared Repository