X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=02a92be1e07e45ba71e4c767ebca0f6a18050ec9;hp=be493fd8a5527f7795446592016c44f47eaa6d09;hb=a40a503f4218296700d791f1b79671bf3d0f1e22;hpb=433f5ba9ca8e445c979b49703ac195f77a94c684 diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index be493fd8a..02a92be1e 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -1185,6 +1185,7 @@ int cmd_setup_relayd(struct ltt_session *session) DBG("Setting relayd for session %s", session->name); + rcu_read_lock(); if (session->current_trace_chunk) { enum lttng_trace_chunk_status status = lttng_trace_chunk_get_id( session->current_trace_chunk, ¤t_chunk_id.value); @@ -1198,8 +1199,6 @@ int cmd_setup_relayd(struct ltt_session *session) } } - rcu_read_lock(); - if (usess && usess->consumer && usess->consumer->type == CONSUMER_DST_NET && usess->consumer->enabled) { /* For each consumer socket, send relayd sockets */ @@ -2572,6 +2571,8 @@ int cmd_start_trace(struct ltt_session *session) unsigned long nb_chan = 0; struct ltt_kernel_session *ksession; struct ltt_ust_session *usess; + const bool session_rotated_after_last_stop = + session->rotated_after_last_stop; assert(session); @@ -2585,6 +2586,22 @@ int cmd_start_trace(struct ltt_session *session) goto error; } + if (session->rotation_state == LTTNG_ROTATION_STATE_ONGOING && + !session->current_trace_chunk) { + /* + * A rotation was launched while the session was stopped and + * it has not been completed yet. It is not possible to start + * the session since starting the session here would require a + * rotation from "NULL" to a new trace chunk. That rotation + * would overlap with the ongoing rotation, which is not + * supported. + */ + WARN("Refusing to start session \"%s\" as a rotation launched after the last \"stop\" is still ongoing", + session->name); + ret = LTTNG_ERR_ROTATION_PENDING; + goto error; + } + /* * Starting a session without channel is useless since after that it's not * possible to enable channel thus inform the client. @@ -2600,21 +2617,45 @@ int cmd_start_trace(struct ltt_session *session) goto error; } + session->active = 1; + session->rotated_after_last_stop = false; if (session->output_traces && !session->current_trace_chunk) { - struct lttng_trace_chunk *trace_chunk; + if (!session->has_been_started) { + struct lttng_trace_chunk *trace_chunk; - trace_chunk = session_create_new_trace_chunk( - session, NULL, NULL, NULL); - if (!trace_chunk) { - ret = LTTNG_ERR_CREATE_DIR_FAIL; - goto error; - } - assert(!session->current_trace_chunk); - ret = session_set_trace_chunk(session, trace_chunk, NULL); - lttng_trace_chunk_put(trace_chunk); - if (ret) { - ret = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER; - goto error; + DBG("Creating initial trace chunk of session \"%s\"", + session->name); + trace_chunk = session_create_new_trace_chunk( + session, NULL, NULL, NULL); + if (!trace_chunk) { + ret = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; + } + assert(!session->current_trace_chunk); + ret = session_set_trace_chunk(session, trace_chunk, + NULL); + lttng_trace_chunk_put(trace_chunk); + if (ret) { + ret = LTTNG_ERR_CREATE_TRACE_CHUNK_FAIL_CONSUMER; + goto error; + } + } else { + DBG("Rotating session \"%s\" from its current \"NULL\" trace chunk to a new chunk", + session->name); + /* + * Rotate existing streams into the new chunk. + * This is a "quiet" rotation has no client has + * explicitly requested this operation. + * + * There is also no need to wait for the rotation + * to complete as it will happen immediately. No data + * was produced as the session was stopped, so the + * rotation should happen on reception of the command. + */ + ret = cmd_rotate_session(session, NULL, true); + if (ret != LTTNG_OK) { + goto error; + } } } @@ -2637,10 +2678,6 @@ int cmd_start_trace(struct ltt_session *session) } } - /* Flag this after a successful start. */ - session->has_been_started = 1; - session->active = 1; - /* * Clear the flag that indicates that a rotation was done while the * session was stopped. @@ -2661,6 +2698,15 @@ int cmd_start_trace(struct ltt_session *session) ret = LTTNG_OK; error: + if (ret == LTTNG_OK) { + /* Flag this after a successful start. */ + session->has_been_started |= 1; + } else { + session->active = 0; + /* Restore initial state on error. */ + session->rotated_after_last_stop = + session_rotated_after_last_stop; + } return ret; } @@ -4861,6 +4907,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); @@ -4878,9 +4930,6 @@ int cmd_rotate_session(struct ltt_session *session, cmd_ret = LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP; goto end; } - - session->rotation_state = LTTNG_ROTATION_STATE_ONGOING; - if (session->active) { new_trace_chunk = session_create_new_trace_chunk(session, NULL, NULL, NULL); @@ -4904,11 +4953,6 @@ int cmd_rotate_session(struct ltt_session *session, goto error; } - assert(chunk_being_archived); - chunk_status = lttng_trace_chunk_get_id(chunk_being_archived, - &ongoing_rotation_chunk_id); - assert(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK); - if (session->kernel_session) { cmd_ret = kernel_rotate_session(session); if (cmd_ret != LTTNG_OK) { @@ -4924,6 +4968,26 @@ int cmd_rotate_session(struct ltt_session *session, } } + if (!session->active) { + session->rotated_after_last_stop = true; + } + + if (!chunk_being_archived) { + DBG("Rotating session \"%s\" from a \"NULL\" trace chunk to a new trace chunk, skipping completion check", + session->name); + if (failed_to_rotate) { + cmd_ret = rotation_fail_code; + goto error; + } + cmd_ret = LTTNG_OK; + goto end; + } + + session->rotation_state = LTTNG_ROTATION_STATE_ONGOING; + chunk_status = lttng_trace_chunk_get_id(chunk_being_archived, + &ongoing_rotation_chunk_id); + assert(chunk_status == LTTNG_TRACE_CHUNK_STATUS_OK); + ret = session_close_trace_chunk(session, chunk_being_archived, quiet_rotation ? NULL : @@ -4948,10 +5012,6 @@ int cmd_rotate_session(struct ltt_session *session, goto error; } - if (!session->active) { - session->rotated_after_last_stop = true; - } - if (rotate_return) { rotate_return->rotation_id = ongoing_rotation_chunk_id; }