The branch, master has been updated via 058f96f4c4e s4/samba: call force_check_log_size() in standard_new_task() via 6fa5fb8ef26 s4/samba: call force_check_log_size() in standard_accept_connection() via 82b64e930b0 s4/samba: call force_check_log_size() in prefork_reload_after_fork() via 19413e76a46 s4: call reopen_logs_internal() in the SIGHUP handler of the prefork process model via 9f71e6173ab s4: replace low-level SIGUP handler with a tevent handler via 516c2a04a24 s4: install tevent tracing hooks to trigger logfile rotation via 68f71f227b1 s4: add samba server tevent trace helper stuff via 3651a51e93b debug: detect logrotation by checking inode number via b7ee3614645 debug: pass struct debug_class *config to do_one_check_log_size() via 29cd139a32d debug: pass struct debug_class *config to reopen_one_log() via ab2c712c016 loadparm: setup debug subsystem setting max_log_size from config from ed21259358e WHATSNEW.txt: fix version to 4.14
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 058f96f4c4eda42b404f0067521d3eafb495fe7d Author: Ralph Boehme <s...@samba.org> Date: Thu Nov 26 15:24:44 2020 +0100 s4/samba: call force_check_log_size() in standard_new_task() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 RN: samba process does not honor max log size Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Mon Dec 7 18:54:29 UTC 2020 on sn-devel-184 commit 6fa5fb8ef26dab862df5c46bb5e74f19839c30e2 Author: Ralph Boehme <s...@samba.org> Date: Thu Nov 26 15:24:26 2020 +0100 s4/samba: call force_check_log_size() in standard_accept_connection() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 82b64e930b0e2d3b2e5186017d9f8e420994136c Author: Ralph Boehme <s...@samba.org> Date: Thu Nov 26 15:23:58 2020 +0100 s4/samba: call force_check_log_size() in prefork_reload_after_fork() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> commit 19413e76a46f07fdd46fde5e60707bb6845a782d Author: Ralph Boehme <s...@samba.org> Date: Mon Nov 23 16:44:04 2020 +0100 s4: call reopen_logs_internal() in the SIGHUP handler of the prefork process model With debug_schedule_reopen_logs() the actual reopen only takes place at some point in the future when a DEBUG message is processed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 9f71e6173ab43a04804ba8061cb0e8ae6c0165bf Author: Ralph Boehme <s...@samba.org> Date: Fri Nov 20 15:21:03 2020 +0100 s4: replace low-level SIGUP handler with a tevent handler Replace the low-level signal handler for SIGHUP with a nice tevent signal handler. The low-level handler sig_hup() installed by setup_signals() remains being used during early startup before a tevent context is available. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 516c2a04a242a539f9fbddb2822295fee233644c Author: Ralph Boehme <s...@samba.org> Date: Thu Nov 26 14:21:58 2020 +0100 s4: install tevent tracing hooks to trigger logfile rotation BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 68f71f227b17774a12c84575c1eecd82279fac95 Author: Ralph Boehme <s...@samba.org> Date: Mon Nov 23 17:53:57 2020 +0100 s4: add samba server tevent trace helper stuff BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 3651a51e93b45104323d5db1d5ea704d4f71acf1 Author: Ralph Boehme <s...@samba.org> Date: Mon Nov 23 16:04:03 2020 +0100 debug: detect logrotation by checking inode number BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit b7ee36146458bcc2c944f5670b7632df8281ae61 Author: Ralph Boehme <s...@samba.org> Date: Mon Nov 23 15:51:09 2020 +0100 debug: pass struct debug_class *config to do_one_check_log_size() Pass a pointer to the struct instead of all struct members individually. No change in behaviour. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 29cd139a32d5dbf36bef68eb9c7f1160201e3042 Author: Ralph Boehme <s...@samba.org> Date: Mon Nov 23 15:46:47 2020 +0100 debug: pass struct debug_class *config to reopen_one_log() Pass a pointer to the struct instead of all struct members individually. No change in behaviour. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ab2c712c016f4e4dacd5064b9eb8f6417f4b9b60 Author: Ralph Boehme <s...@samba.org> Date: Fri Nov 13 12:34:50 2020 +0100 loadparm: setup debug subsystem setting max_log_size from config BUG: https://bugzilla.samba.org/show_bug.cgi?id=14248 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/param/loadparm.c | 1 + lib/util/debug.c | 63 ++++++++++----- source4/samba/process_prefork.c | 16 +++- source4/samba/process_standard.c | 4 + source4/samba/server.c | 46 +++++++++++ source4/samba/server_util.c | 94 ++++++++++++++++++++++ .../winbindd_ads.h => source4/samba/server_util.h | 18 ++--- source4/samba/wscript_build | 9 ++- 8 files changed, 219 insertions(+), 32 deletions(-) create mode 100644 source4/samba/server_util.c copy source3/winbindd/winbindd_ads.h => source4/samba/server_util.h (67%) Changeset truncated at 500 lines: diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index eaf992f209b..3548c47d857 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3201,6 +3201,7 @@ static bool lpcfg_update(struct loadparm_context *lp_ctx) settings.debug_pid = lp_ctx->globals->debug_pid; settings.debug_uid = lp_ctx->globals->debug_uid; settings.debug_class = lp_ctx->globals->debug_class; + settings.max_log_size = lp_ctx->globals->max_log_size; debug_set_settings(&settings, lp_ctx->globals->logging, lp_ctx->globals->syslog, lp_ctx->globals->syslog_only); diff --git a/lib/util/debug.c b/lib/util/debug.c index 402345222e5..18e5b4f6c72 100644 --- a/lib/util/debug.c +++ b/lib/util/debug.c @@ -113,6 +113,8 @@ struct debug_class { */ char *logfile; int fd; + /* inode number of the logfile to detect logfile rotation */ + ino_t ino; }; static const char *default_classname_table[] = { @@ -1082,14 +1084,17 @@ static void debug_callback_log(const char *msg, int msg_level) Fix from dgib...@linuxcare.com. **************************************************************************/ -static bool reopen_one_log(int *fd, const char *logfile) +static bool reopen_one_log(struct debug_class *config) { - int old_fd = *fd; + int old_fd = config->fd; + const char *logfile = config->logfile; + struct stat st; int new_fd; + int ret; if (logfile == NULL) { debug_close_fd(old_fd); - *fd = -1; + config->fd = -1; return true; } @@ -1104,8 +1109,18 @@ static bool reopen_one_log(int *fd, const char *logfile) debug_close_fd(old_fd); smb_set_close_on_exec(new_fd); - *fd = new_fd; + config->fd = new_fd; + ret = fstat(new_fd, &st); + if (ret != 0) { + log_overflow = true; + DBG_ERR("Unable to fstat() new log file '%s': %s\n", + logfile, strerror(errno)); + log_overflow = false; + return false; + } + + config->ino = st.st_ino; return true; } @@ -1164,8 +1179,7 @@ bool reopen_logs_internal(void) state.reopening_logs = true; for (i = DBGC_ALL; i < debug_num_classes; i++) { - ok = reopen_one_log(&dbgc_config[i].fd, - dbgc_config[i].logfile); + ok = reopen_one_log(&dbgc_config[i]); if (!ok) { break; } @@ -1249,51 +1263,62 @@ bool need_to_check_log_size(void) Check to see if the log has grown to be too big. **************************************************************************/ -static void do_one_check_log_size(off_t maxlog, int *_fd, const char *logfile) +static void do_one_check_log_size(off_t maxlog, struct debug_class *config) { - char name[strlen(logfile) + 5]; + char name[strlen(config->logfile) + 5]; struct stat st; - int fd = *_fd; int ret; + bool reopen = false; bool ok; if (maxlog == 0) { return; } - ret = fstat(fd, &st); + ret = stat(config->logfile, &st); if (ret != 0) { return; } - if (st.st_size < maxlog ) { + if (st.st_size >= maxlog ) { + reopen = true; + } + + if (st.st_ino != config->ino) { + reopen = true; + } + + if (!reopen) { return; } /* reopen_logs_internal() modifies *_fd */ (void)reopen_logs_internal(); - fd = *_fd; - if (fd <= 2) { + if (config->fd <= 2) { return; } - ret = fstat(fd, &st); + ret = fstat(config->fd, &st); if (ret != 0) { + config->ino = (ino_t)0; return; } + + config->ino = st.st_ino; + if (st.st_size < maxlog) { return; } - snprintf(name, sizeof(name), "%s.old", logfile); + snprintf(name, sizeof(name), "%s.old", config->logfile); - (void)rename(logfile, name); + (void)rename(config->logfile, name); ok = reopen_logs_internal(); if (ok) { return; } /* We failed to reopen a log - continue using the old name. */ - (void)rename(name, logfile); + (void)rename(name, config->logfile); } static void do_check_log_size(off_t maxlog) @@ -1307,9 +1332,7 @@ static void do_check_log_size(off_t maxlog) if (dbgc_config[i].logfile == NULL) { continue; } - do_one_check_log_size(maxlog, - &dbgc_config[i].fd, - dbgc_config[i].logfile); + do_one_check_log_size(maxlog, &dbgc_config[i]); } } diff --git a/source4/samba/process_prefork.c b/source4/samba/process_prefork.c index f3387d87e61..6a2e3a0acfe 100644 --- a/source4/samba/process_prefork.c +++ b/source4/samba/process_prefork.c @@ -45,6 +45,7 @@ #include "lib/util/tfork.h" #include "lib/messaging/irpc.h" #include "lib/util/util_process.h" +#include "server_util.h" #define min(a, b) (((a) < (b)) ? (a) : (b)) @@ -114,7 +115,7 @@ static void sighup_signal_handler(struct tevent_context *ev, int signum, int count, void *siginfo, void *private_data) { - debug_schedule_reopen_logs(); + reopen_logs_internal(); } static void sigterm_signal_handler(struct tevent_context *ev, @@ -154,6 +155,7 @@ static void prefork_reload_after_fork(void) if (!NT_STATUS_IS_OK(status)) { smb_panic("Failed to re-initialise imessaging after fork"); } + force_check_log_size(); } /* @@ -244,6 +246,7 @@ static void prefork_fork_master( struct tevent_context *ev2; struct task_server *task = NULL; struct process_details pd = initial_process_details; + struct samba_tevent_trace_state *samba_tevent_trace_state = NULL; int control_pipe[2]; t = tfork_create(); @@ -327,6 +330,17 @@ static void prefork_fork_master( */ ev2 = s4_event_context_init(NULL); + samba_tevent_trace_state = create_samba_tevent_trace_state(ev2); + if (samba_tevent_trace_state == NULL) { + TALLOC_FREE(ev); + TALLOC_FREE(ev2); + exit(127); + } + + tevent_set_trace_callback(ev2, + samba_tevent_trace_callback, + samba_tevent_trace_state); + /* setup this new connection: process will bind to it's sockets etc * * While we can use ev for the child, which has been re-initialised diff --git a/source4/samba/process_standard.c b/source4/samba/process_standard.c index 2820e30eace..396054dbc9d 100644 --- a/source4/samba/process_standard.c +++ b/source4/samba/process_standard.c @@ -408,6 +408,8 @@ static void standard_accept_connection( talloc_free(c); talloc_free(s); + force_check_log_size(); + /* setup this new connection. Cluster ID is PID based for this process model */ new_conn(ev, lp_ctx, sock2, cluster_id(pid, 0), private_data, process_context); @@ -514,6 +516,8 @@ static void standard_new_task(struct tevent_context *ev, */ prctl_set_comment("%s[task]", service_name); + force_check_log_size(); + /* * Set up the process context to be passed through to the terminate * and accept_connection functions diff --git a/source4/samba/server.c b/source4/samba/server.c index d3cbd654d76..6e07f048c0f 100644 --- a/source4/samba/server.c +++ b/source4/samba/server.c @@ -46,6 +46,7 @@ #include "lib/util/tfork.h" #include "dsdb/samdb/ldb_modules/util.h" #include "lib/util/server_id.h" +#include "server_util.h" #ifdef HAVE_PTHREAD #include <pthread.h> @@ -154,6 +155,19 @@ static void sigterm_signal_handler(struct tevent_context *ev, sig_term(SIGTERM); } +static void sighup_signal_handler(struct tevent_context *ev, + struct tevent_signal *se, + int signum, int count, void *siginfo, + void *private_data) +{ + struct server_state *state = talloc_get_type_abort( + private_data, struct server_state); + + DBG_DEBUG("Process %s got SIGHUP\n", state->binary_name); + + reopen_logs_internal(); +} + /* setup signal masks */ @@ -572,6 +586,7 @@ static int binary_smbd_main(const char *binary_name, }; struct server_state *state = NULL; struct tevent_signal *se = NULL; + struct samba_tevent_trace_state *samba_tevent_trace_state = NULL; setproctitle("root process"); @@ -729,6 +744,21 @@ static int binary_smbd_main(const char *binary_name, talloc_set_destructor(state->event_ctx, event_ctx_destructor); + samba_tevent_trace_state = create_samba_tevent_trace_state(state); + if (samba_tevent_trace_state == NULL) { + exit_daemon("Samba failed to setup tevent tracing state", + ENOTTY); + /* + * return is never reached but is here to satisfy static + * checkers + */ + return 1; + } + + tevent_set_trace_callback(state->event_ctx, + samba_tevent_trace_callback, + samba_tevent_trace_state); + if (opt_interactive) { /* terminate when stdin goes away */ stdin_event_flags = TEVENT_FD_READ; @@ -817,6 +847,22 @@ static int binary_smbd_main(const char *binary_name, return 1; } + se = tevent_add_signal(state->event_ctx, + state->event_ctx, + SIGHUP, + 0, + sighup_signal_handler, + state); + if (se == NULL) { + TALLOC_FREE(state); + exit_daemon("Initialize SIGHUP handler failed", ENOMEM); + /* + * return is never reached but is here to satisfy static + * checkers + */ + return 1; + } + if (lpcfg_server_role(cmdline_lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC && !lpcfg_parm_bool(cmdline_lp_ctx, NULL, "server role check", "inhibit", false) diff --git a/source4/samba/server_util.c b/source4/samba/server_util.c new file mode 100644 index 00000000000..282ad9b17cd --- /dev/null +++ b/source4/samba/server_util.c @@ -0,0 +1,94 @@ +/* + Unix SMB/CIFS implementation. + + Utility routines + + Copyright (C) 2020 Ralph Boehme <s...@samba.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "lib/tevent/tevent.h" +#include "lib/util/unix_privs.h" +#include "server_util.h" + +struct samba_tevent_trace_state { + size_t events; + time_t last_logsize_check; +}; + +struct samba_tevent_trace_state *create_samba_tevent_trace_state( + TALLOC_CTX *mem_ctx) +{ + return talloc_zero(mem_ctx, struct samba_tevent_trace_state); +} + +void samba_tevent_trace_callback(enum tevent_trace_point point, + void *private_data) +{ + struct samba_tevent_trace_state *state = + talloc_get_type_abort(private_data, + struct samba_tevent_trace_state); + time_t now = time(NULL); + bool do_check_logs = false; + void *priv = NULL; + + switch (point) { + case TEVENT_TRACE_BEFORE_WAIT: + break; + default: + return; + } + + state->events++; + + /* + * Throttling by some random numbers. smbd uses a similar logic + * checking every 50 SMB requests. Assuming 4 events per request + * we get to the number of 200. + */ + if ((state->events % 200) == 0) { + do_check_logs = true; + } + /* + * Throttling by some delay, choosing 29 to avoid lockstep with + * the default tevent tickle timer. + */ + if ((state->last_logsize_check + 29) < now) { + do_check_logs = true; + } + + if (!do_check_logs) { + return; + } + + /* + * need_to_check_log_size() checks both the number of messages + * that have been logged and if the logging backend is actually + * going to file. We want to bypass the "number of messages" + * check, so we have to call force_check_log_size() before. + */ + force_check_log_size(); + if (!need_to_check_log_size()) { + return; + } + + priv = root_privileges(); + check_log_size(); + TALLOC_FREE(priv); + + state->last_logsize_check = now; + return; +} diff --git a/source3/winbindd/winbindd_ads.h b/source4/samba/server_util.h similarity index 67% copy from source3/winbindd/winbindd_ads.h copy to source4/samba/server_util.h index 5f121c89e8f..08c09cc67c2 100644 --- a/source3/winbindd/winbindd_ads.h +++ b/source4/samba/server_util.h @@ -1,9 +1,9 @@ /* Unix SMB/CIFS implementation. - Winbind ADS backend functions + Utility routines - Copyright (C) Volker Lendecke 2017 + Copyright (C) 2020 Ralph Boehme <s...@samba.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -19,15 +19,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef __WINBINDD_ADS_H__ -#define __WINBINDD_ADS_H__ +#ifndef SAMBA_SERVER_UTIL_H +#define SAMBA_SERVER_UTIL_H +struct samba_tevent_trace_state; -#include "ads.h" +struct samba_tevent_trace_state *create_samba_tevent_trace_state( + TALLOC_CTX *mem_ctx); -extern struct winbindd_methods ads_methods; - -ADS_STATUS ads_idmap_cached_connection(ADS_STRUCT **adsp, - const char *dom_name); +void samba_tevent_trace_callback(enum tevent_trace_point point, + void *private_data); #endif diff --git a/source4/samba/wscript_build b/source4/samba/wscript_build index ef0aaf773c1..14267c1c9a5 100644 --- a/source4/samba/wscript_build +++ b/source4/samba/wscript_build @@ -17,11 +17,16 @@ bld.SAMBA_LIBRARY('process_model', enabled=bld.AD_DC_BUILD_IS_ENABLED() ) +bld.SAMBA_SUBSYSTEM('samba_server_util', + source='server_util.c', + deps='samba-util') + bld.SAMBA_BINARY('samba', source='server.c', subsystem_name='service', deps='''events process_model service samba-hostconfig samba-util POPT_SAMBA - popt gensec registry ntvfs share cluster COMMON_SCHANNEL SECRETS''', + popt gensec registry ntvfs share cluster COMMON_SCHANNEL SECRETS + samba_server_util''', pyembed=True, install_path='${SBINDIR}', enabled=bld.AD_DC_BUILD_IS_ENABLED() @@ -48,6 +53,6 @@ bld.SAMBA_MODULE('process_model_prefork', source='process_prefork.c', subsystem='process_model', init_function='process_model_prefork_init', - deps='MESSAGING events ldbsamba cluster samba-sockets process_model messages_dgm', + deps='MESSAGING events ldbsamba cluster samba-sockets process_model messages_dgm samba_server_util', internal_module=False ) -- Samba Shared Repository