]>
Commit | Line | Data |
---|---|---|
1d13e637 AF |
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 | |
5 | ||
6 | This makes winbind use epoll instead of poll | |
7 | --- | |
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(-) | |
12 | ||
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; | |
18 | ||
19 | extern bool override_logfile; | |
20 | ||
21 | +struct tevent_context *winbind_event_context(void) | |
22 | +{ | |
23 | + static struct tevent_context *ev = NULL; | |
24 | + | |
25 | + if (ev != NULL) { | |
26 | + return ev; | |
27 | + } | |
28 | + | |
29 | + /* | |
30 | + * Note we MUST use the NULL context here, not the autofree context, | |
31 | + * to avoid side effects in forked children exiting. | |
32 | + */ | |
33 | + ev = tevent_context_init(NULL); | |
34 | + if (ev == NULL) { | |
35 | + smb_panic("Could not init winbindd's messaging context.\n"); | |
36 | + } | |
37 | + return ev; | |
38 | +} | |
39 | + | |
40 | struct messaging_context *winbind_messaging_context(void) | |
41 | { | |
42 | - struct messaging_context *msg_ctx = server_messaging_context(); | |
43 | - if (likely(msg_ctx != NULL)) { | |
44 | - return msg_ctx; | |
45 | + static struct messaging_context *msg = NULL; | |
46 | + | |
47 | + if (msg != NULL) { | |
48 | + return msg; | |
49 | + } | |
50 | + | |
51 | + /* | |
52 | + * Note we MUST use the NULL context here, not the autofree context, | |
53 | + * to avoid side effects in forked children exiting. | |
54 | + */ | |
55 | + msg = messaging_init(NULL, procid_self(), winbind_event_context()); | |
56 | + if (msg == NULL) { | |
57 | + smb_panic("Could not init winbindd's messaging context.\n"); | |
58 | } | |
59 | - smb_panic("Could not init winbindd's messaging context.\n"); | |
60 | - return NULL; | |
61 | + return msg; | |
62 | } | |
63 | ||
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) | |
72 | ||
73 | -#define winbind_event_context server_event_context | |
74 | - | |
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); | |
86 | ||
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 | |
93 | return NT_STATUS_OK; | |
94 | } | |
95 | ||
96 | +struct child_handler_state { | |
97 | + struct winbindd_child *child; | |
98 | + struct winbindd_cli_state *cli_state; | |
99 | +}; | |
100 | + | |
101 | +static void child_handler(struct tevent_context *ev, struct tevent_fd *fde, | |
102 | + uint16_t flags, void *private_data) | |
103 | +{ | |
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]; | |
108 | + int iov_count; | |
109 | + NTSTATUS status; | |
110 | + | |
111 | + if ((flags & TEVENT_FD_READ) == 0) { | |
112 | + return; | |
113 | + } | |
114 | + | |
115 | + /* fetch a request from the main daemon */ | |
116 | + status = child_read_request(state); | |
117 | + | |
118 | + if (!NT_STATUS_IS_OK(status)) { | |
119 | + /* we lost contact with our parent */ | |
120 | + _exit(0); | |
121 | + } | |
122 | + | |
123 | + DEBUG(4,("child daemon request %d\n", (int)state->request->cmd)); | |
124 | + | |
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); | |
129 | + | |
130 | + DEBUG(4, ("Finished processing child request %d\n", | |
131 | + (int)state->request->cmd)); | |
132 | + | |
133 | + SAFE_FREE(state->request->extra_data.data); | |
134 | + | |
135 | + iov[0].iov_base = (void *)state->response; | |
136 | + iov[0].iov_len = sizeof(struct winbindd_response); | |
137 | + iov_count = 1; | |
138 | + | |
139 | + if (state->response->length > sizeof(struct winbindd_response)) { | |
140 | + iov[1].iov_base = | |
141 | + (void *)state->response->extra_data.data; | |
142 | + iov[1].iov_len = state->response->length-iov[0].iov_len; | |
143 | + iov_count = 2; | |
144 | + } | |
145 | + | |
146 | + DEBUG(10, ("Writing %d bytes to parent\n", | |
147 | + (int)state->response->length)); | |
148 | + | |
149 | + if (write_data_iov(state->sock, iov, iov_count) != | |
150 | + state->response->length) { | |
151 | + DEBUG(0, ("Could not write result\n")); | |
152 | + exit(1); | |
153 | + } | |
154 | +} | |
155 | + | |
156 | /* | |
157 | * In a child there will be only one domain, reference that here. | |
158 | */ | |
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; | |
164 | NTSTATUS status; | |
165 | ssize_t nwritten; | |
166 | ||
167 | @@ -1322,6 +1383,9 @@ static bool fork_domain_child(struct win | |
168 | state.request = &request; | |
169 | state.response = &response; | |
170 | ||
171 | + ch_state.child = child; | |
172 | + ch_state.cli_state = &state; | |
173 | + | |
174 | child->pid = sys_fork(); | |
175 | ||
176 | if (child->pid == -1) { | |
177 | @@ -1464,22 +1528,14 @@ static bool fork_domain_child(struct win | |
178 | } | |
179 | } | |
180 | ||
181 | - while (1) { | |
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")); | |
185 | + exit(1); | |
186 | + } | |
187 | ||
188 | - int ret; | |
189 | - struct pollfd *pfds; | |
190 | - int num_pfds; | |
191 | - int timeout; | |
192 | - struct timeval t; | |
193 | - struct timeval *tp; | |
194 | + while (1) { | |
195 | TALLOC_CTX *frame = talloc_stackframe(); | |
196 | - struct iovec iov[2]; | |
197 | - int iov_count; | |
198 | - | |
199 | - if (run_events_poll(winbind_event_context(), 0, NULL, 0)) { | |
200 | - TALLOC_FREE(frame); | |
201 | - continue; | |
202 | - } | |
203 | ||
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; | |
208 | } | |
209 | ||
210 | - pfds = TALLOC_ZERO_P(talloc_tos(), struct pollfd); | |
211 | - if (pfds == NULL) { | |
212 | - DEBUG(1, ("talloc failed\n")); | |
213 | - _exit(1); | |
214 | - } | |
215 | - | |
216 | - pfds->fd = state.sock; | |
217 | - pfds->events = POLLIN|POLLHUP; | |
218 | - num_pfds = 1; | |
219 | - | |
220 | - timeout = INT_MAX; | |
221 | - | |
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")); | |
226 | - _exit(1); | |
227 | - } | |
228 | - tp = get_timed_events_timeout(winbind_event_context(), &t); | |
229 | - if (tp) { | |
230 | - DEBUG(11,("select will use timeout of %u.%u seconds\n", | |
231 | - (unsigned int)tp->tv_sec, (unsigned int)tp->tv_usec )); | |
232 | - } | |
233 | - | |
234 | - ret = sys_poll(pfds, num_pfds, timeout); | |
235 | - | |
236 | - if (run_events_poll(winbind_event_context(), ret, | |
237 | - pfds, num_pfds)) { | |
238 | - /* We got a signal - continue. */ | |
239 | - TALLOC_FREE(frame); | |
240 | - continue; | |
241 | - } | |
242 | - | |
243 | - TALLOC_FREE(pfds); | |
244 | - | |
245 | - if (ret == 0) { | |
246 | - DEBUG(11,("nothing is ready yet, continue\n")); | |
247 | - TALLOC_FREE(frame); | |
248 | - continue; | |
249 | - } | |
250 | - | |
251 | - if (ret == -1 && errno == EINTR) { | |
252 | - /* We got a signal - continue. */ | |
253 | - TALLOC_FREE(frame); | |
254 | - continue; | |
255 | - } | |
256 | - | |
257 | - if (ret == -1 && errno != EINTR) { | |
258 | - DEBUG(0,("poll error occured\n")); | |
259 | - TALLOC_FREE(frame); | |
260 | - perror("poll"); | |
261 | + if (tevent_loop_once(winbind_event_context()) != 0) { | |
262 | + DEBUG(1, ("tevent_loop_once failed: %s\n", | |
263 | + strerror(errno))); | |
264 | _exit(1); | |
265 | } | |
266 | ||
267 | - /* fetch a request from the main daemon */ | |
268 | - status = child_read_request(&state); | |
269 | - | |
270 | - if (!NT_STATUS_IS_OK(status)) { | |
271 | - /* we lost contact with our parent */ | |
272 | - _exit(0); | |
273 | - } | |
274 | - | |
275 | - DEBUG(4,("child daemon request %d\n", (int)state.request->cmd)); | |
276 | - | |
277 | - ZERO_STRUCTP(state.response); | |
278 | - state.request->null_term = '\0'; | |
279 | - state.mem_ctx = frame; | |
280 | - child_process_request(child, &state); | |
281 | - | |
282 | - DEBUG(4, ("Finished processing child request %d\n", | |
283 | - (int)state.request->cmd)); | |
284 | - | |
285 | - SAFE_FREE(state.request->extra_data.data); | |
286 | - | |
287 | - iov[0].iov_base = (void *)state.response; | |
288 | - iov[0].iov_len = sizeof(struct winbindd_response); | |
289 | - iov_count = 1; | |
290 | - | |
291 | - if (state.response->length > sizeof(struct winbindd_response)) { | |
292 | - iov[1].iov_base = | |
293 | - (void *)state.response->extra_data.data; | |
294 | - iov[1].iov_len = state.response->length-iov[0].iov_len; | |
295 | - iov_count = 2; | |
296 | - } | |
297 | - | |
298 | - DEBUG(10, ("Writing %d bytes to parent\n", | |
299 | - (int)state.response->length)); | |
300 | - | |
301 | - if (write_data_iov(state.sock, iov, iov_count) != | |
302 | - state.response->length) { | |
303 | - DEBUG(0, ("Could not write result\n")); | |
304 | - exit(1); | |
305 | - } | |
306 | TALLOC_FREE(frame); | |
307 | } | |
308 | } |