Fix: leak of consumer_output when using an explicit snapshot output
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index d26d8de0bf661b7714914645558edcb2922e2f1d..b76941648bd50d4a8ddafa6bc2afa8460b8e74b5 100644 (file)
@@ -1039,7 +1039,8 @@ static enum lttng_error_code send_consumer_relayd_socket(
                struct consumer_socket *consumer_sock,
                const char *session_name, const char *hostname,
                int session_live_timer,
-               const uint64_t *current_chunk_id)
+               const uint64_t *current_chunk_id,
+               time_t session_creation_time)
 {
        int ret;
        struct lttcomm_relayd_sock *rsock = NULL;
@@ -1068,7 +1069,7 @@ static enum lttng_error_code send_consumer_relayd_socket(
        ret = consumer_send_relayd_socket(consumer_sock, rsock, consumer,
                        relayd_uri->stype, session_id,
                        session_name, hostname, session_live_timer,
-                       current_chunk_id);
+                       current_chunk_id, session_creation_time);
        if (ret < 0) {
                status = LTTNG_ERR_ENABLE_CONSUMER_FAIL;
                goto close_sock;
@@ -1116,7 +1117,7 @@ static enum lttng_error_code send_consumer_relayd_sockets(
                unsigned int session_id, struct consumer_output *consumer,
                struct consumer_socket *sock, const char *session_name,
                const char *hostname, int session_live_timer,
-               const uint64_t *current_chunk_id)
+               const uint64_t *current_chunk_id, time_t session_creation_time)
 {
        enum lttng_error_code status = LTTNG_OK;
 
@@ -1128,7 +1129,7 @@ static enum lttng_error_code send_consumer_relayd_sockets(
                status = send_consumer_relayd_socket(session_id,
                                &consumer->dst.net.control, consumer, sock,
                                session_name, hostname, session_live_timer,
-                               current_chunk_id);
+                               current_chunk_id, session_creation_time);
                if (status != LTTNG_OK) {
                        goto error;
                }
@@ -1139,7 +1140,7 @@ static enum lttng_error_code send_consumer_relayd_sockets(
                status = send_consumer_relayd_socket(session_id,
                                &consumer->dst.net.data, consumer, sock,
                                session_name, hostname, session_live_timer,
-                               current_chunk_id);
+                               current_chunk_id, session_creation_time);
                if (status != LTTNG_OK) {
                        goto error;
                }
@@ -1195,7 +1196,8 @@ int cmd_setup_relayd(struct ltt_session *session)
                                        usess->consumer, socket,
                                        session->name, session->hostname,
                                        session->live_timer,
-                                       current_chunk_id.is_set ? &current_chunk_id.value : NULL);
+                                       current_chunk_id.is_set ? &current_chunk_id.value : NULL,
+                                       session->creation_time);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
                                goto error;
@@ -1218,7 +1220,8 @@ int cmd_setup_relayd(struct ltt_session *session)
                                        ksess->consumer, socket,
                                        session->name, session->hostname,
                                        session->live_timer,
-                                       current_chunk_id.is_set ? &current_chunk_id.value : NULL);
+                                       current_chunk_id.is_set ? &current_chunk_id.value : NULL,
+                                       session->creation_time);
                        pthread_mutex_unlock(socket->lock);
                        if (ret != LTTNG_OK) {
                                goto error;
@@ -4243,7 +4246,8 @@ static enum lttng_error_code set_relayd_for_snapshot(
                                snap_output->consumer, socket,
                                session->name, session->hostname,
                                session->live_timer,
-                               current_chunk_id.is_set ? &current_chunk_id.value : NULL);
+                               current_chunk_id.is_set ? &current_chunk_id.value : NULL,
+                               session->creation_time);
                pthread_mutex_unlock(socket->lock);
                if (status != LTTNG_OK) {
                        rcu_read_unlock();
@@ -4504,7 +4508,8 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                }
        }
 
