X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-relayd%2Fsession.cpp;h=a8a1520694025f3843b6cfabe9aebddca8a9488a;hp=6e29fbc741afd1efe32723f7342f8cc809fa9a3c;hb=HEAD;hpb=0114db0ec2407029052eb61a0189c9b1cd64d520 diff --git a/src/bin/lttng-relayd/session.cpp b/src/bin/lttng-relayd/session.cpp index 6e29fbc74..8ac4a510d 100644 --- a/src/bin/lttng-relayd/session.cpp +++ b/src/bin/lttng-relayd/session.cpp @@ -8,23 +8,24 @@ */ #define _LGPL_SOURCE +#include "ctf-trace.hpp" +#include "lttng-relayd.hpp" +#include "session.hpp" +#include "sessiond-trace-chunks.hpp" +#include "stream.hpp" +#include "utils.hpp" + #include #include +#include #include #include +#include #include #include -#include #include - -#include "ctf-trace.hpp" -#include "lttng-relayd.hpp" -#include "session.hpp" -#include "sessiond-trace-chunks.hpp" -#include "stream.hpp" -#include -#include "utils.hpp" +#include /* Global session id used in the session creation. */ static uint64_t last_relay_session_id; @@ -40,7 +41,7 @@ static int init_session_output_path_group_by_host(struct relay_session *session) * else * hostname/base_path */ - char *session_directory = NULL; + char *session_directory = nullptr; int ret = 0; if (session->output_path[0] != '\0') { @@ -58,27 +59,27 @@ static int init_session_output_path_group_by_host(struct relay_session *session) * Otherwise, generate the path with session_name-. */ if (session->base_path[0] != '\0') { - ret = asprintf(&session_directory, "%s/%s", session->hostname, - session->base_path); + ret = asprintf(&session_directory, "%s/%s", session->hostname, session->base_path); } else if (session->session_name_contains_creation_time) { - ret = asprintf(&session_directory, "%s/%s", session->hostname, - session->session_name); + ret = asprintf( + &session_directory, "%s/%s", session->hostname, session->session_name); } else { char session_creation_datetime[DATETIME_STR_LEN]; - ret = time_to_datetime_str( - LTTNG_OPTIONAL_GET(session->creation_time), - session_creation_datetime, - sizeof(session_creation_datetime)); + ret = time_to_datetime_str(LTTNG_OPTIONAL_GET(session->creation_time), + session_creation_datetime, + sizeof(session_creation_datetime)); if (ret) { ERR("Failed to format session creation timestamp while initializing session output directory handle"); ret = -1; goto end; } - ret = asprintf(&session_directory, "%s/%s-%s", - session->hostname, session->session_name, - session_creation_datetime); + ret = asprintf(&session_directory, + "%s/%s-%s", + session->hostname, + session->session_name, + session_creation_datetime); } if (ret < 0) { PERROR("Failed to format session directory name"); @@ -98,8 +99,7 @@ end: return ret; } -static int init_session_output_path_group_by_session( - struct relay_session *session) +static int init_session_output_path_group_by_session(struct relay_session *session) { /* * session_directory: @@ -111,7 +111,7 @@ static int init_session_output_path_group_by_session( * integral part of the name and how a user identify a session. */ int ret = 0; - char *session_directory = NULL; + char *session_directory = nullptr; char creation_datetime[DATETIME_STR_LEN]; if (session->output_path[0] != '\0') { @@ -120,18 +120,21 @@ static int init_session_output_path_group_by_session( } ret = time_to_datetime_str(LTTNG_OPTIONAL_GET(session->creation_time), - creation_datetime, sizeof(creation_datetime)); + creation_datetime, + sizeof(creation_datetime)); if (ret) { ERR("Failed to format session creation timestamp while initializing session output directory handle"); ret = -1; goto end; } - ret = asprintf(&session_directory, "%s/%s-%s%s%s", - session->session_name, session->hostname, - creation_datetime, - session->base_path[0] != '\0' ? "/" : "", - session->base_path); + ret = asprintf(&session_directory, + "%s/%s-%s%s%s", + session->session_name, + session->hostname, + creation_datetime, + session->base_path[0] != '\0' ? "/" : "", + session->base_path); if (ret < 0) { PERROR("Failed to format session directory name"); goto end; @@ -171,16 +174,16 @@ static int init_session_output_path(struct relay_session *session) return ret; } -static struct lttng_directory_handle *session_create_output_directory_handle( - struct relay_session *session) +static struct lttng_directory_handle * +session_create_output_directory_handle(struct relay_session *session) { int ret; /* * relayd_output_path/session_directory * e.g. /home/user/lttng-traces/hostname/session_name */ - char *full_session_path = NULL; - struct lttng_directory_handle *handle = NULL; + char *full_session_path = nullptr; + struct lttng_directory_handle *handle = nullptr; pthread_mutex_lock(&session->lock); full_session_path = create_output_path(session->output_path); @@ -188,11 +191,9 @@ static struct lttng_directory_handle *session_create_output_directory_handle( goto end; } - ret = utils_mkdir_recursive( - full_session_path, S_IRWXU | S_IRWXG, -1, -1); + ret = utils_mkdir_recursive(full_session_path, S_IRWXU | S_IRWXG, -1, -1); if (ret) { - ERR("Failed to create session output path \"%s\"", - full_session_path); + ERR("Failed to create session output path \"%s\"", full_session_path); goto end; } @@ -206,7 +207,7 @@ end: static int session_set_anonymous_chunk(struct relay_session *session) { int ret = 0; - struct lttng_trace_chunk *chunk = NULL; + struct lttng_trace_chunk *chunk = nullptr; enum lttng_trace_chunk_status status; struct lttng_directory_handle *output_directory; @@ -234,7 +235,7 @@ static int session_set_anonymous_chunk(struct relay_session *session) } session->current_trace_chunk = chunk; - chunk = NULL; + chunk = nullptr; end: lttng_trace_chunk_put(chunk); lttng_directory_handle_put(output_directory); @@ -260,12 +261,14 @@ static bool is_name_path_safe(const char *name) } /* Does not start with '.'. */ if (name[0] == '.') { - WARN("Name \"%s\" is not allowed to be used in a path since it starts with '.'", name); + WARN("Name \"%s\" is not allowed to be used in a path since it starts with '.'", + name); return false; } /* Does not contain a path-separator. */ if (strchr(name, LTTNG_PATH_SEPARATOR)) { - WARN("Name \"%s\" is not allowed to be used in a path since it contains a path separator", name); + WARN("Name \"%s\" is not allowed to be used in a path since it contains a path separator", + name); return false; } @@ -278,19 +281,20 @@ static bool is_name_path_safe(const char *name) * Return allocated session or else NULL. */ struct relay_session *session_create(const char *session_name, - const char *hostname, const char *base_path, - uint32_t live_timer, - bool snapshot, - const lttng_uuid& sessiond_uuid, - const uint64_t *id_sessiond, - const uint64_t *current_chunk_id, - const time_t *creation_time, - uint32_t major, - uint32_t minor, - bool session_name_contains_creation_time) + const char *hostname, + const char *base_path, + uint32_t live_timer, + bool snapshot, + const lttng_uuid& sessiond_uuid, + const uint64_t *id_sessiond, + const uint64_t *current_chunk_id, + const time_t *creation_time, + uint32_t major, + uint32_t minor, + bool session_name_contains_creation_time) { int ret; - struct relay_session *session = NULL; + struct relay_session *session = nullptr; LTTNG_ASSERT(session_name); LTTNG_ASSERT(hostname); @@ -305,8 +309,7 @@ struct relay_session *session_create(const char *session_name, goto error; } if (strstr(base_path, "../")) { - ERR("Invalid session base path walks up the path hierarchy: \"%s\"", - base_path); + ERR("Invalid session base path walks up the path hierarchy: \"%s\"", base_path); goto error; } @@ -323,35 +326,31 @@ struct relay_session *session_create(const char *session_name, lttng_ht_node_init_u64(&session->session_n, session->id); urcu_ref_init(&session->ref); CDS_INIT_LIST_HEAD(&session->recv_list); - pthread_mutex_init(&session->lock, NULL); - pthread_mutex_init(&session->recv_list_lock, NULL); + pthread_mutex_init(&session->lock, nullptr); + pthread_mutex_init(&session->recv_list_lock, nullptr); - if (lttng_strncpy(session->session_name, session_name, - sizeof(session->session_name))) { + if (lttng_strncpy(session->session_name, session_name, sizeof(session->session_name))) { WARN("Session name exceeds maximal allowed length"); goto error; } - if (lttng_strncpy(session->hostname, hostname, - sizeof(session->hostname))) { + if (lttng_strncpy(session->hostname, hostname, sizeof(session->hostname))) { WARN("Hostname exceeds maximal allowed length"); goto error; } - if (lttng_strncpy(session->base_path, base_path, - sizeof(session->base_path))) { + if (lttng_strncpy(session->base_path, base_path, sizeof(session->base_path))) { WARN("Base path exceeds maximal allowed length"); goto error; } if (creation_time) { LTTNG_OPTIONAL_SET(&session->creation_time, *creation_time); } else { - LTTNG_OPTIONAL_SET(&session->creation_time, time(NULL)); + LTTNG_OPTIONAL_SET(&session->creation_time, time(nullptr)); if (session->creation_time.value == (time_t) -1) { PERROR("Failed to sample session creation time"); goto error; } } - session->session_name_contains_creation_time = - session_name_contains_creation_time; + session->session_name_contains_creation_time = session_name_contains_creation_time; session->ctf_traces_ht = lttng_ht_new(0, LTTNG_HT_TYPE_STRING); if (!session->ctf_traces_ht) { @@ -377,8 +376,8 @@ struct relay_session *session_create(const char *session_name, } } - ret = sessiond_trace_chunk_registry_session_created( - sessiond_trace_chunk_registry, sessiond_uuid); + ret = sessiond_trace_chunk_registry_session_created(sessiond_trace_chunk_registry, + sessiond_uuid); if (ret) { goto error; } @@ -388,24 +387,24 @@ struct relay_session *session_create(const char *session_name, struct lttng_directory_handle *session_output_directory; session->current_trace_chunk = - sessiond_trace_chunk_registry_get_chunk( - sessiond_trace_chunk_registry, - session->sessiond_uuid, - session->id_sessiond.value, - *current_chunk_id); + sessiond_trace_chunk_registry_get_chunk(sessiond_trace_chunk_registry, + session->sessiond_uuid, + session->id_sessiond.value, + *current_chunk_id); if (!session->current_trace_chunk) { char uuid_str[LTTNG_UUID_STR_LEN]; lttng_uuid_to_str(sessiond_uuid, uuid_str); - ERR("Could not find trace chunk: sessiond = {%s}, sessiond session id = %" PRIu64 ", trace chunk id = %" PRIu64, - uuid_str, *id_sessiond, - *current_chunk_id); + ERR("Could not find trace chunk: sessiond = {%s}, sessiond session id = %" PRIu64 + ", trace chunk id = %" PRIu64, + uuid_str, + *id_sessiond, + *current_chunk_id); goto error; } chunk_status = lttng_trace_chunk_get_session_output_directory_handle( - session->current_trace_chunk, - &session_output_directory); + session->current_trace_chunk, &session_output_directory); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { goto error; } @@ -423,8 +422,7 @@ struct relay_session *session_create(const char *session_name, goto error; } } else { - session->output_directory = - session_create_output_directory_handle(session); + session->output_directory = session_create_output_directory_handle(session); if (!session->output_directory) { goto error; } @@ -435,7 +433,7 @@ struct relay_session *session_create(const char *session_name, error: session_put(session); - return NULL; + return nullptr; } /* Should be called with RCU read-side lock held. */ @@ -453,11 +451,11 @@ bool session_get(struct relay_session *session) */ struct relay_session *session_get_by_id(uint64_t id) { - struct relay_session *session = NULL; + struct relay_session *session = nullptr; struct lttng_ht_node_u64 *node; struct lttng_ht_iter iter; - rcu_read_lock(); + lttng::urcu::read_lock_guard read_lock; lttng_ht_lookup(sessions_ht, &id, &iter); node = lttng_ht_iter_get_node_u64(&iter); if (!node) { @@ -467,10 +465,9 @@ struct relay_session *session_get_by_id(uint64_t id) session = lttng::utils::container_of(node, &relay_session::session_n); DBG("Session find by ID %" PRIu64 " id found", id); if (!session_get(session)) { - session = NULL; + session = nullptr; } end: - rcu_read_unlock(); return session; } @@ -501,58 +498,60 @@ bool session_has_ongoing_rotation(const struct relay_session *session) goto end; } - rcu_read_lock(); /* * Sample the 'ongoing_rotation' status of all relay sessions that * originate from the same session daemon session. */ - cds_lfht_for_each_entry(sessions_ht->ht, &iter.iter, iterated_session, - session_n.node) { - if (!session_get(iterated_session)) { - continue; - } - - if (session == iterated_session) { - /* Skip this session. */ - goto next_session_no_unlock; - } - - pthread_mutex_lock(&iterated_session->lock); - - if (!iterated_session->id_sessiond.is_set) { - /* - * Session belongs to a peer that doesn't support - * rotations. - */ - goto next_session; - } - - if (session->sessiond_uuid != iterated_session->sessiond_uuid) { - /* Sessions do not originate from the same sessiond. */ - goto next_session; - } - - if (LTTNG_OPTIONAL_GET(session->id_sessiond) != - LTTNG_OPTIONAL_GET(iterated_session->id_sessiond)) { - /* - * Sessions do not originate from the same sessiond - * session. - */ - goto next_session; - } - - ongoing_rotation = iterated_session->ongoing_rotation; - -next_session: - pthread_mutex_unlock(&iterated_session->lock); -next_session_no_unlock: - session_put(iterated_session); - - if (ongoing_rotation) { - break; + { + lttng::urcu::read_lock_guard read_lock; + + cds_lfht_for_each_entry ( + sessions_ht->ht, &iter.iter, iterated_session, session_n.node) { + if (!session_get(iterated_session)) { + continue; + } + + if (session == iterated_session) { + /* Skip this session. */ + goto next_session_no_unlock; + } + + pthread_mutex_lock(&iterated_session->lock); + + if (!iterated_session->id_sessiond.is_set) { + /* + * Session belongs to a peer that doesn't support + * rotations. + */ + goto next_session; + } + + if (session->sessiond_uuid != iterated_session->sessiond_uuid) { + /* Sessions do not originate from the same sessiond. */ + goto next_session; + } + + if (LTTNG_OPTIONAL_GET(session->id_sessiond) != + LTTNG_OPTIONAL_GET(iterated_session->id_sessiond)) { + /* + * Sessions do not originate from the same sessiond + * session. + */ + goto next_session; + } + + ongoing_rotation = iterated_session->ongoing_rotation; + + next_session: + pthread_mutex_unlock(&iterated_session->lock); + next_session_no_unlock: + session_put(iterated_session); + + if (ongoing_rotation) { + break; + } } } - rcu_read_unlock(); end: return ongoing_rotation; @@ -560,9 +559,7 @@ end: static void rcu_destroy_session(struct rcu_head *rcu_head) { - struct relay_session *session = - caa_container_of(rcu_head, struct relay_session, - rcu_node); + struct relay_session *session = caa_container_of(rcu_head, struct relay_session, rcu_node); /* * Since each trace has a reference on the session, it means * that if we are at the point where we teardown the session, no @@ -587,7 +584,6 @@ static int session_delete(struct relay_session *session) return lttng_ht_del(sessions_ht, &iter); } - static void destroy_session(struct relay_session *session) { int ret; @@ -595,21 +591,20 @@ static void destroy_session(struct relay_session *session) ret = session_delete(session); LTTNG_ASSERT(!ret); lttng_trace_chunk_put(session->current_trace_chunk); - session->current_trace_chunk = NULL; + session->current_trace_chunk = nullptr; lttng_trace_chunk_put(session->pending_closure_trace_chunk); - session->pending_closure_trace_chunk = NULL; - ret = sessiond_trace_chunk_registry_session_destroyed( - sessiond_trace_chunk_registry, session->sessiond_uuid); + session->pending_closure_trace_chunk = nullptr; + ret = sessiond_trace_chunk_registry_session_destroyed(sessiond_trace_chunk_registry, + session->sessiond_uuid); LTTNG_ASSERT(!ret); lttng_directory_handle_put(session->output_directory); - session->output_directory = NULL; + session->output_directory = nullptr; call_rcu(&session->rcu_node, rcu_destroy_session); } static void session_release(struct urcu_ref *ref) { - struct relay_session *session = - lttng::utils::container_of(ref, &relay_session::ref); + struct relay_session *session = lttng::utils::container_of(ref, &relay_session::ref); destroy_session(session); } @@ -619,9 +614,8 @@ void session_put(struct relay_session *session) if (!session) { return; } - rcu_read_lock(); + lttng::urcu::read_lock_guard read_lock; urcu_ref_put(&session->ref, session_release); - rcu_read_unlock(); } int session_close(struct relay_session *session) @@ -633,28 +627,33 @@ int session_close(struct relay_session *session) pthread_mutex_lock(&session->lock); DBG("closing session %" PRIu64 ": is conn already closed %d", - session->id, session->connection_closed); + session->id, + session->connection_closed); session->connection_closed = true; pthread_mutex_unlock(&session->lock); - rcu_read_lock(); - cds_lfht_for_each_entry(session->ctf_traces_ht->ht, - &iter.iter, trace, node.node) { - ret = ctf_trace_close(trace); - if (ret) { - goto rcu_unlock; + { + lttng::urcu::read_lock_guard read_lock; + + cds_lfht_for_each_entry (session->ctf_traces_ht->ht, &iter.iter, trace, node.node) { + ret = ctf_trace_close(trace); + if (ret) { + goto end; + } + } + + cds_list_for_each_entry_rcu(stream, &session->recv_list, recv_node) + { + /* Close streams which have not been published yet. */ + try_stream_close(stream); } } - cds_list_for_each_entry_rcu(stream, &session->recv_list, - recv_node) { - /* Close streams which have not been published yet. */ - try_stream_close(stream); - } -rcu_unlock: - rcu_read_unlock(); + +end: if (ret) { return ret; } + /* Put self-reference from create. */ session_put(session); return ret; @@ -675,7 +674,7 @@ int session_abort(struct relay_session *session) return ret; } -void print_sessions(void) +void print_sessions() { struct lttng_ht_iter iter; struct relay_session *session; @@ -684,17 +683,18 @@ void print_sessions(void) return; } - rcu_read_lock(); - cds_lfht_for_each_entry(sessions_ht->ht, &iter.iter, session, - session_n.node) { - if (!session_get(session)) { - continue; + { + lttng::urcu::read_lock_guard read_lock; + + cds_lfht_for_each_entry (sessions_ht->ht, &iter.iter, session, session_n.node) { + if (!session_get(session)) { + continue; + } + DBG("session %p refcount %ld session %" PRIu64, + session, + session->ref.refcount, + session->id); + session_put(session); } - DBG("session %p refcount %ld session %" PRIu64, - session, - session->ref.refcount, - session->id); - session_put(session); } - rcu_read_unlock(); }