4a9a7a4929200bfd53c838eed13b48f52dd0ae50
[lttng-tools.git] / src / bin / lttng-consumerd / lttng-consumerd.c
1 /*
2 * Copyright (C) 2011 - Julien Desfossez <julien.desfossez@polymtl.ca>
3 * Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License, version 2 only,
7 * as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19 #define _GNU_SOURCE
20 #include <fcntl.h>
21 #include <getopt.h>
22 #include <grp.h>
23 #include <limits.h>
24 #include <pthread.h>
25 #include <signal.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/ipc.h>
30 #include <sys/resource.h>
31 #include <sys/shm.h>
32 #include <sys/socket.h>
33 #include <sys/stat.h>
34 #include <sys/types.h>
35 #include <urcu/list.h>
36 #include <poll.h>
37 #include <unistd.h>
38 #include <sys/mman.h>
39 #include <assert.h>
40 #include <config.h>
41 #include <urcu/compiler.h>
42 #include <ulimit.h>
43
44 #include <common/defaults.h>
45 #include <common/common.h>
46 #include <common/consumer.h>
47 #include <common/consumer-timer.h>
48 #include <common/compat/poll.h>
49 #include <common/sessiond-comm/sessiond-comm.h>
50 #include <common/utils.h>
51
52 #include "lttng-consumerd.h"
53 #include "health-consumerd.h"
54
55 /* TODO : support UST (all direct kernel-ctl accesses). */
56
57 /* threads (channel handling, poll, metadata, sessiond) */
58
59 static pthread_t channel_thread, data_thread, metadata_thread,
60 sessiond_thread, metadata_timer_thread, health_thread;
61
62 /* to count the number of times the user pressed ctrl+c */
63 static int sigintcount = 0;
64
65 /* Argument variables */
66 int lttng_opt_quiet; /* not static in error.h */
67 int lttng_opt_verbose; /* not static in error.h */
68 static int opt_daemon;
69 static const char *progname;
70 static char command_sock_path[PATH_MAX]; /* Global command socket path */
71 static char error_sock_path[PATH_MAX]; /* Global error path */
72 static enum lttng_consumer_type opt_type = LTTNG_CONSUMER_KERNEL;
73
74 /* the liblttngconsumerd context */
75 static struct lttng_consumer_local_data *ctx;
76
77 /* Consumerd health monitoring */
78 struct health_app *health_consumerd;
79
80 const char *tracing_group_name = DEFAULT_TRACING_GROUP;
81
82 int lttng_consumer_ready = NR_LTTNG_CONSUMER_READY;
83
84 enum lttng_consumer_type lttng_consumer_get_type(void)
85 {
86 if (!ctx) {
87 return LTTNG_CONSUMER_UNKNOWN;
88 }
89 return ctx->type;
90 }
91
92 /*
93 * Signal handler for the daemon
94 */
95 static void sighandler(int sig)
96 {
97 if (sig == SIGINT && sigintcount++ == 0) {
98 DBG("ignoring first SIGINT");
99 return;
100 }
101
102 /*
103 * Ignore SIGPIPE because it should not stop the consumer whenever a
104 * SIGPIPE is catched through a FD operation.
105 */
106 if (sig == SIGPIPE) {
107 return;
108 }
109
110 lttng_consumer_should_exit(ctx);
111 }
112
113 /*
114 * Setup signal handler for :
115 * SIGINT, SIGTERM, SIGPIPE
116 */
117 static int set_signal_handler(void)
118 {
119 int ret = 0;
120 struct sigaction sa;
121 sigset_t sigset;
122
123 if ((ret = sigemptyset(&sigset)) < 0) {
124 perror("sigemptyset");
125 return ret;
126 }
127
128 sa.sa_handler = sighandler;
129 sa.sa_mask = sigset;
130 sa.sa_flags = 0;
131 if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
132 perror("sigaction");
133 return ret;
134 }
135
136 if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
137 perror("sigaction");
138 return ret;
139 }
140
141 if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
142 perror("sigaction");
143 return ret;
144 }
145
146 return ret;
147 }
148
149 /*
150 * Usage function on stream file.
151 */
152 static void usage(FILE *fp)
153 {
154 fprintf(fp, "Usage: %s OPTIONS\n\nOptions:\n", progname);
155 fprintf(fp, " -h, --help "
156 "Display this usage.\n");
157 fprintf(fp, " -c, --consumerd-cmd-sock PATH "
158 "Specify path for the command socket\n");
159 fprintf(fp, " -e, --consumerd-err-sock PATH "
160 "Specify path for the error socket\n");
161 fprintf(fp, " -d, --daemonize "
162 "Start as a daemon.\n");
163 fprintf(fp, " -q, --quiet "
164 "No output at all.\n");
165 fprintf(fp, " -v, --verbose "
166 "Verbose mode. Activate DBG() macro.\n");
167 fprintf(fp, " -V, --version "
168 "Show version number.\n");
169 fprintf(fp, " -g, --group NAME "
170 "Specify the tracing group name. (default: tracing)\n");
171 fprintf(fp, " -k, --kernel "
172 "Consumer kernel buffers (default).\n");
173 fprintf(fp, " -u, --ust "
174 "Consumer UST buffers.%s\n",
175 #ifdef HAVE_LIBLTTNG_UST_CTL
176 ""
177 #else
178 " (support not compiled in)"
179 #endif
180 );
181 }
182
183 /*
184 * daemon argument parsing
185 */
186 static void parse_args(int argc, char **argv)
187 {
188 int c;
189
190 static struct option long_options[] = {
191 { "consumerd-cmd-sock", 1, 0, 'c' },
192 { "consumerd-err-sock", 1, 0, 'e' },
193 { "daemonize", 0, 0, 'd' },
194 { "group", 1, 0, 'g' },
195 { "help", 0, 0, 'h' },
196 { "quiet", 0, 0, 'q' },
197 { "verbose", 0, 0, 'v' },
198 { "version", 0, 0, 'V' },
199 { "kernel", 0, 0, 'k' },
200 #ifdef HAVE_LIBLTTNG_UST_CTL
201 { "ust", 0, 0, 'u' },
202 #endif
203 { NULL, 0, 0, 0 }
204 };
205
206 while (1) {
207 int option_index = 0;
208 c = getopt_long(argc, argv, "dhqvVku" "c:e:g:", long_options, &option_index);
209 if (c == -1) {
210 break;
211 }
212
213 switch (c) {
214 case 0:
215 fprintf(stderr, "option %s", long_options[option_index].name);
216 if (optarg) {
217 fprintf(stderr, " with arg %s\n", optarg);
218 }
219 break;
220 case 'c':
221 snprintf(command_sock_path, PATH_MAX, "%s", optarg);
222 break;
223 case 'e':
224 snprintf(error_sock_path, PATH_MAX, "%s", optarg);
225 break;
226 case 'd':
227 opt_daemon = 1;
228 break;
229 case 'g':
230 tracing_group_name = optarg;
231 break;
232 case 'h':
233 usage(stdout);
234 exit(EXIT_SUCCESS);
235 case 'q':
236 lttng_opt_quiet = 1;
237 break;
238 case 'v':
239 lttng_opt_verbose = 1;
240 break;
241 case 'V':
242 fprintf(stdout, "%s\n", VERSION);
243 exit(EXIT_SUCCESS);
244 case 'k':
245 opt_type = LTTNG_CONSUMER_KERNEL;
246 break;
247 #ifdef HAVE_LIBLTTNG_UST_CTL
248 case 'u':
249 # if (CAA_BITS_PER_LONG == 64)
250 opt_type = LTTNG_CONSUMER64_UST;
251 # elif (CAA_BITS_PER_LONG == 32)
252 opt_type = LTTNG_CONSUMER32_UST;
253 # else
254 # error "Unknown bitness"
255 # endif
256 break;
257 #endif
258 default:
259 usage(stderr);
260 exit(EXIT_FAILURE);
261 }
262 }
263 }
264
265 /*
266 * Set open files limit to unlimited. This daemon can open a large number of
267 * file descriptors in order to consumer multiple kernel traces.
268 */
269 static void set_ulimit(void)
270 {
271 int ret;
272 struct rlimit lim;
273
274 /* The kernel does not allowed an infinite limit for open files */
275 lim.rlim_cur = 65535;
276 lim.rlim_max = 65535;
277
278 ret = setrlimit(RLIMIT_NOFILE, &lim);
279 if (ret < 0) {
280 PERROR("failed to set open files limit");
281 }
282 }
283
284 /*
285 * main
286 */
287 int main(int argc, char **argv)
288 {
289 int ret = 0;
290 void *status;
291
292 /* Parse arguments */
293 progname = argv[0];
294 parse_args(argc, argv);
295
296 /* Daemonize */
297 if (opt_daemon) {
298 int i;
299
300 /*
301 * fork
302 * child: setsid, close FD 0, 1, 2, chdir /
303 * parent: exit (if fork is successful)
304 */
305 ret = daemon(0, 0);
306 if (ret < 0) {
307 PERROR("daemon");
308 goto error;
309 }
310 /*
311 * We are in the child. Make sure all other file
312 * descriptors are closed, in case we are called with
313 * more opened file descriptors than the standard ones.
314 */
315 for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
316 (void) close(i);
317 }
318 }
319
320 /* Set up max poll set size */
321 lttng_poll_set_max_size();
322
323 if (*command_sock_path == '\0') {
324 switch (opt_type) {
325 case LTTNG_CONSUMER_KERNEL:
326 snprintf(command_sock_path, PATH_MAX, DEFAULT_KCONSUMERD_CMD_SOCK_PATH,
327 DEFAULT_LTTNG_RUNDIR);
328 break;
329 case LTTNG_CONSUMER64_UST:
330 snprintf(command_sock_path, PATH_MAX,
331 DEFAULT_USTCONSUMERD64_CMD_SOCK_PATH, DEFAULT_LTTNG_RUNDIR);
332 break;
333 case LTTNG_CONSUMER32_UST:
334 snprintf(command_sock_path, PATH_MAX,
335 DEFAULT_USTCONSUMERD32_CMD_SOCK_PATH, DEFAULT_LTTNG_RUNDIR);
336 break;
337 default:
338 WARN("Unknown consumerd type");
339 goto error;
340 }
341 }
342
343 /* Init */
344 lttng_consumer_init();
345 /* Init socket timeouts */
346 lttcomm_init();
347 lttcomm_inet_init();
348
349 if (!getuid()) {
350 /* Set limit for open files */
351 set_ulimit();
352 }
353
354 health_consumerd = health_app_create(NR_HEALTH_CONSUMERD_TYPES);
355 if (!health_consumerd) {
356 goto error;
357 }
358
359 /* create the consumer instance with and assign the callbacks */
360 ctx = lttng_consumer_create(opt_type, lttng_consumer_read_subbuffer,
361 NULL, lttng_consumer_on_recv_stream, NULL);
362 if (ctx == NULL) {
363 goto error;
364 }
365
366 lttng_consumer_set_command_sock_path(ctx, command_sock_path);
367 if (*error_sock_path == '\0') {
368 switch (opt_type) {
369 case LTTNG_CONSUMER_KERNEL:
370 snprintf(error_sock_path, PATH_MAX, DEFAULT_KCONSUMERD_ERR_SOCK_PATH,
371 DEFAULT_LTTNG_RUNDIR);
372 break;
373 case LTTNG_CONSUMER64_UST:
374 snprintf(error_sock_path, PATH_MAX,
375 DEFAULT_USTCONSUMERD64_ERR_SOCK_PATH, DEFAULT_LTTNG_RUNDIR);
376 break;
377 case LTTNG_CONSUMER32_UST:
378 snprintf(error_sock_path, PATH_MAX,
379 DEFAULT_USTCONSUMERD32_ERR_SOCK_PATH, DEFAULT_LTTNG_RUNDIR);
380 break;
381 default:
382 WARN("Unknown consumerd type");
383 goto error;
384 }
385 }
386
387 if (set_signal_handler() < 0) {
388 goto error;
389 }
390
391 /* Connect to the socket created by lttng-sessiond to report errors */
392 DBG("Connecting to error socket %s", error_sock_path);
393 ret = lttcomm_connect_unix_sock(error_sock_path);
394 /* not a fatal error, but all communication with lttng-sessiond will fail */
395 if (ret < 0) {
396 WARN("Cannot connect to error socket (is lttng-sessiond started?)");
397 }
398 lttng_consumer_set_error_sock(ctx, ret);
399
400 /*
401 * Block RT signals used for UST periodical metadata flush and the live
402 * timer in main, and create a dedicated thread to handle these signals.
403 */
404 consumer_signal_init();
405
406 ctx->type = opt_type;
407
408 /* Initialize communication library */
409 lttcomm_init();
410
411 ret = utils_create_pipe(health_quit_pipe);
412 if (ret < 0) {
413 goto error_health_pipe;
414 }
415
416 /* Create thread to manage the client socket */
417 ret = pthread_create(&health_thread, NULL,
418 thread_manage_health, (void *) NULL);
419 if (ret != 0) {
420 PERROR("pthread_create health");
421 goto health_error;
422 }
423
424 /*
425 * Wait for health thread to be initialized before letting the
426 * sessiond thread reply to the sessiond that we are ready.
427 */
428 while (uatomic_read(&lttng_consumer_ready)) {
429 sleep(1);
430 }
431 cmm_smp_mb(); /* Read ready before following operations */
432
433 /* Create thread to manage channels */
434 ret = pthread_create(&channel_thread, NULL, consumer_thread_channel_poll,
435 (void *) ctx);
436 if (ret != 0) {
437 perror("pthread_create");
438 goto channel_error;
439 }
440
441 /* Create thread to manage the polling/writing of trace metadata */
442 ret = pthread_create(&metadata_thread, NULL, consumer_thread_metadata_poll,
443 (void *) ctx);
444 if (ret != 0) {
445 perror("pthread_create");
446 goto metadata_error;
447 }
448
449 /* Create thread to manage the polling/writing of trace data */
450 ret = pthread_create(&data_thread, NULL, consumer_thread_data_poll,
451 (void *) ctx);
452 if (ret != 0) {
453 perror("pthread_create");
454 goto data_error;
455 }
456
457 /* Create the thread to manage the receive of fd */
458 ret = pthread_create(&sessiond_thread, NULL, consumer_thread_sessiond_poll,
459 (void *) ctx);
460 if (ret != 0) {
461 perror("pthread_create");
462 goto sessiond_error;
463 }
464
465 /*
466 * Create the thread to manage the UST metadata periodic timer and
467 * live timer.
468 */
469 ret = pthread_create(&metadata_timer_thread, NULL,
470 consumer_timer_thread, (void *) ctx);
471 if (ret != 0) {
472 perror("pthread_create");
473 goto metadata_timer_error;
474 }
475
476 ret = pthread_detach(metadata_timer_thread);
477 if (ret) {
478 errno = ret;
479 perror("pthread_detach");
480 }
481
482 metadata_timer_error:
483 ret = pthread_join(sessiond_thread, &status);
484 if (ret != 0) {
485 perror("pthread_join");
486 goto error;
487 }
488
489 sessiond_error:
490 ret = pthread_join(data_thread, &status);
491 if (ret != 0) {
492 perror("pthread_join");
493 goto error;
494 }
495
496 data_error:
497 ret = pthread_join(metadata_thread, &status);
498 if (ret != 0) {
499 perror("pthread_join");
500 goto error;
501 }
502
503 metadata_error:
504 ret = pthread_join(channel_thread, &status);
505 if (ret != 0) {
506 perror("pthread_join");
507 goto error;
508 }
509
510 channel_error:
511 ret = pthread_join(health_thread, &status);
512 if (ret != 0) {
513 PERROR("pthread_join health thread");
514 goto error; /* join error, exit without cleanup */
515 }
516
517 health_error:
518 utils_close_pipe(health_quit_pipe);
519
520 error_health_pipe:
521 if (!ret) {
522 ret = EXIT_SUCCESS;
523 lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_EXIT_SUCCESS);
524 goto end;
525 }
526
527 error:
528 ret = EXIT_FAILURE;
529 if (ctx) {
530 lttng_consumer_send_error(ctx, LTTCOMM_CONSUMERD_EXIT_FAILURE);
531 }
532
533 end:
534 lttng_consumer_destroy(ctx);
535 lttng_consumer_cleanup();
536 if (health_consumerd) {
537 health_app_destroy(health_consumerd);
538 }
539
540 return ret;
541 }
This page took 0.039491 seconds and 3 git commands to generate.