clang-tidy: apply suggested fixes
[lttng-tools.git] / src / bin / lttng-sessiond / session.cpp
1 /*
2 * Copyright (C) 2011 EfficiOS Inc.
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include "buffer-registry.hpp"
10 #include "cmd.hpp"
11 #include "kernel.hpp"
12 #include "lttng-sessiond.hpp"
13 #include "session.hpp"
14 #include "timer.hpp"
15 #include "trace-ust.hpp"
16 #include "ust-app.hpp"
17 #include "utils.hpp"
18
19 #include <common/common.hpp>
20 #include <common/ctl/format.hpp>
21 #include <common/sessiond-comm/sessiond-comm.hpp>
22 #include <common/trace-chunk.hpp>
23 #include <common/urcu.hpp>
24 #include <common/utils.hpp>
25
26 #include <lttng/location-internal.hpp>
27
28 #include <dirent.h>
29 #include <inttypes.h>
30 #include <limits.h>
31 #include <pthread.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <urcu.h>
38
39 namespace {
40 struct ltt_session_destroy_notifier_element {
41 ltt_session_destroy_notifier notifier;
42 void *user_data;
43 };
44
45 struct ltt_session_clear_notifier_element {
46 ltt_session_clear_notifier notifier;
47 void *user_data;
48 };
49
50 namespace ls = lttng::sessiond;
51
52 /*
53 * NOTES:
54 *
55 * No ltt_session.lock is taken here because those data structure are widely
56 * spread across the lttng-tools code base so before calling functions below
57 * that can read/write a session, the caller MUST acquire the session lock
58 * using session_lock() and session_unlock().
59 */
60
61 /* These characters are forbidden in a session name. Used by validate_name. */
62 const char *forbidden_name_chars = "/";
63
64 /* Global hash table to keep the sessions, indexed by id. */
65 struct lttng_ht *ltt_sessions_ht_by_id = nullptr;
66 /* Global hash table to keep the sessions, indexed by name. */
67 struct lttng_ht *ltt_sessions_ht_by_name = nullptr;
68
69 /*
70 * Init tracing session list.
71 *
72 * Please see session.h for more explanation and correct usage of the list.
73 */
74 struct ltt_session_list the_session_list;
75
76 /*
77 * Return a ltt_session structure ptr that matches name. If no session found,
78 * NULL is returned. This must be called with the session list lock held using
79 * session_lock_list and session_unlock_list.
80 * A reference to the session is implicitly acquired by this function.
81 */
82 struct ltt_session *session_find_by_name(const char *name)
83 {
84 struct ltt_session *iter;
85
86 LTTNG_ASSERT(name);
87 ASSERT_SESSION_LIST_LOCKED();
88
89 DBG2("Trying to find session by name %s", name);
90
91 cds_list_for_each_entry (iter, &the_session_list.head, list) {
92 if (!strncmp(iter->name, name, NAME_MAX) && !iter->destroyed) {
93 goto found;
94 }
95 }
96
97 return nullptr;
98 found:
99 return session_get(iter) ? iter : nullptr;
100 }
101
102 /*
103 * Return an ltt_session that matches the id. If no session is found,
104 * NULL is returned. This must be called with rcu_read_lock and
105 * session list lock held (to guarantee the lifetime of the session).
106 */
107 struct ltt_session *session_find_by_id(uint64_t id)
108 {
109 struct lttng_ht_node_u64 *node;
110 struct lttng_ht_iter iter;
111 struct ltt_session *ls;
112
113 ASSERT_RCU_READ_LOCKED();
114 ASSERT_SESSION_LIST_LOCKED();
115
116 if (!ltt_sessions_ht_by_id) {
117 goto end;
118 }
119
120 lttng_ht_lookup(ltt_sessions_ht_by_id, &id, &iter);
121 node = lttng_ht_iter_get_node<lttng_ht_node_u64>(&iter);
122 if (node == nullptr) {
123 goto end;
124 }
125 ls = lttng::utils::container_of(node, &ltt_session::node);
126
127 DBG3("Session %" PRIu64 " found by id.", id);
128 return session_get(ls) ? ls : nullptr;
129
130 end:
131 DBG3("Session %" PRIu64 " NOT found by id", id);
132 return nullptr;
133 }
134 } /* namespace */
135
136 /*
137 * Validate the session name for forbidden characters.
138 *
139 * Return 0 on success else -1 meaning a forbidden char. has been found.
140 */
141 static int validate_name(const char *name)
142 {
143 int ret;
144 char *tok, *tmp_name;
145
146 LTTNG_ASSERT(name);
147
148 tmp_name = strdup(name);
149 if (!tmp_name) {
150 /* ENOMEM here. */
151 ret = -1;
152 goto error;
153 }
154
155 tok = strpbrk(tmp_name, forbidden_name_chars);
156 if (tok) {
157 DBG("Session name %s contains a forbidden character", name);
158 /* Forbidden character has been found. */
159 ret = -1;
160 goto error;
161 }
162 ret = 0;
163
164 error:
165 free(tmp_name);
166 return ret;
167 }
168
169 /*
170 * Add a ltt_session structure to the global list.
171 *
172 * The caller MUST acquire the session list lock before.
173 * Returns the unique identifier for the session.
174 */
175 static uint64_t add_session_list(struct ltt_session *ls)
176 {
177 LTTNG_ASSERT(ls);
178
179 cds_list_add(&ls->list, &the_session_list.head);
180 return the_session_list.next_uuid++;
181 }
182
183 /*
184 * Delete a ltt_session structure to the global list.
185 *
186 * The caller MUST acquire the session list lock before.
187 */
188 static void del_session_list(struct ltt_session *ls)
189 {
190 LTTNG_ASSERT(ls);
191
192 cds_list_del(&ls->list);
193 }
194
195 /*
196 * Return a pointer to the session list.
197 */
198 struct ltt_session_list *session_get_list()
199 {
200 return &the_session_list;
201 }
202
203 /*
204 * Returns once the session list is empty.
205 */
206 void session_list_wait_empty(std::unique_lock<std::mutex> list_lock)
207 {
208 /* Keep waiting until the session list is empty. */
209 the_session_list.removal_cond.wait(list_lock,
210 [] { return cds_list_empty(&the_session_list.head); });
211 }
212
213 /*
214 * Try to acquire session list lock
215 */
216 int session_trylock_list() noexcept
217 {
218 /* Return 0 if successfully acquired. */
219 return the_session_list.lock.try_lock() ? 0 : 1;
220 }
221
222 /*
223 * Get the session's consumer destination type.
224 */
225 enum consumer_dst_type session_get_consumer_destination_type(const ltt_session::locked_ref& session)
226 {
227 /*
228 * The output information is duplicated in both of those session types.
229 * Hence, it doesn't matter from which it is retrieved. However, it is
230 * possible for only one of them to be set.
231 */
232 return session->kernel_session ? session->kernel_session->consumer->type :
233 session->ust_session->consumer->type;
234 }
235
236 /*
237 * Get the session's consumer network hostname.
238 * The caller must ensure that the destination is of type "net".
239 */
240 const char *session_get_net_consumer_hostname(const ltt_session::locked_ref& session)
241 {
242 const char *hostname = nullptr;
243 const struct consumer_output *output;
244
245 output = session->kernel_session ? session->kernel_session->consumer :
246 session->ust_session->consumer;
247
248 /*
249 * hostname is assumed to be the same for both control and data
250 * connections.
251 */
252 switch (output->dst.net.control.dtype) {
253 case LTTNG_DST_IPV4:
254 hostname = output->dst.net.control.dst.ipv4;
255 break;
256 case LTTNG_DST_IPV6:
257 hostname = output->dst.net.control.dst.ipv6;
258 break;
259 default:
260 abort();
261 }
262 return hostname;
263 }
264
265 /*
266 * Get the session's consumer network control and data ports.
267 * The caller must ensure that the destination is of type "net".
268 */
269 void session_get_net_consumer_ports(const ltt_session::locked_ref& session,
270 uint16_t *control_port,
271 uint16_t *data_port)
272 {
273 const struct consumer_output *output;
274
275 output = session->kernel_session ? session->kernel_session->consumer :
276 session->ust_session->consumer;
277 *control_port = output->dst.net.control.port;
278 *data_port = output->dst.net.data.port;
279 }
280
281 /*
282 * Get the location of the latest trace archive produced by a rotation.
283 */
284 struct lttng_trace_archive_location *
285 session_get_trace_archive_location(const ltt_session::locked_ref& session)
286 {
287 int ret;
288 struct lttng_trace_archive_location *location = nullptr;
289 char *chunk_path = nullptr;
290
291 if (session->rotation_state != LTTNG_ROTATION_STATE_COMPLETED ||
292 !session->last_archived_chunk_name) {
293 goto end;
294 }
295
296 switch (session_get_consumer_destination_type(session)) {
297 case CONSUMER_DST_LOCAL:
298 ret = asprintf(&chunk_path,
299 "%s/" DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY "/%s",
300 session_get_base_path(session),
301 session->last_archived_chunk_name);
302 if (ret == -1) {
303 goto end;
304 }
305 location = lttng_trace_archive_location_local_create(chunk_path);
306 break;
307 case CONSUMER_DST_NET:
308 {
309 const char *hostname;
310 uint16_t control_port, data_port;
311
312 hostname = session_get_net_consumer_hostname(session);
313 session_get_net_consumer_ports(session, &control_port, &data_port);
314 location = lttng_trace_archive_location_relay_create(
315 hostname,
316 LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP,
317 control_port,
318 data_port,
319 session->last_chunk_path);
320 break;
321 }
322 default:
323 abort();
324 }
325 end:
326 free(chunk_path);
327 return location;
328 }
329
330 /*
331 * Allocate the ltt_sessions_ht_by_id and ltt_sessions_ht_by_name HT.
332 *
333 * The session list lock must be held.
334 */
335 static int ltt_sessions_ht_alloc()
336 {
337 int ret = 0;
338
339 DBG("Allocating ltt_sessions_ht_by_id");
340 ltt_sessions_ht_by_id = lttng_ht_new(0, LTTNG_HT_TYPE_U64);
341 if (!ltt_sessions_ht_by_id) {
342 ret = -1;
343 ERR("Failed to allocate ltt_sessions_ht_by_id");
344 goto end;
345 }
346
347 DBG("Allocating ltt_sessions_ht_by_name");
348 ltt_sessions_ht_by_name = lttng_ht_new(0, LTTNG_HT_TYPE_STRING);
349 if (!ltt_sessions_ht_by_name) {
350 ret = -1;
351 ERR("Failed to allocate ltt_sessions_ht_by_name");
352 goto end;
353 }
354
355 end:
356 return ret;
357 }
358
359 /*
360 * Destroy the ltt_sessions_ht_by_id HT.
361 *
362 * The session list lock must be held.
363 */
364 static void ltt_sessions_ht_destroy()
365 {
366 if (ltt_sessions_ht_by_id) {
367 lttng_ht_destroy(ltt_sessions_ht_by_id);
368 ltt_sessions_ht_by_id = nullptr;
369 }
370
371 if (ltt_sessions_ht_by_name) {
372 lttng_ht_destroy(ltt_sessions_ht_by_name);
373 ltt_sessions_ht_by_name = nullptr;
374 }
375
376 return;
377 }
378
379 /*
380 * Add a ltt_session to the ltt_sessions_ht_by_id and ltt_sessions_ht_by_name.
381 * If unallocated, the ltt_sessions_ht_by_id and ltt_sessions_ht_by_name. HTs
382 * are allocated. The session list lock must be held.
383 */
384 static void add_session_ht(struct ltt_session *ls)
385 {
386 int ret;
387
388 LTTNG_ASSERT(ls);
389
390 if (!ltt_sessions_ht_by_id) {
391 ret = ltt_sessions_ht_alloc();
392 if (ret) {
393 ERR("Error allocating the sessions HT");
394 goto end;
395 }
396 }
397
398 /* Should always be present with ltt_sessions_ht_by_id. */
399 LTTNG_ASSERT(ltt_sessions_ht_by_name);
400
401 lttng_ht_node_init_u64(&ls->node, ls->id);
402 lttng_ht_add_unique_u64(ltt_sessions_ht_by_id, &ls->node);
403
404 lttng_ht_node_init_str(&ls->node_by_name, ls->name);
405 lttng_ht_add_unique_str(ltt_sessions_ht_by_name, &ls->node_by_name);
406
407 end:
408 return;
409 }
410
411 /*
412 * Test if ltt_sessions_ht_by_id/name are empty.
413 * Return `false` if hash table objects are null.
414 * The session list lock must be held.
415 */
416 static bool ltt_sessions_ht_empty()
417 {
418 bool empty = false;
419
420 if (!ltt_sessions_ht_by_id) {
421 /* The hash tables do not exist yet. */
422 goto end;
423 }
424
425 LTTNG_ASSERT(ltt_sessions_ht_by_name);
426
427 if (lttng_ht_get_count(ltt_sessions_ht_by_id) != 0) {
428 /* Not empty.*/
429 goto end;
430 }
431
432 /*
433 * At this point it is expected that the `ltt_sessions_ht_by_name` ht is
434 * empty.
435 *
436 * The removal from both hash tables is done in two different
437 * places:
438 * - removal from `ltt_sessions_ht_by_name` is done during
439 * `session_destroy()`
440 * - removal from `ltt_sessions_ht_by_id` is done later
441 * in `session_release()` on the last reference put.
442 *
443 * This means that it is possible for `ltt_sessions_ht_by_name` to be
444 * empty but for `ltt_sessions_ht_by_id` to still contain objects when
445 * multiple sessions exists. The reverse is false, hence this sanity
446 * check.
447 */
448 LTTNG_ASSERT(lttng_ht_get_count(ltt_sessions_ht_by_name) == 0);
449 empty = true;
450 end:
451 return empty;
452 }
453
454 /*
455 * Remove a ltt_session from the ltt_sessions_ht_by_id.
456 * If empty, the ltt_sessions_ht_by_id/name HTs are freed.
457 * The session list lock must be held.
458 */
459 static void del_session_ht(struct ltt_session *ls)
460 {
461 struct lttng_ht_iter iter;
462 int ret;
463
464 LTTNG_ASSERT(ls);
465 LTTNG_ASSERT(ltt_sessions_ht_by_id);
466 LTTNG_ASSERT(ltt_sessions_ht_by_name);
467
468 iter.iter.node = &ls->node.node;
469 ret = lttng_ht_del(ltt_sessions_ht_by_id, &iter);
470 LTTNG_ASSERT(!ret);
471
472 if (ltt_sessions_ht_empty()) {
473 DBG("Empty ltt_sessions_ht_by_id/name, destroying hast tables");
474 ltt_sessions_ht_destroy();
475 }
476 }
477
478 /*
479 * Acquire session lock
480 */
481 void session_lock(const ltt_session *session)
482 {
483 LTTNG_ASSERT(session);
484 session->lock();
485 }
486
487 void ltt_session::lock() const noexcept
488 {
489 pthread_mutex_lock(&_lock);
490 }
491
492 void ltt_session::unlock() const noexcept
493 {
494 ltt_session::_const_session_unlock(*this);
495 }
496
497 /*
498 * Release session lock
499 */
500 void session_unlock(const ltt_session *session)
501 {
502 LTTNG_ASSERT(session);
503 session->unlock();
504 }
505
506 void ltt_session::_const_session_unlock(const ltt_session& session)
507 {
508 pthread_mutex_unlock(&session._lock);
509 }
510
511 static int _session_set_trace_chunk_no_lock_check(const ltt_session::locked_ref& session,
512 struct lttng_trace_chunk *new_trace_chunk,
513 struct lttng_trace_chunk **_current_trace_chunk)
514 {
515 int ret = 0;
516 unsigned int i, refs_to_acquire = 0, refs_acquired = 0, refs_to_release = 0;
517 struct cds_lfht_iter iter;
518 struct consumer_socket *socket;
519 struct lttng_trace_chunk *current_trace_chunk;
520 uint64_t chunk_id;
521 enum lttng_trace_chunk_status chunk_status;
522
523 const lttng::urcu::read_lock_guard read_lock;
524 /*
525 * Ownership of current trace chunk is transferred to
526 * `current_trace_chunk`.
527 */
528 current_trace_chunk = session->current_trace_chunk;
529 session->current_trace_chunk = nullptr;
530 if (session->ust_session) {
531 lttng_trace_chunk_put(session->ust_session->current_trace_chunk);
532 session->ust_session->current_trace_chunk = nullptr;
533 }
534 if (session->kernel_session) {
535 lttng_trace_chunk_put(session->kernel_session->current_trace_chunk);
536 session->kernel_session->current_trace_chunk = nullptr;
537 }
538 if (!new_trace_chunk) {
539 ret = 0;
540 goto end;
541 }
542 chunk_status = lttng_trace_chunk_get_id(new_trace_chunk, &chunk_id);
543 LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
544
545 refs_to_acquire = 1;
546 refs_to_acquire += !!session->ust_session;
547 refs_to_acquire += !!session->kernel_session;
548
549 for (refs_acquired = 0; refs_acquired < refs_to_acquire; refs_acquired++) {
550 if (!lttng_trace_chunk_get(new_trace_chunk)) {
551 ERR("Failed to acquire reference to new trace chunk of session \"%s\"",
552 session->name);
553 goto error;
554 }
555 }
556
557 if (session->ust_session) {
558 const uint64_t relayd_id = session->ust_session->consumer->net_seq_index;
559 const bool is_local_trace = session->ust_session->consumer->type ==
560 CONSUMER_DST_LOCAL;
561
562 session->ust_session->current_trace_chunk = new_trace_chunk;
563 if (is_local_trace) {
564 enum lttng_error_code ret_error_code;
565
566 ret_error_code =
567 ust_app_create_channel_subdirectories(session->ust_session);
568 if (ret_error_code != LTTNG_OK) {
569 goto error;
570 }
571 }
572 cds_lfht_for_each_entry (
573 session->ust_session->consumer->socks->ht, &iter, socket, node.node) {
574 pthread_mutex_lock(socket->lock);
575 ret = consumer_create_trace_chunk(socket,
576 relayd_id,
577 session->id,
578 new_trace_chunk,
579 DEFAULT_UST_TRACE_DIR);
580 pthread_mutex_unlock(socket->lock);
581 if (ret) {
582 goto error;
583 }
584 }
585 }
586 if (session->kernel_session) {
587 const uint64_t relayd_id = session->kernel_session->consumer->net_seq_index;
588 const bool is_local_trace = session->kernel_session->consumer->type ==
589 CONSUMER_DST_LOCAL;
590
591 session->kernel_session->current_trace_chunk = new_trace_chunk;
592 if (is_local_trace) {
593 enum lttng_error_code ret_error_code;
594
595 ret_error_code =
596 kernel_create_channel_subdirectories(session->kernel_session);
597 if (ret_error_code != LTTNG_OK) {
598 goto error;
599 }
600 }
601 cds_lfht_for_each_entry (
602 session->kernel_session->consumer->socks->ht, &iter, socket, node.node) {
603 pthread_mutex_lock(socket->lock);
604 ret = consumer_create_trace_chunk(socket,
605 relayd_id,
606 session->id,
607 new_trace_chunk,
608 DEFAULT_KERNEL_TRACE_DIR);
609 pthread_mutex_unlock(socket->lock);
610 if (ret) {
611 goto error;
612 }
613 }
614 }
615
616 /*
617 * Update local current trace chunk state last, only if all remote
618 * creations succeeded.
619 */
620 session->current_trace_chunk = new_trace_chunk;
621 LTTNG_OPTIONAL_SET(&session->most_recent_chunk_id, chunk_id);
622 end:
623 if (_current_trace_chunk) {
624 *_current_trace_chunk = current_trace_chunk;
625 current_trace_chunk = nullptr;
626 }
627 end_no_move:
628 lttng_trace_chunk_put(current_trace_chunk);
629 return ret;
630 error:
631 if (session->ust_session) {
632 session->ust_session->current_trace_chunk = nullptr;
633 }
634 if (session->kernel_session) {
635 session->kernel_session->current_trace_chunk = nullptr;
636 }
637 /*
638 * Release references taken in the case where all references could not
639 * be acquired.
640 */
641 refs_to_release = refs_to_acquire - refs_acquired;
642 for (i = 0; i < refs_to_release; i++) {
643 lttng_trace_chunk_put(new_trace_chunk);
644 }
645 ret = -1;
646 goto end_no_move;
647 }
648
649 struct lttng_trace_chunk *
650 session_create_new_trace_chunk(const ltt_session::locked_ref& session,
651 const struct consumer_output *consumer_output_override,
652 const char *session_base_path_override,
653 const char *chunk_name_override)
654 {
655 int ret;
656 struct lttng_trace_chunk *trace_chunk = nullptr;
657 enum lttng_trace_chunk_status chunk_status;
658 const time_t chunk_creation_ts = time(nullptr);
659 bool is_local_trace;
660 const char *base_path;
661 struct lttng_directory_handle *session_output_directory = nullptr;
662 const struct lttng_credentials session_credentials = {
663 .uid = LTTNG_OPTIONAL_INIT_VALUE(session->uid),
664 .gid = LTTNG_OPTIONAL_INIT_VALUE(session->gid),
665 };
666 uint64_t next_chunk_id;
667 const struct consumer_output *output;
668 const char *new_path;
669
670 if (consumer_output_override) {
671 output = consumer_output_override;
672 } else {
673 LTTNG_ASSERT(session->ust_session || session->kernel_session);
674 output = session->ust_session ? session->ust_session->consumer :
675 session->kernel_session->consumer;
676 }
677
678 is_local_trace = output->type == CONSUMER_DST_LOCAL;
679 base_path = session_base_path_override ?: consumer_output_get_base_path(output);
680
681 if (chunk_creation_ts == (time_t) -1) {
682 PERROR("Failed to sample time while creation session \"%s\" trace chunk",
683 session->name);
684 goto error;
685 }
686
687 next_chunk_id =
688 session->most_recent_chunk_id.is_set ? session->most_recent_chunk_id.value + 1 : 0;
689
690 if (session->current_trace_chunk &&
691 !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) {
692 chunk_status = lttng_trace_chunk_rename_path(session->current_trace_chunk,
693 DEFAULT_CHUNK_TMP_OLD_DIRECTORY);
694 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
695 goto error;
696 }
697 }
698 if (!session->current_trace_chunk) {
699 if (!session->rotated) {
700 new_path = "";
701 } else {
702 new_path = nullptr;
703 }
704 } else {
705 new_path = DEFAULT_CHUNK_TMP_NEW_DIRECTORY;
706 }
707
708 trace_chunk = lttng_trace_chunk_create(next_chunk_id, chunk_creation_ts, new_path);
709 if (!trace_chunk) {
710 goto error;
711 }
712
713 if (chunk_name_override) {
714 chunk_status = lttng_trace_chunk_override_name(trace_chunk, chunk_name_override);
715 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
716 goto error;
717 }
718 }
719
720 if (!is_local_trace) {
721 /*
722 * No need to set crendentials and output directory
723 * for remote trace chunks.
724 */
725 goto end;
726 }
727
728 chunk_status = lttng_trace_chunk_set_credentials(trace_chunk, &session_credentials);
729 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
730 goto error;
731 }
732
733 DBG("Creating base output directory of session \"%s\" at %s", session->name, base_path);
734 ret = utils_mkdir_recursive(base_path, S_IRWXU | S_IRWXG, session->uid, session->gid);
735 if (ret) {
736 goto error;
737 }
738 session_output_directory = lttng_directory_handle_create(base_path);
739 if (!session_output_directory) {
740 goto error;
741 }
742 chunk_status = lttng_trace_chunk_set_as_owner(trace_chunk, session_output_directory);
743 lttng_directory_handle_put(session_output_directory);
744 session_output_directory = nullptr;
745 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
746 goto error;
747 }
748 end:
749 return trace_chunk;
750 error:
751 lttng_directory_handle_put(session_output_directory);
752 lttng_trace_chunk_put(trace_chunk);
753 trace_chunk = nullptr;
754 goto end;
755 }
756
757 int session_close_trace_chunk(const ltt_session::locked_ref& session,
758 struct lttng_trace_chunk *trace_chunk,
759 enum lttng_trace_chunk_command_type close_command,
760 char *closed_trace_chunk_path)
761 {
762 int ret = 0;
763 bool error_occurred = false;
764 struct cds_lfht_iter iter;
765 struct consumer_socket *socket;
766 enum lttng_trace_chunk_status chunk_status;
767 const time_t chunk_close_timestamp = time(nullptr);
768 const char *new_path;
769
770 chunk_status = lttng_trace_chunk_set_close_command(trace_chunk, close_command);
771 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
772 ret = -1;
773 goto end;
774 }
775
776 if (chunk_close_timestamp == (time_t) -1) {
777 ERR("Failed to sample the close timestamp of the current trace chunk of session \"%s\"",
778 session->name);
779 ret = -1;
780 goto end;
781 }
782
783 if (close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE && !session->rotated) {
784 /* New chunk stays in session output directory. */
785 new_path = "";
786 } else {
787 /* Use chunk name for new chunk. */
788 new_path = nullptr;
789 }
790 if (session->current_trace_chunk &&
791 !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) {
792 /* Rename new chunk path. */
793 chunk_status =
794 lttng_trace_chunk_rename_path(session->current_trace_chunk, new_path);
795 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
796 ret = -1;
797 goto end;
798 }
799 }
800 if (!lttng_trace_chunk_get_name_overridden(trace_chunk) &&
801 close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION) {
802 const char *old_path;
803
804 if (!session->rotated) {
805 old_path = "";
806 } else {
807 old_path = nullptr;
808 }
809 /* We need to move back the .tmp_old_chunk to its rightful place. */
810 chunk_status = lttng_trace_chunk_rename_path(trace_chunk, old_path);
811 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
812 ret = -1;
813 goto end;
814 }
815 }
816 if (close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED) {
817 session->rotated = true;
818 }
819 chunk_status = lttng_trace_chunk_set_close_timestamp(trace_chunk, chunk_close_timestamp);
820 if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
821 ERR("Failed to set the close timestamp of the current trace chunk of session \"%s\"",
822 session->name);
823 ret = -1;
824 goto end;
825 }
826
827 if (session->ust_session) {
828 const uint64_t relayd_id = session->ust_session->consumer->net_seq_index;
829
830 cds_lfht_for_each_entry (
831 session->ust_session->consumer->socks->ht, &iter, socket, node.node) {
832 pthread_mutex_lock(socket->lock);
833 ret = consumer_close_trace_chunk(socket,
834 relayd_id,
835 session->id,
836 trace_chunk,
837 closed_trace_chunk_path);
838 pthread_mutex_unlock(socket->lock);
839 if (ret) {
840 ERR("Failed to close trace chunk on user space consumer");
841 error_occurred = true;
842 }
843 }
844 }
845 if (session->kernel_session) {
846 const uint64_t relayd_id = session->kernel_session->consumer->net_seq_index;
847
848 cds_lfht_for_each_entry (
849 session->kernel_session->consumer->socks->ht, &iter, socket, node.node) {
850 pthread_mutex_lock(socket->lock);
851 ret = consumer_close_trace_chunk(socket,
852 relayd_id,
853 session->id,
854 trace_chunk,
855 closed_trace_chunk_path);
856 pthread_mutex_unlock(socket->lock);
857 if (ret) {
858 ERR("Failed to close trace chunk on kernel consumer");
859 error_occurred = true;
860 }
861 }
862 }
863 ret = error_occurred ? -1 : 0;
864 end:
865 return ret;
866 }
867
868 /*
869 * This function skips the metadata channel as the begin/end timestamps of a
870 * metadata packet are useless.
871 *
872 * Moreover, opening a packet after a "clear" will cause problems for live
873 * sessions as it will introduce padding that was not part of the first trace
874 * chunk. The relay daemon expects the content of the metadata stream of
875 * successive metadata trace chunks to be strict supersets of one another.
876 *
877 * For example, flushing a packet at the beginning of the metadata stream of
878 * a trace chunk resulting from a "clear" session command will cause the
879 * size of the metadata stream of the new trace chunk to not match the size of
880 * the metadata stream of the original chunk. This will confuse the relay
881 * daemon as the same "offset" in a metadata stream will no longer point
882 * to the same content.
883 */
884 static enum lttng_error_code session_kernel_open_packets(const ltt_session::locked_ref& session)
885 {
886 enum lttng_error_code ret = LTTNG_OK;
887 struct consumer_socket *socket;
888 struct lttng_ht_iter iter;
889 struct cds_lfht_node *node;
890 struct ltt_kernel_channel *chan;
891
892 const lttng::urcu::read_lock_guard read_lock;
893
894 cds_lfht_first(session->kernel_session->consumer->socks->ht, &iter.iter);
895 node = cds_lfht_iter_get_node(&iter.iter);
896 socket = caa_container_of(node, typeof(*socket), node.node);
897
898 cds_list_for_each_entry (chan, &session->kernel_session->channel_list.head, list) {
899 int open_ret;
900
901 DBG("Open packet of kernel channel: channel key = %" PRIu64
902 ", session name = %s, session_id = %" PRIu64,
903 chan->key,
904 session->name,
905 session->id);
906
907 open_ret = consumer_open_channel_packets(socket, chan->key);
908 if (open_ret < 0) {
909 /* General error (no known error expected). */
910 ret = LTTNG_ERR_UNK;
911 goto end;
912 }
913 }
914
915 end:
916 return ret;
917 }
918
919 enum lttng_error_code session_open_packets(const ltt_session::locked_ref& session)
920 {
921 enum lttng_error_code ret = LTTNG_OK;
922
923 DBG("Opening packets of session channels: session name = %s, session id = %" PRIu64,
924 session->name,
925 session->id);
926
927 if (session->ust_session) {
928 ret = ust_app_open_packets(session);
929 if (ret != LTTNG_OK) {
930 goto end;
931 }
932 }
933
934 if (session->kernel_session) {
935 ret = session_kernel_open_packets(session);
936 if (ret != LTTNG_OK) {
937 goto end;
938 }
939 }
940
941 end:
942 return ret;
943 }
944
945 /*
946 * Set a session's current trace chunk.
947 *
948 * Must be called with the session lock held.
949 */
950 int session_set_trace_chunk(const ltt_session::locked_ref& session,
951 struct lttng_trace_chunk *new_trace_chunk,
952 struct lttng_trace_chunk **current_trace_chunk)
953 {
954 ASSERT_LOCKED(session->_lock);
955 return _session_set_trace_chunk_no_lock_check(
956 session, new_trace_chunk, current_trace_chunk);
957 }
958
959 static void session_notify_destruction(const ltt_session::locked_ref& session)
960 {
961 size_t i;
962 const auto count = lttng_dynamic_array_get_count(&session->destroy_notifiers);
963
964 for (i = 0; i < count; i++) {
965 const struct ltt_session_destroy_notifier_element *element =
966 (ltt_session_destroy_notifier_element *) lttng_dynamic_array_get_element(
967 &session->destroy_notifiers, i);
968
969 element->notifier(session, element->user_data);
970 }
971 }
972
973 /*
974 * Fire each clear notifier once, and remove them from the array.
975 */
976 void session_notify_clear(const ltt_session::locked_ref& session)
977 {
978 size_t i;
979 const auto count = lttng_dynamic_array_get_count(&session->clear_notifiers);
980
981 for (i = 0; i < count; i++) {
982 const struct ltt_session_clear_notifier_element *element =
983 (ltt_session_clear_notifier_element *) lttng_dynamic_array_get_element(
984 &session->clear_notifiers, i);
985
986 element->notifier(session, element->user_data);
987 }
988 lttng_dynamic_array_clear(&session->clear_notifiers);
989 }
990
991 static void session_release(struct urcu_ref *ref)
992 {
993 int ret;
994 struct ltt_ust_session *usess;
995 struct ltt_kernel_session *ksess;
996 struct ltt_session *session = lttng::utils::container_of(ref, &ltt_session::ref_count);
997 const bool session_published = session->published;
998
999 LTTNG_ASSERT(!session->chunk_being_archived);
1000
1001 usess = session->ust_session;
1002 ksess = session->kernel_session;
1003
1004 /* Clean kernel session teardown, keeping data for destroy notifier. */
1005 kernel_destroy_session(ksess);
1006
1007 /* UST session teardown, keeping data for destroy notifier. */
1008 if (usess) {
1009 /* Close any relayd session */
1010 consumer_output_send_destroy_relayd(usess->consumer);
1011
1012 /* Destroy every UST application related to this session. */
1013 ret = ust_app_destroy_trace_all(usess);
1014 if (ret) {
1015 ERR("Error in ust_app_destroy_trace_all");
1016 }
1017
1018 /* Clean up the rest, keeping destroy notifier data. */
1019 trace_ust_destroy_session(usess);
1020 }
1021
1022 /*
1023 * Must notify the kernel thread here to update it's poll set in order to
1024 * remove the channel(s)' fd just destroyed.
1025 */
1026 ret = notify_thread_pipe(the_kernel_poll_pipe[1]);
1027 if (ret < 0) {
1028 PERROR("write kernel poll pipe");
1029 }
1030
1031 DBG("Destroying session %s (id %" PRIu64 ")", session->name, session->id);
1032
1033 snapshot_destroy(&session->snapshot);
1034
1035 if (session_published) {
1036 ASSERT_SESSION_LIST_LOCKED();
1037 del_session_list(session);
1038 del_session_ht(session);
1039 }
1040
1041 /*
1042 * The notifiers make use of free-functions that expect a locked reference to a session.
1043 * To create such a reference, we need to acquire the lock and acquire a reference (increase
1044 * the ref-count). To ensure the release of the reference does not re-cross the zero value,
1045 * set the refcount to a tombstone value.
1046 */
1047 session->ref_count.refcount = 0xDEAD5E55;
1048 session_notify_destruction([session]() {
1049 session_lock(session);
1050 session_get(session);
1051 return ltt_session::make_locked_ref(*session);
1052 }());
1053
1054 pthread_mutex_destroy(&session->_lock);
1055
1056 consumer_output_put(session->consumer);
1057 kernel_free_session(ksess);
1058 session->kernel_session = nullptr;
1059 if (usess) {
1060 trace_ust_free_session(usess);
1061 session->ust_session = nullptr;
1062 }
1063 lttng_dynamic_array_reset(&session->destroy_notifiers);
1064 lttng_dynamic_array_reset(&session->clear_notifiers);
1065 free(session->last_archived_chunk_name);
1066 free(session->base_path);
1067 lttng_trigger_put(session->rotate_trigger);
1068 free(session);
1069 if (session_published) {
1070 /*
1071 * Notify after free-ing to ensure the memory is
1072 * reclaimed before the main thread exits (and prevent memory leak
1073 * reports).
1074 */
1075 ASSERT_SESSION_LIST_LOCKED();
1076 the_session_list.removal_cond.notify_all();
1077 }
1078 }
1079
1080 /*
1081 * Acquire a reference to a session.
1082 * This function may fail (return false); its return value must be checked.
1083 */
1084 bool session_get(struct ltt_session *session)
1085 {
1086 return urcu_ref_get_unless_zero(&session->ref_count);
1087 }
1088
1089 /*
1090 * Release a reference to a session.
1091 */
1092 void session_put(struct ltt_session *session)
1093 {
1094 if (!session) {
1095 return;
1096 }
1097 /*
1098 * The session list lock must be held as any session_put()
1099 * may cause the removal of the session from the session_list.
1100 */
1101 ASSERT_SESSION_LIST_LOCKED();
1102 LTTNG_ASSERT(session->ref_count.refcount);
1103 urcu_ref_put(&session->ref_count, session_release);
1104 }
1105
1106 /*
1107 * Destroy a session.
1108 *
1109 * This method does not immediately release/free the session as other
1110 * components may still hold a reference to the session. However,
1111 * the session should no longer be presented to the user.
1112 *
1113 * Releases the session list's reference to the session
1114 * and marks it as destroyed. Iterations on the session list should be
1115 * mindful of the "destroyed" flag.
1116 */
1117 void session_destroy(struct ltt_session *session)
1118 {
1119 int ret;
1120 struct lttng_ht_iter iter;
1121
1122 LTTNG_ASSERT(!session->destroyed);
1123 session->destroyed = true;
1124
1125 /*
1126 * Remove immediately from the "session by name" hash table. Only one
1127 * session is expected to exist with a given name for at any given time.
1128 *
1129 * Even if a session still technically exists for a little while longer,
1130 * there is no point in performing action on a "destroyed" session.
1131 */
1132 iter.iter.node = &session->node_by_name.node;
1133 ret = lttng_ht_del(ltt_sessions_ht_by_name, &iter);
1134 LTTNG_ASSERT(!ret);
1135
1136 session_put(session);
1137 }
1138
1139 int session_add_destroy_notifier(const ltt_session::locked_ref& session,
1140 ltt_session_destroy_notifier notifier,
1141 void *user_data)
1142 {
1143 const struct ltt_session_destroy_notifier_element element = { .notifier = notifier,
1144 .user_data = user_data };
1145
1146 return lttng_dynamic_array_add_element(&session->destroy_notifiers, &element);
1147 }
1148
1149 int session_add_clear_notifier(const ltt_session::locked_ref& session,
1150 ltt_session_clear_notifier notifier,
1151 void *user_data)
1152 {
1153 const struct ltt_session_clear_notifier_element element = { .notifier = notifier,
1154 .user_data = user_data };
1155
1156 return lttng_dynamic_array_add_element(&session->clear_notifiers, &element);
1157 }
1158
1159 /*
1160 * Create a new session and add it to the session list.
1161 * Session list lock must be held by the caller.
1162 */
1163 enum lttng_error_code
1164 session_create(const char *name, uid_t uid, gid_t gid, struct ltt_session **out_session)
1165 {
1166 int ret;
1167 enum lttng_error_code ret_code;
1168 struct ltt_session *new_session = nullptr;
1169
1170 ASSERT_SESSION_LIST_LOCKED();
1171 if (name) {
1172 struct ltt_session *clashing_session;
1173
1174 clashing_session = session_find_by_name(name);
1175 if (clashing_session) {
1176 session_put(clashing_session);
1177 ret_code = LTTNG_ERR_EXIST_SESS;
1178 goto error;
1179 }
1180 }
1181 new_session = zmalloc<ltt_session>();
1182 if (!new_session) {
1183 PERROR("Failed to allocate an ltt_session structure");
1184 ret_code = LTTNG_ERR_NOMEM;
1185 goto error;
1186 }
1187
1188 lttng_dynamic_array_init(&new_session->destroy_notifiers,
1189 sizeof(struct ltt_session_destroy_notifier_element),
1190 nullptr);
1191 lttng_dynamic_array_init(&new_session->clear_notifiers,
1192 sizeof(struct ltt_session_clear_notifier_element),
1193 nullptr);
1194 urcu_ref_init(&new_session->ref_count);
1195 pthread_mutex_init(&new_session->_lock, nullptr);
1196
1197 new_session->creation_time = time(nullptr);
1198 if (new_session->creation_time == (time_t) -1) {
1199 PERROR("Failed to sample session creation time");
1200 ret_code = LTTNG_ERR_SESSION_FAIL;
1201 goto error;
1202 }
1203
1204 /* Create default consumer output. */
1205 new_session->consumer = consumer_create_output(CONSUMER_DST_LOCAL);
1206 if (new_session->consumer == nullptr) {
1207 ret_code = LTTNG_ERR_NOMEM;
1208 goto error;
1209 }
1210
1211 if (name) {
1212 ret = lttng_strncpy(new_session->name, name, sizeof(new_session->name));
1213 if (ret) {
1214 ret_code = LTTNG_ERR_SESSION_INVALID_CHAR;
1215 goto error;
1216 }
1217 ret = validate_name(name);
1218 if (ret < 0) {
1219 ret_code = LTTNG_ERR_SESSION_INVALID_CHAR;
1220 goto error;
1221 }
1222 } else {
1223 int i = 0;
1224 bool found_name = false;
1225 char datetime[16];
1226 struct tm *timeinfo;
1227
1228 timeinfo = localtime(&new_session->creation_time);
1229 if (!timeinfo) {
1230 ret_code = LTTNG_ERR_SESSION_FAIL;
1231 goto error;
1232 }
1233 strftime(datetime, sizeof(datetime), "%Y%m%d-%H%M%S", timeinfo);
1234 for (i = 0; i < INT_MAX; i++) {
1235 struct ltt_session *clashing_session;
1236
1237 if (i == 0) {
1238 ret = snprintf(new_session->name,
1239 sizeof(new_session->name),
1240 "%s-%s",
1241 DEFAULT_SESSION_NAME,
1242 datetime);
1243 } else {
1244 ret = snprintf(new_session->name,
1245 sizeof(new_session->name),
1246 "%s%d-%s",
1247 DEFAULT_SESSION_NAME,
1248 i,
1249 datetime);
1250 }
1251 new_session->name_contains_creation_time = true;
1252 if (ret == -1 || ret >= sizeof(new_session->name)) {
1253 /*
1254 * Null-terminate in case the name is used
1255 * in logging statements.
1256 */
1257 new_session->name[sizeof(new_session->name) - 1] = '\0';
1258 ret_code = LTTNG_ERR_SESSION_FAIL;
1259 goto error;
1260 }
1261
1262 clashing_session = session_find_by_name(new_session->name);
1263 session_put(clashing_session);
1264 if (!clashing_session) {
1265 found_name = true;
1266 break;
1267 }
1268 }
1269 if (found_name) {
1270 DBG("Generated session name \"%s\"", new_session->name);
1271 new_session->has_auto_generated_name = true;
1272 } else {
1273 ERR("Failed to auto-generate a session name");
1274 ret_code = LTTNG_ERR_SESSION_FAIL;
1275 goto error;
1276 }
1277 }
1278
1279 ret = gethostname(new_session->hostname, sizeof(new_session->hostname));
1280 if (ret < 0) {
1281 if (errno == ENAMETOOLONG) {
1282 new_session->hostname[sizeof(new_session->hostname) - 1] = '\0';
1283 ERR("Hostname exceeds the maximal permitted length and has been truncated to %s",
1284 new_session->hostname);
1285 } else {
1286 ret_code = LTTNG_ERR_SESSION_FAIL;
1287 goto error;
1288 }
1289 }
1290
1291 new_session->uid = uid;
1292 new_session->gid = gid;
1293
1294 ret = snapshot_init(&new_session->snapshot);
1295 if (ret < 0) {
1296 ret_code = LTTNG_ERR_NOMEM;
1297 goto error;
1298 }
1299
1300 new_session->rotation_state = LTTNG_ROTATION_STATE_NO_ROTATION;
1301
1302 /* Add new session to the session list. */
1303 new_session->id = add_session_list(new_session);
1304
1305 /*
1306 * Add the new session to the ltt_sessions_ht_by_id.
1307 * No ownership is taken by the hash table; it is merely
1308 * a wrapper around the session list used for faster access
1309 * by session id.
1310 */
1311 add_session_ht(new_session);
1312 new_session->published = true;
1313
1314 /*
1315 * Consumer is left to NULL since the create_session_uri command will
1316 * set it up and, if valid, assign it to the session.
1317 */
1318 DBG("Tracing session %s created with ID %" PRIu64 " by uid = %d, gid = %d",
1319 new_session->name,
1320 new_session->id,
1321 new_session->uid,
1322 new_session->gid);
1323 ret_code = LTTNG_OK;
1324 end:
1325 if (new_session) {
1326 (void) session_get(new_session);
1327 *out_session = new_session;
1328 }
1329 return ret_code;
1330 error:
1331 session_put(new_session);
1332 new_session = nullptr;
1333 goto end;
1334 }
1335
1336 /*
1337 * Check if the UID matches the session. Root user has access to all
1338 * sessions.
1339 */
1340 bool session_access_ok(const ltt_session::locked_ref& session, uid_t uid)
1341 {
1342 return (uid == session->uid) || uid == 0;
1343 }
1344
1345 /*
1346 * Set a session's rotation state and reset all associated state.
1347 *
1348 * This function resets the rotation state (check timers, pending
1349 * flags, etc.) and sets the result of the last rotation. The result
1350 * can be queries by a liblttng-ctl client.
1351 *
1352 * Be careful of the result passed to this function. For instance,
1353 * on failure to launch a rotation, a client will expect the rotation
1354 * state to be set to "NO_ROTATION". If an error occurred while the
1355 * rotation was "ONGOING", result should be set to "ERROR", which will
1356 * allow a client to report it.
1357 *
1358 * Must be called with the session and session_list locks held.
1359 */
1360 int session_reset_rotation_state(const ltt_session::locked_ref& session,
1361 enum lttng_rotation_state result)
1362 {
1363 int ret = 0;
1364
1365 ASSERT_SESSION_LIST_LOCKED();
1366
1367 session->rotation_state = result;
1368 if (session->rotation_pending_check_timer_enabled) {
1369 ret = timer_session_rotation_pending_check_stop(session);
1370 }
1371 if (session->chunk_being_archived) {
1372 uint64_t chunk_id;
1373 enum lttng_trace_chunk_status chunk_status;
1374
1375 chunk_status = lttng_trace_chunk_get_id(session->chunk_being_archived, &chunk_id);
1376 LTTNG_ASSERT(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
1377 LTTNG_OPTIONAL_SET(&session->last_archived_chunk_id, chunk_id);
1378 lttng_trace_chunk_put(session->chunk_being_archived);
1379 session->chunk_being_archived = nullptr;
1380 /*
1381 * Fire the clear reply notifiers if we are completing a clear
1382 * rotation.
1383 */
1384 session_notify_clear(session);
1385 }
1386 return ret;
1387 }
1388
1389 /*
1390 * Sample the id of a session looked up via its name.
1391 * Here the term "sampling" hint the caller that this return the id at a given
1392 * point in time with no guarantee that the session for which the id was
1393 * sampled still exist at that point.
1394 *
1395 * Return 0 when the session is not found,
1396 * Return 1 when the session is found and set `id`.
1397 */
1398 bool sample_session_id_by_name(const char *name, uint64_t *id)
1399 {
1400 bool found = false;
1401 struct lttng_ht_node_str *node;
1402 struct lttng_ht_iter iter;
1403 struct ltt_session *ls;
1404
1405 const lttng::urcu::read_lock_guard read_lock;
1406
1407 if (!ltt_sessions_ht_by_name) {
1408 found = false;
1409 goto end;
1410 }
1411
1412 lttng_ht_lookup(ltt_sessions_ht_by_name, name, &iter);
1413 node = lttng_ht_iter_get_node<lttng_ht_node_str>(&iter);
1414 if (node == nullptr) {
1415 found = false;
1416 goto end;
1417 }
1418
1419 ls = lttng::utils::container_of(node, &ltt_session::node_by_name);
1420 *id = ls->id;
1421 found = true;
1422
1423 DBG3("Session id `%" PRIu64 "` sampled for session `%s", *id, name);
1424 end:
1425 return found;
1426 }
1427
1428 void ltt_session::_locked_session_release(ltt_session *session)
1429 {
1430 if (!session) {
1431 return;
1432 }
1433
1434 session_unlock(session);
1435 session_put(session);
1436 }
1437
1438 void ltt_session::_locked_const_session_release(const ltt_session *session)
1439 {
1440 if (!session) {
1441 return;
1442 }
1443
1444 ltt_session::_const_session_unlock(*session);
1445 ltt_session::_const_session_put(session);
1446 }
1447
1448 ltt_session::locked_ref ltt_session::find_locked_session(ltt_session::id_t id)
1449 {
1450 const lttng::urcu::read_lock_guard rcu_lock;
1451 auto session = session_find_by_id(id);
1452
1453 if (!session) {
1454 LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
1455 }
1456
1457 /*
1458 * The pointer falling out of scope will unlock and release the reference to the
1459 * session.
1460 */
1461 session_lock(session);
1462 return ltt_session::make_locked_ref(*session);
1463 }
1464
1465 ltt_session::locked_ref ltt_session::find_locked_session(lttng::c_string_view name)
1466 {
1467 const lttng::urcu::read_lock_guard rcu_lock;
1468 auto session = session_find_by_name(name.data());
1469
1470 if (!session) {
1471 LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
1472 }
1473
1474 session_lock(session);
1475 return ltt_session::make_locked_ref(*session);
1476 }
1477
1478 ltt_session::const_locked_ref ltt_session::find_locked_const_session(ltt_session::id_t id)
1479 {
1480 const lttng::urcu::read_lock_guard rcu_lock;
1481 const auto *session = session_find_by_id(id);
1482
1483 if (!session) {
1484 LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
1485 }
1486
1487 session_lock(session);
1488 return ltt_session::make_locked_ref(*session);
1489 }
1490
1491 ltt_session::const_locked_ref ltt_session::find_locked_const_session(lttng::c_string_view name)
1492 {
1493 const lttng::urcu::read_lock_guard rcu_lock;
1494 const auto *session = session_find_by_name(name.data());
1495
1496 if (!session) {
1497 LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
1498 }
1499
1500 session_lock(session);
1501 return ltt_session::make_locked_ref(*session);
1502 }
1503
1504 ltt_session::ref ltt_session::find_session(ltt_session::id_t id)
1505 {
1506 const lttng::urcu::read_lock_guard rcu_lock;
1507 auto session = session_find_by_id(id);
1508
1509 if (!session) {
1510 LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
1511 }
1512
1513 return ltt_session::make_ref(*session);
1514 }
1515
1516 ltt_session::ref ltt_session::find_session(lttng::c_string_view name)
1517 {
1518 const lttng::urcu::read_lock_guard rcu_lock;
1519 auto session = session_find_by_name(name.data());
1520
1521 if (!session) {
1522 LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
1523 }
1524
1525 return ltt_session::make_ref(*session);
1526 }
1527
1528 ltt_session::const_ref ltt_session::find_const_session(ltt_session::id_t id)
1529 {
1530 const lttng::urcu::read_lock_guard rcu_lock;
1531 const auto *session = session_find_by_id(id);
1532
1533 if (!session) {
1534 LTTNG_THROW_SESSION_NOT_FOUND_BY_ID_ERROR(id);
1535 }
1536
1537 return ltt_session::make_ref(*session);
1538 }
1539
1540 ltt_session::const_ref ltt_session::find_const_session(lttng::c_string_view name)
1541 {
1542 const lttng::urcu::read_lock_guard rcu_lock;
1543 const auto *session = session_find_by_name(name.data());
1544
1545 if (!session) {
1546 LTTNG_THROW_SESSION_NOT_FOUND_BY_NAME_ERROR(name.data());
1547 }
1548
1549 return ltt_session::make_ref(*session);
1550 }
1551
1552 void ltt_session::_const_session_put(const ltt_session *session)
1553 {
1554 /*
1555 * The session list lock must be held as any session_put()
1556 * may cause the removal of the session from the session_list.
1557 */
1558 ASSERT_SESSION_LIST_LOCKED();
1559 LTTNG_ASSERT(session->ref_count.refcount);
1560 urcu_ref_put(&session->ref_count, session_release);
1561 }
1562
1563 std::unique_lock<std::mutex> ls::lock_session_list()
1564 {
1565 return std::unique_lock<std::mutex>(the_session_list.lock);
1566 }
1567
1568 lttng::sessiond::user_space_consumer_channel_keys
1569 ltt_session::user_space_consumer_channel_keys() const
1570 {
1571 switch (ust_session->buffer_type) {
1572 case LTTNG_BUFFER_PER_PID:
1573 return lttng::sessiond::user_space_consumer_channel_keys(*ust_session,
1574 *ust_app_get_all());
1575 case LTTNG_BUFFER_PER_UID:
1576 return lttng::sessiond::user_space_consumer_channel_keys(
1577 *ust_session, ust_session->buffer_reg_uid_list);
1578 default:
1579 abort();
1580 }
1581 }
1582
1583 ls::user_space_consumer_channel_keys::iterator
1584 ls::user_space_consumer_channel_keys::begin() const noexcept
1585 {
1586 return ls::user_space_consumer_channel_keys::iterator(_creation_context);
1587 }
1588
1589 ls::user_space_consumer_channel_keys::iterator
1590 ls::user_space_consumer_channel_keys::end() const noexcept
1591 {
1592 return ls::user_space_consumer_channel_keys::iterator(_creation_context, true);
1593 }
1594
1595 ls::user_space_consumer_channel_keys::iterator&
1596 ls::user_space_consumer_channel_keys::iterator::operator++()
1597 {
1598 if (_is_end) {
1599 LTTNG_THROW_OUT_OF_RANGE(fmt::format(
1600 "Attempted to advance channel key iterator past the end of channel keys: iteration_mode={}",
1601 _creation_context._session.buffer_type));
1602 }
1603
1604 switch (_creation_context._session.buffer_type) {
1605 case LTTNG_BUFFER_PER_PID:
1606 _advance_one_per_pid();
1607 break;
1608 case LTTNG_BUFFER_PER_UID:
1609 _advance_one_per_uid();
1610 break;
1611 default:
1612 abort();
1613 }
1614
1615 return *this;
1616 }
1617
1618 namespace {
1619 bool is_list_empty(const cds_list_head *head)
1620 {
1621 return head == head->next;
1622 }
1623
1624 bool is_last_element_of_list(const cds_list_head *head)
1625 {
1626 return head->next == head->prev;
1627 }
1628 } /* namespace */
1629
1630 ls::user_space_consumer_channel_keys::iterator::iterator(
1631 const _iterator_creation_context& creation_context, bool is_end) :
1632 _creation_context(creation_context), _is_end(is_end)
1633 {
1634 if (_is_end) {
1635 return;
1636 }
1637
1638 switch (_creation_context._mode) {
1639 case _iteration_mode::PER_PID:
1640 _init_per_pid();
1641 break;
1642 case _iteration_mode::PER_UID:
1643 _init_per_uid();
1644 break;
1645 }
1646 }
1647
1648 void ls::user_space_consumer_channel_keys::iterator::_skip_to_next_app_per_pid(
1649 bool try_current) noexcept
1650 {
1651 auto& position = _position._per_pid;
1652
1653 while (true) {
1654 if (!try_current) {
1655 lttng_ht_get_next(_creation_context._container.apps,
1656 &position.app_iterator);
1657 } else {
1658 try_current = false;
1659 }
1660
1661 const auto app_node =
1662 lttng_ht_iter_get_node<lttng_ht_node_ulong>(&position.app_iterator);
1663 if (!app_node) {
1664 _is_end = true;
1665 return;
1666 }
1667
1668 const auto& app = *lttng::utils::container_of(app_node, &ust_app::pid_n);
1669 auto app_session = ust_app_lookup_app_session(&_creation_context._session, &app);
1670
1671 if (!app_session) {
1672 /* This app is not traced by the target session. */
1673 continue;
1674 }
1675
1676 position.current_app_session = app_session->lock();
1677
1678 auto *registry = ust_app_get_session_registry(
1679 (*_position._per_pid.current_app_session)->get_identifier());
1680 if (!registry) {
1681 DBG_FMT("Application session is being torn down: skipping application: app={}",
1682 app);
1683 continue;
1684 }
1685
1686 position.current_registry_session = registry;
1687 lttng_ht_get_first((*position.current_app_session)->channels,
1688 &_position.channel_iterator);
1689 break;
1690 }
1691 }
1692
1693 void ls::user_space_consumer_channel_keys::iterator::_init_per_pid() noexcept
1694 {
1695 auto& position = _position._per_pid;
1696
1697 lttng_ht_get_first(_creation_context._container.apps, &position.app_iterator);
1698 _skip_to_next_app_per_pid(true);
1699 }
1700
1701 void ls::user_space_consumer_channel_keys::iterator::_init_per_uid() noexcept
1702 {
1703 auto& position = _position._per_uid;
1704
1705 /* Start the iteration: get the first registry and point to its first channel. */
1706 if (is_list_empty(&_creation_context._session.buffer_reg_uid_list)) {
1707 _is_end = true;
1708 return;
1709 }
1710
1711 position.current_registry = lttng::utils::container_of(
1712 _creation_context._session.buffer_reg_uid_list.next, &buffer_reg_uid::lnode);
1713 lttng_ht_get_first(position.current_registry->registry->channels,
1714 &_position.channel_iterator);
1715 }
1716
1717 void ls::user_space_consumer_channel_keys::iterator::_advance_one_per_pid()
1718 {
1719 auto& position = _position._per_pid;
1720
1721 if (!cds_lfht_iter_get_node(&_position.channel_iterator.iter)) {
1722 /* Reached the last channel. Move on to the next app. */
1723 _skip_to_next_app_per_pid(false);
1724 return;
1725 }
1726
1727 const auto current_app_node =
1728 lttng_ht_iter_get_node<lttng_ht_node_ulong>(&position.app_iterator);
1729 LTTNG_ASSERT(current_app_node);
1730
1731 lttng_ht_get_next((*position.current_app_session)->channels, &_position.channel_iterator);
1732 }
1733
1734 void ls::user_space_consumer_channel_keys::iterator::_advance_one_per_uid()
1735 {
1736 auto& position = _position._per_uid;
1737
1738 if (!cds_lfht_iter_get_node(&_position.channel_iterator.iter)) {
1739 /* Reached the last channel of the registry. Move on to the next registry. */
1740 if (is_last_element_of_list(&position.current_registry->lnode)) {
1741 _is_end = true;
1742 return;
1743 }
1744
1745 position.current_registry = lttng::utils::container_of(
1746 position.current_registry->lnode.next, &buffer_reg_uid::lnode);
1747 cds_lfht_first(position.current_registry->registry->channels->ht,
1748 &_position.channel_iterator.iter);
1749
1750 /* Assumes a registry can't be empty. */
1751 LTTNG_ASSERT(cds_lfht_iter_get_node(&_position.channel_iterator.iter));
1752 }
1753
1754 cds_lfht_next(position.current_registry->registry->channels->ht,
1755 &_position.channel_iterator.iter);
1756 }
1757
1758 bool ls::user_space_consumer_channel_keys::iterator::operator==(const iterator& other) const noexcept
1759 {
1760 if (_is_end && other._is_end) {
1761 return true;
1762 }
1763
1764 /* Channel keys are unique; use them to compare the iterators. */
1765 return !_is_end && !other._is_end && **this == *other;
1766 }
1767
1768 bool ls::user_space_consumer_channel_keys::iterator::operator!=(const iterator& other) const noexcept
1769 {
1770 return !(*this == other);
1771 }
1772
1773 ls::user_space_consumer_channel_keys::iterator::key
1774 ls::user_space_consumer_channel_keys::iterator::_get_current_value_per_pid() const noexcept
1775 {
1776 auto& position = _position._per_pid;
1777
1778 const auto *channel_node =
1779 lttng_ht_iter_get_node<lttng_ht_node_str>(&_position.channel_iterator);
1780 const auto current_app_node =
1781 lttng_ht_iter_get_node<lttng_ht_node_ulong>(&position.app_iterator);
1782 LTTNG_ASSERT(current_app_node);
1783
1784 const auto& app = *lttng::utils::container_of(current_app_node, &ust_app::pid_n);
1785
1786 if (channel_node) {
1787 const auto& channel =
1788 *lttng::utils::container_of(channel_node, &ust_app_channel::node);
1789
1790 return { static_cast<consumer_bitness>(app.abi.bits_per_long),
1791 channel.key,
1792 ls::user_space_consumer_channel_keys::channel_type::DATA };
1793 } else {
1794 LTTNG_ASSERT(position.current_registry_session);
1795
1796 /*
1797 * Once the last data channel is delivered (iter points to the 'end' of the ht),
1798 * deliver the metadata channel's key.
1799 */
1800 return { static_cast<consumer_bitness>(app.abi.bits_per_long),
1801 position.current_registry_session->_metadata_key,
1802 ls::user_space_consumer_channel_keys::channel_type::METADATA };
1803 }
1804 }
1805
1806 ls::user_space_consumer_channel_keys::iterator::key
1807 ls::user_space_consumer_channel_keys::iterator::_get_current_value_per_uid() const noexcept
1808 {
1809 const auto *channel_node =
1810 lttng_ht_iter_get_node<lttng_ht_node_u64>(&_position.channel_iterator);
1811
1812 if (channel_node) {
1813 const auto& channel =
1814 *lttng::utils::container_of(channel_node, &buffer_reg_channel::node);
1815
1816 return { static_cast<consumer_bitness>(
1817 _position._per_uid.current_registry->bits_per_long),
1818 channel.consumer_key,
1819 ls::user_space_consumer_channel_keys::channel_type::DATA };
1820 } else {
1821 /*
1822 * Once the last data channel is delivered (iter points to the 'end' of the ht),
1823 * deliver the metadata channel's key.
1824 */
1825 return { static_cast<consumer_bitness>(
1826 _position._per_uid.current_registry->bits_per_long),
1827 _position._per_uid.current_registry->registry->reg.ust->_metadata_key,
1828 ls::user_space_consumer_channel_keys::channel_type::METADATA };
1829 }
1830 }
1831
1832 ls::user_space_consumer_channel_keys::iterator::key
1833 ls::user_space_consumer_channel_keys::iterator::operator*() const
1834 {
1835 if (_is_end) {
1836 LTTNG_THROW_OUT_OF_RANGE(
1837 "Attempt to use operator* on user_space_consumer_channel_keys iterator at the end position");
1838 }
1839
1840 switch (_creation_context._mode) {
1841 case _iteration_mode::PER_PID:
1842 return _get_current_value_per_pid();
1843 case _iteration_mode::PER_UID:
1844 return _get_current_value_per_uid();
1845 }
1846
1847 std::abort();
1848 }
1849
1850 ls::ust::registry_session *ls::user_space_consumer_channel_keys::iterator::get_registry_session()
1851 {
1852 if (_is_end) {
1853 LTTNG_THROW_OUT_OF_RANGE(
1854 "Attempt to get registry session on user_space_consumer_channel_keys iterator at the end position");
1855 }
1856
1857 switch (_creation_context._mode) {
1858 case _iteration_mode::PER_PID:
1859 return _get_registry_session_per_pid();
1860 case _iteration_mode::PER_UID:
1861 return _get_registry_session_per_uid();
1862 }
1863
1864 std::abort();
1865 }
1866
1867 ls::ust::registry_session *
1868 ls::user_space_consumer_channel_keys::iterator::_get_registry_session_per_pid()
1869 {
1870 return _position._per_pid.current_registry_session;
1871 }
1872
1873 ls::ust::registry_session *
1874 ls::user_space_consumer_channel_keys::iterator::_get_registry_session_per_uid()
1875 {
1876 return _position._per_uid.current_registry->registry->reg.ust;
1877 }
This page took 0.095652 seconds and 4 git commands to generate.