2 * Copyright (C) 2011 - David Goulet <david.goulet@polymtl.ca>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License, version 2 only,
6 * as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 #include <sys/types.h>
30 #include <common/common.h>
31 #include <common/utils.h>
32 #include <common/trace-chunk.h>
33 #include <common/sessiond-comm/sessiond-comm.h>
34 #include <lttng/location-internal.h>
35 #include "lttng-sessiond.h"
40 #include "trace-ust.h"
44 struct ltt_session_destroy_notifier_element
{
45 ltt_session_destroy_notifier notifier
;
49 struct ltt_session_clear_notifier_element
{
50 ltt_session_clear_notifier notifier
;
57 * No ltt_session.lock is taken here because those data structure are widely
58 * spread across the lttng-tools code base so before caling functions below
59 * that can read/write a session, the caller MUST acquire the session lock
60 * using session_lock() and session_unlock().
64 * Init tracing session list.
66 * Please see session.h for more explanation and correct usage of the list.
68 static struct ltt_session_list ltt_session_list
= {
69 .head
= CDS_LIST_HEAD_INIT(ltt_session_list
.head
),
70 .lock
= PTHREAD_MUTEX_INITIALIZER
,
71 .removal_cond
= PTHREAD_COND_INITIALIZER
,
75 /* These characters are forbidden in a session name. Used by validate_name. */
76 static const char *forbidden_name_chars
= "/";
78 /* Global hash table to keep the sessions, indexed by id. */
79 static struct lttng_ht
*ltt_sessions_ht_by_id
= NULL
;
82 * Validate the session name for forbidden characters.
84 * Return 0 on success else -1 meaning a forbidden char. has been found.
86 static int validate_name(const char *name
)
93 tmp_name
= strdup(name
);
100 tok
= strpbrk(tmp_name
, forbidden_name_chars
);
102 DBG("Session name %s contains a forbidden character", name
);
103 /* Forbidden character has been found. */
115 * Add a ltt_session structure to the global list.
117 * The caller MUST acquire the session list lock before.
118 * Returns the unique identifier for the session.
120 static uint64_t add_session_list(struct ltt_session
*ls
)
124 cds_list_add(&ls
->list
, <t_session_list
.head
);
125 return ltt_session_list
.next_uuid
++;
129 * Delete a ltt_session structure to the global list.
131 * The caller MUST acquire the session list lock before.
133 static void del_session_list(struct ltt_session
*ls
)
137 cds_list_del(&ls
->list
);
141 * Return a pointer to the session list.
143 struct ltt_session_list
*session_get_list(void)
145 return <t_session_list
;
149 * Returns once the session list is empty.
151 void session_list_wait_empty(void)
153 pthread_mutex_lock(<t_session_list
.lock
);
154 while (!cds_list_empty(<t_session_list
.head
)) {
155 pthread_cond_wait(<t_session_list
.removal_cond
,
156 <t_session_list
.lock
);
158 pthread_mutex_unlock(<t_session_list
.lock
);
162 * Acquire session list lock
164 void session_lock_list(void)
166 pthread_mutex_lock(<t_session_list
.lock
);
170 * Try to acquire session list lock
172 int session_trylock_list(void)
174 return pthread_mutex_trylock(<t_session_list
.lock
);
178 * Release session list lock
180 void session_unlock_list(void)
182 pthread_mutex_unlock(<t_session_list
.lock
);
186 * Get the session's consumer destination type.
188 * The caller must hold the session lock.
190 enum consumer_dst_type
session_get_consumer_destination_type(
191 const struct ltt_session
*session
)
194 * The output information is duplicated in both of those session types.
195 * Hence, it doesn't matter from which it is retrieved. However, it is
196 * possible for only one of them to be set.
198 return session
->kernel_session
?
199 session
->kernel_session
->consumer
->type
:
200 session
->ust_session
->consumer
->type
;
204 * Get the session's consumer network hostname.
205 * The caller must ensure that the destination is of type "net".
207 * The caller must hold the session lock.
209 const char *session_get_net_consumer_hostname(const struct ltt_session
*session
)
211 const char *hostname
= NULL
;
212 const struct consumer_output
*output
;
214 output
= session
->kernel_session
?
215 session
->kernel_session
->consumer
:
216 session
->ust_session
->consumer
;
219 * hostname is assumed to be the same for both control and data
222 switch (output
->dst
.net
.control
.dtype
) {
224 hostname
= output
->dst
.net
.control
.dst
.ipv4
;
227 hostname
= output
->dst
.net
.control
.dst
.ipv6
;
236 * Get the session's consumer network control and data ports.
237 * The caller must ensure that the destination is of type "net".
239 * The caller must hold the session lock.
241 void session_get_net_consumer_ports(const struct ltt_session
*session
,
242 uint16_t *control_port
, uint16_t *data_port
)
244 const struct consumer_output
*output
;
246 output
= session
->kernel_session
?
247 session
->kernel_session
->consumer
:
248 session
->ust_session
->consumer
;
249 *control_port
= output
->dst
.net
.control
.port
;
250 *data_port
= output
->dst
.net
.data
.port
;
254 * Get the location of the latest trace archive produced by a rotation.
256 * The caller must hold the session lock.
258 struct lttng_trace_archive_location
*session_get_trace_archive_location(
259 const struct ltt_session
*session
)
262 struct lttng_trace_archive_location
*location
= NULL
;
263 char *chunk_path
= NULL
;
265 if (session
->rotation_state
!= LTTNG_ROTATION_STATE_COMPLETED
||
266 !session
->last_archived_chunk_name
) {
270 switch (session_get_consumer_destination_type(session
)) {
271 case CONSUMER_DST_LOCAL
:
272 ret
= asprintf(&chunk_path
,
273 "%s/" DEFAULT_ARCHIVED_TRACE_CHUNKS_DIRECTORY
"/%s",
274 session_get_base_path(session
),
275 session
->last_archived_chunk_name
);
279 location
= lttng_trace_archive_location_local_create(
282 case CONSUMER_DST_NET
:
284 const char *hostname
;
285 uint16_t control_port
, data_port
;
287 hostname
= session_get_net_consumer_hostname(session
);
288 session_get_net_consumer_ports(session
,
291 location
= lttng_trace_archive_location_relay_create(
293 LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP
,
294 control_port
, data_port
, session
->last_chunk_path
);
306 * Allocate the ltt_sessions_ht_by_id HT.
308 * The session list lock must be held.
310 static int ltt_sessions_ht_alloc(void)
314 DBG("Allocating ltt_sessions_ht_by_id");
315 ltt_sessions_ht_by_id
= lttng_ht_new(0, LTTNG_HT_TYPE_U64
);
316 if (!ltt_sessions_ht_by_id
) {
318 ERR("Failed to allocate ltt_sessions_ht_by_id");
326 * Destroy the ltt_sessions_ht_by_id HT.
328 * The session list lock must be held.
330 static void ltt_sessions_ht_destroy(void)
332 if (!ltt_sessions_ht_by_id
) {
335 ht_cleanup_push(ltt_sessions_ht_by_id
);
336 ltt_sessions_ht_by_id
= NULL
;
340 * Add a ltt_session to the ltt_sessions_ht_by_id.
341 * If unallocated, the ltt_sessions_ht_by_id HT is allocated.
342 * The session list lock must be held.
344 static void add_session_ht(struct ltt_session
*ls
)
350 if (!ltt_sessions_ht_by_id
) {
351 ret
= ltt_sessions_ht_alloc();
353 ERR("Error allocating the sessions HT");
357 lttng_ht_node_init_u64(&ls
->node
, ls
->id
);
358 lttng_ht_add_unique_u64(ltt_sessions_ht_by_id
, &ls
->node
);
365 * Test if ltt_sessions_ht_by_id is empty.
366 * Return 1 if empty, 0 if not empty.
367 * The session list lock must be held.
369 static int ltt_sessions_ht_empty(void)
373 if (!ltt_sessions_ht_by_id
) {
378 ret
= lttng_ht_get_count(ltt_sessions_ht_by_id
) ? 0 : 1;
384 * Remove a ltt_session from the ltt_sessions_ht_by_id.
385 * If empty, the ltt_sessions_ht_by_id HT is freed.
386 * The session list lock must be held.
388 static void del_session_ht(struct ltt_session
*ls
)
390 struct lttng_ht_iter iter
;
394 assert(ltt_sessions_ht_by_id
);
396 iter
.iter
.node
= &ls
->node
.node
;
397 ret
= lttng_ht_del(ltt_sessions_ht_by_id
, &iter
);
400 if (ltt_sessions_ht_empty()) {
401 DBG("Empty ltt_sessions_ht_by_id, destroying it");
402 ltt_sessions_ht_destroy();
407 * Acquire session lock
409 void session_lock(struct ltt_session
*session
)
413 pthread_mutex_lock(&session
->lock
);
417 * Release session lock
419 void session_unlock(struct ltt_session
*session
)
423 pthread_mutex_unlock(&session
->lock
);
427 int _session_set_trace_chunk_no_lock_check(struct ltt_session
*session
,
428 struct lttng_trace_chunk
*new_trace_chunk
,
429 struct lttng_trace_chunk
**_current_trace_chunk
)
432 unsigned int i
, refs_to_acquire
= 0, refs_acquired
= 0, refs_to_release
= 0;
433 struct cds_lfht_iter iter
;
434 struct consumer_socket
*socket
;
435 struct lttng_trace_chunk
*current_trace_chunk
;
437 enum lttng_trace_chunk_status chunk_status
;
441 * Ownership of current trace chunk is transferred to
442 * `current_trace_chunk`.
444 current_trace_chunk
= session
->current_trace_chunk
;
445 session
->current_trace_chunk
= NULL
;
446 if (session
->ust_session
) {
447 lttng_trace_chunk_put(
448 session
->ust_session
->current_trace_chunk
);
449 session
->ust_session
->current_trace_chunk
= NULL
;
451 if (session
->kernel_session
) {
452 lttng_trace_chunk_put(
453 session
->kernel_session
->current_trace_chunk
);
454 session
->kernel_session
->current_trace_chunk
= NULL
;
456 if (!new_trace_chunk
) {
460 chunk_status
= lttng_trace_chunk_get_id(new_trace_chunk
, &chunk_id
);
461 assert(chunk_status
== LTTNG_TRACE_CHUNK_STATUS_OK
);
464 refs_to_acquire
+= !!session
->ust_session
;
465 refs_to_acquire
+= !!session
->kernel_session
;
467 for (refs_acquired
= 0; refs_acquired
< refs_to_acquire
;
469 if (!lttng_trace_chunk_get(new_trace_chunk
)) {
470 ERR("Failed to acquire reference to new trace chunk of session \"%s\"",
476 if (session
->ust_session
) {
477 const uint64_t relayd_id
=
478 session
->ust_session
->consumer
->net_seq_index
;
479 const bool is_local_trace
=
480 session
->ust_session
->consumer
->type
==
483 session
->ust_session
->current_trace_chunk
= new_trace_chunk
;
484 if (is_local_trace
) {
485 enum lttng_error_code ret_error_code
;
487 ret_error_code
= ust_app_create_channel_subdirectories(
488 session
->ust_session
);
489 if (ret_error_code
!= LTTNG_OK
) {
493 cds_lfht_for_each_entry(
494 session
->ust_session
->consumer
->socks
->ht
,
495 &iter
, socket
, node
.node
) {
496 pthread_mutex_lock(socket
->lock
);
497 ret
= consumer_create_trace_chunk(socket
,
499 session
->id
, new_trace_chunk
,
500 DEFAULT_UST_TRACE_DIR
);
501 pthread_mutex_unlock(socket
->lock
);
507 if (session
->kernel_session
) {
508 const uint64_t relayd_id
=
509 session
->kernel_session
->consumer
->net_seq_index
;
510 const bool is_local_trace
=
511 session
->kernel_session
->consumer
->type
==
514 session
->kernel_session
->current_trace_chunk
= new_trace_chunk
;
515 if (is_local_trace
) {
516 enum lttng_error_code ret_error_code
;
518 ret_error_code
= kernel_create_channel_subdirectories(
519 session
->kernel_session
);
520 if (ret_error_code
!= LTTNG_OK
) {
524 cds_lfht_for_each_entry(
525 session
->kernel_session
->consumer
->socks
->ht
,
526 &iter
, socket
, node
.node
) {
527 pthread_mutex_lock(socket
->lock
);
528 ret
= consumer_create_trace_chunk(socket
,
530 session
->id
, new_trace_chunk
,
531 DEFAULT_KERNEL_TRACE_DIR
);
532 pthread_mutex_unlock(socket
->lock
);
540 * Update local current trace chunk state last, only if all remote
541 * creations succeeded.
543 session
->current_trace_chunk
= new_trace_chunk
;
544 LTTNG_OPTIONAL_SET(&session
->most_recent_chunk_id
, chunk_id
);
546 if (_current_trace_chunk
) {
547 *_current_trace_chunk
= current_trace_chunk
;
548 current_trace_chunk
= NULL
;
552 lttng_trace_chunk_put(current_trace_chunk
);
555 if (session
->ust_session
) {
556 session
->ust_session
->current_trace_chunk
= NULL
;
558 if (session
->kernel_session
) {
559 session
->kernel_session
->current_trace_chunk
= NULL
;
562 * Release references taken in the case where all references could not
565 refs_to_release
= refs_to_acquire
- refs_acquired
;
566 for (i
= 0; i
< refs_to_release
; i
++) {
567 lttng_trace_chunk_put(new_trace_chunk
);
573 struct lttng_trace_chunk
*session_create_new_trace_chunk(
574 const struct ltt_session
*session
,
575 const struct consumer_output
*consumer_output_override
,
576 const char *session_base_path_override
,
577 const char *chunk_name_override
)
580 struct lttng_trace_chunk
*trace_chunk
= NULL
;
581 enum lttng_trace_chunk_status chunk_status
;
582 const time_t chunk_creation_ts
= time(NULL
);
584 const char *base_path
;
585 struct lttng_directory_handle
*session_output_directory
= NULL
;
586 const struct lttng_credentials session_credentials
= {
590 uint64_t next_chunk_id
;
591 const struct consumer_output
*output
;
593 if (consumer_output_override
) {
594 output
= consumer_output_override
;
596 assert(session
->ust_session
|| session
->kernel_session
);
597 output
= session
->ust_session
?
598 session
->ust_session
->consumer
:
599 session
->kernel_session
->consumer
;
602 is_local_trace
= output
->type
== CONSUMER_DST_LOCAL
;
603 base_path
= session_base_path_override
? :
604 consumer_output_get_base_path(output
);
606 if (chunk_creation_ts
== (time_t) -1) {
607 PERROR("Failed to sample time while creation session \"%s\" trace chunk",
612 next_chunk_id
= session
->most_recent_chunk_id
.is_set
?
613 session
->most_recent_chunk_id
.value
+ 1 : 0;
615 trace_chunk
= lttng_trace_chunk_create(next_chunk_id
,
621 if (chunk_name_override
) {
622 chunk_status
= lttng_trace_chunk_override_name(trace_chunk
,
623 chunk_name_override
);
624 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
629 if (!is_local_trace
) {
631 * No need to set crendentials and output directory
632 * for remote trace chunks.
637 chunk_status
= lttng_trace_chunk_set_credentials(trace_chunk
,
638 &session_credentials
);
639 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
643 DBG("Creating base output directory of session \"%s\" at %s",
644 session
->name
, base_path
);
645 ret
= utils_mkdir_recursive(base_path
, S_IRWXU
| S_IRWXG
,
646 session
->uid
, session
->gid
);
650 session_output_directory
= lttng_directory_handle_create(base_path
);
651 if (!session_output_directory
) {
654 chunk_status
= lttng_trace_chunk_set_as_owner(trace_chunk
,
655 session_output_directory
);
656 lttng_directory_handle_put(session_output_directory
);
657 session_output_directory
= NULL
;
658 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
664 lttng_directory_handle_put(session_output_directory
);
665 lttng_trace_chunk_put(trace_chunk
);
670 int session_close_trace_chunk(struct ltt_session
*session
,
671 struct lttng_trace_chunk
*trace_chunk
,
672 enum lttng_trace_chunk_command_type close_command
,
673 char *closed_trace_chunk_path
)
676 bool error_occurred
= false;
677 struct cds_lfht_iter iter
;
678 struct consumer_socket
*socket
;
679 enum lttng_trace_chunk_status chunk_status
;
680 const time_t chunk_close_timestamp
= time(NULL
);
682 chunk_status
= lttng_trace_chunk_set_close_command(
683 trace_chunk
, close_command
);
684 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
689 if (chunk_close_timestamp
== (time_t) -1) {
690 ERR("Failed to sample the close timestamp of the current trace chunk of session \"%s\"",
695 chunk_status
= lttng_trace_chunk_set_close_timestamp(trace_chunk
,
696 chunk_close_timestamp
);
697 if (chunk_status
!= LTTNG_TRACE_CHUNK_STATUS_OK
) {
698 ERR("Failed to set the close timestamp of the current trace chunk of session \"%s\"",
704 if (session
->ust_session
) {
705 const uint64_t relayd_id
=
706 session
->ust_session
->consumer
->net_seq_index
;
708 cds_lfht_for_each_entry(
709 session
->ust_session
->consumer
->socks
->ht
,
710 &iter
, socket
, node
.node
) {
711 pthread_mutex_lock(socket
->lock
);
712 ret
= consumer_close_trace_chunk(socket
,
715 trace_chunk
, closed_trace_chunk_path
);
716 pthread_mutex_unlock(socket
->lock
);
718 ERR("Failed to close trace chunk on user space consumer");
719 error_occurred
= true;
723 if (session
->kernel_session
) {
724 const uint64_t relayd_id
=
725 session
->kernel_session
->consumer
->net_seq_index
;
727 cds_lfht_for_each_entry(
728 session
->kernel_session
->consumer
->socks
->ht
,
729 &iter
, socket
, node
.node
) {
730 pthread_mutex_lock(socket
->lock
);
731 ret
= consumer_close_trace_chunk(socket
,
734 trace_chunk
, closed_trace_chunk_path
);
735 pthread_mutex_unlock(socket
->lock
);
737 ERR("Failed to close trace chunk on kernel consumer");
738 error_occurred
= true;
742 ret
= error_occurred
? -1 : 0;
748 * Set a session's current trace chunk.
750 * Must be called with the session lock held.
752 int session_set_trace_chunk(struct ltt_session
*session
,
753 struct lttng_trace_chunk
*new_trace_chunk
,
754 struct lttng_trace_chunk
**current_trace_chunk
)
756 ASSERT_LOCKED(session
->lock
);
757 return _session_set_trace_chunk_no_lock_check(session
, new_trace_chunk
,
758 current_trace_chunk
);
762 void session_notify_destruction(const struct ltt_session
*session
)
765 const size_t count
= lttng_dynamic_array_get_count(
766 &session
->destroy_notifiers
);
768 for (i
= 0; i
< count
; i
++) {
769 const struct ltt_session_destroy_notifier_element
*element
=
770 lttng_dynamic_array_get_element(
771 &session
->destroy_notifiers
, i
);
773 element
->notifier(session
, element
->user_data
);
778 * Fire each clear notifier once, and remove them from the array.
780 void session_notify_clear(struct ltt_session
*session
)
783 const size_t count
= lttng_dynamic_array_get_count(
784 &session
->clear_notifiers
);
786 for (i
= 0; i
< count
; i
++) {
787 const struct ltt_session_clear_notifier_element
*element
=
788 lttng_dynamic_array_get_element(
789 &session
->clear_notifiers
, i
);
791 element
->notifier(session
, element
->user_data
);
793 lttng_dynamic_array_clear(&session
->clear_notifiers
);
797 void session_release(struct urcu_ref
*ref
)
800 struct ltt_ust_session
*usess
;
801 struct ltt_kernel_session
*ksess
;
802 struct ltt_session
*session
= container_of(ref
, typeof(*session
), ref
);
803 const bool session_published
= session
->published
;
805 assert(!session
->chunk_being_archived
);
807 usess
= session
->ust_session
;
808 ksess
= session
->kernel_session
;
810 /* Clean kernel session teardown, keeping data for destroy notifier. */
811 kernel_destroy_session(ksess
);
813 /* UST session teardown, keeping data for destroy notifier. */
815 /* Close any relayd session */
816 consumer_output_send_destroy_relayd(usess
->consumer
);
818 /* Destroy every UST application related to this session. */
819 ret
= ust_app_destroy_trace_all(usess
);
821 ERR("Error in ust_app_destroy_trace_all");
824 /* Clean up the rest, keeping destroy notifier data. */
825 trace_ust_destroy_session(usess
);
829 * Must notify the kernel thread here to update it's poll set in order to
830 * remove the channel(s)' fd just destroyed.
832 ret
= notify_thread_pipe(kernel_poll_pipe
[1]);
834 PERROR("write kernel poll pipe");
837 DBG("Destroying session %s (id %" PRIu64
")", session
->name
, session
->id
);
839 snapshot_destroy(&session
->snapshot
);
841 pthread_mutex_destroy(&session
->lock
);
843 if (session_published
) {
844 ASSERT_LOCKED(ltt_session_list
.lock
);
845 del_session_list(session
);
846 del_session_ht(session
);
848 session_notify_destruction(session
);
850 consumer_output_put(session
->consumer
);
851 kernel_free_session(ksess
);
852 session
->kernel_session
= NULL
;
854 trace_ust_free_session(usess
);
855 session
->ust_session
= NULL
;
857 lttng_dynamic_array_reset(&session
->destroy_notifiers
);
858 lttng_dynamic_array_reset(&session
->clear_notifiers
);
859 free(session
->last_archived_chunk_name
);
860 free(session
->base_path
);
862 if (session_published
) {
864 * Broadcast after free-ing to ensure the memory is
865 * reclaimed before the main thread exits.
867 pthread_cond_broadcast(<t_session_list
.removal_cond
);
872 * Acquire a reference to a session.
873 * This function may fail (return false); its return value must be checked.
875 bool session_get(struct ltt_session
*session
)
877 return urcu_ref_get_unless_zero(&session
->ref
);
881 * Release a reference to a session.
883 void session_put(struct ltt_session
*session
)
889 * The session list lock must be held as any session_put()
890 * may cause the removal of the session from the session_list.
892 ASSERT_LOCKED(ltt_session_list
.lock
);
893 assert(session
->ref
.refcount
);
894 urcu_ref_put(&session
->ref
, session_release
);
900 * This method does not immediately release/free the session as other
901 * components may still hold a reference to the session. However,
902 * the session should no longer be presented to the user.
904 * Releases the session list's reference to the session
905 * and marks it as destroyed. Iterations on the session list should be
906 * mindful of the "destroyed" flag.
908 void session_destroy(struct ltt_session
*session
)
910 assert(!session
->destroyed
);
911 session
->destroyed
= true;
912 session_put(session
);
915 int session_add_destroy_notifier(struct ltt_session
*session
,
916 ltt_session_destroy_notifier notifier
, void *user_data
)
918 const struct ltt_session_destroy_notifier_element element
= {
919 .notifier
= notifier
,
920 .user_data
= user_data
923 return lttng_dynamic_array_add_element(&session
->destroy_notifiers
,
927 int session_add_clear_notifier(struct ltt_session
*session
,
928 ltt_session_clear_notifier notifier
, void *user_data
)
930 const struct ltt_session_clear_notifier_element element
= {
931 .notifier
= notifier
,
932 .user_data
= user_data
935 return lttng_dynamic_array_add_element(&session
->clear_notifiers
,
940 * Return a ltt_session structure ptr that matches name. If no session found,
941 * NULL is returned. This must be called with the session list lock held using
942 * session_lock_list and session_unlock_list.
943 * A reference to the session is implicitly acquired by this function.
945 struct ltt_session
*session_find_by_name(const char *name
)
947 struct ltt_session
*iter
;
950 ASSERT_LOCKED(ltt_session_list
.lock
);
952 DBG2("Trying to find session by name %s", name
);
954 cds_list_for_each_entry(iter
, <t_session_list
.head
, list
) {
955 if (!strncmp(iter
->name
, name
, NAME_MAX
) &&
963 return session_get(iter
) ? iter
: NULL
;
967 * Return an ltt_session that matches the id. If no session is found,
968 * NULL is returned. This must be called with rcu_read_lock and
969 * session list lock held (to guarantee the lifetime of the session).
971 struct ltt_session
*session_find_by_id(uint64_t id
)
973 struct lttng_ht_node_u64
*node
;
974 struct lttng_ht_iter iter
;
975 struct ltt_session
*ls
;
977 ASSERT_LOCKED(ltt_session_list
.lock
);
979 if (!ltt_sessions_ht_by_id
) {
983 lttng_ht_lookup(ltt_sessions_ht_by_id
, &id
, &iter
);
984 node
= lttng_ht_iter_get_node_u64(&iter
);
988 ls
= caa_container_of(node
, struct ltt_session
, node
);
990 DBG3("Session %" PRIu64
" found by id.", id
);
991 return session_get(ls
) ? ls
: NULL
;
994 DBG3("Session %" PRIu64
" NOT found by id", id
);
999 * Create a new session and add it to the session list.
1000 * Session list lock must be held by the caller.
1002 enum lttng_error_code
session_create(const char *name
, uid_t uid
, gid_t gid
,
1003 struct ltt_session
**out_session
)
1006 enum lttng_error_code ret_code
;
1007 struct ltt_session
*new_session
= NULL
;
1009 ASSERT_LOCKED(ltt_session_list
.lock
);
1011 struct ltt_session
*clashing_session
;
1013 clashing_session
= session_find_by_name(name
);
1014 if (clashing_session
) {
1015 session_put(clashing_session
);
1016 ret_code
= LTTNG_ERR_EXIST_SESS
;
1020 new_session
= zmalloc(sizeof(struct ltt_session
));
1022 PERROR("Failed to allocate an ltt_session structure");
1023 ret_code
= LTTNG_ERR_NOMEM
;
1027 lttng_dynamic_array_init(&new_session
->destroy_notifiers
,
1028 sizeof(struct ltt_session_destroy_notifier_element
),
1030 lttng_dynamic_array_init(&new_session
->clear_notifiers
,
1031 sizeof(struct ltt_session_clear_notifier_element
),
1033 urcu_ref_init(&new_session
->ref
);
1034 pthread_mutex_init(&new_session
->lock
, NULL
);
1036 new_session
->creation_time
= time(NULL
);
1037 if (new_session
->creation_time
== (time_t) -1) {
1038 PERROR("Failed to sample session creation time");
1039 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1043 /* Create default consumer output. */
1044 new_session
->consumer
= consumer_create_output(CONSUMER_DST_LOCAL
);
1045 if (new_session
->consumer
== NULL
) {
1046 ret_code
= LTTNG_ERR_NOMEM
;
1051 ret
= lttng_strncpy(new_session
->name
, name
, sizeof(new_session
->name
));
1053 ret_code
= LTTNG_ERR_SESSION_INVALID_CHAR
;
1056 ret
= validate_name(name
);
1058 ret_code
= LTTNG_ERR_SESSION_INVALID_CHAR
;
1063 bool found_name
= false;
1065 struct tm
*timeinfo
;
1067 timeinfo
= localtime(&new_session
->creation_time
);
1069 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1072 strftime(datetime
, sizeof(datetime
), "%Y%m%d-%H%M%S", timeinfo
);
1073 for (i
= 0; i
< INT_MAX
; i
++) {
1074 struct ltt_session
*clashing_session
;
1077 ret
= snprintf(new_session
->name
,
1078 sizeof(new_session
->name
),
1080 DEFAULT_SESSION_NAME
,
1083 ret
= snprintf(new_session
->name
,
1084 sizeof(new_session
->name
),
1086 DEFAULT_SESSION_NAME
, i
,
1089 new_session
->name_contains_creation_time
= true;
1090 if (ret
== -1 || ret
>= sizeof(new_session
->name
)) {
1092 * Null-terminate in case the name is used
1093 * in logging statements.
1095 new_session
->name
[sizeof(new_session
->name
) - 1] = '\0';
1096 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1101 session_find_by_name(new_session
->name
);
1102 session_put(clashing_session
);
1103 if (!clashing_session
) {
1109 DBG("Generated session name \"%s\"", new_session
->name
);
1110 new_session
->has_auto_generated_name
= true;
1112 ERR("Failed to auto-generate a session name");
1113 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1118 ret
= gethostname(new_session
->hostname
, sizeof(new_session
->hostname
));
1120 if (errno
== ENAMETOOLONG
) {
1121 new_session
->hostname
[sizeof(new_session
->hostname
) - 1] = '\0';
1122 ERR("Hostname exceeds the maximal permitted length and has been truncated to %s",
1123 new_session
->hostname
);
1125 ret_code
= LTTNG_ERR_SESSION_FAIL
;
1130 new_session
->uid
= uid
;
1131 new_session
->gid
= gid
;
1133 ret
= snapshot_init(&new_session
->snapshot
);
1135 ret_code
= LTTNG_ERR_NOMEM
;
1139 new_session
->rotation_state
= LTTNG_ROTATION_STATE_NO_ROTATION
;
1141 /* Add new session to the session list. */
1142 new_session
->id
= add_session_list(new_session
);
1145 * Add the new session to the ltt_sessions_ht_by_id.
1146 * No ownership is taken by the hash table; it is merely
1147 * a wrapper around the session list used for faster access
1150 add_session_ht(new_session
);
1151 new_session
->published
= true;
1154 * Consumer is left to NULL since the create_session_uri command will
1155 * set it up and, if valid, assign it to the session.
1157 DBG("Tracing session %s created with ID %" PRIu64
" by uid = %d, gid = %d",
1158 new_session
->name
, new_session
->id
, new_session
->uid
,
1160 ret_code
= LTTNG_OK
;
1163 (void) session_get(new_session
);
1164 *out_session
= new_session
;
1168 session_put(new_session
);
1174 * Check if the UID or GID match the session. Root user has access to all
1177 int session_access_ok(struct ltt_session
*session
, uid_t uid
, gid_t gid
)
1181 if (uid
!= session
->uid
&& gid
!= session
->gid
&& uid
!= 0) {
1189 * Set a session's rotation state and reset all associated state.
1191 * This function resets the rotation state (check timers, pending
1192 * flags, etc.) and sets the result of the last rotation. The result
1193 * can be queries by a liblttng-ctl client.
1195 * Be careful of the result passed to this function. For instance,
1196 * on failure to launch a rotation, a client will expect the rotation
1197 * state to be set to "NO_ROTATION". If an error occurred while the
1198 * rotation was "ONGOING", result should be set to "ERROR", which will
1199 * allow a client to report it.
1201 * Must be called with the session and session_list locks held.
1203 int session_reset_rotation_state(struct ltt_session
*session
,
1204 enum lttng_rotation_state result
)
1208 ASSERT_LOCKED(ltt_session_list
.lock
);
1209 ASSERT_LOCKED(session
->lock
);
1211 session
->rotation_state
= result
;
1212 if (session
->rotation_pending_check_timer_enabled
) {
1213 ret
= timer_session_rotation_pending_check_stop(session
);
1215 if (session
->chunk_being_archived
) {
1217 enum lttng_trace_chunk_status chunk_status
;
1219 chunk_status
= lttng_trace_chunk_get_id(
1220 session
->chunk_being_archived
,
1222 assert(chunk_status
== LTTNG_TRACE_CHUNK_STATUS_OK
);
1223 LTTNG_OPTIONAL_SET(&session
->last_archived_chunk_id
,
1225 lttng_trace_chunk_put(session
->chunk_being_archived
);
1226 session
->chunk_being_archived
= NULL
;
1228 * Fire the clear reply notifiers if we are completing a clear
1231 session_notify_clear(session
);