configure: add '-Wmissing-noreturn' to warning flags
[lttng-tools.git] / src / bin / lttng-consumerd / lttng-consumerd.cpp
CommitLineData
d4a1283e 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
d4a1283e 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
d4a1283e 6 *
d4a1283e
JD
7 */
8
6c1c0768 9#define _LGPL_SOURCE
d4a1283e
JD
10#include <fcntl.h>
11#include <getopt.h>
12#include <grp.h>
13#include <limits.h>
14#include <pthread.h>
15#include <signal.h>
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19#include <sys/ipc.h>
1ccfc0e3 20#include <sys/resource.h>
d4a1283e
JD
21#include <sys/shm.h>
22#include <sys/socket.h>
23#include <sys/stat.h>
24#include <sys/types.h>
25#include <urcu/list.h>
26#include <poll.h>
27#include <unistd.h>
03424a9b 28#include <sys/mman.h>
7753dea8 29#include <urcu/compiler.h>
1ccfc0e3 30#include <ulimit.h>
d4a1283e 31
db758600
DG
32#include <common/defaults.h>
33#include <common/common.h>
c8fea79c
JR
34#include <common/consumer/consumer.h>
35#include <common/consumer/consumer-timer.h>
fb3a43a9 36#include <common/compat/poll.h>
e8fa9fb0 37#include <common/compat/getenv.h>
10a8a223 38#include <common/sessiond-comm/sessiond-comm.h>
5c635c72 39#include <common/utils.h>
10a8a223
DG
40
41#include "lttng-consumerd.h"
1fc79fb4 42#include "health-consumerd.h"
d4a1283e 43
d8ef542d 44/* threads (channel handling, poll, metadata, sessiond) */
331744e3 45
5c635c72
MD
46static pthread_t channel_thread, data_thread, metadata_thread,
47 sessiond_thread, metadata_timer_thread, health_thread;
13675d0e 48static bool metadata_timer_thread_online;
d4a1283e 49
3183dbb0 50/* to count the number of times the user pressed ctrl+c */
13e44745
JD
51static int sigintcount = 0;
52
d4a1283e 53/* Argument variables */
97e19046
DG
54int lttng_opt_quiet; /* not static in error.h */
55int lttng_opt_verbose; /* not static in error.h */
c7e35b03
JR
56int lttng_opt_mi; /* not static in error.h */
57
d4a1283e
JD
58static int opt_daemon;
59static const char *progname;
6533b585
DG
60static char command_sock_path[PATH_MAX]; /* Global command socket path */
61static char error_sock_path[PATH_MAX]; /* Global error path */
3bd1e081 62static enum lttng_consumer_type opt_type = LTTNG_CONSUMER_KERNEL;
d4a1283e 63
7753dea8 64/* the liblttngconsumerd context */
3bd1e081 65static struct lttng_consumer_local_data *ctx;
cb040cc1 66
1fc79fb4
MD
67/* Consumerd health monitoring */
68struct health_app *health_consumerd;
69
6c71277b
MD
70const char *tracing_group_name = DEFAULT_TRACING_GROUP;
71
748b7b07
MD
72int lttng_consumer_ready = NR_LTTNG_CONSUMER_READY;
73
5c635c72
MD
74enum lttng_consumer_type lttng_consumer_get_type(void)
75{
76 if (!ctx) {
77 return LTTNG_CONSUMER_UNKNOWN;
78 }
79 return ctx->type;
80}
81
d4a1283e 82/*
6533b585 83 * Signal handler for the daemon
d4a1283e 84 */
881fc67f 85static void sighandler(int sig, siginfo_t *siginfo, void *arg)
d4a1283e 86{
13e44745
JD
87 if (sig == SIGINT && sigintcount++ == 0) {
88 DBG("ignoring first SIGINT");
89 return;
90 }
91
881fc67f
MD
92 if (sig == SIGBUS) {
93 int write_ret;
94 const char msg[] = "Received SIGBUS, aborting program.\n";
95
96 lttng_consumer_sigbus_handle(siginfo->si_addr);
97 /*
98 * If ustctl did not catch this signal (triggering a
99 * siglongjmp), abort the program. Otherwise, the execution
100 * will resume from the ust-ctl call which caused this error.
101 *
102 * The return value is ignored since the program aborts anyhow.
103 */
104 write_ret = write(STDERR_FILENO, msg, sizeof(msg));
105 (void) write_ret;
106 abort();
107 }
108
6a0caa9b
MD
109 if (ctx) {
110 lttng_consumer_should_exit(ctx);
111 }
d4a1283e
JD
112}
113
114/*
6533b585 115 * Setup signal handler for :
881fc67f 116 * SIGINT, SIGTERM, SIGPIPE, SIGBUS
d4a1283e
JD
117 */
118static int set_signal_handler(void)
119{
120 int ret = 0;
121 struct sigaction sa;
122 sigset_t sigset;
123
124 if ((ret = sigemptyset(&sigset)) < 0) {
8fdf2d4d 125 PERROR("sigemptyset");
d4a1283e
JD
126 return ret;
127 }
128
d4a1283e 129 sa.sa_mask = sigset;
881fc67f 130 sa.sa_flags = SA_SIGINFO;
0072e5e2 131
881fc67f 132 sa.sa_sigaction = sighandler;
d4a1283e 133 if ((ret = sigaction(SIGTERM, &sa, NULL)) < 0) {
8fdf2d4d 134 PERROR("sigaction");
d4a1283e
JD
135 return ret;
136 }
137
138 if ((ret = sigaction(SIGINT, &sa, NULL)) < 0) {
8fdf2d4d 139 PERROR("sigaction");
d4a1283e
JD
140 return ret;
141 }
142
881fc67f
MD
143 if ((ret = sigaction(SIGBUS, &sa, NULL)) < 0) {
144 PERROR("sigaction");
145 return ret;
146 }
147
148 sa.sa_flags = 0;
0072e5e2 149 sa.sa_handler = SIG_IGN;
d4a1283e 150 if ((ret = sigaction(SIGPIPE, &sa, NULL)) < 0) {
8fdf2d4d 151 PERROR("sigaction");
d4a1283e
JD
152 return ret;
153 }
154
155 return ret;
156}
157
d4a1283e 158/*
3183dbb0 159 * Usage function on stream file.
d4a1283e 160 */
3183dbb0 161static void usage(FILE *fp)
d4a1283e 162{
3183dbb0
DG
163 fprintf(fp, "Usage: %s OPTIONS\n\nOptions:\n", progname);
164 fprintf(fp, " -h, --help "
d4a1283e 165 "Display this usage.\n");
6c71277b 166 fprintf(fp, " -c, --consumerd-cmd-sock PATH "
d4a1283e 167 "Specify path for the command socket\n");
6c71277b 168 fprintf(fp, " -e, --consumerd-err-sock PATH "
d4a1283e 169 "Specify path for the error socket\n");
3183dbb0 170 fprintf(fp, " -d, --daemonize "
d4a1283e 171 "Start as a daemon.\n");
3183dbb0 172 fprintf(fp, " -q, --quiet "
d4a1283e 173 "No output at all.\n");
3183dbb0 174 fprintf(fp, " -v, --verbose "
d4a1283e 175 "Verbose mode. Activate DBG() macro.\n");
3183dbb0 176 fprintf(fp, " -V, --version "
d4a1283e 177 "Show version number.\n");
6c71277b
MD
178 fprintf(fp, " -g, --group NAME "
179 "Specify the tracing group name. (default: tracing)\n");
3183dbb0 180 fprintf(fp, " -k, --kernel "
3bd1e081 181 "Consumer kernel buffers (default).\n");
3183dbb0 182 fprintf(fp, " -u, --ust "
3bd1e081 183 "Consumer UST buffers.%s\n",
74d0b642 184#ifdef HAVE_LIBLTTNG_UST_CTL
3bd1e081
MD
185 ""
186#else
187 " (support not compiled in)"
188#endif
189 );
d4a1283e
JD
190}
191
192/*
193 * daemon argument parsing
194 */
8f7a281b 195static int parse_args(int argc, char **argv)
d4a1283e 196{
8f7a281b 197 int c, ret = 0;
d4a1283e
JD
198
199 static struct option long_options[] = {
7753dea8
MD
200 { "consumerd-cmd-sock", 1, 0, 'c' },
201 { "consumerd-err-sock", 1, 0, 'e' },
d4a1283e 202 { "daemonize", 0, 0, 'd' },
6c71277b 203 { "group", 1, 0, 'g' },
d4a1283e
JD
204 { "help", 0, 0, 'h' },
205 { "quiet", 0, 0, 'q' },
206 { "verbose", 0, 0, 'v' },
207 { "version", 0, 0, 'V' },
3bd1e081 208 { "kernel", 0, 0, 'k' },
74d0b642 209#ifdef HAVE_LIBLTTNG_UST_CTL
3bd1e081
MD
210 { "ust", 0, 0, 'u' },
211#endif
d4a1283e
JD
212 { NULL, 0, 0, 0 }
213 };
214
215 while (1) {
216 int option_index = 0;
5acdb082
MD
217 c = getopt_long(argc, argv, "dhqvVku" "c:e:g:",
218 long_options, &option_index);
d4a1283e
JD
219 if (c == -1) {
220 break;
221 }
222
223 switch (c) {
914a571b 224 case 0:
5acdb082
MD
225 fprintf(stderr, "option %s",
226 long_options[option_index].name);
914a571b
JD
227 if (optarg) {
228 fprintf(stderr, " with arg %s\n", optarg);
8f7a281b
MD
229 ret = -1;
230 goto end;
914a571b
JD
231 }
232 break;
233 case 'c':
e8fa9fb0
MD
234 if (lttng_is_setuid_setgid()) {
235 WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
236 "-c, --consumerd-cmd-sock");
237 } else {
238 snprintf(command_sock_path, PATH_MAX, "%s", optarg);
239 }
914a571b
JD
240 break;
241 case 'e':
e8fa9fb0
MD
242 if (lttng_is_setuid_setgid()) {
243 WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
244 "-e, --consumerd-err-sock");
245 } else {
246 snprintf(error_sock_path, PATH_MAX, "%s", optarg);
247 }
914a571b
JD
248 break;
249 case 'd':
250 opt_daemon = 1;
251 break;
6c71277b 252 case 'g':
e8fa9fb0
MD
253 if (lttng_is_setuid_setgid()) {
254 WARN("Getting '%s' argument from setuid/setgid binary refused for security reasons.",
255 "-g, --group");
256 } else {
257 tracing_group_name = optarg;
258 }
6c71277b 259 break;
914a571b 260 case 'h':
3183dbb0
DG
261 usage(stdout);
262 exit(EXIT_SUCCESS);
914a571b 263 case 'q':
97e19046 264 lttng_opt_quiet = 1;
914a571b
JD
265 break;
266 case 'v':
0ca413e0 267 lttng_opt_verbose = 3;
914a571b
JD
268 break;
269 case 'V':
270 fprintf(stdout, "%s\n", VERSION);
271 exit(EXIT_SUCCESS);
3bd1e081
MD
272 case 'k':
273 opt_type = LTTNG_CONSUMER_KERNEL;
274 break;
74d0b642 275#ifdef HAVE_LIBLTTNG_UST_CTL
3bd1e081 276 case 'u':
7753dea8
MD
277# if (CAA_BITS_PER_LONG == 64)
278 opt_type = LTTNG_CONSUMER64_UST;
279# elif (CAA_BITS_PER_LONG == 32)
280 opt_type = LTTNG_CONSUMER32_UST;
281# else
282# error "Unknown bitness"
283# endif
3bd1e081
MD
284 break;
285#endif
914a571b 286 default:
3183dbb0 287 usage(stderr);
8f7a281b
MD
288 ret = -1;
289 goto end;
d4a1283e
JD
290 }
291 }
8f7a281b
MD
292end:
293 return ret;
d4a1283e
JD
294}
295
1ccfc0e3
DG
296/*
297 * Set open files limit to unlimited. This daemon can open a large number of
298 * file descriptors in order to consumer multiple kernel traces.
299 */
300static void set_ulimit(void)
301{
302 int ret;
303 struct rlimit lim;
304
305 /* The kernel does not allowed an infinite limit for open files */
306 lim.rlim_cur = 65535;
307 lim.rlim_max = 65535;
308
309 ret = setrlimit(RLIMIT_NOFILE, &lim);
310 if (ret < 0) {
311 PERROR("failed to set open files limit");
312 }
313}
314
d4a1283e
JD
315/*
316 * main
317 */
318int main(int argc, char **argv)
319{
72f11bd7 320 int ret = 0, retval = 0;
d4a1283e 321 void *status;
6a0caa9b 322 struct lttng_consumer_local_data *tmp_ctx;
d4a1283e 323
fe19a07a
MD
324 rcu_register_thread();
325
5e8e3a00
JG
326 if (run_as_create_worker(argv[0], NULL, NULL) < 0) {
327 goto exit_set_signal_handler;
328 }
329
72f11bd7
MD
330 if (set_signal_handler()) {
331 retval = -1;
332 goto exit_set_signal_handler;
333 }
334
d4a1283e
JD
335 /* Parse arguments */
336 progname = argv[0];
72f11bd7
MD
337 if (parse_args(argc, argv)) {
338 retval = -1;
339 goto exit_options;
340 }
d4a1283e
JD
341
342 /* Daemonize */
343 if (opt_daemon) {
ceed52b5
MD
344 int i;
345
346 /*
347 * fork
348 * child: setsid, close FD 0, 1, 2, chdir /
349 * parent: exit (if fork is successful)
350 */
d4a1283e
JD
351 ret = daemon(0, 0);
352 if (ret < 0) {
ceed52b5 353 PERROR("daemon");
72f11bd7
MD
354 retval = -1;
355 goto exit_options;
d4a1283e 356 }
ceed52b5
MD
357 /*
358 * We are in the child. Make sure all other file
359 * descriptors are closed, in case we are called with
360 * more opened file descriptors than the standard ones.
361 */
362 for (i = 3; i < sysconf(_SC_OPEN_MAX); i++) {
363 (void) close(i);
364 }
d4a1283e
JD
365 }
366
72f11bd7
MD
367 /*
368 * Starting from here, we can create threads. This needs to be after
369 * lttng_daemonize due to RCU.
370 */
371
372 health_consumerd = health_app_create(NR_HEALTH_CONSUMERD_TYPES);
373 if (!health_consumerd) {
374 retval = -1;
375 goto exit_health_consumerd_cleanup;
376 }
377
9d035200 378 if (*command_sock_path == '\0') {
7753dea8
MD
379 switch (opt_type) {
380 case LTTNG_CONSUMER_KERNEL:
72f11bd7
MD
381 ret = snprintf(command_sock_path, PATH_MAX,
382 DEFAULT_KCONSUMERD_CMD_SOCK_PATH,
990570ed 383 DEFAULT_LTTNG_RUNDIR);
72f11bd7
MD
384 if (ret < 0) {
385 retval = -1;
386 goto exit_init_data;
387 }
7753dea8
MD
388 break;
389 case LTTNG_CONSUMER64_UST:
72f11bd7
MD
390 ret = snprintf(command_sock_path, PATH_MAX,
391 DEFAULT_USTCONSUMERD64_CMD_SOCK_PATH,
392 DEFAULT_LTTNG_RUNDIR);
393 if (ret < 0) {
394 retval = -1;
395 goto exit_init_data;
396 }
7753dea8
MD
397 break;
398 case LTTNG_CONSUMER32_UST:
72f11bd7
MD
399 ret = snprintf(command_sock_path, PATH_MAX,
400 DEFAULT_USTCONSUMERD32_CMD_SOCK_PATH,
401 DEFAULT_LTTNG_RUNDIR);
402 if (ret < 0) {
403 retval = -1;
404 goto exit_init_data;
405 }
7753dea8
MD
406 break;
407 default:
72f11bd7
MD
408 ERR("Unknown consumerd type");
409 retval = -1;
410 goto exit_init_data;
7753dea8 411 }
d4a1283e 412 }
e4421fec
DG
413
414 /* Init */
72f11bd7
MD
415 if (lttng_consumer_init()) {
416 retval = -1;
417 goto exit_init_data;
282dadbc
MD
418 }
419
72f11bd7 420 /* Initialize communication library */
e98ec547 421 lttcomm_init();
72f11bd7 422 /* Initialize TCP timeout values */
e98ec547 423 lttcomm_inet_init();
e4421fec 424
1ccfc0e3
DG
425 if (!getuid()) {
426 /* Set limit for open files */
427 set_ulimit();
428 }
429
5348b470 430 /* create the consumer instance with and assign the callbacks */
d41f73b7
MD
431 ctx = lttng_consumer_create(opt_type, lttng_consumer_read_subbuffer,
432 NULL, lttng_consumer_on_recv_stream, NULL);
72f11bd7
MD
433 if (!ctx) {
434 retval = -1;
435 goto exit_init_data;
cb040cc1
JD
436 }
437
3bd1e081 438 lttng_consumer_set_command_sock_path(ctx, command_sock_path);
9d035200 439 if (*error_sock_path == '\0') {
7753dea8
MD
440 switch (opt_type) {
441 case LTTNG_CONSUMER_KERNEL:
72f11bd7
MD
442 ret = snprintf(error_sock_path, PATH_MAX,
443 DEFAULT_KCONSUMERD_ERR_SOCK_PATH,
990570ed 444 DEFAULT_LTTNG_RUNDIR);
72f11bd7
MD
445 if (ret < 0) {
446 retval = -1;
447 goto exit_init_data;
448 }
7753dea8
MD
449 break;
450 case LTTNG_CONSUMER64_UST:
72f11bd7
MD
451 ret = snprintf(error_sock_path, PATH_MAX,
452 DEFAULT_USTCONSUMERD64_ERR_SOCK_PATH,
453 DEFAULT_LTTNG_RUNDIR);
454 if (ret < 0) {
455 retval = -1;
456 goto exit_init_data;
457 }
7753dea8
MD
458 break;
459 case LTTNG_CONSUMER32_UST:
72f11bd7
MD
460 ret = snprintf(error_sock_path, PATH_MAX,
461 DEFAULT_USTCONSUMERD32_ERR_SOCK_PATH,
462 DEFAULT_LTTNG_RUNDIR);
463 if (ret < 0) {
464 retval = -1;
465 goto exit_init_data;
466 }
7753dea8
MD
467 break;
468 default:
72f11bd7
MD
469 ERR("Unknown consumerd type");
470 retval = -1;
471 goto exit_init_data;
7753dea8 472 }
d4a1283e
JD
473 }
474
32258573 475 /* Connect to the socket created by lttng-sessiond to report errors */
d4a1283e 476 DBG("Connecting to error socket %s", error_sock_path);
1ce86c9a 477 ret = lttcomm_connect_unix_sock(error_sock_path);
72f11bd7
MD
478 /*
479 * Not a fatal error, but all communication with lttng-sessiond will
480 * fail.
481 */
1ce86c9a 482 if (ret < 0) {
99bab54f 483 WARN("Cannot connect to error socket (is lttng-sessiond started?)");
d4a1283e 484 }
3bd1e081 485 lttng_consumer_set_error_sock(ctx, ret);
d4a1283e 486
331744e3 487 /*
d3e2ba59
JD
488 * Block RT signals used for UST periodical metadata flush and the live
489 * timer in main, and create a dedicated thread to handle these signals.
331744e3 490 */
72f11bd7
MD
491 if (consumer_signal_init()) {
492 retval = -1;
493 goto exit_init_data;
494 }
d3e2ba59 495
331744e3
JD
496 ctx->type = opt_type;
497
72f11bd7
MD
498 if (utils_create_pipe(health_quit_pipe)) {
499 retval = -1;
500 goto exit_health_pipe;
5c635c72
MD
501 }
502
503 /* Create thread to manage the client socket */
1a1a34b4 504 ret = pthread_create(&health_thread, default_pthread_attr(),
5c635c72 505 thread_manage_health, (void *) NULL);
72f11bd7
MD
506 if (ret) {
507 errno = ret;
5c635c72 508 PERROR("pthread_create health");
72f11bd7
MD
509 retval = -1;
510 goto exit_health_thread;
5c635c72
MD
511 }
512
748b7b07
MD
513 /*
514 * Wait for health thread to be initialized before letting the
515 * sessiond thread reply to the sessiond that we are ready.
516 */
517 while (uatomic_read(&lttng_consumer_ready)) {
1f3130d5 518 usleep(100000);
748b7b07
MD
519 }
520 cmm_smp_mb(); /* Read ready before following operations */
521
13675d0e
MD
522 /*
523 * Create the thread to manage the UST metadata periodic timer and
524 * live timer.
525 */
526 ret = pthread_create(&metadata_timer_thread, NULL,
527 consumer_timer_thread, (void *) ctx);
528 if (ret) {
529 errno = ret;
530 PERROR("pthread_create");
531 retval = -1;
532 goto exit_metadata_timer_thread;
533 }
534 metadata_timer_thread_online = true;
535
d8ef542d 536 /* Create thread to manage channels */
1a1a34b4 537 ret = pthread_create(&channel_thread, default_pthread_attr(),
72f11bd7 538 consumer_thread_channel_poll,
d8ef542d 539 (void *) ctx);
72f11bd7
MD
540 if (ret) {
541 errno = ret;
542 PERROR("pthread_create");
543 retval = -1;
544 goto exit_channel_thread;
d8ef542d
MD
545 }
546
7d980def 547 /* Create thread to manage the polling/writing of trace metadata */
1a1a34b4 548 ret = pthread_create(&metadata_thread, default_pthread_attr(),
72f11bd7 549 consumer_thread_metadata_poll,
7d980def 550 (void *) ctx);
72f11bd7
MD
551 if (ret) {
552 errno = ret;
553 PERROR("pthread_create");
554 retval = -1;
555 goto exit_metadata_thread;
7d980def
DG
556 }
557
558 /* Create thread to manage the polling/writing of trace data */
1a1a34b4
MJ
559 ret = pthread_create(&data_thread, default_pthread_attr(),
560 consumer_thread_data_poll, (void *) ctx);
72f11bd7
MD
561 if (ret) {
562 errno = ret;
563 PERROR("pthread_create");
564 retval = -1;
565 goto exit_data_thread;
d4a1283e
JD
566 }
567
7b336484 568 /* Create the thread to manage the reception of fds */
1a1a34b4 569 ret = pthread_create(&sessiond_thread, default_pthread_attr(),
72f11bd7 570 consumer_thread_sessiond_poll,
cb040cc1 571 (void *) ctx);
72f11bd7
MD
572 if (ret) {
573 errno = ret;
574 PERROR("pthread_create");
575 retval = -1;
576 goto exit_sessiond_thread;
df27ef7b
DG
577 }
578
331744e3 579
72f11bd7
MD
580 /*
581 * This is where we start awaiting program completion (e.g. through
582 * signal that asks threads to teardown.
583 */
584
df27ef7b 585 ret = pthread_join(sessiond_thread, &status);
72f11bd7
MD
586 if (ret) {
587 errno = ret;
588 PERROR("pthread_join sessiond_thread");
589 retval = -1;
d4a1283e 590 }
72f11bd7 591exit_sessiond_thread:
d4a1283e 592
df27ef7b 593 ret = pthread_join(data_thread, &status);
72f11bd7
MD
594 if (ret) {
595 errno = ret;
596 PERROR("pthread_join data_thread");
597 retval = -1;
df27ef7b 598 }
72f11bd7 599exit_data_thread:
df27ef7b 600
df27ef7b 601 ret = pthread_join(metadata_thread, &status);
72f11bd7
MD
602 if (ret) {
603 errno = ret;
604 PERROR("pthread_join metadata_thread");
605 retval = -1;
df27ef7b 606 }
72f11bd7 607exit_metadata_thread:
df27ef7b 608
d8ef542d 609 ret = pthread_join(channel_thread, &status);
72f11bd7
MD
610 if (ret) {
611 errno = ret;
612 PERROR("pthread_join channel_thread");
613 retval = -1;
d8ef542d 614 }
72f11bd7 615exit_channel_thread:
d8ef542d 616
13675d0e
MD
617exit_metadata_timer_thread:
618
5c635c72 619 ret = pthread_join(health_thread, &status);
72f11bd7
MD
620 if (ret) {
621 errno = ret;
622 PERROR("pthread_join health_thread");
623 retval = -1;
5c635c72 624 }
72f11bd7 625exit_health_thread:
5c635c72 626
5c635c72 627 utils_close_pipe(health_quit_pipe);
72f11bd7 628exit_health_pipe:
5c635c72 629
72f11bd7 630exit_init_data:
4d62fbf8
MD
631 /*
632 * Wait for all pending call_rcu work to complete before tearing
633 * down data structures. call_rcu worker may be trying to
634 * perform lookups in those structures.
635 */
636 rcu_barrier();
3bd1e081 637 lttng_consumer_cleanup();
13675d0e
MD
638 /*
639 * Tearing down the metadata timer thread in a
640 * non-fully-symmetric fashion compared to its creation in case
641 * lttng_consumer_cleanup() ends up tearing down timers (which
642 * requires the timer thread to be alive).
643 */
644 if (metadata_timer_thread_online) {
645 /*
646 * Ensure the metadata timer thread exits only after all other
647 * threads are gone, because it is required to perform timer
648 * teardown synchronization.
649 */
650 kill(getpid(), LTTNG_CONSUMER_SIG_EXIT);
651 ret = pthread_join(metadata_timer_thread, &status);
652 if (ret) {
653 errno = ret;
654 PERROR("pthread_join metadata_timer_thread");
655 retval = -1;
656 }
99b597c0
JR
657 ret = consumer_timer_thread_get_channel_monitor_pipe();
658 if (ret >= 0) {
659 ret = close(ret);
660 if (ret) {
661 PERROR("close channel monitor pipe");
662 }
663 }
13675d0e
MD
664 metadata_timer_thread_online = false;
665 }
666 tmp_ctx = ctx;
667 ctx = NULL;
668 cmm_barrier(); /* Clear ctx for signal handler. */
669 lttng_consumer_destroy(tmp_ctx);
72f11bd7 670
1fc79fb4
MD
671 if (health_consumerd) {
672 health_app_destroy(health_consumerd);
673 }
38303ec8
JG
674 /* Ensure all prior call_rcu are done. */
675 rcu_barrier();
d4a1283e 676
38303ec8 677 run_as_destroy_worker();
72f11bd7 678
38303ec8
JG
679exit_health_consumerd_cleanup:
680exit_options:
72f11bd7 681exit_set_signal_handler:
6bf8b7f3 682
fe19a07a
MD
683 rcu_unregister_thread();
684
72f11bd7
MD
685 if (!retval) {
686 exit(EXIT_SUCCESS);
687 } else {
688 exit(EXIT_FAILURE);
689 }
d4a1283e 690}
This page took 0.099445 seconds and 4 git commands to generate.