From: Jérémie Galarneau Date: Fri, 20 Dec 2019 06:41:37 +0000 (-0500) Subject: relayd: share the same output directory handle accross sessions X-Git-Tag: v2.12.0-rc1~45 X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=7ceefac4c8474606312e25ab822e510c41a3d644;p=lttng-tools.git relayd: share the same output directory handle accross sessions Now that lttng_directory_handles are reference counted, they can be shared by multiple sessions and trace chunks. These modifications cause sessions that share a trace chunk to share their session output directory handle. Moreover, the session output directory handle is now created on session creation. Hence, a directory handle (fd) is not created everytime a trace chunk is created. The goal of this modification is to make it easier to track file descriptors in the relay daemon, but it is also more efficient overall (less opening of file descriptors) and will error-out during the creation of a session rather than a trace chunk which is handled more gracefully accross the toolchain. Signed-off-by: Jérémie Galarneau Change-Id: I47e46ee253db646da1490380612def741c2f4102 --- diff --git a/src/bin/lttng-relayd/main.c b/src/bin/lttng-relayd/main.c index 62e1cf930..25a32a70b 100644 --- a/src/bin/lttng-relayd/main.c +++ b/src/bin/lttng-relayd/main.c @@ -2632,7 +2632,6 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, struct lttng_trace_chunk *chunk = NULL, *published_chunk = NULL; enum lttng_error_code reply_code = LTTNG_OK; enum lttng_trace_chunk_status chunk_status; - struct lttng_directory_handle *session_output = NULL; const char *new_path; if (!session || !conn->version_check_done) { @@ -2729,15 +2728,9 @@ static int relay_create_trace_chunk(const struct lttcomm_relayd_hdr *recv_hdr, goto end; } - session_output = session_create_output_directory_handle( - conn->session); - if (!session_output) { - reply_code = LTTNG_ERR_CREATE_DIR_FAIL; - goto end; - } - chunk_status = lttng_trace_chunk_set_as_owner(chunk, session_output); - lttng_directory_handle_put(session_output); - session_output = NULL; + assert(conn->session->output_directory); + chunk_status = lttng_trace_chunk_set_as_owner(chunk, + conn->session->output_directory); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { reply_code = LTTNG_ERR_UNK; ret = -1; @@ -2796,7 +2789,6 @@ end: end_no_reply: lttng_trace_chunk_put(chunk); lttng_trace_chunk_put(published_chunk); - lttng_directory_handle_put(session_output); return ret; } diff --git a/src/bin/lttng-relayd/session.c b/src/bin/lttng-relayd/session.c index 1a1cadfdf..d83838521 100644 --- a/src/bin/lttng-relayd/session.c +++ b/src/bin/lttng-relayd/session.c @@ -181,6 +181,38 @@ 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) +{ + 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; + + pthread_mutex_lock(&session->lock); + full_session_path = create_output_path(session->output_path); + if (!full_session_path) { + goto end; + } + + 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); + goto end; + } + + handle = lttng_directory_handle_create(full_session_path); +end: + pthread_mutex_unlock(&session->lock); + free(full_session_path); + return handle; +} + static int session_set_anonymous_chunk(struct relay_session *session) { int ret = 0; @@ -353,6 +385,9 @@ struct relay_session *session_create(const char *session_name, } if (id_sessiond && current_chunk_id) { + enum lttng_trace_chunk_status chunk_status; + struct lttng_directory_handle *session_output_directory; + session->current_trace_chunk = sessiond_trace_chunk_registry_get_chunk( sessiond_trace_chunk_registry, @@ -368,6 +403,16 @@ struct relay_session *session_create(const char *session_name, *current_chunk_id); goto error; } + + chunk_status = lttng_trace_chunk_get_session_output_directory_handle( + session->current_trace_chunk, + &session_output_directory); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + goto error; + } + + assert(session_output_directory); + session->output_directory = session_output_directory; } else if (!id_sessiond) { /* * Pre-2.11 peers will not announce trace chunks. An @@ -378,6 +423,12 @@ struct relay_session *session_create(const char *session_name, if (ret) { goto error; } + } else { + session->output_directory = + session_create_output_directory_handle(session); + if (!session->output_directory) { + goto error; + } } lttng_ht_add_unique_u64(sessions_ht, &session->session_n); @@ -467,6 +518,8 @@ static void destroy_session(struct relay_session *session) ret = sessiond_trace_chunk_registry_session_destroyed( sessiond_trace_chunk_registry, session->sessiond_uuid); assert(!ret); + lttng_directory_handle_put(session->output_directory); + session->output_directory = NULL; call_rcu(&session->rcu_node, rcu_destroy_session); } @@ -562,35 +615,3 @@ void print_sessions(void) } rcu_read_unlock(); } - -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; - - pthread_mutex_lock(&session->lock); - full_session_path = create_output_path(session->output_path); - if (!full_session_path) { - goto end; - } - - 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); - goto end; - } - - handle = lttng_directory_handle_create(full_session_path); -end: - pthread_mutex_unlock(&session->lock); - free(full_session_path); - return handle; -} diff --git a/src/bin/lttng-relayd/session.h b/src/bin/lttng-relayd/session.h index 43f76a4aa..fa48d0974 100644 --- a/src/bin/lttng-relayd/session.h +++ b/src/bin/lttng-relayd/session.h @@ -139,6 +139,7 @@ struct relay_session { * while new chunk has a temporary directory name. */ bool ongoing_rotation; + struct lttng_directory_handle *output_directory; struct rcu_head rcu_node; /* For call_rcu teardown. */ }; @@ -160,9 +161,6 @@ void session_put(struct relay_session *session); int session_close(struct relay_session *session); int session_abort(struct relay_session *session); -struct lttng_directory_handle *session_create_output_directory_handle( - struct relay_session *session); - void print_sessions(void); #endif /* _SESSION_H */ diff --git a/src/common/trace-chunk.c b/src/common/trace-chunk.c index cd81909ff..7407f38f3 100644 --- a/src/common/trace-chunk.c +++ b/src/common/trace-chunk.c @@ -983,6 +983,31 @@ end: return status; } +LTTNG_HIDDEN +enum lttng_trace_chunk_status +lttng_trace_chunk_get_session_output_directory_handle( + struct lttng_trace_chunk *chunk, + struct lttng_directory_handle **handle) +{ + enum lttng_trace_chunk_status status = LTTNG_TRACE_CHUNK_STATUS_OK; + + pthread_mutex_lock(&chunk->lock); + if (!chunk->session_output_directory) { + status = LTTNG_TRACE_CHUNK_STATUS_NONE; + *handle = NULL; + goto end; + } else { + const bool reference_acquired = lttng_directory_handle_get( + chunk->session_output_directory); + + assert(reference_acquired); + *handle = chunk->session_output_directory; + } +end: + pthread_mutex_unlock(&chunk->lock); + return status; +} + LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_borrow_chunk_directory_handle( struct lttng_trace_chunk *chunk, diff --git a/src/common/trace-chunk.h b/src/common/trace-chunk.h index c2fcd17e9..0f3dc678b 100644 --- a/src/common/trace-chunk.h +++ b/src/common/trace-chunk.h @@ -152,6 +152,12 @@ enum lttng_trace_chunk_status lttng_trace_chunk_set_as_user( struct lttng_trace_chunk *chunk, struct lttng_directory_handle *chunk_directory); +LTTNG_HIDDEN +enum lttng_trace_chunk_status +lttng_trace_chunk_get_session_output_directory_handle( + struct lttng_trace_chunk *chunk, + struct lttng_directory_handle **handle); + LTTNG_HIDDEN enum lttng_trace_chunk_status lttng_trace_chunk_borrow_chunk_directory_handle( struct lttng_trace_chunk *chunk,