2 * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
4 * SPDX-License-Identifier: GPL-2.0-only
17 #include <sys/types.h>
20 #include <common/common.h>
21 #include <common/utils.h>
22 #include <common/trace-chunk.h>
23 #include <common/sessiond-comm/sessiond-comm.h>
24 #include <lttng/location-internal.h>
25 #include "lttng-sessiond.h"
30 #include "trace-ust.h"
34 struct ltt_session_destroy_notifier_element
{
35 ltt_session_destroy_notifier notifier
;
39 struct ltt_session_clear_notifier_element
{
40 ltt_session_clear_notifier notifier
;
47 * No ltt_session.lock is taken here because those data structure are widely
48 * spread across the lttng-tools code base so before caling functions below
49 * that can read/write a session, the caller MUST acquire the session lock
50 * using session_lock() and session_unlock().
54 * Init tracing session list.
56 * Please see session.h for more explanation and correct usage of the list.
58 static struct ltt_session_list ltt_session_list
= {
59 .head
= CDS_LIST_HEAD_INIT(ltt_session_list
.head
),
60 .lock
= PTHREAD_MUTEX_INITIALIZER
,
61 .removal_cond
= PTHREAD_COND_INITIALIZER
,
65 /* These characters are forbidden in a session name. Used by validate_name. */
66 static const char *forbidden_name_chars
= "/";
68 /* Global hash table to keep the sessions, indexed by id. */
69 static struct lttng_ht
*ltt_sessions_ht_by_id
= NULL
;
72 * Validate the session name for forbidden characters.
74 * Return 0 on success else -1 meaning a forbidden char. has been found.
76 static int validate_name(const char *name
)
83 tmp_name
= strdup(name
);
90 tok
= strpbrk(tmp_name
, forbidden_name_chars
);
92 DBG("Session name %s contains a forbidden character", name
);
93 /* Forbidden character has been found. */
105 * Add a ltt_session structure to the global list.
107 * The caller MUST acquire the session list lock before.
108 * Returns the unique identifier for the session.
110 static uint64_t add_session_list(struct ltt_session
*ls
)
114 cds_list_add(&ls
->list
, <t_session_list
.head
);
115 return ltt_session_list
.next_uuid
++;
119 * Delete a ltt_session structure to the global list.
121 * The caller MUST acquire the session list lock before.
123 static void del_session_list(struct ltt_session
*ls
)
127 cds_list_del(&ls
->list
);
131 * Return a pointer to the session list.
133 struct ltt_session_list
*session_get_list(void)
135 return <t_session_list
;
139 * Returns once the session list is empty.
141 void session_list_wait_empty(void)
143 pthread_mutex_lock(<t_session_list
.lock
);
144 while (!cds_list_empty(<t_session_list
.head
)) {
145 pthread_cond_wait(<t_session_list
.removal_cond
,
146 <t_session_list
.lock
);
148 pthread_mutex_unlock(<t_session_list
.lock
);
152 * Acquire session list lock
154 void session_lock_list(void)
156 pthread_mutex_lock(<t_session_list
.lock
);
160 * Try to acquire session list lock
162 int session_trylock_list(void)
164 return pthread_mutex_trylock(<t_session_list
.lock
);
168 * Release session list lock
170 void session_unlock_list(void)
172 pthread_mutex_unlock(<t_session_list
.lock
);
176 * Get the session's consumer destination type.
178 * The caller must hold the session lock.
180 enum consumer_dst_type
session_get_consumer_destination_type(
181 const struct ltt_session
*session
)
184 * The output information is duplicated in both of those session types.
185 * Hence, it doesn't matter from which it is retrieved. However, it is
186 * possible for only one of them to be set.
188 return session
->kernel_session
?
189 session
->kernel_session
->consumer
->type
:
190 session
->ust_session
->consumer
->type
;
194 * Get the session's consumer network hostname.
195 * The caller must ensure that the destination is of type "net".
197 * The caller must hold the session lock.
199 const char *session_get_net_consumer_hostname(const struct ltt_session
*session
)
201 const char *hostname
= NULL
;
202 const struct consumer_output
*output
;
204 output
= session
->kernel_session
?
205 session
->kernel_session
->consumer
:
206 session
->ust_session
->consumer
;
209 * hostname is assumed to be the same for both control and data
212 switch (output
->dst
.net
.control
.dtype
) {
214 hostname
= output
->dst
.net
.control
.dst
.ipv4
;
217 hostname
= output
->dst
.net
.control
.dst
.ipv6
;
226 * Get the session's consumer network control and data ports.
227 * The caller must ensure that the destination is of type "net".
229 * The caller must hold the session lock.
231 void session_get_net_consumer_ports(const struct ltt_session
*session
,
232 uint16_t *control_port
, uint16_t *data_port
)
234 const struct consumer_output
*output
;
236 output
= session
->kernel_session
?
237 session
->kernel_session
->consumer
:
238 session
->ust_session
->consumer
;
239 *control_port
= output
->dst
.net
.control
.port
;
240 *data_port
= output
->dst
.net
.data
.port
;
244 * Get the location of the latest trace archive produced by a rotation.
246 * The caller must hold the session lock.
248 struct lttng_trace_archive_location
*session_get_trace_archive_location(
249 const struct ltt_session
*session
)
252 struct lttng_trace_archive_location
*location
= NULL
;
253 char *chunk_path
= NULL
;
255 if (session
->rotation_state
!= LTTNG_ROTATION_STATE_COMPLETED
||
256 !session
->last_archived_chunk_name
) {
260 switch (session_get_consumer_destination_type(session
)) {
261 case CONSUMER_DST_LOCAL
:
262 ret
= asprintf(&chunk_path
,
263 "%s/" DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY
"/%s",
264 session_get_base_path(session
),
265 session
->last_archived_chunk_name
);
269 location
= lttng_trace_archive_location_local_create(
272 case CONSUMER_DST_NET
:
274 const char *hostname
;
275 uint16_t control_port
, data_port
;
277 hostname
= session_get_net_consumer_hostname(session
);
278 session_get_net_consumer_ports(session
,
281 location
= lttng_trace_archive_location_relay_create(
283 LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP
,
284 control_port
, data_port
, session
->last_chunk_path
);
296 * Allocate the ltt_sessions_ht_by_id HT.
298 * The session list lock must be held.
300 static int ltt_sessions_ht_alloc(void)
304 DBG("Allocating ltt_sessions_ht_by_id");
305 ltt_sessions_ht_by_id
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
306 if (!ltt_sessions_ht_by_id
) {
308 ERR("Failed to allocate ltt_sessions_ht_by_id");
316 * Destroy the ltt_sessions_ht_by_id HT.
318 * The session list lock must be held.
320 static void ltt_sessions_ht_destroy(void)
322 if (!ltt_sessions_ht_by_id
) {
325 ht_cleanup_push(ltt_sessions_ht_by_id
);
326 ltt_sessions_ht_by_id
= NULL
;
330 * Add a ltt_session to the ltt_sessions_ht_by_id.
331 * If unallocated, the ltt_sessions_ht_by_id HT is allocated.
332 * The session list lock must be held.
334 static void add_session_ht(struct ltt_session
*ls
)
340 if (!ltt_sessions_ht_by_id
) {
341 ret
= ltt_sessions_ht_alloc();
343 ERR("Error allocating the sessions HT");
347 lttng_ht_node_init_u64(&ls
->node
, ls
->id
);
348 lttng_ht_add_unique_u64(ltt_sessions_ht_by_id
, &ls
->node
);
355 * Test if ltt_sessions_ht_by_id is empty.
356 * Return 1 if empty, 0 if not empty.
357 * The session list lock must be held.
359 static int ltt_sessions_ht_empty(void)
363 if (!ltt_sessions_ht_by_id
) {
368 ret
= lttng_ht_get_count(ltt_sessions_ht_by_id
) ? 0 : 1;
374 * Remove a ltt_session from the ltt_sessions_ht_by_id.
375 * If empty, the ltt_sessions_ht_by_id HT is freed.
376 * The session list lock must be held.
378 static void del_session_ht(struct ltt_session
*ls
)
380 struct lttng_ht_iter iter
;
384 assert(ltt_sessions_ht_by_id
);
386 iter
.iter
.node
= &ls
->node
.node
;
387 ret
= lttng_ht_del(ltt_sessions_ht_by_id
, &iter
);
390 if (ltt_sessions_ht_empty()) {
391 DBG("Empty ltt_sessions_ht_by_id, destroying it");
392 ltt_sessions_ht_destroy();
397 * Acquire session lock
399 void session_lock(struct ltt_session
*session
)
403 pthread_mutex_lock(&session
->lock
);
407 * Release session lock
409 void session_unlock(struct ltt_session
*session
)
413 pthread_mutex_unlock(&session
->lock
);
417 int _session_set_trace_chunk_no_lock_check(struct ltt_session
*session
,
418 struct lttng_trace_chunk
*new_trace_chunk
,
419 struct lttng_trace_chunk
**_current_trace_chunk
)
422 unsigned int i
, refs_to_acquire
= 0, refs_acquired
= 0, refs_to_release
= 0;
423 struct cds_lfht_iter iter
;
424 struct consumer_socket
*socket
;
425 struct lttng_trace_chunk
*current_trace_chunk
;
427 enum lttng_trace_chunk_status chunk_status
;
431 * Ownership of current trace chunk is transferred to
432 * `current_trace_chunk`.
434 current_trace_chunk
= session
->current_trace_chunk
;
435 session
->current_trace_chunk
= NULL
;
436 if (session
->ust_session
) {
437 lttng_trace_chunk_put(
438 session
->ust_session
->current_trace_chunk
);
439 session
->ust_session
->current_trace_chunk
= NULL
;
441 if (session
->kernel_session
) {
442 lttng_trace_chunk_put(
443 session
->kernel_session
->current_trace_chunk
);
444 session
->kernel_session
->current_trace_chunk
= NULL
;
446 if (!new_trace_chunk
) {
450 chunk_status
= lttng_trace_chunk_get_id(new_trace_chunk
, &chunk_id
);
451 assert(chunk_status
== LTTNG_TRACE_CHUNK_STATUS_OK
);
454 refs_to_acquire
+= !!session
->ust_session
;
455 refs_to_acquire
+= !!session
->kernel_session
;
457 for (refs_acquired
= 0; refs_acquired
< refs_to_acquire
;
459 if (!lttng_trace_chunk_get(new_trace_chunk
)) {
460 ERR("Failed to acquire reference to new trace chunk of session \"%s\"",
466 if (session
->ust_session
) {
467 const uint64_t relayd_id
=
468 session
->ust_session
->consumer
->net_seq_index
;
469 const bool is_local_trace
=
470 session
->ust_session
->consumer
->type
==
473 session
->ust_session
->current_trace_chunk
= new_trace_chunk
;
474 if (is_local_trace
) {
475 enum lttng_error_code ret_error_code
;
477 ret_error_code
= ust_app_create_channel_subdirectories(
478 session
->ust_session
);
479 if (ret_error_code
!= LTTNG_OK
) {
483 cds_lfht_for_each_entry(
484 session
->ust_session
->consumer
->socks
->ht
,
485 &iter
, socket
, node
.node
) {
486 pthread_mutex_lock(socket
->lock
);
487 ret
= consumer_create_trace_chunk(socket
,
489 session
->id
, new_trace_chunk
,
490 DEFAULT_UST_TRACE_DIR
);
491 pthread_mutex_unlock(socket
->lock
);
497 if (session
->kernel_session
) {
498 const uint64_t relayd_id
=
499 session
->kernel_session
->consumer
->net_seq_index
;
500 const bool is_local_trace
=
501 session
->kernel_session
->consumer
->type
==
504 session
->kernel_session
->current_trace_chunk
= new_trace_chunk
;
505 if (is_local_trace
) {
506 enum lttng_error_code ret_error_code
;
508 ret_error_code
= kernel_create_channel_subdirectories(
509 session
->kernel_session
);
510 if (ret_error_code
!= LTTNG_OK
) {
514 cds_lfht_for_each_entry(
515 session
->kernel_session
->consumer
->socks
->ht
,
516 &iter
, socket
, node
.node
) {
517 pthread_mutex_lock(socket
->lock
);
518 ret
= consumer_create_trace_chunk(socket
,
520 session
->id
, new_trace_chunk
,
521 DEFAULT_KERNEL_TRACE_DIR
);
522 pthread_mutex_unlock(socket
->lock
);
530 * Update local current trace chunk state last, only if all remote
531 * creations succeeded.
533 session
->current_trace_chunk
= new_trace_chunk
;
534 LTTNG_OPTIONAL_SET(&session
->most_recent_chunk_id
, chunk_id
);
536 if (_current_trace_chunk
) {
537 *_current_trace_chunk
= current_trace_chunk
;
538 current_trace_chunk
= NULL
;
542 lttng_trace_chunk_put(current_trace_chunk
);
545 if (session
->ust_session
) {
546 session
->ust_session
->current_trace_chunk
= NULL
;
548 if (session
->kernel_session
) {
549 session
->kernel_session
->current_trace_chunk
= NULL
;
552 * Release references taken in the case where all references could not
555 refs_to_release
= refs_to_acquire
- refs_acquired
;
556 for (i
= 0; i
< refs_to_release
; i
++) {
557 lttng_trace_chunk_put(new_trace_chunk
);
563 struct lttng_trace_chunk
*session_create_new_trace_chunk(
564 const struct ltt_session
*session
,
565 const struct consumer_output
*consumer_output_override
,
566 const char *session_base_path_override
,
567 const char *chunk_name_override
)
570 struct lttng_trace_chunk
*trace_chunk
= NULL
;
571 enum lttng_trace_chunk_status chunk_status
;
572 const time_t chunk_creation_ts
= time(NULL
);
574 const char *base_path
;
575 struct lttng_directory_handle
*session_output_directory
= NULL
;
576 const struct lttng_credentials session_credentials
= {
580 uint64_t next_chunk_id
;
581 const struct consumer_output
*output
;
582 const char *new_path
;
584 if (consumer_output_override
) {
585 output
= consumer_output_override
;
587 assert(session
->ust_session
|| session
->kernel_session
);
588 output
= session
->ust_session
?
589 session
->ust_session
->consumer
:
590 session
->kernel_session
->consumer
;
593 is_local_trace
= output
->type
== CONSUMER_DST_LOCAL
;
594 base_path
= session_base_path_override
? :
595 consumer_output_get_base_path(output
);
597 if (chunk_creation_ts
== (time_t) -1) {
598 PERROR("Failed to sample time while creation session \"%s\" trace chunk",
603 next_chunk_id
= session
->most_recent_chunk_id
.is_set
?
604 session
->most_recent_chunk_id
.value
+ 1 : 0;
606 if (session
->current_trace_chunk
&&
607 !lttng_trace_chunk_get_name_overridden(session
->current_trace_chunk
)) {
608 chunk_status
= lttng_trace_chunk_rename_path(session
->current_trace_chunk
,
609 DEFAULT_CHUNK_TMP_OLD_DIRECTORY
);
610 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
614 if (!session
->current_trace_chunk
) {
615 if (!session
->rotated
) {
621 new_path
= DEFAULT_CHUNK_TMP_NEW_DIRECTORY
;
624 trace_chunk
= lttng_trace_chunk_create(next_chunk_id
,
625 chunk_creation_ts
, new_path
);
630 if (chunk_name_override
) {
631 chunk_status
= lttng_trace_chunk_override_name(trace_chunk
,
632 chunk_name_override
);
633 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
638 if (!is_local_trace
) {
640 * No need to set crendentials and output directory
641 * for remote trace chunks.
646 chunk_status
= lttng_trace_chunk_set_credentials(trace_chunk
,
647 &session_credentials
);
648 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
652 DBG("Creating base output directory of session \"%s\" at %s",
653 session
->name
, base_path
);
654 ret
= utils_mkdir_recursive(base_path
, S_IRWXU
| S_IRWXG
,
655 session
->uid
, session
->gid
);
659 session_output_directory
= lttng_directory_handle_create(base_path
);
660 if (!session_output_directory
) {
663 chunk_status
= lttng_trace_chunk_set_as_owner(trace_chunk
,
664 session_output_directory
);
665 lttng_directory_handle_put(session_output_directory
);
666 session_output_directory
= NULL
;
667 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
673 lttng_directory_handle_put(session_output_directory
);
674 lttng_trace_chunk_put(trace_chunk
);
679 int session_close_trace_chunk(struct ltt_session
*session
,
680 struct lttng_trace_chunk
*trace_chunk
,
681 enum lttng_trace_chunk_command_type close_command
,
682 char *closed_trace_chunk_path
)
685 bool error_occurred
= false;
686 struct cds_lfht_iter iter
;
687 struct consumer_socket
*socket
;
688 enum lttng_trace_chunk_status chunk_status
;
689 const time_t chunk_close_timestamp
= time(NULL
);
690 const char *new_path
;
692 chunk_status
= lttng_trace_chunk_set_close_command(
693 trace_chunk
, close_command
);
694 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
699 if (chunk_close_timestamp
== (time_t) -1) {
700 ERR("Failed to sample the close timestamp of the current trace chunk of session \"%s\"",
706 if (close_command
== LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE
&& !session
->rotated
) {
707 /* New chunk stays in session output directory. */
710 /* Use chunk name for new chunk. */
713 if (session
->current_trace_chunk
&&
714 !lttng_trace_chunk_get_name_overridden(session
->current_trace_chunk
)) {
715 /* Rename new chunk path. */
716 chunk_status
= lttng_trace_chunk_rename_path(session
->current_trace_chunk
,
718 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
723 if (!lttng_trace_chunk_get_name_overridden(trace_chunk
) &&
724 close_command
== LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION
) {
725 const char *old_path
;
727 if (!session
->rotated
) {
732 /* We need to move back the .tmp_old_chunk to its rightful place. */
733 chunk_status
= lttng_trace_chunk_rename_path(trace_chunk
,
735 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
740 if (close_command
== LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED
) {
741 session
->rotated
= true;
743 chunk_status
= lttng_trace_chunk_set_close_timestamp(trace_chunk
,
744 chunk_close_timestamp
);
745 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
746 ERR("Failed to set the close timestamp of the current trace chunk of session \"%s\"",
752 if (session
->ust_session
) {
753 const uint64_t relayd_id
=
754 session
->ust_session
->consumer
->net_seq_index
;
756 cds_lfht_for_each_entry(
757 session
->ust_session
->consumer
->socks
->ht
,
758 &iter
, socket
, node
.node
) {
759 pthread_mutex_lock(socket
->lock
);
760 ret
= consumer_close_trace_chunk(socket
,
763 trace_chunk
, closed_trace_chunk_path
);
764 pthread_mutex_unlock(socket
->lock
);
766 ERR("Failed to close trace chunk on user space consumer");
767 error_occurred
= true;
771 if (session
->kernel_session
) {
772 const uint64_t relayd_id
=
773 session
->kernel_session
->consumer
->net_seq_index
;
775 cds_lfht_for_each_entry(
776 session
->kernel_session
->consumer
->socks
->ht
,
777 &iter
, socket
, node
.node
) {
778 pthread_mutex_lock(socket
->lock
);
779 ret
= consumer_close_trace_chunk(socket
,
782 trace_chunk
, closed_trace_chunk_path
);
783 pthread_mutex_unlock(socket
->lock
);
785 ERR("Failed to close trace chunk on kernel consumer");
786 error_occurred
= true;
790 ret
= error_occurred
? -1 : 0;
796 * Set a session's current trace chunk.
798 * Must be called with the session lock held.
800 int session_set_trace_chunk(struct ltt_session
*session
,
801 struct lttng_trace_chunk
*new_trace_chunk
,
802 struct lttng_trace_chunk
**current_trace_chunk
)
804 ASSERT_LOCKED(session
->lock
);
805 return _session_set_trace_chunk_no_lock_check(session
, new_trace_chunk
,
806 current_trace_chunk
);
810 void session_notify_destruction(const struct ltt_session
*session
)
813 const size_t count
= lttng_dynamic_array_get_count(
814 &session
->destroy_notifiers
);
816 for (i
= 0; i
< count
; i
++) {
817 const struct ltt_session_destroy_notifier_element
*element
=
818 lttng_dynamic_array_get_element(
819 &session
->destroy_notifiers
, i
);
821 element
->notifier(session
, element
->user_data
);
826 * Fire each clear notifier once, and remove them from the array.
828 void session_notify_clear(struct ltt_session
*session
)
831 const size_t count
= lttng_dynamic_array_get_count(
832 &session
->clear_notifiers
);
834 for (i
= 0; i
< count
; i
++) {
835 const struct ltt_session_clear_notifier_element
*element
=
836 lttng_dynamic_array_get_element(
837 &session
->clear_notifiers
, i
);
839 element
->notifier(session
, element
->user_data
);
841 lttng_dynamic_array_clear(&session
->clear_notifiers
);
845 void session_release(struct urcu_ref
*ref
)
848 struct ltt_ust_session
*usess
;
849 struct ltt_kernel_session
*ksess
;
850 struct ltt_session
*session
= container_of(ref
, typeof(*session
), ref
);
851 const bool session_published
= session
->published
;
853 assert(!session
->chunk_being_archived
);
855 usess
= session
->ust_session
;
856 ksess
= session
->kernel_session
;
858 /* Clean kernel session teardown, keeping data for destroy notifier. */
859 kernel_destroy_session(ksess
);
861 /* UST session teardown, keeping data for destroy notifier. */
863 /* Close any relayd session */
864 consumer_output_send_destroy_relayd(usess
->consumer
);
866 /* Destroy every UST application related to this session. */
867 ret
= ust_app_destroy_trace_all(usess
);
869 ERR("Error in ust_app_destroy_trace_all");
872 /* Clean up the rest, keeping destroy notifier data. */
873 trace_ust_destroy_session(usess
);
877 * Must notify the kernel thread here to update it's poll set in order to
878 * remove the channel(s)' fd just destroyed.
880 ret
= notify_thread_pipe(kernel_poll_pipe
[1]);
882 PERROR("write kernel poll pipe");
885 DBG("Destroying session %s (id %" PRIu64
")", session
->name
, session
->id
);
887 snapshot_destroy(&session
->snapshot
);
889 pthread_mutex_destroy(&session
->lock
);
891 if (session_published
) {
892 ASSERT_LOCKED(ltt_session_list
.lock
);
893 del_session_list(session
);
894 del_session_ht(session
);
896 session_notify_destruction(session
);
898 consumer_output_put(session
->consumer
);
899 kernel_free_session(ksess
);
900 session
->kernel_session
= NULL
;
902 trace_ust_free_session(usess
);
903 session
->ust_session
= NULL
;
905 lttng_dynamic_array_reset(&session
->destroy_notifiers
);
906 lttng_dynamic_array_reset(&session
->clear_notifiers
);
907 free(session
->last_archived_chunk_name
);
908 free(session
->base_path
);
910 if (session_published
) {
912 * Broadcast after free-ing to ensure the memory is
913 * reclaimed before the main thread exits.
915 pthread_cond_broadcast(<t_session_list
.removal_cond
);
920 * Acquire a reference to a session.
921 * This function may fail (return false); its return value must be checked.
923 bool session_get(struct ltt_session
*session
)
925 return urcu_ref_get_unless_zero(&session
->ref
);
929 * Release a reference to a session.
931 void session_put(struct ltt_session
*session
)
937 * The session list lock must be held as any session_put()
938 * may cause the removal of the session from the session_list.
940 ASSERT_LOCKED(ltt_session_list
.lock
);
941 assert(session
->ref
.refcount
);
942 urcu_ref_put(&session
->ref
, session_release
);
948 * This method does not immediately release/free the session as other
949 * components may still hold a reference to the session. However,
950 * the session should no longer be presented to the user.
952 * Releases the session list's reference to the session
953 * and marks it as destroyed. Iterations on the session list should be
954 * mindful of the "destroyed" flag.
956 void session_destroy(struct ltt_session
*session
)
958 assert(!session
->destroyed
);
959 session
->destroyed
= true;
960 session_put(session
);
963 int session_add_destroy_notifier(struct ltt_session
*session
,
964 ltt_session_destroy_notifier notifier
, void *user_data
)
966 const struct ltt_session_destroy_notifier_element element
= {
967 .notifier
= notifier
,
968 .user_data
= user_data
971 return lttng_dynamic_array_add_element(&session
->destroy_notifiers
,
975 int session_add_clear_notifier(struct ltt_session
*session
,
976 ltt_session_clear_notifier notifier
, void *user_data
)
978 const struct ltt_session_clear_notifier_element element
= {
979 .notifier
= notifier
,
980 .user_data
= user_data
983 return lttng_dynamic_array_add_element(&session
->clear_notifiers
,
988 * Return a ltt_session structure ptr that matches name. If no session found,
989 * NULL is returned. This must be called with the session list lock held using
990 * session_lock_list and session_unlock_list.
991 * A reference to the session is implicitly acquired by this function.
993 struct ltt_session
*session_find_by_name(const char *name
)
995 struct ltt_session
*iter
;
998 ASSERT_LOCKED(ltt_session_list
.lock
);
1000 DBG2("Trying to find session by name %s", name
);
1002 cds_list_for_each_entry(iter
, <t_session_list
.head
, list
) {
1003 if (!strncmp(iter
->name
, name
, NAME_MAX
) &&
1011 return session_get(iter
) ? iter
: NULL
;
1015 * Return an ltt_session that matches the id. If no session is found,
1016 * NULL is returned. This must be called with rcu_read_lock and
1017 * session list lock held (to guarantee the lifetime of the session).
1019 struct ltt_session
*session_find_by_id(uint64_t id
)
1021 struct lttng_ht_node_u64
*node
;
1022 struct lttng_ht_iter iter
;
1023 struct ltt_session
*ls
;
1025 ASSERT_LOCKED(ltt_session_list
.lock
);
1027 if (!ltt_sessions_ht_by_id
) {
1031 lttng_ht_lookup(ltt_sessions_ht_by_id
, &id
, &iter
);
1032 node
= lttng_ht_iter_get_node_u64(&iter
);
1036 ls
= caa_container_of(node
, struct ltt_session
, node
);
1038 DBG3("Session %" PRIu64
" found by id.", id
);
1039 return session_get(ls
) ? ls
: NULL
;
1042 DBG3("Session %" PRIu64
" NOT found by id", id
);
1047 * Create a new session and add it to the session list.
1048 * Session list lock must be held by the caller.
1050 enum lttng_error_code
session_create(const char *name
, uid_t uid
, gid_t gid
,
1051 struct ltt_session
**out_session
)
1054 enum lttng_error_code ret_code
;
1055 struct ltt_session
*new_session
= NULL
;
1057 ASSERT_LOCKED(ltt_session_list
.lock
);
1059 struct ltt_session
*clashing_session
;
1061 clashing_session
= session_find_by_name(name
);
1062 if (clashing_session
) {
1063 session_put(clashing_session
);
1064 ret_code
= LTTNG_ERR_EXIST_SESS
;
1068 new_session
= zmalloc(sizeof(struct ltt_session
));
1070 PERROR("Failed to allocate an ltt_session structure");
1071 ret_code
= LTTNG_ERR_NOMEM
;
1075 lttng_dynamic_array_init(&new_session
->destroy_notifiers
,
1076 sizeof(struct ltt_session_destroy_notifier_element
),
1078 lttng_dynamic_array_init(&new_session
->clear_notifiers
,
1079 sizeof(struct ltt_session_clear_notifier_element
),
1081 urcu_ref_init(&new_session
->ref
);
1082 pthread_mutex_init(&new_session
->lock
, NULL
);
1084 new_session
->creation_time
= time(NULL
);
1085 if (new_session
->creation_time
== (time_t) -1) {
1086 PERROR("Failed to sample session creation time");
1087 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1091 /* Create default consumer output. */
1092 new_session
->consumer
= consumer_create_output(CONSUMER_DST_LOCAL
);
1093 if (new_session
->consumer
== NULL
) {
1094 ret_code
= LTTNG_ERR_NOMEM
;
1099 ret
= lttng_strncpy(new_session
->name
, name
, sizeof(new_session
->name
));
1101 ret_code
= LTTNG_ERR_SESSION_INVALID_CHAR
;
1104 ret
= validate_name(name
);
1106 ret_code
= LTTNG_ERR_SESSION_INVALID_CHAR
;
1111 bool found_name
= false;
1113 struct tm
*timeinfo
;
1115 timeinfo
= localtime(&new_session
->creation_time
);
1117 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1120 strftime(datetime
, sizeof(datetime
), "%Y%m%d-%H%M%S", timeinfo
);
1121 for (i
= 0; i
< INT_MAX
; i
++) {
1122 struct ltt_session
*clashing_session
;
1125 ret
= snprintf(new_session
->name
,
1126 sizeof(new_session
->name
),
1128 DEFAULT_SESSION_NAME
,
1131 ret
= snprintf(new_session
->name
,
1132 sizeof(new_session
->name
),
1134 DEFAULT_SESSION_NAME
, i
,
1137 new_session
->name_contains_creation_time
= true;
1138 if (ret
== -1 || ret
>= sizeof(new_session
->name
)) {
1140 * Null-terminate in case the name is used
1141 * in logging statements.
1143 new_session
->name
[sizeof(new_session
->name
) - 1] = '\0';
1144 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1149 session_find_by_name(new_session
->name
);
1150 session_put(clashing_session
);
1151 if (!clashing_session
) {
1157 DBG("Generated session name \"%s\"", new_session
->name
);
1158 new_session
->has_auto_generated_name
= true;
1160 ERR("Failed to auto-generate a session name");
1161 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1166 ret
= gethostname(new_session
->hostname
, sizeof(new_session
->hostname
));
1168 if (errno
== ENAMETOOLONG
) {
1169 new_session
->hostname
[sizeof(new_session
->hostname
) - 1] = '\0';
1170 ERR("Hostname exceeds the maximal permitted length and has been truncated to %s",
1171 new_session
->hostname
);
1173 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1178 new_session
->uid
= uid
;
1179 new_session
->gid
= gid
;
1181 ret
= snapshot_init(&new_session
->snapshot
);
1183 ret_code
= LTTNG_ERR_NOMEM
;
1187 new_session
->rotation_state
= LTTNG_ROTATION_STATE_NO_ROTATION
;
1189 /* Add new session to the session list. */
1190 new_session
->id
= add_session_list(new_session
);
1193 * Add the new session to the ltt_sessions_ht_by_id.
1194 * No ownership is taken by the hash table; it is merely
1195 * a wrapper around the session list used for faster access
1198 add_session_ht(new_session
);
1199 new_session
->published
= true;
1202 * Consumer is left to NULL since the create_session_uri command will
1203 * set it up and, if valid, assign it to the session.
1205 DBG("Tracing session %s created with ID %" PRIu64
" by uid = %d, gid = %d",
1206 new_session
->name
, new_session
->id
, new_session
->uid
,
1208 ret_code
= LTTNG_OK
;
1211 (void) session_get(new_session
);
1212 *out_session
= new_session
;
1216 session_put(new_session
);
1222 * Check if the UID or GID match the session. Root user has access to all
1225 int session_access_ok(struct ltt_session
*session
, uid_t uid
, gid_t gid
)
1229 if (uid
!= session
->uid
&& gid
!= session
->gid
&& uid
!= 0) {
1237 * Set a session's rotation state and reset all associated state.
1239 * This function resets the rotation state (check timers, pending
1240 * flags, etc.) and sets the result of the last rotation. The result
1241 * can be queries by a liblttng-ctl client.
1243 * Be careful of the result passed to this function. For instance,
1244 * on failure to launch a rotation, a client will expect the rotation
1245 * state to be set to "NO_ROTATION". If an error occurred while the
1246 * rotation was "ONGOING", result should be set to "ERROR", which will
1247 * allow a client to report it.
1249 * Must be called with the session and session_list locks held.
1251 int session_reset_rotation_state(struct ltt_session
*session
,
1252 enum lttng_rotation_state result
)
1256 ASSERT_LOCKED(ltt_session_list
.lock
);
1257 ASSERT_LOCKED(session
->lock
);
1259 session
->rotation_state
= result
;
1260 if (session
->rotation_pending_check_timer_enabled
) {
1261 ret
= timer_session_rotation_pending_check_stop(session
);
1263 if (session
->chunk_being_archived
) {
1265 enum lttng_trace_chunk_status chunk_status
;
1267 chunk_status
= lttng_trace_chunk_get_id(
1268 session
->chunk_being_archived
,
1270 assert(chunk_status
== LTTNG_TRACE_CHUNK_STATUS_OK
);
1271 LTTNG_OPTIONAL_SET(&session
->last_archived_chunk_id
,
1273 lttng_trace_chunk_put(session
->chunk_being_archived
);
1274 session
->chunk_being_archived
= NULL
;
1276 * Fire the clear reply notifiers if we are completing a clear
1279 session_notify_clear(session
);