+++ /dev/null
-From 1d94210adc6e0bb8a08fbfc1a516a0f958dbf744 Mon Sep 17 00:00:00 2001
-From: Volker Lendecke <vl@samba.org>
-Date: Wed, 16 Jan 2013 12:00:00 +0100
-Subject: [PATCH 1/2] winbind: Use standard tevent_context_init
-
-This makes winbind use epoll instead of poll
----
- source3/winbindd/winbindd.c | 38 ++++++++++++++++++++++++++++++++-----
- source3/winbindd/winbindd.h | 2 --
- source3/winbindd/winbindd_proto.h | 1 +
- 3 files changed, 34 insertions(+), 7 deletions(-)
-
-Index: samba-3.6.22/source3/winbindd/winbindd.c
-===================================================================
---- samba-3.6.22.orig/source3/winbindd/winbindd.c
-+++ samba-3.6.22/source3/winbindd/winbindd.c
-@@ -48,14 +48,42 @@ static bool interactive = False;
-
- extern bool override_logfile;
-
-+struct tevent_context *winbind_event_context(void)
-+{
-+ static struct tevent_context *ev = NULL;
-+
-+ if (ev != NULL) {
-+ return ev;
-+ }
-+
-+ /*
-+ * Note we MUST use the NULL context here, not the autofree context,
-+ * to avoid side effects in forked children exiting.
-+ */
-+ ev = tevent_context_init(NULL);
-+ if (ev == NULL) {
-+ smb_panic("Could not init winbindd's messaging context.\n");
-+ }
-+ return ev;
-+}
-+
- struct messaging_context *winbind_messaging_context(void)
- {
-- struct messaging_context *msg_ctx = server_messaging_context();
-- if (likely(msg_ctx != NULL)) {
-- return msg_ctx;
-+ static struct messaging_context *msg = NULL;
-+
-+ if (msg != NULL) {
-+ return msg;
-+ }
-+
-+ /*
-+ * Note we MUST use the NULL context here, not the autofree context,
-+ * to avoid side effects in forked children exiting.
-+ */
-+ msg = messaging_init(NULL, procid_self(), winbind_event_context());
-+ if (msg == NULL) {
-+ smb_panic("Could not init winbindd's messaging context.\n");
- }
-- smb_panic("Could not init winbindd's messaging context.\n");
-- return NULL;
-+ return msg;
- }
-
- /* Reload configuration */
-Index: samba-3.6.22/source3/winbindd/winbindd.h
-===================================================================
---- samba-3.6.22.orig/source3/winbindd/winbindd.h
-+++ samba-3.6.22/source3/winbindd/winbindd.h
-@@ -397,6 +397,4 @@ struct WINBINDD_CCACHE_ENTRY {
- #define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */
- #define DOM_SEQUENCE_NONE ((uint32)-1)
-
--#define winbind_event_context server_event_context
--
- #endif /* _WINBINDD_H */
-Index: samba-3.6.22/source3/winbindd/winbindd_proto.h
-===================================================================
---- samba-3.6.22.orig/source3/winbindd/winbindd_proto.h
-+++ samba-3.6.22/source3/winbindd/winbindd_proto.h
-@@ -34,6 +34,7 @@ bool winbindd_use_cache(void);
- void winbindd_register_handlers(void);
- const char *get_winbind_pipe_dir(void);
- char *get_winbind_priv_pipe_dir(void);
-+struct tevent_context *winbind_event_context(void);
- int main(int argc, char **argv, char **envp);
-
- /* The following definitions come from winbindd/winbindd_ads.c */
-Index: samba-3.6.22/source3/winbindd/winbindd_dual.c
-===================================================================
---- samba-3.6.22.orig/source3/winbindd/winbindd_dual.c
-+++ samba-3.6.22/source3/winbindd/winbindd_dual.c
-@@ -1284,6 +1284,66 @@ NTSTATUS winbindd_reinit_after_fork(cons
- return NT_STATUS_OK;
- }
-
-+struct child_handler_state {
-+ struct winbindd_child *child;
-+ struct winbindd_cli_state *cli_state;
-+};
-+
-+static void child_handler(struct tevent_context *ev, struct tevent_fd *fde,
-+ uint16_t flags, void *private_data)
-+{
-+ struct child_handler_state *ch_state =
-+ (struct child_handler_state *)private_data;
-+ struct winbindd_cli_state *state = ch_state->cli_state;
-+ struct iovec iov[2];
-+ int iov_count;
-+ NTSTATUS status;
-+
-+ if ((flags & TEVENT_FD_READ) == 0) {
-+ return;
-+ }
-+
-+ /* fetch a request from the main daemon */
-+ status = child_read_request(state);
-+
-+ if (!NT_STATUS_IS_OK(status)) {
-+ /* we lost contact with our parent */
-+ _exit(0);
-+ }
-+
-+ DEBUG(4,("child daemon request %d\n", (int)state->request->cmd));
-+
-+ ZERO_STRUCTP(state->response);
-+ state->request->null_term = '\0';
-+ state->mem_ctx = talloc_tos();
-+ child_process_request(ch_state->child, state);
-+
-+ DEBUG(4, ("Finished processing child request %d\n",
-+ (int)state->request->cmd));
-+
-+ SAFE_FREE(state->request->extra_data.data);
-+
-+ iov[0].iov_base = (void *)state->response;
-+ iov[0].iov_len = sizeof(struct winbindd_response);
-+ iov_count = 1;
-+
-+ if (state->response->length > sizeof(struct winbindd_response)) {
-+ iov[1].iov_base =
-+ (void *)state->response->extra_data.data;
-+ iov[1].iov_len = state->response->length-iov[0].iov_len;
-+ iov_count = 2;
-+ }
-+
-+ DEBUG(10, ("Writing %d bytes to parent\n",
-+ (int)state->response->length));
-+
-+ if (write_data_iov(state->sock, iov, iov_count) !=
-+ state->response->length) {
-+ DEBUG(0, ("Could not write result\n"));
-+ exit(1);
-+ }
-+}
-+
- /*
- * In a child there will be only one domain, reference that here.
- */
-@@ -1301,6 +1361,7 @@ static bool fork_domain_child(struct win
- struct winbindd_request request;
- struct winbindd_response response;
- struct winbindd_domain *primary_domain = NULL;
-+ struct child_handler_state ch_state;
- NTSTATUS status;
- ssize_t nwritten;
-
-@@ -1322,6 +1383,9 @@ static bool fork_domain_child(struct win
- state.request = &request;
- state.response = &response;
-
-+ ch_state.child = child;
-+ ch_state.cli_state = &state;
-+
- child->pid = sys_fork();
-
- if (child->pid == -1) {
-@@ -1464,22 +1528,14 @@ static bool fork_domain_child(struct win
- }
- }
-
-- while (1) {
-+ if (tevent_add_fd(winbind_event_context(), NULL, state.sock,
-+ TEVENT_FD_READ, child_handler, &ch_state) == NULL) {
-+ DEBUG(1, ("tevent_add_fd failed\n"));
-+ exit(1);
-+ }
-
-- int ret;
-- struct pollfd *pfds;
-- int num_pfds;
-- int timeout;
-- struct timeval t;
-- struct timeval *tp;
-+ while (1) {
- TALLOC_CTX *frame = talloc_stackframe();
-- struct iovec iov[2];
-- int iov_count;
--
-- if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {
-- TALLOC_FREE(frame);
-- continue;
-- }
-
- if (child->domain && child->domain->startup &&
- (time_mono(NULL) > child->domain->startup_time + 30)) {
-@@ -1489,99 +1545,12 @@ static bool fork_domain_child(struct win
- child->domain->startup = False;
- }
-
-- pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);
-- if (pfds == NULL) {
-- DEBUG(1, ("talloc failed\n"));
-- _exit(1);
-- }
--
-- pfds->fd = state.sock;
-- pfds->events = POLLIN|POLLHUP;
-- num_pfds = 1;
--
-- timeout = INT_MAX;
--
-- if (!event_add_to_poll_args(
-- winbind_event_context(), talloc_tos(),
-- &pfds, &num_pfds, &timeout)) {
-- DEBUG(1, ("event_add_to_poll_args failed\n"));
-- _exit(1);
-- }
-- tp = get_timed_events_timeout(winbind_event_context(), &t);
-- if (tp) {
-- DEBUG(11,("select will use timeout of %u.%u seconds\n",
-- (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec ));
-- }
--
-- ret = sys_poll(pfds, num_pfds, timeout);
--
-- if (run_events_poll(winbind_event_context(), ret,
-- pfds, num_pfds)) {
-- /* We got a signal - continue. */
-- TALLOC_FREE(frame);
-- continue;
-- }
--
-- TALLOC_FREE(pfds);
--
-- if (ret == 0) {
-- DEBUG(11,("nothing is ready yet, continue\n"));
-- TALLOC_FREE(frame);
-- continue;
-- }
--
-- if (ret == -1 && errno == EINTR) {
-- /* We got a signal - continue. */
-- TALLOC_FREE(frame);
-- continue;
-- }
--
-- if (ret == -1 && errno != EINTR) {
-- DEBUG(0,("poll error occured\n"));
-- TALLOC_FREE(frame);
-- perror("poll");
-+ if (tevent_loop_once(winbind_event_context()) != 0) {
-+ DEBUG(1, ("tevent_loop_once failed: %s\n",
-+ strerror(errno)));
- _exit(1);
- }
-
-- /* fetch a request from the main daemon */
-- status = child_read_request(&state);
--
-- if (!NT_STATUS_IS_OK(status)) {
-- /* we lost contact with our parent */
-- _exit(0);
-- }
--
-- DEBUG(4,("child daemon request %d\n", (int)state.request->cmd));
--
-- ZERO_STRUCTP(state.response);
-- state.request->null_term = '\0';
-- state.mem_ctx = frame;
-- child_process_request(child, &state);
--
-- DEBUG(4, ("Finished processing child request %d\n",
-- (int)state.request->cmd));
--
-- SAFE_FREE(state.request->extra_data.data);
--
-- iov[0].iov_base = (void *)state.response;
-- iov[0].iov_len = sizeof(struct winbindd_response);
-- iov_count = 1;
--
-- if (state.response->length > sizeof(struct winbindd_response)) {
-- iov[1].iov_base =
-- (void *)state.response->extra_data.data;
-- iov[1].iov_len = state.response->length-iov[0].iov_len;
-- iov_count = 2;
-- }
--
-- DEBUG(10, ("Writing %d bytes to parent\n",
-- (int)state.response->length));
--
-- if (write_data_iov(state.sock, iov, iov_count) !=
-- state.response->length) {
-- DEBUG(0, ("Could not write result\n"));
-- exit(1);
-- }
- TALLOC_FREE(frame);
- }
- }