1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

smbd: add option "smbd:debug events" for tevent handling duration threshold warnings

Can be used to enable printing an error message if tevent event handlers ran
longer then three seconds. Also logs a message with a loglevel of 3 if there
were no events at hall.

Enabled by default with 'log level = 10' or
'smbd profiling level = on'...

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15624

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Guenther Deschner <gd@samba.org>
This commit is contained in:
Ralph Boehme 2024-03-20 14:28:43 +01:00 committed by Günther Deschner
parent 679e12aee2
commit 90d776cb18

View File

@ -1739,8 +1739,36 @@ struct smbd_tevent_trace_state {
struct tevent_context *ev;
TALLOC_CTX *frame;
SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
struct timeval before_wait_tv;
struct timeval after_wait_tv;
};
static inline void smbd_tevent_trace_callback_before_wait(
struct smbd_tevent_trace_state *state)
{
struct timeval now = timeval_current();
struct timeval diff;
diff = tevent_timeval_until(&state->after_wait_tv, &now);
if (diff.tv_sec > 3) {
DBG_ERR("Handling event took %ld seconds!\n", (long)diff.tv_sec);
}
state->before_wait_tv = now;
}
static inline void smbd_tevent_trace_callback_after_wait(
struct smbd_tevent_trace_state *state)
{
struct timeval now = timeval_current();
struct timeval diff;
diff = tevent_timeval_until(&state->before_wait_tv, &now);
if (diff.tv_sec > 30) {
DBG_NOTICE("No event for %ld seconds!\n", (long)diff.tv_sec);
}
state->after_wait_tv = now;
}
static inline void smbd_tevent_trace_callback_before_loop_once(
struct smbd_tevent_trace_state *state)
{
@ -1776,6 +1804,30 @@ static void smbd_tevent_trace_callback(enum tevent_trace_point point,
errno = 0;
}
static void smbd_tevent_trace_callback_debug(enum tevent_trace_point point,
void *private_data)
{
struct smbd_tevent_trace_state *state =
(struct smbd_tevent_trace_state *)private_data;
switch (point) {
case TEVENT_TRACE_BEFORE_WAIT:
smbd_tevent_trace_callback_before_wait(state);
break;
case TEVENT_TRACE_AFTER_WAIT:
smbd_tevent_trace_callback_after_wait(state);
break;
case TEVENT_TRACE_BEFORE_LOOP_ONCE:
smbd_tevent_trace_callback_before_loop_once(state);
break;
case TEVENT_TRACE_AFTER_LOOP_ONCE:
smbd_tevent_trace_callback_after_loop_once(state);
break;
}
errno = 0;
}
static void smbd_tevent_trace_callback_profile(enum tevent_trace_point point,
void *private_data)
{
@ -1784,6 +1836,7 @@ static void smbd_tevent_trace_callback_profile(enum tevent_trace_point point,
switch (point) {
case TEVENT_TRACE_BEFORE_WAIT:
smbd_tevent_trace_callback_before_wait(state);
if (!smbprofile_dump_pending()) {
/*
* If there's no dump pending
@ -1796,6 +1849,7 @@ static void smbd_tevent_trace_callback_profile(enum tevent_trace_point point,
SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
break;
case TEVENT_TRACE_AFTER_WAIT:
smbd_tevent_trace_callback_after_wait(state);
SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
if (!smbprofile_dump_pending()) {
/*
@ -1843,7 +1897,13 @@ void smbd_process(struct tevent_context *ev_ctx,
struct smbd_tevent_trace_state trace_state = {
.ev = ev_ctx,
.frame = talloc_stackframe(),
.before_wait_tv = tv,
.after_wait_tv = tv,
};
bool debug = lp_parm_bool(GLOBAL_SECTION_SNUM,
"smbd",
"debug events",
CHECK_DEBUGLVL(DBGLVL_DEBUG));
NTTIME now = timeval_to_nttime(&tv);
char *chroot_dir = NULL;
int rc;
@ -2090,6 +2150,10 @@ void smbd_process(struct tevent_context *ev_ctx,
tevent_set_trace_callback(ev_ctx,
smbd_tevent_trace_callback_profile,
&trace_state);
} else if (debug) {
tevent_set_trace_callback(ev_ctx,
smbd_tevent_trace_callback_debug,
&trace_state);
} else {
tevent_set_trace_callback(ev_ctx,
smbd_tevent_trace_callback,