sessiond: snapshot: set trace chunk to NULL before closing it
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index 869215b8d920cb7d2a0bd33d22129c34024e199e..53850f74aae784b97a668f30c429c92cca8858be 100644 (file)
@@ -998,6 +998,8 @@ static enum lttng_error_code create_connect_relayd(struct lttng_uri *uri,
 
        /* Create socket for control stream. */
        if (uri->stype == LTTNG_STREAM_CONTROL) {
+               uint64_t result_flags;
+
                DBG3("Creating relayd stream socket from URI");
 
                /* Check relayd version */
@@ -1012,6 +1014,16 @@ static enum lttng_error_code create_connect_relayd(struct lttng_uri *uri,
                }
                consumer->relay_major_version = rsock->major;
                consumer->relay_minor_version = rsock->minor;
+               ret = relayd_get_configuration(rsock, 0,
+                               &result_flags);
+               if (ret < 0) {
+                       ERR("Unable to get relayd configuration");
+                       status = LTTNG_ERR_RELAYD_CONNECT_FAIL;
+                       goto close_sock;
+               }
+               if (result_flags & LTTCOMM_RELAYD_CONFIGURATION_FLAG_CLEAR_ALLOWED) {
+                       consumer->relay_allows_clear = true;
+               }
        } else if (uri->stype == LTTNG_STREAM_DATA) {
                DBG3("Creating relayd data socket from URI");
        } else {
@@ -1224,6 +1236,8 @@ int cmd_setup_relayd(struct ltt_session *session)
                        usess->consumer->relay_major_version;
                session->consumer->relay_minor_version =
                        usess->consumer->relay_minor_version;
+               session->consumer->relay_allows_clear =
+                       usess->consumer->relay_allows_clear;
        }
 
        if (ksess && ksess->consumer && ksess->consumer->type == CONSUMER_DST_NET
@@ -1250,6 +1264,8 @@ int cmd_setup_relayd(struct ltt_session *session)
                        ksess->consumer->relay_major_version;
                session->consumer->relay_minor_version =
                        ksess->consumer->relay_minor_version;
+               session->consumer->relay_allows_clear =
+                       ksess->consumer->relay_allows_clear;
        }
 
 error:
@@ -2620,6 +2636,8 @@ int cmd_start_trace(struct ltt_session *session)
        struct ltt_ust_session *usess;
        const bool session_rotated_after_last_stop =
                        session->rotated_after_last_stop;
+       const bool session_cleared_after_last_stop =
+                       session->cleared_after_last_stop;
 
        assert(session);
 
@@ -2666,6 +2684,7 @@ int cmd_start_trace(struct ltt_session *session)
 
        session->active = 1;
        session->rotated_after_last_stop = false;
+       session->cleared_after_last_stop = false;
        if (session->output_traces && !session->current_trace_chunk) {
                if (!session->has_been_started) {
                        struct lttng_trace_chunk *trace_chunk;
@@ -2699,7 +2718,8 @@ int cmd_start_trace(struct ltt_session *session)
                         * was produced as the session was stopped, so the
                         * rotation should happen on reception of the command.
                         */
-                       ret = cmd_rotate_session(session, NULL, true);
+                       ret = cmd_rotate_session(session, NULL, true,
+                                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION);
                        if (ret != LTTNG_OK) {
                                goto error;
                        }
@@ -2753,6 +2773,8 @@ error:
                /* Restore initial state on error. */
                session->rotated_after_last_stop =
                                session_rotated_after_last_stop;
+               session->cleared_after_last_stop =
+                               session_cleared_after_last_stop;
        }
        return ret;
 }
@@ -3306,14 +3328,13 @@ int cmd_destroy_session(struct ltt_session *session,
                session->rotate_size = 0;
        }
 
-       if (session->most_recent_chunk_id.is_set &&
-                       session->most_recent_chunk_id.value != 0 &&
-                       session->current_trace_chunk && session->output_traces) {
+       if (session->rotated && session->current_trace_chunk && session->output_traces) {
                /*
                 * Perform a last rotation on destruction if rotations have
                 * occurred during the session's lifetime.
                 */
-               ret = cmd_rotate_session(session, NULL, false);
+               ret = cmd_rotate_session(session, NULL, false,
+                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED);
                if (ret != LTTNG_OK) {
                        ERR("Failed to perform an implicit rotation as part of the destruction of session \"%s\": %s",
                                        session->name, lttng_strerror(-ret));
@@ -3332,7 +3353,8 @@ int cmd_destroy_session(struct ltt_session *session,
                 * emitted and no renaming of the current trace chunk takes
                 * place.
                 */
-               ret = cmd_rotate_session(session, NULL, true);
+               ret = cmd_rotate_session(session, NULL, true,
+                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION);
                if (ret != LTTNG_OK) {
                        ERR("Failed to perform a quiet rotation as part of the destruction of session \"%s\": %s",
                                        session->name, lttng_strerror(-ret));
@@ -4691,8 +4713,14 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                }
        }
 
-       if (session_close_trace_chunk(
-                           session, session->current_trace_chunk, NULL, NULL)) {
+       if (session_set_trace_chunk(session, NULL, &snapshot_trace_chunk)) {
+               ERR("Failed to release the current trace chunk of session \"%s\"",
+                               session->name);
+               ret_code = LTTNG_ERR_UNK;
+       }
+
+       if (session_close_trace_chunk(session, snapshot_trace_chunk,
+                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION, NULL)) {
                /*
                 * Don't goto end; make sure the chunk is closed for the session
                 * to allow future snapshots.
@@ -4701,11 +4729,6 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                                session->name);
                ret_code = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER;
        }
-       if (session_set_trace_chunk(session, NULL, NULL)) {
-               ERR("Failed to release the current trace chunk of session \"%s\"",
-                               session->name);
-               ret_code = LTTNG_ERR_UNK;
-       }
 error:
        if (original_ust_consumer_output) {
                session->ust_session->consumer = original_ust_consumer_output;
@@ -4886,7 +4909,8 @@ int cmd_set_session_shm_path(struct ltt_session *session,
  */
 int cmd_rotate_session(struct ltt_session *session,
                struct lttng_rotate_session_return *rotate_return,
-               bool quiet_rotation)
+               bool quiet_rotation,
+               enum lttng_trace_chunk_command_type command)
 {
        int ret;
        uint64_t ongoing_rotation_chunk_id;
@@ -4947,6 +4971,18 @@ int cmd_rotate_session(struct ltt_session *session,
                cmd_ret = LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP;
                goto end;
        }
+
+       /*
+        * After a stop followed by a clear, disallow following rotations a they would
+        * generate empty chunks.
+        */
+       if (session->cleared_after_last_stop) {
+               DBG("Session \"%s\" was already cleared after stop, refusing rotation",
+                               session->name);
+               cmd_ret = LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR;
+               goto end;
+       }
+
        if (session->active) {
                new_trace_chunk = session_create_new_trace_chunk(session, NULL,
                                NULL, NULL);
@@ -5006,11 +5042,7 @@ int cmd_rotate_session(struct ltt_session *session,
        assert(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK);
 
        ret = session_close_trace_chunk(session, chunk_being_archived,
-                       quiet_rotation ?
-                                       NULL :
-                                       &((enum lttng_trace_chunk_command_type){
-                                                       LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED}),
-                       session->last_chunk_path);
+               command, session->last_chunk_path);
        if (ret) {
                cmd_ret = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER;
                goto error;
This page took 0.025075 seconds and 4 git commands to generate.