waf: Remove lib prefix from libraries manually.
[kai/samba.git] / source4 / smbd / process_thread.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    thread model: standard (1 thread per client connection)
5
6    Copyright (C) Andrew Tridgell 2003-2005
7    Copyright (C) James J Myers 2003 <myersjj@samba.org>
8    Copyright (C) Stefan (metze) Metzmacher 2004
9    
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14    
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19    
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "version.h"
26 #include <pthread.h>
27 #ifdef HAVE_BACKTRACE
28 #include <execinfo.h>
29 #endif
30 #include "system/wait.h"
31 #include "system/filesys.h"
32 #include "system/time.h"
33 #include "lib/events/events.h"
34 #include "lib/util/dlinklist.h"
35 #include "lib/util/mutex.h"
36 #include "smbd/process_model.h"
37
38 static pthread_key_t title_key;
39
40 struct new_conn_state {
41         struct tevent_context *ev;
42         struct socket_context *sock;
43         struct loadparm_context *lp_ctx;
44         void (*new_conn)(struct tevent_context *, struct loadparm_context *lp_ctx, struct socket_context *, uint32_t , void *);
45         void *private_data;
46 };
47
48 static void *thread_connection_fn(void *thread_parm)
49 {
50         struct new_conn_state *new_conn = talloc_get_type(thread_parm, struct new_conn_state);
51
52         new_conn->new_conn(new_conn->ev, new_conn->lp_ctx, new_conn->sock, pthread_self(), new_conn->private_data);
53
54         /* run this connection from here */
55         event_loop_wait(new_conn->ev);
56
57         talloc_free(new_conn);
58
59         return NULL;
60 }
61
62 /*
63   called when a listening socket becomes readable
64 */
65 static void thread_accept_connection(struct tevent_context *ev, 
66                                      struct loadparm_context *lp_ctx,
67                                      struct socket_context *sock,
68                                      void (*new_conn)(struct tevent_context *, 
69                                                       struct loadparm_context *,
70                                                       struct socket_context *, 
71                                                       uint32_t , void *), 
72                                      void *private_data)
73 {               
74         NTSTATUS status;
75         int rc;
76         pthread_t thread_id;
77         pthread_attr_t thread_attr;
78         struct new_conn_state *state;
79         struct tevent_context *ev2;
80
81         ev2 = s4_event_context_init(ev);
82         if (ev2 == NULL) return;
83
84         state = talloc(ev2, struct new_conn_state);
85         if (state == NULL) {
86                 talloc_free(ev2);
87                 return;
88         }
89
90         state->new_conn = new_conn;
91         state->private_data  = private_data;
92         state->lp_ctx   = lp_ctx;
93         state->ev       = ev2;
94
95         /* accept an incoming connection. */
96         status = socket_accept(sock, &state->sock);
97         if (!NT_STATUS_IS_OK(status)) {
98                 talloc_free(ev2);
99                 /* We need to throttle things until the system clears
100                    enough resources to handle this new socket. If we
101                    don't then we will spin filling the log and causing
102                    more problems. We don't panic as this is probably a
103                    temporary resource constraint */
104                 sleep(1);
105                 return;
106         }
107
108         talloc_steal(state, state->sock);
109
110         pthread_attr_init(&thread_attr);
111         pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
112         rc = pthread_create(&thread_id, &thread_attr, thread_connection_fn, state);
113         pthread_attr_destroy(&thread_attr);
114         if (rc == 0) {
115                 DEBUG(4,("accept_connection_thread: created thread_id=%lu for fd=%d\n", 
116                         (unsigned long int)thread_id, socket_get_fd(sock)));
117         } else {
118                 DEBUG(0,("accept_connection_thread: thread create failed for fd=%d, rc=%d\n", socket_get_fd(sock), rc));
119                 talloc_free(ev2);
120         }
121 }
122
123
124 struct new_task_state {
125         struct tevent_context *ev;
126         struct loadparm_context *lp_ctx;
127         void (*new_task)(struct tevent_context *, struct loadparm_context *, 
128                          uint32_t , void *);
129         void *private_data;
130 };
131
132 static void *thread_task_fn(void *thread_parm)
133 {
134         struct new_task_state *new_task = talloc_get_type(thread_parm, struct new_task_state);
135
136         new_task->new_task(new_task->ev, new_task->lp_ctx, pthread_self(),
137                            new_task->private_data);
138
139         /* run this connection from here */
140         event_loop_wait(new_task->ev);
141
142         talloc_free(new_task);
143
144         return NULL;
145 }
146
147 /*
148   called when a new task is needed
149 */
150 static void thread_new_task(struct tevent_context *ev, 
151                             struct loadparm_context *lp_ctx,
152                             const char *service_name,
153                             void (*new_task)(struct tevent_context *, 
154                                              struct loadparm_context *,
155                                              uint32_t , void *), 
156                             void *private_data)
157 {               
158         int rc;
159         pthread_t thread_id;
160         pthread_attr_t thread_attr;
161         struct new_task_state *state;
162         struct tevent_context *ev2;
163
164         ev2 = s4_event_context_init(ev);
165         if (ev2 == NULL) return;
166
167         state = talloc(ev2, struct new_task_state);
168         if (state == NULL) {
169                 talloc_free(ev2);
170                 return;
171         }
172
173         state->new_task = new_task;
174         state->lp_ctx   = lp_ctx;
175         state->private_data  = private_data;
176         state->ev       = ev2;
177
178         pthread_attr_init(&thread_attr);
179         pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
180         rc = pthread_create(&thread_id, &thread_attr, thread_task_fn, state);
181         pthread_attr_destroy(&thread_attr);
182         if (rc == 0) {
183                 DEBUG(4,("thread_new_task: created %s thread_id=%lu\n", 
184                          service_name, (unsigned long int)thread_id));
185         } else {
186                 DEBUG(0,("thread_new_task: thread create for %s failed rc=%d\n", service_name, rc));
187                 talloc_free(ev2);
188         }
189 }
190
191 /* called when a task goes down */
192 static void thread_terminate(struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, const char *reason)
193 {
194         DEBUG(10,("thread_terminate: reason[%s]\n",reason));
195
196         talloc_free(event_ctx);
197
198         /* terminate this thread */
199         pthread_exit(NULL);  /* thread cleanup routine will do actual cleanup */
200 }
201
202 /* called to set a title of a task or connection */
203 static void thread_set_title(struct tevent_context *ev, const char *title) 
204 {
205         char *old_title;
206         char *new_title;
207
208         old_title = pthread_getspecific(title_key);
209         talloc_free(old_title);
210
211         new_title = talloc_strdup(ev, title);
212         pthread_setspecific(title_key, new_title);
213 }
214
215 /*
216   mutex init function for thread model
217 */
218 static int thread_mutex_init(smb_mutex_t *mutex, const char *name)
219 {
220         pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
221         mutex->mutex = memdup(&m, sizeof(m));
222         if (! mutex->mutex) {
223                 errno = ENOMEM;
224                 return -1;
225         }
226         return pthread_mutex_init((pthread_mutex_t *)mutex->mutex, NULL);
227 }
228
229 /*
230   mutex destroy function for thread model
231 */
232 static int thread_mutex_destroy(smb_mutex_t *mutex, const char *name)
233 {
234         return pthread_mutex_destroy((pthread_mutex_t *)mutex->mutex);
235 }
236
237 static void mutex_start_timer(struct timespec *tp1)
238 {
239         clock_gettime_mono(tp1);
240 }
241
242 static double mutex_end_timer(struct timespec tp1)
243 {
244         struct timespec tp2;
245
246         clock_gettime_mono(&tp2);
247         return((tp2.tv_sec - tp1.tv_sec) + 
248                (tp2.tv_nsec - tp1.tv_nsec)*1.0e-9);
249 }
250
251 /*
252   mutex lock function for thread model
253 */
254 static int thread_mutex_lock(smb_mutex_t *mutexP, const char *name)
255 {
256         pthread_mutex_t *mutex = (pthread_mutex_t *)mutexP->mutex;
257         int rc;
258         double t;
259         struct timespec tp1;
260         /* Test below is ONLY for debugging */
261         if ((rc = pthread_mutex_trylock(mutex))) {
262                 if (rc == EBUSY) {
263                         mutex_start_timer(&tp1);
264                         printf("mutex lock: thread %d, lock %s not available\n", 
265                                 (uint32_t)pthread_self(), name);
266                         print_suspicious_usage("mutex_lock", name);
267                         pthread_mutex_lock(mutex);
268                         t = mutex_end_timer(tp1);
269                         printf("mutex lock: thread %d, lock %s now available, waited %g seconds\n", 
270                                 (uint32_t)pthread_self(), name, t);
271                         return 0;
272                 }
273                 printf("mutex lock: thread %d, lock %s failed rc=%d\n", 
274                                 (uint32_t)pthread_self(), name, rc);
275                 SMB_ASSERT(errno == 0); /* force error */
276         }
277         return 0;
278 }
279
280 /* 
281    mutex unlock for thread model
282 */
283 static int thread_mutex_unlock(smb_mutex_t *mutex, const char *name)
284 {
285         return pthread_mutex_unlock((pthread_mutex_t *)mutex->mutex);
286 }
287
288 /*****************************************************************
289  Read/write lock routines.
290 *****************************************************************/  
291 /*
292   rwlock init function for thread model
293 */
294 static int thread_rwlock_init(smb_rwlock_t *rwlock, const char *name)
295 {
296         pthread_rwlock_t m = PTHREAD_RWLOCK_INITIALIZER;
297         rwlock->rwlock = memdup(&m, sizeof(m));
298         if (! rwlock->rwlock) {
299                 errno = ENOMEM;
300                 return -1;
301         }
302         return pthread_rwlock_init((pthread_rwlock_t *)rwlock->rwlock, NULL);
303 }
304
305 /*
306   rwlock destroy function for thread model
307 */
308 static int thread_rwlock_destroy(smb_rwlock_t *rwlock, const char *name)
309 {
310         return pthread_rwlock_destroy((pthread_rwlock_t *)rwlock->rwlock);
311 }
312
313 /*
314   rwlock lock for read function for thread model
315 */
316 static int thread_rwlock_lock_read(smb_rwlock_t *rwlockP, const char *name)
317 {
318         pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock;
319         int rc;
320         double t;
321         struct timespec tp1;
322         /* Test below is ONLY for debugging */
323         if ((rc = pthread_rwlock_tryrdlock(rwlock))) {
324                 if (rc == EBUSY) {
325                         mutex_start_timer(&tp1);
326                         printf("rwlock lock_read: thread %d, lock %s not available\n", 
327                                 (uint32_t)pthread_self(), name);
328                         print_suspicious_usage("rwlock_lock_read", name);
329                         pthread_rwlock_rdlock(rwlock);
330                         t = mutex_end_timer(tp1);
331                         printf("rwlock lock_read: thread %d, lock %s now available, waited %g seconds\n", 
332                                 (uint32_t)pthread_self(), name, t);
333                         return 0;
334                 }
335                 printf("rwlock lock_read: thread %d, lock %s failed rc=%d\n", 
336                                 (uint32_t)pthread_self(), name, rc);
337                 SMB_ASSERT(errno == 0); /* force error */
338         }
339         return 0;
340 }
341
342 /*
343   rwlock lock for write function for thread model
344 */
345 static int thread_rwlock_lock_write(smb_rwlock_t *rwlockP, const char *name)
346 {
347         pthread_rwlock_t *rwlock = (pthread_rwlock_t *)rwlockP->rwlock;
348         int rc;
349         double t;
350         struct timespec tp1;
351         /* Test below is ONLY for debugging */
352         if ((rc = pthread_rwlock_trywrlock(rwlock))) {
353                 if (rc == EBUSY) {
354                         mutex_start_timer(&tp1);
355                         printf("rwlock lock_write: thread %d, lock %s not available\n", 
356                                 (uint32_t)pthread_self(), name);
357                         print_suspicious_usage("rwlock_lock_write", name);
358                         pthread_rwlock_wrlock(rwlock);
359                         t = mutex_end_timer(tp1);
360                         printf("rwlock lock_write: thread %d, lock %s now available, waited %g seconds\n", 
361                                 (uint32_t)pthread_self(), name, t);
362                         return 0;
363                 }
364                 printf("rwlock lock_write: thread %d, lock %s failed rc=%d\n", 
365                                 (uint32_t)pthread_self(), name, rc);
366                 SMB_ASSERT(errno == 0); /* force error */
367         }
368         return 0;
369 }
370
371
372 /* 
373    rwlock unlock for thread model
374 */
375 static int thread_rwlock_unlock(smb_rwlock_t *rwlock, const char *name)
376 {
377         return pthread_rwlock_unlock((pthread_rwlock_t *)rwlock->rwlock);
378 }
379
380 /*****************************************************************
381  Log suspicious usage (primarily for possible thread-unsafe behavior).
382 *****************************************************************/  
383 static void thread_log_suspicious_usage(const char* from, const char* info)
384 {
385         DEBUG(1,("log_suspicious_usage: from %s info='%s'\n", from, info));
386 #ifdef HAVE_BACKTRACE
387         {
388                 void *addresses[10];
389                 int num_addresses = backtrace(addresses, 8);
390                 char **bt_symbols = backtrace_symbols(addresses, num_addresses);
391                 int i;
392
393                 if (bt_symbols) {
394                         for (i=0; i<num_addresses; i++) {
395                                 DEBUG(1,("log_suspicious_usage: %s%s\n", DEBUGTAB(1), bt_symbols[i]));
396                         }
397                         free(bt_symbols);
398                 }
399         }
400 #endif
401 }
402
403 /*****************************************************************
404  Log suspicious usage to stdout (primarily for possible thread-unsafe behavior.
405  Used in mutex code where DEBUG calls would cause recursion.
406 *****************************************************************/  
407 static void thread_print_suspicious_usage(const char* from, const char* info)
408 {
409         printf("log_suspicious_usage: from %s info='%s'\n", from, info);
410 #ifdef HAVE_BACKTRACE
411         {
412                 void *addresses[10];
413                 int num_addresses = backtrace(addresses, 8);
414                 char **bt_symbols = backtrace_symbols(addresses, num_addresses);
415                 int i;
416
417                 if (bt_symbols) {
418                         for (i=0; i<num_addresses; i++) {
419                                 printf("log_suspicious_usage: %s%s\n", DEBUGTAB(1), bt_symbols[i]);
420                         }
421                         free(bt_symbols);
422                 }
423         }
424 #endif
425 }
426
427 static uint32_t thread_get_task_id(void)
428 {
429         return (uint32_t)pthread_self();
430 }
431
432 static void thread_log_task_id(int fd)
433 {
434         char *s= NULL;
435
436         asprintf(&s, "thread[%u][%s]:\n", 
437                 (uint32_t)pthread_self(),
438                 (const char *)pthread_getspecific(title_key));
439         if (!s) return;
440         write(fd, s, strlen(s));
441         free(s);
442 }
443
444 /****************************************************************************
445 catch serious errors
446 ****************************************************************************/
447 static void thread_sig_fault(int sig)
448 {
449         DEBUG(0,("===============================================================\n"));
450         DEBUG(0,("TERMINAL ERROR: Recursive signal %d in thread [%u][%s] (%s)\n",
451                 sig,(uint32_t)pthread_self(),
452                 (const char *)pthread_getspecific(title_key),
453                 SAMBA_VERSION_STRING));
454         DEBUG(0,("===============================================================\n"));
455         exit(1); /* kill the whole server for now */
456 }
457
458 /*******************************************************************
459 setup our recursive fault handlers
460 ********************************************************************/
461 static void thread_fault_setup(void)
462 {
463 #ifdef SIGSEGV
464         CatchSignal(SIGSEGV, thread_sig_fault);
465 #endif
466 #ifdef SIGBUS
467         CatchSignal(SIGBUS, thread_sig_fault);
468 #endif
469 #ifdef SIGABRT
470         CatchSignal(SIGABRT, thread_sig_fault);
471 #endif
472 }
473
474 /*******************************************************************
475 report a fault in a thread
476 ********************************************************************/
477 static void thread_fault_handler(int sig)
478 {
479         static int counter;
480         
481         /* try to catch recursive faults */
482         thread_fault_setup();
483         
484         counter++;      /* count number of faults that have occurred */
485
486         DEBUG(0,("===============================================================\n"));
487         DEBUG(0,("INTERNAL ERROR: Signal %d in thread [%u] [%s] (%s)\n",
488                 sig,(uint32_t)pthread_self(),
489                 (const char *)pthread_getspecific(title_key),
490                 SAMBA_VERSION_STRING));
491         DEBUG(0,("Please read the file BUGS.txt in the distribution\n"));
492         DEBUG(0,("===============================================================\n"));
493 #ifdef HAVE_BACKTRACE
494         {
495                 void *addresses[10];
496                 int num_addresses = backtrace(addresses, 8);
497                 char **bt_symbols = backtrace_symbols(addresses, num_addresses);
498                 int i;
499
500                 if (bt_symbols) {
501                         for (i=0; i<num_addresses; i++) {
502                                 DEBUG(1,("fault_report: %s%s\n", DEBUGTAB(1), bt_symbols[i]));
503                         }
504                         free(bt_symbols);
505                 }
506         }
507 #endif
508         pthread_exit(NULL); /* terminate failing thread only */
509 }
510
511 /*
512   called when the process model is selected
513 */
514 static void thread_model_init(struct tevent_context *event_context)
515 {
516         struct mutex_ops m_ops;
517         struct debug_ops d_ops;
518
519         ZERO_STRUCT(m_ops);
520         ZERO_STRUCT(d_ops);
521
522         pthread_key_create(&title_key, NULL);
523         pthread_setspecific(title_key, talloc_strdup(event_context, ""));
524
525         /* register mutex/rwlock handlers */
526         m_ops.mutex_init = thread_mutex_init;
527         m_ops.mutex_lock = thread_mutex_lock;
528         m_ops.mutex_unlock = thread_mutex_unlock;
529         m_ops.mutex_destroy = thread_mutex_destroy;
530         
531         m_ops.rwlock_init = thread_rwlock_init;
532         m_ops.rwlock_lock_write = thread_rwlock_lock_write;
533         m_ops.rwlock_lock_read = thread_rwlock_lock_read;
534         m_ops.rwlock_unlock = thread_rwlock_unlock;
535         m_ops.rwlock_destroy = thread_rwlock_destroy;
536
537         register_mutex_handlers("thread", &m_ops);
538
539         register_fault_handler("thread", thread_fault_handler);
540
541         d_ops.log_suspicious_usage = thread_log_suspicious_usage;
542         d_ops.print_suspicious_usage = thread_print_suspicious_usage;
543         d_ops.get_task_id = thread_get_task_id;
544         d_ops.log_task_id = thread_log_task_id;
545
546         register_debug_handlers("thread", &d_ops);
547 }
548
549
550 static const struct model_ops thread_ops = {
551         .name                   = "thread",
552         .model_init             = thread_model_init,
553         .accept_connection      = thread_accept_connection,
554         .new_task               = thread_new_task,
555         .terminate              = thread_terminate,
556         .set_title              = thread_set_title,
557 };
558
559 /*
560   initialise the thread process model, registering ourselves with the model subsystem
561  */
562 NTSTATUS process_model_thread_init(void)
563 {
564         NTSTATUS ret;
565
566         /* register ourselves with the PROCESS_MODEL subsystem. */
567         ret = register_process_model(&thread_ops);
568         if (!NT_STATUS_IS_OK(ret)) {
569                 DEBUG(0,("Failed to register process_model 'thread'!\n"));
570                 return ret;
571         }
572
573         return ret;
574 }