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