-       if (session_close_trace_chunk(session, session->current_trace_chunk)) {
+       if (session_close_trace_chunk(
+                           session, session->current_trace_chunk, NULL)) {
                /*
                 * Don't goto end; make sure the chunk is closed for the session
                 * to allow future snapshots.
@@ -4535,10 +4540,9 @@ int cmd_snapshot_record(struct ltt_session *session,
 {
        enum lttng_error_code cmd_ret = LTTNG_OK;
        int ret;
-       unsigned int use_tmp_output = 0;
-       struct snapshot_output tmp_output;
        unsigned int snapshot_success = 0;
        char datetime[16];
+       struct snapshot_output *tmp_output = NULL;
 
        assert(session);
        assert(output);
@@ -4570,11 +4574,17 @@ int cmd_snapshot_record(struct ltt_session *session,
 
        /* Use temporary output for the session. */
        if (*output->ctrl_url != '\0') {
+               tmp_output = snapshot_output_alloc();
+               if (!tmp_output) {
+                       cmd_ret = LTTNG_ERR_NOMEM;
+                       goto error;
+               }
+
                ret = snapshot_output_init(session, output->max_size,
                                output->name,
                                output->ctrl_url, output->data_url,
                                session->consumer,
-                               &tmp_output, NULL);
+                               tmp_output, NULL);
                if (ret < 0) {
                        if (ret == -ENOMEM) {
                                cmd_ret = LTTNG_ERR_NOMEM;
@@ -4584,15 +4594,11 @@ int cmd_snapshot_record(struct ltt_session *session,
                        goto error;
                }
                /* Use the global session count for the temporary snapshot. */
-               tmp_output.nb_snapshot = session->snapshot.nb_snapshot;
+               tmp_output->nb_snapshot = session->snapshot.nb_snapshot;
 
                /* Use the global datetime */
-               memcpy(tmp_output.datetime, datetime, sizeof(datetime));
-               use_tmp_output = 1;
-       }
-
-       if (use_tmp_output) {
-               cmd_ret = snapshot_record(session, &tmp_output, wait);
+               memcpy(tmp_output->datetime, datetime, sizeof(datetime));
+               cmd_ret = snapshot_record(session, tmp_output, wait);
                if (cmd_ret != LTTNG_OK) {
                        goto error;
                }
@@ -4604,30 +4610,35 @@ int cmd_snapshot_record(struct ltt_session *session,
                rcu_read_lock();
                cds_lfht_for_each_entry(session->snapshot.output_ht->ht,
                                &iter.iter, sout, node.node) {
+                       struct snapshot_output output_copy;
+
                        /*
-                        * Make a local copy of the output and assign the
-                        * possible temporary value given by the caller.
+                        * Make a local copy of the output and override output
+                        * parameters with those provided as part of the
+                        * command.
                         */
-                       memcpy(&tmp_output, sout, sizeof(tmp_output));
+                       memcpy(&output_copy, sout, sizeof(output_copy));
 
                        if (output->max_size != (uint64_t) -1ULL) {
-                               tmp_output.max_size = output->max_size;
+                               output_copy.max_size = output->max_size;
                        }
 
-                       tmp_output.nb_snapshot = session->snapshot.nb_snapshot;
-                       memcpy(tmp_output.datetime, datetime, sizeof(datetime));
+                       output_copy.nb_snapshot = session->snapshot.nb_snapshot;
+                       memcpy(output_copy.datetime, datetime,
+                                       sizeof(datetime));
 
                        /* Use temporary name. */
                        if (*output->name != '\0') {
-                               if (lttng_strncpy(tmp_output.name, output->name,
-                                               sizeof(tmp_output.name))) {
+                               if (lttng_strncpy(output_copy.name,
+                                               output->name,
+                                               sizeof(output_copy.name))) {
                                        cmd_ret = LTTNG_ERR_INVALID;
                                        rcu_read_unlock();
                                        goto error;
                                }
                        }
 
-                       cmd_ret = snapshot_record(session, &tmp_output, wait);
+                       cmd_ret = snapshot_record(session, &output_copy, wait);
                        if (cmd_ret != LTTNG_OK) {
                                rcu_read_unlock();
                                goto error;
@@ -4644,6 +4655,9 @@ int cmd_snapshot_record(struct ltt_session *session,
        }
 
 error:
+       if (tmp_output) {
+               snapshot_output_destroy(tmp_output);
+       }
        return cmd_ret;
 }
 
@@ -4750,14 +4764,6 @@ int cmd_rotate_session(struct ltt_session *session,
                        &ongoing_rotation_chunk_id);
        assert(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
 
-       chunk_status = lttng_trace_chunk_set_close_command(
-                       chunk_being_archived,
-                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
-       if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) {
-               cmd_ret = LTTNG_ERR_FATAL;
-               goto error;
-       }
-
        if (session->kernel_session) {
                cmd_ret = kernel_rotate_session(session);
                if (cmd_ret != LTTNG_OK) {
@@ -4771,7 +4777,9 @@ int cmd_rotate_session(struct ltt_session *session,
                }
        }
 
-       ret = session_close_trace_chunk(session, chunk_being_archived);
+       ret = session_close_trace_chunk(session, chunk_being_archived,
+                       &((enum lttng_trace_chunk_command_type) {
+                                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED}));
        if (ret) {
                cmd_ret = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER;
                goto error;
This page took 0.028807 seconds and 4 git commands to generate.