1 From 1d94210adc6e0bb8a08fbfc1a516a0f958dbf744 Mon Sep 17 00:00:00 2001
2 From: Volker Lendecke <vl@samba.org>
3 Date: Wed, 16 Jan 2013 12:00:00 +0100
4 Subject: [PATCH 1/2] winbind: Use standard tevent_context_init
6 This makes winbind use epoll instead of poll
8 source3/winbindd/winbindd.c | 38 ++++++++++++++++++++++++++++++++-----
9 source3/winbindd/winbindd.h | 2 --
10 source3/winbindd/winbindd_proto.h | 1 +
11 3 files changed, 34 insertions(+), 7 deletions(-)
13 Index: samba-3.6.22/source3/winbindd/winbindd.c
14 ===================================================================
15 --- samba-3.6.22.orig/source3/winbindd/winbindd.c
16 +++ samba-3.6.22/source3/winbindd/winbindd.c
17 @@ -48,14 +48,42 @@ static bool interactive = False;
19 extern bool override_logfile;
21 +struct tevent_context *winbind_event_context(void)
23 + static struct tevent_context *ev = NULL;
30 + * Note we MUST use the NULL context here, not the autofree context,
31 + * to avoid side effects in forked children exiting.
33 + ev = tevent_context_init(NULL);
35 + smb_panic("Could not init winbindd's messaging context.\n");
40 struct messaging_context *winbind_messaging_context(void)
42 - struct messaging_context *msg_ctx = server_messaging_context();
43 - if (likely(msg_ctx != NULL)) {
45 + static struct messaging_context *msg = NULL;
52 + * Note we MUST use the NULL context here, not the autofree context,
53 + * to avoid side effects in forked children exiting.
55 + msg = messaging_init(NULL, procid_self(), winbind_event_context());
57 + smb_panic("Could not init winbindd's messaging context.\n");
59 - smb_panic("Could not init winbindd's messaging context.\n");
64 /* Reload configuration */
65 Index: samba-3.6.22/source3/winbindd/winbindd.h
66 ===================================================================
67 --- samba-3.6.22.orig/source3/winbindd/winbindd.h
68 +++ samba-3.6.22/source3/winbindd/winbindd.h
69 @@ -397,6 +397,4 @@ struct WINBINDD_CCACHE_ENTRY {
70 #define WINBINDD_PAM_AUTH_KRB5_RENEW_TIME 2592000 /* one month */
71 #define DOM_SEQUENCE_NONE ((uint32)-1)
73 -#define winbind_event_context server_event_context
75 #endif /* _WINBINDD_H */
76 Index: samba-3.6.22/source3/winbindd/winbindd_proto.h
77 ===================================================================
78 --- samba-3.6.22.orig/source3/winbindd/winbindd_proto.h
79 +++ samba-3.6.22/source3/winbindd/winbindd_proto.h
80 @@ -34,6 +34,7 @@ bool winbindd_use_cache(void);
81 void winbindd_register_handlers(void);
82 const char *get_winbind_pipe_dir(void);
83 char *get_winbind_priv_pipe_dir(void);
84 +struct tevent_context *winbind_event_context(void);
85 int main(int argc, char **argv, char **envp);
87 /* The following definitions come from winbindd/winbindd_ads.c */
88 Index: samba-3.6.22/source3/winbindd/winbindd_dual.c
89 ===================================================================
90 --- samba-3.6.22.orig/source3/winbindd/winbindd_dual.c
91 +++ samba-3.6.22/source3/winbindd/winbindd_dual.c
92 @@ -1284,6 +1284,66 @@ NTSTATUS winbindd_reinit_after_fork(cons
96 +struct child_handler_state {
97 + struct winbindd_child *child;
98 + struct winbindd_cli_state *cli_state;
101 +static void child_handler(struct tevent_context *ev, struct tevent_fd *fde,
102 + uint16_t flags, void *private_data)
104 + struct child_handler_state *ch_state =
105 + (struct child_handler_state *)private_data;
106 + struct winbindd_cli_state *state = ch_state->cli_state;
107 + struct iovec iov[2];
111 + if ((flags & TEVENT_FD_READ) == 0) {
115 + /* fetch a request from the main daemon */
116 + status = child_read_request(state);
118 + if (!NT_STATUS_IS_OK(status)) {
119 + /* we lost contact with our parent */
123 + DEBUG(4,("child daemon request %d\n", (int)state->request->cmd));
125 + ZERO_STRUCTP(state->response);
126 + state->request->null_term = '\0';
127 + state->mem_ctx = talloc_tos();
128 + child_process_request(ch_state->child, state);
130 + DEBUG(4, ("Finished processing child request %d\n",
131 + (int)state->request->cmd));
133 + SAFE_FREE(state->request->extra_data.data);
135 + iov[0].iov_base = (void *)state->response;
136 + iov[0].iov_len = sizeof(struct winbindd_response);
139 + if (state->response->length > sizeof(struct winbindd_response)) {
141 + (void *)state->response->extra_data.data;
142 + iov[1].iov_len = state->response->length-iov[0].iov_len;
146 + DEBUG(10, ("Writing %d bytes to parent\n",
147 + (int)state->response->length));
149 + if (write_data_iov(state->sock, iov, iov_count) !=
150 + state->response->length) {
151 + DEBUG(0, ("Could not write result\n"));
157 * In a child there will be only one domain, reference that here.
159 @@ -1301,6 +1361,7 @@ static bool fork_domain_child(struct win
160 struct winbindd_request request;
161 struct winbindd_response response;
162 struct winbindd_domain *primary_domain = NULL;
163 + struct child_handler_state ch_state;
167 @@ -1322,6 +1383,9 @@ static bool fork_domain_child(struct win
168 state.request = &request;
169 state.response = &response;
171 + ch_state.child = child;
172 + ch_state.cli_state = &state;
174 child->pid = sys_fork();
176 if (child->pid == -1) {
177 @@ -1464,22 +1528,14 @@ static bool fork_domain_child(struct win
182 + if (tevent_add_fd(winbind_event_context(), NULL, state.sock,
183 + TEVENT_FD_READ, child_handler, &ch_state) == NULL) {
184 + DEBUG(1, ("tevent_add_fd failed\n"));
189 - struct pollfd *pfds;
193 - struct timeval *tp;
195 TALLOC_CTX *frame = talloc_stackframe();
196 - struct iovec iov[2];
199 - if (run_events_poll(winbind_event_context(), 0, NULL, 0)) {
200 - TALLOC_FREE(frame);
204 if (child->domain && child->domain->startup &&
205 (time_mono(NULL) > child->domain->startup_time + 30)) {
206 @@ -1489,99 +1545,12 @@ static bool fork_domain_child(struct win
207 child->domain->startup = False;
210 - pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd);
211 - if (pfds == NULL) {
212 - DEBUG(1, ("talloc failed\n"));
216 - pfds->fd = state.sock;
217 - pfds->events = POLLIN|POLLHUP;
222 - if (!event_add_to_poll_args(
223 - winbind_event_context(), talloc_tos(),
224 - &pfds, &num_pfds, &timeout)) {
225 - DEBUG(1, ("event_add_to_poll_args failed\n"));
228 - tp = get_timed_events_timeout(winbind_event_context(), &t);
230 - DEBUG(11,("select will use timeout of %u.%u seconds\n",
231 - (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec ));
234 - ret = sys_poll(pfds, num_pfds, timeout);
236 - if (run_events_poll(winbind_event_context(), ret,
238 - /* We got a signal - continue. */
239 - TALLOC_FREE(frame);
246 - DEBUG(11,("nothing is ready yet, continue\n"));
247 - TALLOC_FREE(frame);
251 - if (ret == -1 && errno == EINTR) {
252 - /* We got a signal - continue. */
253 - TALLOC_FREE(frame);
257 - if (ret == -1 && errno != EINTR) {
258 - DEBUG(0,("poll error occured\n"));
259 - TALLOC_FREE(frame);
261 + if (tevent_loop_once(winbind_event_context()) != 0) {
262 + DEBUG(1, ("tevent_loop_once failed: %s\n",
267 - /* fetch a request from the main daemon */
268 - status = child_read_request(&state);
270 - if (!NT_STATUS_IS_OK(status)) {
271 - /* we lost contact with our parent */
275 - DEBUG(4,("child daemon request %d\n", (int)state.request->cmd));
277 - ZERO_STRUCTP(state.response);
278 - state.request->null_term = '\0';
279 - state.mem_ctx = frame;
280 - child_process_request(child, &state);
282 - DEBUG(4, ("Finished processing child request %d\n",
283 - (int)state.request->cmd));
285 - SAFE_FREE(state.request->extra_data.data);
287 - iov[0].iov_base = (void *)state.response;
288 - iov[0].iov_len = sizeof(struct winbindd_response);
291 - if (state.response->length > sizeof(struct winbindd_response)) {
293 - (void *)state.response->extra_data.data;
294 - iov[1].iov_len = state.response->length-iov[0].iov_len;
298 - DEBUG(10, ("Writing %d bytes to parent\n",
299 - (int)state.response->length));
301 - if (write_data_iov(state.sock, iov, iov_count) !=
302 - state.response->length) {
303 - DEBUG(0, ("Could not write result\n"));