From 174e4b0a8e5cdc0ebf2aea34330ea7067ca6d551 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 14:23:50 +0100 Subject: [PATCH 1/9] s3:torture: call fault_setup() to get usage backtraces Signed-off-by: Stefan Metzmacher --- source3/torture/torture.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index b59ac30..5b72222 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -9316,6 +9316,7 @@ static void usage(void) setup_logging("smbtorture", DEBUG_STDOUT); load_case_tables(); + fault_setup(); if (is_default_dyn_CONFIGFILE()) { if(getenv("SMB_CONF_PATH")) { -- 1.7.9.5 From 3cb48e5a75367b6607f832e27e164fdeffba96c8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 14:29:51 +0100 Subject: [PATCH 2/9] s3:selftest: generate ${SELFTESTPREFIX}/subunit with the raw output Signed-off-by: Stefan Metzmacher --- source3/selftest/s3-selftest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/selftest/s3-selftest.sh b/source3/selftest/s3-selftest.sh index 10cf115..f02054b 100755 --- a/source3/selftest/s3-selftest.sh +++ b/source3/selftest/s3-selftest.sh @@ -45,7 +45,7 @@ else --srcdir="${SOURCEDIR}/.." \ --socket-wrapper ${TESTS} \ && touch ${SELFTESTPREFIX}/st_done ) | \ - ${FILTER_XFAIL} | ${SUBUNIT_FORMATTER} + tee ${SELFTESTPREFIX}/subunit | ${FILTER_XFAIL} | ${SUBUNIT_FORMATTER} EXIT_STATUS=$? st_test_done -- 1.7.9.5 From e7888dd60ca4da9fdaa8fe0d7ce135d47b3801d4 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 10:31:36 +0100 Subject: [PATCH 3/9] tevent: call epoll_panic() if EPOLL_CTL_DEL failed Signed-off-by: Stefan Metzmacher --- lib/tevent/tevent_epoll.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index 8696215..fd0c6ff 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -240,9 +240,8 @@ static void epoll_del_event(struct epoll_event_context *epoll_ev, struct tevent_ event.events = epoll_map_flags(fde->flags); event.data.ptr = fde; if (epoll_ctl(epoll_ev->epoll_fd, EPOLL_CTL_DEL, fde->fd, &event) != 0) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, - "epoll_del_event failed! probable early close bug (%s)\n", - strerror(errno)); + epoll_panic(epoll_ev, "EPOLL_CTL_DEL failed", false); + return; } fde->additional_flags &= ~EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT; } -- 1.7.9.5 From 57b472e782be3c74d214a5cba74cd535c135aae1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 11:24:59 +0100 Subject: [PATCH 4/9] tevent: remember the errno from select(), poll() and epoll_wait() Signed-off-by: Stefan Metzmacher --- lib/tevent/tevent_epoll.c | 6 ++++-- lib/tevent/tevent_poll.c | 4 +++- lib/tevent/tevent_select.c | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index fd0c6ff..c7e9894 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -312,6 +312,7 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval #define MAXEVENTS 1 struct epoll_event events[MAXEVENTS]; int timeout = -1; + int wait_errno; if (epoll_ev->epoll_fd == -1) return -1; @@ -327,15 +328,16 @@ static int epoll_event_loop(struct epoll_event_context *epoll_ev, struct timeval tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); ret = epoll_wait(epoll_ev->epoll_fd, events, MAXEVENTS, timeout); + wait_errno = errno; tevent_trace_point_callback(epoll_ev->ev, TEVENT_TRACE_AFTER_WAIT); - if (ret == -1 && errno == EINTR && epoll_ev->ev->signal_events) { + if (ret == -1 && wait_errno == EINTR && epoll_ev->ev->signal_events) { if (tevent_common_check_signal(epoll_ev->ev)) { return 0; } } - if (ret == -1 && errno != EINTR) { + if (ret == -1 && wait_errno != EINTR) { epoll_panic(epoll_ev, "epoll_wait() failed", true); return -1; } diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c index 89b3bbc..81a7176 100644 --- a/lib/tevent/tevent_poll.c +++ b/lib/tevent/tevent_poll.c @@ -444,6 +444,7 @@ static int poll_event_loop_poll(struct tevent_context *ev, int timeout = -1; unsigned first_fd; unsigned i; + int poll_errno; if (ev->signal_events && tevent_common_check_signal(ev)) { return 0; @@ -462,9 +463,10 @@ static int poll_event_loop_poll(struct tevent_context *ev, tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_BEFORE_WAIT); pollrtn = poll(poll_ev->fds, poll_ev->num_fds, timeout); + poll_errno = errno; tevent_trace_point_callback(poll_ev->ev, TEVENT_TRACE_AFTER_WAIT); - if (pollrtn == -1 && errno == EINTR && ev->signal_events) { + if (pollrtn == -1 && poll_errno == EINTR && ev->signal_events) { tevent_common_check_signal(ev); return 0; } diff --git a/lib/tevent/tevent_select.c b/lib/tevent/tevent_select.c index 7e0c927..ffb0d18 100644 --- a/lib/tevent/tevent_select.c +++ b/lib/tevent/tevent_select.c @@ -144,6 +144,7 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru fd_set r_fds, w_fds; struct tevent_fd *fde; int selrtn; + int select_errno; /* we maybe need to recalculate the maxfd */ if (select_ev->maxfd == EVENT_INVALID_MAXFD) { @@ -175,15 +176,16 @@ static int select_event_loop_select(struct select_event_context *select_ev, stru tevent_trace_point_callback(select_ev->ev, TEVENT_TRACE_BEFORE_WAIT); selrtn = select(select_ev->maxfd+1, &r_fds, &w_fds, NULL, tvalp); + select_errno = errno; tevent_trace_point_callback(select_ev->ev, TEVENT_TRACE_AFTER_WAIT); - if (selrtn == -1 && errno == EINTR && + if (selrtn == -1 && select_errno == EINTR && select_ev->ev->signal_events) { tevent_common_check_signal(select_ev->ev); return 0; } - if (selrtn == -1 && errno == EBADF) { + if (selrtn == -1 && select_errno == EBADF) { /* the socket is dead! this should never happen as the socket should have first been made readable and that should have removed -- 1.7.9.5 From 4aa8099a53b1a5db04756e4f20c39ad3bfffac08 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 12:10:26 +0100 Subject: [PATCH 5/9] tevent: add epoll_ctl_panic_fallback() for testing Signed-off-by: Stefan Metzmacher --- lib/tevent/tevent_epoll.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index c7e9894..329e85ae 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -58,7 +58,19 @@ static int epoll_wait_panic_fallback(int epfd, return epoll_wait(epfd, events, maxevents, timeout); } +static int epoll_ctl_panic_fallback(int epfd, int op, int fd, struct epoll_event *event) +{ + /* 50% of the time, fail... */ + if ((random() % 2) == 0) { + errno = EINVAL; + return -1; + } + + return epoll_ctl(epfd, op, fd, event); +} + #define epoll_wait epoll_wait_panic_fallback +#define epoll_ctl epoll_ctl_panic_fallback #endif /* -- 1.7.9.5 From 466d7076c3239224328fa8170f7fa1141ffff301 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 16:33:56 +0100 Subject: [PATCH 6/9] SIGN tevent: avoid any operation on epoll_ev after a epoll_panic() This calls TALLOC_FREE(ev->additional_data), which is epoll_ev within epoll_panic() before calling the fallback handler. In order to natice that a epoll_panic() happened, a caller can register a pointer to a bool variable under epoll_ev->panic_state. As epoll_check_reopen() can fail due to a epoll_panic(), we need to force the replay flag if we have called any event handler. --- lib/tevent/tevent_epoll.c | 79 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 71 insertions(+), 8 deletions(-) diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index 329e85ae..3be5af7 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -40,6 +40,8 @@ struct epoll_event_context { pid_t pid; + bool panic_force_replay; + bool *panic_state; bool (*panic_fallback)(struct tevent_context *ev, bool replay); }; @@ -102,8 +104,21 @@ static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason, bool replay) { struct tevent_context *ev = epoll_ev->ev; + bool (*panic_fallback)(struct tevent_context *ev, bool replay); + + panic_fallback = epoll_ev->panic_fallback; + + if (epoll_ev->panic_state != NULL) { + *epoll_ev->panic_state = true; + } - if (epoll_ev->panic_fallback == NULL) { + if (epoll_ev->panic_force_replay) { + replay = true; + } + + TALLOC_FREE(ev->additional_data); + + if (panic_fallback == NULL) { tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s (%s) replay[%u] - calling abort()\n", reason, strerror(errno), (unsigned)replay); @@ -114,7 +129,7 @@ static void epoll_panic(struct epoll_event_context *epoll_ev, "%s (%s) replay[%u] - calling panic_fallback\n", reason, strerror(errno), (unsigned)replay); - if (!epoll_ev->panic_fallback(ev, replay)) { + if (!panic_fallback(ev, replay)) { /* Fallback failed. */ tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s (%s) replay[%u] - calling abort()\n", @@ -177,6 +192,8 @@ static void epoll_add_event(struct epoll_event_context *epoll_ev, struct tevent_ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) { struct tevent_fd *fde; + bool *caller_panic_state = epoll_ev->panic_state; + bool panic_triggered = false; if (epoll_ev->pid == getpid()) { return; @@ -185,8 +202,7 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) close(epoll_ev->epoll_fd); epoll_ev->epoll_fd = epoll_create(64); if (epoll_ev->epoll_fd == -1) { - tevent_debug(epoll_ev->ev, TEVENT_DEBUG_FATAL, - "Failed to recreate epoll handle after fork\n"); + epoll_panic(epoll_ev, "epoll_create() failed", false); return; } @@ -196,9 +212,17 @@ static void epoll_check_reopen(struct epoll_event_context *epoll_ev) } epoll_ev->pid = getpid(); + epoll_ev->panic_state = &panic_triggered; for (fde=epoll_ev->ev->fd_events;fde;fde=fde->next) { epoll_add_event(epoll_ev, fde); + if (panic_triggered) { + if (caller_panic_state != NULL) { + *caller_panic_state = true; + } + return; + } } + epoll_ev->panic_state = NULL; } #define EPOLL_ADDITIONAL_FD_FLAG_HAS_EVENT (1<<0) @@ -429,15 +453,30 @@ static int epoll_event_context_init(struct tevent_context *ev) static int epoll_event_fd_destructor(struct tevent_fd *fde) { struct tevent_context *ev = fde->event_ctx; - struct epoll_event_context *epoll_ev = NULL; if (ev) { - epoll_ev = talloc_get_type(ev->additional_data, - struct epoll_event_context); + struct epoll_event_context *epoll_ev = + talloc_get_type_abort(ev->additional_data, + struct epoll_event_context); + bool panic_triggered = false; + + epoll_ev->panic_state = &panic_triggered; + + /* + * we must remove the event from the list + * otherwise a panic fallback handler may + * reuse invalid memory + */ + DLIST_REMOVE(ev->fd_events, fde); epoll_check_reopen(epoll_ev); - epoll_del_event(epoll_ev, fde); + if (!panic_triggered) { + epoll_del_event(epoll_ev, fde); + } + if (!panic_triggered) { + epoll_ev->panic_state = NULL; + } } return tevent_common_fd_destructor(fde); @@ -457,14 +496,23 @@ static struct tevent_fd *epoll_event_add_fd(struct tevent_context *ev, TALLOC_CT struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, struct epoll_event_context); struct tevent_fd *fde; + bool panic_triggered = false; + epoll_ev->panic_state = &panic_triggered; epoll_check_reopen(epoll_ev); + if (!panic_triggered) { + epoll_ev->panic_state = NULL; + } fde = tevent_common_add_fd(ev, mem_ctx, fd, flags, handler, private_data, handler_name, location); if (!fde) return NULL; + if (panic_triggered) { + return fde; + } + talloc_set_destructor(fde, epoll_event_fd_destructor); epoll_add_event(epoll_ev, fde); @@ -479,6 +527,7 @@ static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) { struct tevent_context *ev; struct epoll_event_context *epoll_ev; + bool panic_triggered = false; if (fde->flags == flags) return; @@ -487,7 +536,12 @@ static void epoll_event_set_fd_flags(struct tevent_fd *fde, uint16_t flags) fde->flags = flags; + epoll_ev->panic_state = &panic_triggered; epoll_check_reopen(epoll_ev); + if (panic_triggered) { + return; + } + epoll_ev->panic_state = NULL; epoll_change_event(epoll_ev, fde); } @@ -500,6 +554,7 @@ static int epoll_event_loop_once(struct tevent_context *ev, const char *location struct epoll_event_context *epoll_ev = talloc_get_type(ev->additional_data, struct epoll_event_context); struct timeval tval; + bool panic_triggered = false; if (ev->signal_events && tevent_common_check_signal(ev)) { @@ -516,7 +571,15 @@ static int epoll_event_loop_once(struct tevent_context *ev, const char *location return 0; } + epoll_ev->panic_state = &panic_triggered; + epoll_ev->panic_force_replay = true; epoll_check_reopen(epoll_ev); + if (panic_triggered) { + errno = EINVAL; + return -1; + } + epoll_ev->panic_force_replay = false; + epoll_ev->panic_state = NULL; return epoll_event_loop(epoll_ev, &tval); } -- 1.7.9.5 From 1dbfc852a2bcc82c77c279983a9ded6c8d73f9a8 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 16:45:25 +0100 Subject: [PATCH 7/9] TODO split... tevent_standard --- lib/tevent/tevent_standard.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c index d7a5bd7..2584994 100644 --- a/lib/tevent/tevent_standard.c +++ b/lib/tevent/tevent_standard.c @@ -68,7 +68,6 @@ static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) /* First switch all the ops to poll. */ glue->epoll_ops = NULL; - TALLOC_FREE(ev->additional_data); /* * Set custom_ops the same as poll. @@ -128,6 +127,22 @@ static int std_event_loop_once(struct tevent_context *ev, const char *location) return glue->poll_ops->loop_once(ev, location); } +static int std_event_loop_wait(struct tevent_context *ev, const char *location) +{ + void *glue_ptr = talloc_parent(ev->ops); + struct std_event_glue *glue = + talloc_get_type_abort(glue_ptr, + struct std_event_glue); + int ret; + + ret = glue->epoll_ops->loop_wait(ev, location); + if (glue->epoll_ops != NULL) { + /* No fallback */ + return ret; + } + + return glue->poll_ops->loop_wait(ev, location); +} /* Initialize the epoll backend and allow it to call a switch function if epoll fails at runtime. @@ -184,6 +199,7 @@ static int std_event_context_init(struct tevent_context *ev) *glue->glue_ops = *glue->epoll_ops; glue->glue_ops->context_init = std_event_context_init; glue->glue_ops->loop_once = std_event_loop_once; + glue->glue_ops->loop_wait = std_event_loop_wait; ret = glue->epoll_ops->context_init(ev); if (ret == -1) { -- 1.7.9.5 From cc49824a51d4fc860c7752c74e93f2620dd6d367 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 12:13:00 +0100 Subject: [PATCH 8/9] HACK TEST_PANIC_FALLBACK --- lib/tevent/tevent_epoll.c | 1 + source3/torture/torture.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index 3be5af7..bd1e895 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -45,6 +45,7 @@ struct epoll_event_context { bool (*panic_fallback)(struct tevent_context *ev, bool replay); }; +#define TEST_PANIC_FALLBACK #ifdef TEST_PANIC_FALLBACK static int epoll_wait_panic_fallback(int epfd, struct epoll_event *events, diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 5b72222..ceab6f7 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -8516,6 +8516,20 @@ static void wbclient_done(struct tevent_req *req) d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err)); } +static void s3t_event_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + +static void s3t_event_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) +{ + char *s = NULL; + if (vasprintf(&s, fmt, ap) == -1) { + return; + } + d_printf("s3t_event: %s", s); + free(s); +} + static bool run_local_wbclient(int dummy) { struct event_context *ev; @@ -8526,10 +8540,11 @@ static bool run_local_wbclient(int dummy) BlockSignals(True, SIGPIPE); - ev = tevent_context_init_byname(talloc_tos(), "epoll"); + ev = tevent_context_init_byname(talloc_tos(), "standard"); if (ev == NULL) { goto fail; } + tevent_set_debug(ev, s3t_event_debug, NULL); wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs); if (wb_ctx == NULL) { -- 1.7.9.5 From e53b7441ef61e68a4d8ba97ade480e56cb74d641 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 15 Feb 2013 16:46:21 +0100 Subject: [PATCH 9/9] reproduce... --- lib/tevent/tevent_epoll.c | 18 ++++++++--- lib/tevent/tevent_poll.c | 47 ++++++++++++++++++++++++++++ lib/tevent/tevent_standard.c | 14 +++++++++ libcli/smb/smbXcli_base.c | 15 +++++++++ source3/script/tests/test_smbtorture_s3.sh | 2 +- source3/winbindd/winbindd.c | 2 +- 6 files changed, 91 insertions(+), 7 deletions(-) diff --git a/lib/tevent/tevent_epoll.c b/lib/tevent/tevent_epoll.c index bd1e895..37378b3 100644 --- a/lib/tevent/tevent_epoll.c +++ b/lib/tevent/tevent_epoll.c @@ -47,24 +47,30 @@ struct epoll_event_context { #define TEST_PANIC_FALLBACK #ifdef TEST_PANIC_FALLBACK +static int epoll_wait_panic_ctr; static int epoll_wait_panic_fallback(int epfd, struct epoll_event *events, int maxevents, int timeout) { + epoll_wait_panic_ctr++; + /* 50% of the time, fail... */ if ((random() % 2) == 0) { - errno = EINVAL; - return -1; +// errno = EINVAL; +// return -1; } return epoll_wait(epfd, events, maxevents, timeout); } +static int epoll_ctl_panic_ctr; static int epoll_ctl_panic_fallback(int epfd, int op, int fd, struct epoll_event *event) { + epoll_ctl_panic_ctr++; + /* 50% of the time, fail... */ - if ((random() % 2) == 0) { + if (epoll_ctl_panic_ctr == 2) {//(random() % 2) == 0) { errno = EINVAL; return -1; } @@ -127,8 +133,10 @@ static void epoll_panic(struct epoll_event_context *epoll_ev, } tevent_debug(ev, TEVENT_DEBUG_WARNING, - "%s (%s) replay[%u] - calling panic_fallback\n", - reason, strerror(errno), (unsigned)replay); + "%s (%s) replay[%u] - calling panic_fallback w[%d] c[%d]\n", + reason, strerror(errno), (unsigned)replay, + epoll_wait_panic_ctr, + epoll_ctl_panic_ctr); if (!panic_fallback(ev, replay)) { /* Fallback failed. */ diff --git a/lib/tevent/tevent_poll.c b/lib/tevent/tevent_poll.c index 81a7176..704b164 100644 --- a/lib/tevent/tevent_poll.c +++ b/lib/tevent/tevent_poll.c @@ -58,7 +58,11 @@ struct poll_event_context { static int poll_event_context_destructor(struct poll_event_context *poll_ev) { struct tevent_fd *fd, *fn; + struct tevent_context *ev = poll_ev->ev; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); for (fd = poll_ev->fresh; fd; fd = fn) { fn = fd->next; fd->event_ctx = NULL; @@ -92,6 +96,8 @@ static int poll_event_context_init(struct tevent_context *ev) { struct poll_event_context *poll_ev; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); /* * we might be called during tevent_re_initialise() * which means we need to free our old additional_data @@ -108,6 +114,9 @@ static int poll_event_context_init(struct tevent_context *ev) poll_ev->signal_fd = -1; ev->additional_data = poll_ev; talloc_set_destructor(poll_ev, poll_event_context_destructor); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); return 0; } @@ -221,6 +230,9 @@ static int poll_event_fd_destructor(struct tevent_fd *fde) poll_ev->fdes[del_idx] = NULL; poll_event_wake_pollthread(poll_ev); done: + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); return tevent_common_fd_destructor(fde); } @@ -235,7 +247,13 @@ static int poll_fresh_fde_destructor(struct tevent_fd *fde) poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); DLIST_REMOVE(poll_ev->fresh, fde); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); done: return tevent_common_fd_destructor(fde); } @@ -265,9 +283,15 @@ _PRIVATE_ void tevent_poll_event_add_fd_internal(struct tevent_context *ev, struct poll_event_context *poll_ev = talloc_get_type_abort( ev->additional_data, struct poll_event_context); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); fde->additional_flags = UINT64_MAX; fde->additional_data = NULL; DLIST_ADD(poll_ev->fresh, fde); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); talloc_set_destructor(fde, poll_fresh_fde_destructor); } @@ -287,6 +311,9 @@ static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev, ev->additional_data, struct poll_event_context); struct tevent_fd *fde; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); if (fd < 0) { return NULL; } @@ -306,7 +333,21 @@ static struct tevent_fd *poll_event_add_fd(struct tevent_context *ev, fde->additional_flags = UINT64_MAX; fde->additional_data = NULL; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); +if (poll_ev->fresh) { + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: fresh[%p] p[%p] n[%p]\n", + __location__, __FUNCTION__, + poll_ev->fresh, poll_ev->fresh->prev, poll_ev->fresh->next); +} DLIST_ADD(poll_ev->fresh, fde); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: fresh[%p] p[%p] n[%p]\n", + __location__, __FUNCTION__, + poll_ev->fresh, poll_ev->fresh->prev, poll_ev->fresh->next); talloc_set_destructor(fde, poll_fresh_fde_destructor); poll_event_wake_pollthread(poll_ev); @@ -422,8 +463,14 @@ static bool poll_event_setup_fresh(struct tevent_context *ev, poll_ev->fdes[poll_ev->num_fds] = fde; next = fde->next; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); DLIST_REMOVE(poll_ev->fresh, fde); DLIST_ADD(ev->fd_events, fde); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: ev[%p] poll[%p] fresh[%p]\n", + __location__, __FUNCTION__, + ev, poll_ev, poll_ev->fresh); talloc_set_destructor(fde, poll_event_fd_destructor); diff --git a/lib/tevent/tevent_standard.c b/lib/tevent/tevent_standard.c index 2584994..7bd8f04 100644 --- a/lib/tevent/tevent_standard.c +++ b/lib/tevent/tevent_standard.c @@ -64,10 +64,14 @@ static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) struct tevent_fd *fde; struct tevent_fd *fde_next; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); glue->fallback_replay = replay; /* First switch all the ops to poll. */ glue->epoll_ops = NULL; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); /* * Set custom_ops the same as poll. @@ -75,12 +79,16 @@ static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) *glue->glue_ops = *glue->poll_ops; glue->glue_ops->context_init = std_event_context_init; + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); /* Next initialize the poll backend. */ ret = glue->poll_ops->context_init(ev); if (ret != 0) { return false; } + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); /* * Now we have to change all the existing file descriptor * events from the epoll backend to the poll backend. @@ -94,10 +102,16 @@ static bool std_fallback_to_poll(struct tevent_context *ev, bool replay) /* Remove from the ev->fd_events list. */ DLIST_REMOVE(ev->fd_events, fde); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); /* Re-add this event as a poll backend event. */ tevent_poll_event_add_fd_internal(ev, fde); + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); } + tevent_debug(ev, TEVENT_DEBUG_FATAL, "%s:%s: \n", + __location__, __FUNCTION__); return true; } diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 421e884..3db5aed 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -4412,6 +4412,20 @@ NTSTATUS smbXcli_negprot_recv(struct tevent_req *req) return tevent_req_simple_recv_ntstatus(req); } +static void smbXcli_negprot_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) PRINTF_ATTRIBUTE(3,0); + +static void smbXcli_negprot_debug(void *context, enum tevent_debug_level level, + const char *fmt, va_list ap) +{ + char *s = NULL; + if (vasprintf(&s, fmt, ap) == -1) { + return; + } + DEBUG(0,("smbXcli_negprot: %s", s)); + free(s); +} + NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn, uint32_t timeout_msec, enum protocol_types min_protocol, @@ -4434,6 +4448,7 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn, if (ev == NULL) { goto fail; } + tevent_set_debug(ev, smbXcli_negprot_debug, NULL); req = smbXcli_negprot_send(frame, ev, conn, timeout_msec, min_protocol, max_protocol); if (req == NULL) { diff --git a/source3/script/tests/test_smbtorture_s3.sh b/source3/script/tests/test_smbtorture_s3.sh index 07d940f..1e7405c 100755 --- a/source3/script/tests/test_smbtorture_s3.sh +++ b/source3/script/tests/test_smbtorture_s3.sh @@ -23,6 +23,6 @@ incdir=`dirname $0`/../../../testprogs/blackbox failed=0 -testit "smbtorture" $VALGRIND $SMBTORTURE $unc -U"$username"%"$password" $ADDARGS $t || failed=`expr $failed + 1` +testit "smbtorture" $S3VALGRIND $SMBTORTURE $unc -U"$username"%"$password" $ADDARGS $t || failed=`expr $failed + 1` testok $0 $failed diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index ebaa080..a4b4264 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -52,7 +52,7 @@ extern bool override_logfile; struct tevent_context *winbind_event_context(void) { static struct tevent_context *ev = NULL; - +return server_event_context(); if (ev != NULL) { return ev; } -- 1.7.9.5