sessiond: cmd_rotate_session: introduce command argument
[lttng-tools.git] / src / bin / lttng-sessiond / cmd.c
index e067cb835e1a2739dfa35f83ce32a3d3c59b586a..7af855eacb14e13b204730cdd2848f888c3bc352 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:
@@ -1260,7 +1276,7 @@ error:
 /*
  * Start a kernel session by opening all necessary streams.
  */
-static int start_kernel_session(struct ltt_kernel_session *ksess)
+int start_kernel_session(struct ltt_kernel_session *ksess)
 {
        int ret;
        struct ltt_kernel_channel *kchan;
@@ -1322,6 +1338,53 @@ error:
        return ret;
 }
 
+int stop_kernel_session(struct ltt_kernel_session *ksess)
+{
+       struct ltt_kernel_channel *kchan;
+       bool error_occurred = false;
+       int ret;
+
+       if (!ksess || !ksess->active) {
+               return LTTNG_OK;
+       }
+       DBG("Stopping kernel tracing");
+
+       ret = kernel_stop_session(ksess);
+       if (ret < 0) {
+               ret = LTTNG_ERR_KERN_STOP_FAIL;
+               goto error;
+       }
+
+       kernel_wait_quiescent();
+
+       /* Flush metadata after stopping (if exists) */
+       if (ksess->metadata_stream_fd >= 0) {
+               ret = kernel_metadata_flush_buffer(ksess->metadata_stream_fd);
+               if (ret < 0) {
+                       ERR("Kernel metadata flush failed");
+                       error_occurred = true;
+               }
+       }
+
+       /* Flush all buffers after stopping */
+       cds_list_for_each_entry(kchan, &ksess->channel_list.head, list) {
+               ret = kernel_flush_buffer(kchan);
+               if (ret < 0) {
+                       ERR("Kernel flush buffer error");
+                       error_occurred = true;
+               }
+       }
+
+       ksess->active = 0;
+       if (error_occurred) {
+               ret = LTTNG_ERR_UNK;
+       } else {
+               ret = LTTNG_OK;
+       }
+error:
+       return ret;
+}
+
 /*
  * Command LTTNG_DISABLE_CHANNEL processed by the client thread.
  */
@@ -2652,7 +2715,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;
                        }
@@ -2716,14 +2780,12 @@ error:
 int cmd_stop_trace(struct ltt_session *session)
 {
        int ret;
-       struct ltt_kernel_channel *kchan;
        struct ltt_kernel_session *ksession;
        struct ltt_ust_session *usess;
-       bool error_occurred = false;
 
        assert(session);
 
-       DBG("Begin stop session %s (id %" PRIu64 ")", session->name, session->id);
+       DBG("Begin stop session \"%s\" (id %" PRIu64 ")", session->name, session->id);
        /* Short cut */
        ksession = session->kernel_session;
        usess = session->ust_session;
@@ -2734,39 +2796,9 @@ int cmd_stop_trace(struct ltt_session *session)
                goto error;
        }
 
-       /* Kernel tracer */
-       if (ksession && ksession->active) {
-               DBG("Stop kernel tracing");
-
-               ret = kernel_stop_session(ksession);
-               if (ret < 0) {
-                       ret = LTTNG_ERR_KERN_STOP_FAIL;
-                       goto error;
-               }
-
-               kernel_wait_quiescent();
-
-               /* Flush metadata after stopping (if exists) */
-               if (ksession->metadata_stream_fd >= 0) {
-                       ret = kernel_metadata_flush_buffer(ksession->metadata_stream_fd);
-                       if (ret < 0) {
-                               ERR("Kernel metadata flush failed");
-                               error_occurred = true;
-                       }
-               }
-
-               /* Flush all buffers after stopping */
-               cds_list_for_each_entry(kchan, &ksession->channel_list.head, list) {
-                       ret = kernel_flush_buffer(kchan);
-                       if (ret < 0) {
-                               ERR("Kernel flush buffer error");
-                               error_occurred = true;
-                       }
-               }
-
-               ksession->active = 0;
-               DBG("Kernel session stopped %s (id %" PRIu64 ")", session->name,
-                               session->id);
+       ret = stop_kernel_session(ksession);
+       if (ret != LTTNG_OK) {
+               goto error;
        }
 
        if (usess && usess->active) {
@@ -2777,9 +2809,11 @@ int cmd_stop_trace(struct ltt_session *session)
                }
        }
 
+       DBG("Completed stop session \"%s\" (id %" PRIu64 ")", session->name,
+                       session->id);
        /* Flag inactive after a successful stop. */
        session->active = 0;
-       ret = !error_occurred ? LTTNG_OK : LTTNG_ERR_UNK;
+       ret = LTTNG_OK;
 
 error:
        return ret;
@@ -3296,7 +3330,8 @@ int cmd_destroy_session(struct ltt_session *session,
                 * 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));
@@ -3315,7 +3350,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));
@@ -4674,8 +4710,8 @@ enum lttng_error_code snapshot_record(struct ltt_session *session,
                }
        }
 
-       if (session_close_trace_chunk(
-                           session, session->current_trace_chunk, NULL, NULL)) {
+       if (session_close_trace_chunk(session, session->current_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.
@@ -4869,7 +4905,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;
@@ -4907,6 +4944,12 @@ int cmd_rotate_session(struct ltt_session *session,
                goto end;
        }
 
+       /* Unsupported feature in lttng-modules before 2.8 (lack of sequence number). */
+       if (session->kernel_session && !kernel_supports_ring_buffer_packet_sequence_number()) {
+               cmd_ret = LTTNG_ERR_ROTATION_NOT_AVAILABLE_KERNEL;
+               goto end;
+       }
+
        if (session->rotation_state == LTTNG_ROTATION_STATE_ONGOING) {
                DBG("Refusing to launch a rotation; a rotation is already in progress for session %s",
                                session->name);
@@ -4983,11 +5026,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.026802 seconds and 4 git commands to generate.