]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/samba/samba-3.6.x-winbind_tevent_poll.patch
samba: add current RHEL6 patches
[ipfire-2.x.git] / src / patches / samba / samba-3.6.x-winbind_tevent_poll.patch
CommitLineData
1d13e637
AF
1From 1d94210adc6e0bb8a08fbfc1a516a0f958dbf744 Mon Sep 17 00:00:00 2001
2From: Volker Lendecke <vl@samba.org>
3Date: Wed, 16 Jan 2013 12:00:00 +0100
4Subject: [PATCH 1/2] winbind: Use standard tevent_context_init
5
6This 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
13Index: 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 */
65Index: 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 */
76Index: 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 */
88Index: 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 }