]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/samba/samba-3.6.x-winbind_tevent_poll.patch
Merge branch 'core110'
[ipfire-2.x.git] / src / patches / samba / samba-3.6.x-winbind_tevent_poll.patch
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 }