relayd: share the same output directory handle accross sessions
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 20 Dec 2019 06:41:37 +0000 (01:41 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 30 Jan 2020 06:55:34 +0000 (01:55 -0500)
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 <jeremie.galarneau@efficios.com>
Change-Id: I47e46ee253db646da1490380612def741c2f4102

src/bin/lttng-relayd/main.c
src/bin/lttng-relayd/session.c
src/bin/lttng-relayd/session.h
src/common/trace-chunk.c
src/common/trace-chunk.h

index 62e1cf9309e4355c7b6e892fc999a20c665557a9..25a32a70b7b8488435474461e7a92ea9b161bf73 100644 (file)
@@ -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_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) {
        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;
        }
 
                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;
        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);
 end_no_reply:
        lttng_trace_chunk_put(chunk);
        lttng_trace_chunk_put(published_chunk);
-       lttng_directory_handle_put(session_output);
        return ret;
 }
 
        return ret;
 }
 
index 1a1cadfdfa1ba3829efe46f217b014fa4983e511..d838385210389642950213d8fe5b68a47a586a97 100644 (file)
@@ -181,6 +181,38 @@ static int init_session_output_path(struct relay_session *session)
        return ret;
 }
 
        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;
 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) {
        }
 
        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,
                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;
                 }
                                        *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
        } 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;
                }
                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);
        }
 
        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);
        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);
 }
 
        call_rcu(&session->rcu_node, rcu_destroy_session);
 }
 
@@ -562,35 +615,3 @@ void print_sessions(void)
        }
        rcu_read_unlock();
 }
        }
        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;
-}
index 43f76a4aad54eadc7ac3e53f311bab00a748653b..fa48d0974b57eb0580dbf28e75e5dd0bcc30863e 100644 (file)
@@ -139,6 +139,7 @@ struct relay_session {
         * while new chunk has a temporary directory name.
         */
        bool ongoing_rotation;
         * 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. */
 };
 
        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);
 
 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 */
 void print_sessions(void);
 
 #endif /* _SESSION_H */
index cd81909ffc70ee6a36e464ae2d134e2dfbdd9cc9..7407f38f391ce60351d9746bfa0813a2429679be 100644 (file)
@@ -983,6 +983,31 @@ end:
        return status;
 }
 
        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,
 LTTNG_HIDDEN
 enum lttng_trace_chunk_status lttng_trace_chunk_borrow_chunk_directory_handle(
                struct lttng_trace_chunk *chunk,
index c2fcd17e96059dc4ba584d3baa39ce23ae5e735f..0f3dc678bfedcc92225069b0282d04035c19b51d 100644 (file)
@@ -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);
 
                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,
 LTTNG_HIDDEN
 enum lttng_trace_chunk_status lttng_trace_chunk_borrow_chunk_directory_handle(
                struct lttng_trace_chunk *chunk,
This page took 0.039474 seconds and 5 git commands to generate.