2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
9 #include <lttng/trigger/trigger.h>
10 #include <lttng/notification/channel-internal.h>
11 #include <lttng/notification/notification-internal.h>
12 #include <lttng/condition/condition-internal.h>
13 #include <lttng/condition/buffer-usage-internal.h>
14 #include <common/error.h>
15 #include <common/config/session-config.h>
16 #include <common/defaults.h>
17 #include <common/utils.h>
18 #include <common/align.h>
19 #include <common/time.h>
20 #include <sys/eventfd.h>
25 #include "notification-thread.h"
26 #include "notification-thread-events.h"
27 #include "notification-thread-commands.h"
28 #include "lttng-sessiond.h"
29 #include "health-sessiond.h"
33 #include <common/kernel-ctl/kernel-ctl.h>
36 #include <urcu/list.h>
37 #include <urcu/rculfhash.h>
40 * Destroy the thread data previously created by the init function.
42 void notification_thread_handle_destroy(
43 struct notification_thread_handle
*handle
)
51 assert(cds_list_empty(&handle
->cmd_queue
.list
));
52 pthread_mutex_destroy(&handle
->cmd_queue
.lock
);
53 sem_destroy(&handle
->ready
);
55 if (handle
->cmd_queue
.event_pipe
) {
56 lttng_pipe_destroy(handle
->cmd_queue
.event_pipe
);
58 if (handle
->channel_monitoring_pipes
.ust32_consumer
>= 0) {
59 ret
= close(handle
->channel_monitoring_pipes
.ust32_consumer
);
61 PERROR("close 32-bit consumer channel monitoring pipe");
64 if (handle
->channel_monitoring_pipes
.ust64_consumer
>= 0) {
65 ret
= close(handle
->channel_monitoring_pipes
.ust64_consumer
);
67 PERROR("close 64-bit consumer channel monitoring pipe");
70 if (handle
->channel_monitoring_pipes
.kernel_consumer
>= 0) {
71 ret
= close(handle
->channel_monitoring_pipes
.kernel_consumer
);
73 PERROR("close kernel consumer channel monitoring pipe");
77 /* TODO: refactor this if needed. Lifetime of the kernel notification
79 * event_trigger_sources.kernel_tracer is owned by the main thread and
80 * is closed at this point.
82 handle
->event_trigger_sources
.kernel_tracer
= -1;
88 * TODO: refactor this if needed. Lifetime of the kernel notification event source.
89 * The kernel_notification_monitor_fd ownwership remain to the main thread.
90 * This is because we need to close this fd before removing the modules.
92 struct notification_thread_handle
*notification_thread_handle_create(
93 struct lttng_pipe
*ust32_channel_monitor_pipe
,
94 struct lttng_pipe
*ust64_channel_monitor_pipe
,
95 struct lttng_pipe
*kernel_channel_monitor_pipe
,
96 int kernel_notification_monitor_fd
)
99 struct notification_thread_handle
*handle
;
100 struct lttng_pipe
*event_pipe
= NULL
;
102 handle
= zmalloc(sizeof(*handle
));
107 handle
->event_trigger_sources
.kernel_tracer
= -1;
109 sem_init(&handle
->ready
, 0, 0);
111 event_pipe
= lttng_pipe_open(FD_CLOEXEC
);
113 ERR("event_pipe creation");
117 handle
->cmd_queue
.event_pipe
= event_pipe
;
120 CDS_INIT_LIST_HEAD(&handle
->cmd_queue
.list
);
121 ret
= pthread_mutex_init(&handle
->cmd_queue
.lock
, NULL
);
126 if (ust32_channel_monitor_pipe
) {
127 handle
->channel_monitoring_pipes
.ust32_consumer
=
128 lttng_pipe_release_readfd(
129 ust32_channel_monitor_pipe
);
130 if (handle
->channel_monitoring_pipes
.ust32_consumer
< 0) {
134 handle
->channel_monitoring_pipes
.ust32_consumer
= -1;
136 if (ust64_channel_monitor_pipe
) {
137 handle
->channel_monitoring_pipes
.ust64_consumer
=
138 lttng_pipe_release_readfd(
139 ust64_channel_monitor_pipe
);
140 if (handle
->channel_monitoring_pipes
.ust64_consumer
< 0) {
144 handle
->channel_monitoring_pipes
.ust64_consumer
= -1;
146 if (kernel_channel_monitor_pipe
) {
147 handle
->channel_monitoring_pipes
.kernel_consumer
=
148 lttng_pipe_release_readfd(
149 kernel_channel_monitor_pipe
);
150 if (handle
->channel_monitoring_pipes
.kernel_consumer
< 0) {
154 handle
->channel_monitoring_pipes
.kernel_consumer
= -1;
157 handle
->event_trigger_sources
.kernel_tracer
= kernel_notification_monitor_fd
;
159 CDS_INIT_LIST_HEAD(&handle
->event_trigger_sources
.list
);
160 ret
= pthread_mutex_init(&handle
->event_trigger_sources
.lock
, NULL
);
167 lttng_pipe_destroy(event_pipe
);
168 notification_thread_handle_destroy(handle
);
173 char *get_notification_channel_sock_path(void)
176 bool is_root
= !getuid();
179 sock_path
= zmalloc(LTTNG_PATH_MAX
);
185 ret
= snprintf(sock_path
, LTTNG_PATH_MAX
,
186 DEFAULT_GLOBAL_NOTIFICATION_CHANNEL_UNIX_SOCK
);
191 const char *home_path
= utils_get_home_dir();
194 ERR("Can't get HOME directory for socket creation");
198 ret
= snprintf(sock_path
, LTTNG_PATH_MAX
,
199 DEFAULT_HOME_NOTIFICATION_CHANNEL_UNIX_SOCK
,
213 void notification_channel_socket_destroy(int fd
)
216 char *sock_path
= get_notification_channel_sock_path();
218 DBG("[notification-thread] Destroying notification channel socket");
221 ret
= unlink(sock_path
);
224 PERROR("unlink notification channel socket");
230 PERROR("close notification channel socket");
235 int notification_channel_socket_create(void)
238 char *sock_path
= get_notification_channel_sock_path();
240 DBG("[notification-thread] Creating notification channel UNIX socket at %s",
243 ret
= lttcomm_create_unix_sock(sock_path
);
245 ERR("[notification-thread] Failed to create notification socket");
250 ret
= chmod(sock_path
, S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
);
252 ERR("Set file permissions failed: %s", sock_path
);
253 PERROR("chmod notification channel socket");
260 ret
= utils_get_group_id(config
.tracing_group_name
.value
, true,
263 /* Default to root group. */
267 ret
= chown(sock_path
, 0, gid
);
269 ERR("Failed to set the notification channel socket's group");
275 DBG("[notification-thread] Notification channel UNIX socket created (fd = %i)",
280 if (fd
>= 0 && close(fd
) < 0) {
281 PERROR("close notification channel socket");
288 int init_poll_set(struct lttng_poll_event
*poll_set
,
289 struct notification_thread_handle
*handle
,
290 int notification_channel_socket
)
295 * Create pollset with size 6:
296 * - notification channel socket (listen for new connections),
297 * - command queue event fd (internal sessiond commands),
298 * - consumerd (32-bit user space) channel monitor pipe,
299 * - consumerd (64-bit user space) channel monitor pipe,
300 * - consumerd (kernel) channel monitor pipe.
301 * - kernel trigger event pipe,
303 ret
= lttng_poll_create(poll_set
, 6, LTTNG_CLOEXEC
);
308 ret
= lttng_poll_add(poll_set
, notification_channel_socket
,
309 LPOLLIN
| LPOLLERR
| LPOLLHUP
| LPOLLRDHUP
);
311 ERR("[notification-thread] Failed to add notification channel socket to pollset");
314 ret
= lttng_poll_add(poll_set
, lttng_pipe_get_readfd(handle
->cmd_queue
.event_pipe
),
317 ERR("[notification-thread] Failed to add notification command queue event fd to pollset");
320 ret
= lttng_poll_add(poll_set
,
321 handle
->channel_monitoring_pipes
.ust32_consumer
,
324 ERR("[notification-thread] Failed to add ust-32 channel monitoring pipe fd to pollset");
327 ret
= lttng_poll_add(poll_set
,
328 handle
->channel_monitoring_pipes
.ust64_consumer
,
331 ERR("[notification-thread] Failed to add ust-64 channel monitoring pipe fd to pollset");
334 if (handle
->channel_monitoring_pipes
.kernel_consumer
< 0) {
335 goto skip_kernel_consumer
;
337 ret
= lttng_poll_add(poll_set
,
338 handle
->channel_monitoring_pipes
.kernel_consumer
,
341 ERR("[notification-thread] Failed to add kernel channel monitoring pipe fd to pollset");
345 skip_kernel_consumer
:
346 if (handle
->event_trigger_sources
.kernel_tracer
< 0) {
350 ret
= lttng_poll_add(poll_set
,
351 handle
->event_trigger_sources
.kernel_tracer
,
354 ERR("[notification-thread] Failed to add kernel trigger notification monitoring pipe fd to pollset");
360 lttng_poll_clean(poll_set
);
365 void fini_thread_state(struct notification_thread_state
*state
)
369 if (state
->client_socket_ht
) {
370 ret
= handle_notification_thread_client_disconnect_all(state
);
372 ret
= cds_lfht_destroy(state
->client_socket_ht
, NULL
);
375 if (state
->client_id_ht
) {
376 ret
= cds_lfht_destroy(state
->client_id_ht
, NULL
);
379 if (state
->triggers_ht
) {
380 ret
= handle_notification_thread_trigger_unregister_all(state
);
382 ret
= cds_lfht_destroy(state
->triggers_ht
, NULL
);
385 if (state
->channel_triggers_ht
) {
386 ret
= cds_lfht_destroy(state
->channel_triggers_ht
, NULL
);
389 if (state
->channel_state_ht
) {
390 ret
= cds_lfht_destroy(state
->channel_state_ht
, NULL
);
393 if (state
->notification_trigger_clients_ht
) {
394 ret
= cds_lfht_destroy(state
->notification_trigger_clients_ht
,
398 if (state
->channels_ht
) {
399 ret
= cds_lfht_destroy(state
->channels_ht
, NULL
);
402 if (state
->sessions_ht
) {
403 ret
= cds_lfht_destroy(state
->sessions_ht
, NULL
);
406 if (state
->trigger_tokens_ht
) {
407 ret
= cds_lfht_destroy(state
->trigger_tokens_ht
, NULL
);
410 if (state
->triggers_by_name_ht
) {
411 ret
= cds_lfht_destroy(state
->triggers_by_name_ht
, NULL
);
415 * Must be destroyed after all channels have been destroyed.
416 * See comment in struct lttng_session_trigger_list.
418 if (state
->session_triggers_ht
) {
419 ret
= cds_lfht_destroy(state
->session_triggers_ht
, NULL
);
422 if (state
->notification_channel_socket
>= 0) {
423 notification_channel_socket_destroy(
424 state
->notification_channel_socket
);
426 if (state
->executor
) {
427 action_executor_destroy(state
->executor
);
429 lttng_poll_clean(&state
->events
);
433 void mark_thread_as_ready(struct notification_thread_handle
*handle
)
435 DBG("Marking notification thread as ready");
436 sem_post(&handle
->ready
);
440 void wait_until_thread_is_ready(struct notification_thread_handle
*handle
)
442 DBG("Waiting for notification thread to be ready");
443 sem_wait(&handle
->ready
);
444 DBG("Notification thread is ready");
448 int init_thread_state(struct notification_thread_handle
*handle
,
449 struct notification_thread_state
*state
)
453 memset(state
, 0, sizeof(*state
));
454 state
->notification_channel_socket
= -1;
455 state
->trigger_id
.token_generator
= 1;
456 lttng_poll_init(&state
->events
);
458 ret
= notification_channel_socket_create();
462 state
->notification_channel_socket
= ret
;
464 ret
= init_poll_set(&state
->events
, handle
,
465 state
->notification_channel_socket
);
470 DBG("[notification-thread] Listening on notification channel socket");
471 ret
= lttcomm_listen_unix_sock(state
->notification_channel_socket
);
473 ERR("[notification-thread] Listen failed on notification channel socket");
477 state
->client_socket_ht
= cds_lfht_new(DEFAULT_HT_SIZE
, 1, 0,
478 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
479 if (!state
->client_socket_ht
) {
483 state
->client_id_ht
= cds_lfht_new(DEFAULT_HT_SIZE
, 1, 0,
484 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
485 if (!state
->client_id_ht
) {
489 state
->channel_triggers_ht
= cds_lfht_new(DEFAULT_HT_SIZE
, 1, 0,
490 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
491 if (!state
->channel_triggers_ht
) {
495 state
->session_triggers_ht
= cds_lfht_new(DEFAULT_HT_SIZE
, 1, 0,
496 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
497 if (!state
->session_triggers_ht
) {
501 state
->channel_state_ht
= cds_lfht_new(DEFAULT_HT_SIZE
, 1, 0,
502 CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
503 if (!state
->channel_state_ht
) {
507 state
->notification_trigger_clients_ht
= cds_lfht_new(DEFAULT_HT_SIZE
,
508 1, 0, CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
509 if (!state
->notification_trigger_clients_ht
) {
513 state
->channels_ht
= cds_lfht_new(DEFAULT_HT_SIZE
,
514 1, 0, CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
515 if (!state
->channels_ht
) {
518 state
->sessions_ht
= cds_lfht_new(DEFAULT_HT_SIZE
,
519 1, 0, CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
520 if (!state
->sessions_ht
) {
523 state
->triggers_ht
= cds_lfht_new(DEFAULT_HT_SIZE
,
524 1, 0, CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
525 if (!state
->triggers_ht
) {
528 state
->trigger_tokens_ht
= cds_lfht_new(DEFAULT_HT_SIZE
,
529 1, 0, CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
530 if (!state
->trigger_tokens_ht
) {
533 state
->triggers_by_name_ht
= cds_lfht_new(DEFAULT_HT_SIZE
,
534 1, 0, CDS_LFHT_AUTO_RESIZE
| CDS_LFHT_ACCOUNTING
, NULL
);
535 if (!state
->triggers_by_name_ht
) {
538 state
->executor
= action_executor_create(handle
);
539 if (!state
->executor
) {
542 mark_thread_as_ready(handle
);
546 fini_thread_state(state
);
551 int handle_channel_monitoring_pipe(int fd
, uint32_t revents
,
552 struct notification_thread_handle
*handle
,
553 struct notification_thread_state
*state
)
556 enum lttng_domain_type domain
;
558 if (fd
== handle
->channel_monitoring_pipes
.ust32_consumer
||
559 fd
== handle
->channel_monitoring_pipes
.ust64_consumer
) {
560 domain
= LTTNG_DOMAIN_UST
;
561 } else if (fd
== handle
->channel_monitoring_pipes
.kernel_consumer
) {
562 domain
= LTTNG_DOMAIN_KERNEL
;
567 if (revents
& (LPOLLERR
| LPOLLHUP
| LPOLLRDHUP
)) {
568 ret
= lttng_poll_del(&state
->events
, fd
);
570 ERR("[notification-thread] Failed to remove consumer monitoring pipe from poll set");
575 ret
= handle_notification_thread_channel_sample(
578 ERR("[notification-thread] Consumer sample handling error occurred");
586 static int handle_trigger_event_pipe(int fd
,
588 struct notification_thread_handle
*handle
,
589 struct notification_thread_state
*state
)
592 enum lttng_domain_type domain
;
594 if (revents
& (LPOLLERR
| LPOLLHUP
| LPOLLRDHUP
)) {
595 ret
= lttng_poll_del(&state
->events
, fd
);
597 ERR("[notification-thread] Failed to remove event monitoring pipe from poll set");
602 if (fd
== handle
->event_trigger_sources
.kernel_tracer
) {
603 domain
= LTTNG_DOMAIN_KERNEL
;
605 domain
= LTTNG_DOMAIN_UST
;
608 ret
= handle_notification_thread_event(state
, fd
, domain
);
610 ERR("[notification-thread] Event sample handling error occurred for fd: %d", fd
);
618 static bool fd_is_event_source(struct notification_thread_handle
*handle
, int fd
)
620 struct notification_event_trigger_source_element
*source_element
, *tmp
;
621 cds_list_for_each_entry_safe(source_element
, tmp
,
622 &handle
->event_trigger_sources
.list
, node
) {
623 if (source_element
->fd
!= fd
) {
628 if (fd
== handle
->event_trigger_sources
.kernel_tracer
) {
635 * This thread services notification channel clients and commands received
636 * from various lttng-sessiond components over a command queue.
639 void *thread_notification(void *data
)
642 struct notification_thread_handle
*handle
= data
;
643 struct notification_thread_state state
;
645 DBG("[notification-thread] Started notification thread");
647 health_register(health_sessiond
, HEALTH_SESSIOND_TYPE_NOTIFICATION
);
648 rcu_register_thread();
652 ERR("[notification-thread] Invalid thread context provided");
656 health_code_update();
658 ret
= init_thread_state(handle
, &state
);
667 DBG("[notification-thread] Entering poll wait");
668 ret
= lttng_poll_wait(&state
.events
, -1);
669 DBG("[notification-thread] Poll wait returned (%i)", ret
);
673 * Restart interrupted system call.
675 if (errno
== EINTR
) {
678 ERR("[notification-thread] Error encountered during lttng_poll_wait (%i)", ret
);
683 for (i
= 0; i
< fd_count
; i
++) {
684 int fd
= LTTNG_POLL_GETFD(&state
.events
, i
);
685 uint32_t revents
= LTTNG_POLL_GETEV(&state
.events
, i
);
687 DBG("[notification-thread] Handling fd (%i) activity (%u)", fd
, revents
);
689 if (fd
== state
.notification_channel_socket
) {
690 if (revents
& LPOLLIN
) {
691 ret
= handle_notification_thread_client_connect(
697 (LPOLLERR
| LPOLLHUP
| LPOLLRDHUP
)) {
698 ERR("[notification-thread] Notification socket poll error");
701 ERR("[notification-thread] Unexpected poll events %u for notification socket %i", revents
, fd
);
704 } else if (fd
== lttng_pipe_get_readfd(handle
->cmd_queue
.event_pipe
)) {
705 ret
= handle_notification_thread_command(handle
,
708 DBG("[notification-thread] Error encountered while servicing command queue");
710 } else if (ret
> 0) {
713 } else if (fd
== handle
->channel_monitoring_pipes
.ust32_consumer
||
714 fd
== handle
->channel_monitoring_pipes
.ust64_consumer
||
715 fd
== handle
->channel_monitoring_pipes
.kernel_consumer
) {
716 ret
= handle_channel_monitoring_pipe(fd
,
717 revents
, handle
, &state
);
721 } else if (fd_is_event_source(handle
, fd
)) {
722 ret
= handle_trigger_event_pipe(fd
, revents
, handle
, &state
);
727 /* Activity on a client's socket. */
728 if (revents
& (LPOLLERR
| LPOLLHUP
| LPOLLRDHUP
)) {
730 * It doesn't matter if a command was
731 * pending on the client socket at this
732 * point since it now has no way to
733 * receive the notifications to which
734 * it was subscribing or unsubscribing.
736 ret
= handle_notification_thread_client_disconnect(
742 if (revents
& LPOLLIN
) {
743 ret
= handle_notification_thread_client_in(
750 if (revents
& LPOLLOUT
) {
751 ret
= handle_notification_thread_client_out(
763 fini_thread_state(&state
);
765 rcu_thread_offline();
766 rcu_unregister_thread();
767 health_unregister(health_sessiond
);
772 bool shutdown_notification_thread(void *thread_data
)
774 struct notification_thread_handle
*handle
= thread_data
;
776 notification_thread_command_quit(handle
);
780 struct lttng_thread
*launch_notification_thread(
781 struct notification_thread_handle
*handle
)
783 struct lttng_thread
*thread
;
785 thread
= lttng_thread_create("Notification",
787 shutdown_notification_thread
,
795 * Wait for the thread to be marked as "ready" before returning
796 * as other subsystems depend on the notification subsystem
797 * (e.g. rotation thread).
799 wait_until_thread_is_ready(handle
);