2 * Copyright (C) 2011 EfficiOS Inc.
3 * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
4 * Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 * SPDX-License-Identifier: GPL-2.0-only
10 #include "dispatch.hpp"
11 #include "fd-limit.hpp"
12 #include "health-sessiond.hpp"
13 #include "lttng-sessiond.hpp"
14 #include "testpoint.hpp"
16 #include "ust-app.hpp"
18 #include <common/futex.hpp>
19 #include <common/macros.hpp>
20 #include <common/urcu.hpp>
27 struct thread_notifiers
{
28 struct ust_cmd_queue
*ust_cmd_queue
;
29 int apps_cmd_pipe_write_fd
;
30 int apps_cmd_notify_pipe_write_fd
;
31 int dispatch_thread_exit
;
36 * For each tracing session, update newly registered apps. The session list
37 * lock MUST be acquired before calling this.
39 static void update_ust_app(int app_sock
)
41 struct ltt_session
*sess
, *stmp
;
42 const struct ltt_session_list
*session_list
= session_get_list();
45 /* Consumer is in an ERROR state. Stop any application update. */
46 if (uatomic_read(&the_ust_consumerd_state
) == CONSUMER_ERROR
) {
47 /* Stop the update process since the consumer is dead. */
51 lttng::urcu::read_lock_guard read_lock
;
52 LTTNG_ASSERT(app_sock
>= 0);
53 app
= ust_app_find_by_sock(app_sock
);
56 * Application can be unregistered before so
57 * this is possible hence simply stopping the
60 DBG3("UST app update failed to find app sock %d", app_sock
);
64 /* Update all event notifiers for the app. */
65 ust_app_global_update_event_notifier_rules(app
);
67 /* For all tracing session(s) */
68 cds_list_for_each_entry_safe (sess
, stmp
, &session_list
->head
, list
) {
69 if (!session_get(sess
)) {
73 if (!sess
->active
|| !sess
->ust_session
|| !sess
->ust_session
->active
) {
77 ust_app_global_update(sess
->ust_session
, app
);
85 * Sanitize the wait queue of the dispatch registration thread meaning removing
86 * invalid nodes from it. This is to avoid memory leaks for the case the UST
87 * notify socket is never received.
89 static void sanitize_wait_queue(struct ust_reg_wait_queue
*wait_queue
)
91 int ret
, nb_fd
= 0, i
;
92 unsigned int fd_added
= 0;
93 struct lttng_poll_event events
;
94 struct ust_reg_wait_node
*wait_node
= nullptr, *tmp_wait_node
;
96 LTTNG_ASSERT(wait_queue
);
98 lttng_poll_init(&events
);
100 /* Just skip everything for an empty queue. */
101 if (!wait_queue
->count
) {
105 ret
= lttng_poll_create(&events
, wait_queue
->count
, LTTNG_CLOEXEC
);
110 cds_list_for_each_entry_safe (wait_node
, tmp_wait_node
, &wait_queue
->head
, head
) {
111 LTTNG_ASSERT(wait_node
->app
);
112 ret
= lttng_poll_add(&events
, wait_node
->app
->sock
, LPOLLIN
);
125 * Poll but don't block so we can quickly identify the faulty events and
126 * clean them afterwards from the wait queue.
128 ret
= lttng_poll_wait(&events
, 0);
134 for (i
= 0; i
< nb_fd
; i
++) {
136 uint32_t revents
= LTTNG_POLL_GETEV(&events
, i
);
137 int pollfd
= LTTNG_POLL_GETFD(&events
, i
);
139 cds_list_for_each_entry_safe (wait_node
, tmp_wait_node
, &wait_queue
->head
, head
) {
140 if (pollfd
== wait_node
->app
->sock
&& (revents
& (LPOLLHUP
| LPOLLERR
))) {
141 cds_list_del(&wait_node
->head
);
143 ust_app_put(wait_node
->app
);
147 * Silence warning of use-after-free in
148 * cds_list_for_each_entry_safe which uses
149 * __typeof__(*wait_node).
154 ERR("Unexpected poll events %u for sock %d", revents
, pollfd
);
161 DBG("Wait queue sanitized, %d node were cleaned up", nb_fd
);
165 lttng_poll_clean(&events
);
169 lttng_poll_clean(&events
);
171 ERR("Unable to sanitize wait queue");
176 * Send a socket to a thread This is called from the dispatch UST registration
177 * thread once all sockets are set for the application.
179 * The sock value can be invalid, we don't really care, the thread will handle
180 * it and make the necessary cleanup if so.
182 * On success, return 0 else a negative value being the errno message of the
185 static int send_socket_to_thread(int fd
, int sock
)
190 * It's possible that the FD is set as invalid with -1 concurrently just
191 * before calling this function being a shutdown state of the thread.
198 ret
= lttng_write(fd
, &sock
, sizeof(sock
));
199 if (ret
< sizeof(sock
)) {
200 PERROR("write apps pipe %d", fd
);
207 /* All good. Don't send back the write positive ret value. */
213 static void cleanup_ust_dispatch_thread(void *data
)
219 * Dispatch request from the registration threads to the application
220 * communication thread.
222 static void *thread_dispatch_ust_registration(void *data
)
225 struct cds_wfcq_node
*node
;
226 struct ust_command
*ust_cmd
= nullptr;
227 struct ust_reg_wait_node
*wait_node
= nullptr, *tmp_wait_node
;
228 struct ust_reg_wait_queue wait_queue
= {
232 struct thread_notifiers
*notifiers
= (thread_notifiers
*) data
;
234 rcu_register_thread();
236 health_register(the_health_sessiond
, HEALTH_SESSIOND_TYPE_APP_REG_DISPATCH
);
238 if (testpoint(sessiond_thread_app_reg_dispatch
)) {
239 goto error_testpoint
;
242 health_code_update();
244 CDS_INIT_LIST_HEAD(&wait_queue
.head
);
246 DBG("[thread] Dispatch UST command started");
249 health_code_update();
251 /* Atomically prepare the queue futex */
252 futex_nto1_prepare(¬ifiers
->ust_cmd_queue
->futex
);
254 if (CMM_LOAD_SHARED(notifiers
->dispatch_thread_exit
)) {
259 struct ust_app
*app
= nullptr;
263 * Make sure we don't have node(s) that have hung up before receiving
264 * the notify socket. This is to clean the list in order to avoid
265 * memory leaks from notify socket that are never seen.
267 sanitize_wait_queue(&wait_queue
);
269 health_code_update();
270 /* Dequeue command for registration */
271 node
= cds_wfcq_dequeue_blocking(¬ifiers
->ust_cmd_queue
->head
,
272 ¬ifiers
->ust_cmd_queue
->tail
);
273 if (node
== nullptr) {
274 DBG("Woken up but nothing in the UST command queue");
275 /* Continue thread execution */
279 ust_cmd
= lttng::utils::container_of(node
, &ust_command::node
);
281 DBG("Dispatching UST registration pid:%d ppid:%d uid:%d"
282 " gid:%d sock:%d name:%s (version %d.%d)",
283 ust_cmd
->reg_msg
.pid
,
284 ust_cmd
->reg_msg
.ppid
,
285 ust_cmd
->reg_msg
.uid
,
286 ust_cmd
->reg_msg
.gid
,
288 ust_cmd
->reg_msg
.name
,
289 ust_cmd
->reg_msg
.major
,
290 ust_cmd
->reg_msg
.minor
);
292 if (ust_cmd
->reg_msg
.type
== LTTNG_UST_CTL_SOCKET_CMD
) {
293 wait_node
= zmalloc
<ust_reg_wait_node
>();
295 PERROR("zmalloc wait_node dispatch");
296 ret
= close(ust_cmd
->sock
);
298 PERROR("close ust sock dispatch %d", ust_cmd
->sock
);
300 lttng_fd_put(LTTNG_FD_APPS
, 1);
305 CDS_INIT_LIST_HEAD(&wait_node
->head
);
307 /* Create application object if socket is CMD. */
308 wait_node
->app
= ust_app_create(&ust_cmd
->reg_msg
, ust_cmd
->sock
);
309 if (!wait_node
->app
) {
310 ret
= close(ust_cmd
->sock
);
312 PERROR("close ust sock dispatch %d", ust_cmd
->sock
);
314 lttng_fd_put(LTTNG_FD_APPS
, 1);
322 * Add application to the wait queue so we can set the notify
323 * socket before putting this object in the global ht.
325 cds_list_add(&wait_node
->head
, &wait_queue
.head
);
331 * We have to continue here since we don't have the notify
332 * socket and the application MUST be added to the hash table
333 * only at that moment.
338 * Look for the application in the local wait queue and set the
339 * notify socket if found.
341 cds_list_for_each_entry_safe (
342 wait_node
, tmp_wait_node
, &wait_queue
.head
, head
) {
343 health_code_update();
344 if (wait_node
->app
->pid
== ust_cmd
->reg_msg
.pid
) {
345 wait_node
->app
->notify_sock
= ust_cmd
->sock
;
346 cds_list_del(&wait_node
->head
);
348 app
= wait_node
->app
;
351 DBG3("UST app notify socket %d is set",
358 * With no application at this stage the received socket is
359 * basically useless so close it before we free the cmd data
360 * structure for good.
363 ret
= close(ust_cmd
->sock
);
365 PERROR("close ust sock dispatch %d", ust_cmd
->sock
);
367 lttng_fd_put(LTTNG_FD_APPS
, 1);
377 * Lock the global session list so from the register up to the
378 * registration done message, no thread can see the application
379 * and change its state.
381 const auto list_lock
= lttng::sessiond::lock_session_list();
382 lttng::urcu::read_lock_guard read_lock
;
385 * Add application to the global hash table. This needs to be
386 * done before the update to the UST registry can locate the
391 /* Set app version. This call will print an error if needed. */
392 (void) ust_app_version(app
);
394 (void) ust_app_setup_event_notifier_group(app
);
396 /* Send notify socket through the notify pipe. */
397 ret
= send_socket_to_thread(
398 notifiers
->apps_cmd_notify_pipe_write_fd
, app
->notify_sock
);
401 * No notify thread, stop the UST tracing. However, this is
402 * not an internal error of the this thread thus setting
403 * the health error code to a normal exit.
410 * Update newly registered application with the tracing
411 * registry info already enabled information.
413 update_ust_app(app
->sock
);
416 * Don't care about return value. Let the manage apps threads
417 * handle app unregistration upon socket close.
419 (void) ust_app_register_done(app
);
422 * Even if the application socket has been closed, send the app
423 * to the thread and unregistration will take place at that
426 ret
= send_socket_to_thread(notifiers
->apps_cmd_pipe_write_fd
,
430 * No apps. thread, stop the UST tracing. However, this is
431 * not an internal error of the this thread thus setting
432 * the health error code to a normal exit.
438 } while (node
!= nullptr);
441 /* Futex wait on queue. Blocking call on futex() */
442 futex_nto1_wait(¬ifiers
->ust_cmd_queue
->futex
);
445 /* Normal exit, no error */
449 /* Clean up wait queue. */
450 cds_list_for_each_entry_safe (wait_node
, tmp_wait_node
, &wait_queue
.head
, head
) {
451 cds_list_del(&wait_node
->head
);
456 /* Empty command queue. */
458 /* Dequeue command for registration */
459 node
= cds_wfcq_dequeue_blocking(¬ifiers
->ust_cmd_queue
->head
,
460 ¬ifiers
->ust_cmd_queue
->tail
);
461 if (node
== nullptr) {
464 ust_cmd
= lttng::utils::container_of(node
, &ust_command::node
);
465 ret
= close(ust_cmd
->sock
);
467 PERROR("close ust sock exit dispatch %d", ust_cmd
->sock
);
469 lttng_fd_put(LTTNG_FD_APPS
, 1);
474 DBG("Dispatch thread dying");
477 ERR("Health error occurred in %s", __func__
);
479 health_unregister(the_health_sessiond
);
480 rcu_unregister_thread();
484 static bool shutdown_ust_dispatch_thread(void *data
)
486 struct thread_notifiers
*notifiers
= (thread_notifiers
*) data
;
488 CMM_STORE_SHARED(notifiers
->dispatch_thread_exit
, 1);
489 futex_nto1_wake(¬ifiers
->ust_cmd_queue
->futex
);
493 bool launch_ust_dispatch_thread(struct ust_cmd_queue
*cmd_queue
,
494 int apps_cmd_pipe_write_fd
,
495 int apps_cmd_notify_pipe_write_fd
)
497 struct lttng_thread
*thread
;
498 struct thread_notifiers
*notifiers
;
500 notifiers
= zmalloc
<thread_notifiers
>();
504 notifiers
->ust_cmd_queue
= cmd_queue
;
505 notifiers
->apps_cmd_pipe_write_fd
= apps_cmd_pipe_write_fd
;
506 notifiers
->apps_cmd_notify_pipe_write_fd
= apps_cmd_notify_pipe_write_fd
;
508 thread
= lttng_thread_create("UST registration dispatch",
509 thread_dispatch_ust_registration
,
510 shutdown_ust_dispatch_thread
,
511 cleanup_ust_dispatch_thread
,
516 lttng_thread_put(thread
);