X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=50bacf0c236dc3ea4917a6f4100a80aa39b98623;hp=545269525ccb73c909d73cba1fcda1ff306496b1;hb=d5a1b7aa06b4c924b1cd30623758343c74ecab5c;hpb=9402c5b93a3e3344612a9938878bddb1430a3418 diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 545269525..50bacf0c2 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -4521,27 +4521,33 @@ int cmd_set_session_shm_path(struct ltt_session *session, * Ask the consumer to rotate the session output directory. * The session lock must be held. * - * Return LTTNG_OK on success or else a LTTNG_ERR code. + * Returns LTTNG_OK on success or else a negative LTTng error code. */ int cmd_rotate_session(struct ltt_session *session, struct lttng_rotate_session_return *rotate_return) { int ret; + enum lttng_error_code cmd_ret = LTTNG_OK; size_t strf_ret; struct tm *timeinfo; char datetime[21]; time_t now; + /* + * Used to roll-back timestamps in case of failure to launch the + * rotation. + */ + time_t original_last_chunk_start_ts, original_current_chunk_start_ts; assert(session); if (!session->has_been_started) { - ret = -LTTNG_ERR_START_SESSION_ONCE; + cmd_ret = LTTNG_ERR_START_SESSION_ONCE; goto end; } if (session->live_timer || session->snapshot_mode || !session->output_traces) { - ret = -LTTNG_ERR_ROTATION_NOT_AVAILABLE; + cmd_ret = LTTNG_ERR_ROTATION_NOT_AVAILABLE; goto end; } @@ -4551,14 +4557,14 @@ int cmd_rotate_session(struct ltt_session *session, if (session->consumer->type == CONSUMER_DST_NET && (session->consumer->relay_major_version == 2 && session->consumer->relay_minor_version < 11)) { - ret = -LTTNG_ERR_ROTATION_NOT_AVAILABLE_RELAY; + cmd_ret = LTTNG_ERR_ROTATION_NOT_AVAILABLE_RELAY; goto end; } if (session->rotation_state == LTTNG_ROTATION_STATE_ONGOING) { - ret = -LTTNG_ERR_ROTATION_PENDING; DBG("Refusing to launch a rotation; a rotation is already in progress for session %s", session->name); + cmd_ret = LTTNG_ERR_ROTATION_PENDING; goto end; } @@ -4569,7 +4575,7 @@ int cmd_rotate_session(struct ltt_session *session, if (session->rotated_after_last_stop) { DBG("Session \"%s\" was already rotated after stop, refusing rotation", session->name); - ret = -LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP; + cmd_ret = LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP; goto end; } @@ -4587,7 +4593,7 @@ int cmd_rotate_session(struct ltt_session *session, sizeof(session->rotation_chunk.current_rotate_path)); if (ret) { ERR("Failed to copy session base path to current rotation chunk path"); - ret = -LTTNG_ERR_UNK; + cmd_ret = LTTNG_ERR_UNK; goto end; } } else { @@ -4600,7 +4606,7 @@ int cmd_rotate_session(struct ltt_session *session, sizeof(session->rotation_chunk.current_rotate_path)); if (ret) { ERR("Failed to copy the active tracing path to the current rotate path"); - ret = -LTTNG_ERR_UNK; + cmd_ret = LTTNG_ERR_UNK; goto end; } } @@ -4611,45 +4617,43 @@ int cmd_rotate_session(struct ltt_session *session, * archive id. */ session->current_archive_id++; - /* - * A rotation has a local step even if the destination is a relay - * daemon; the buffers must be consumed by the consumer daemon. - */ - session->rotation_pending_local = true; - session->rotation_pending_relay = - session_get_consumer_destination_type(session) == CONSUMER_DST_NET; - session->rotation_state = LTTNG_ROTATION_STATE_ONGOING; - ret = notification_thread_command_session_rotation_ongoing( - notification_thread_handle, - session->name, session->uid, session->gid, - session->current_archive_id - 1); - if (ret != LTTNG_OK) { - ERR("Failed to notify notification thread that a session rotation is ongoing for session %s", - session->name); - } - /* Create the path name for the next chunk. */ now = time(NULL); if (now == (time_t) -1) { - ret = -LTTNG_ERR_ROTATION_NOT_AVAILABLE; + cmd_ret = LTTNG_ERR_ROTATION_NOT_AVAILABLE; goto end; } + + /* Sample chunk bounds for roll-back in case of error. */ + original_last_chunk_start_ts = session->last_chunk_start_ts; + original_current_chunk_start_ts = session->current_chunk_start_ts; + session->last_chunk_start_ts = session->current_chunk_start_ts; session->current_chunk_start_ts = now; timeinfo = localtime(&now); if (!timeinfo) { PERROR("Failed to sample local time in rotate session command"); - ret = -LTTNG_ERR_UNK; + cmd_ret = LTTNG_ERR_UNK; goto end; } strf_ret = strftime(datetime, sizeof(datetime), "%Y%m%dT%H%M%S%z", timeinfo); if (!strf_ret) { ERR("Failed to format local time timestamp in rotate session command"); - ret = -LTTNG_ERR_UNK; + cmd_ret = LTTNG_ERR_UNK; goto end; } + + /* + * A rotation has a local step even if the destination is a relay + * daemon; the buffers must be consumed by the consumer daemon. + */ + session->rotation_pending_local = true; + session->rotation_pending_relay = + session_get_consumer_destination_type(session) == CONSUMER_DST_NET; + session->rotation_state = LTTNG_ROTATION_STATE_ONGOING; + if (session->kernel_session) { /* * The active path for the next rotation/destroy. @@ -4662,8 +4666,8 @@ int cmd_rotate_session(struct ltt_session *session, datetime, session->current_archive_id + 1); if (ret < 0 || ret == sizeof(session->rotation_chunk.active_tracing_path)) { ERR("Failed to format active kernel tracing path in rotate session command"); - ret = -LTTNG_ERR_UNK; - goto end; + cmd_ret = LTTNG_ERR_UNK; + goto error; } /* * The sub-directory for the consumer @@ -4675,8 +4679,8 @@ int cmd_rotate_session(struct ltt_session *session, session->current_archive_id + 1); if (ret < 0 || ret == sizeof(session->kernel_session->consumer->chunk_path)) { ERR("Failed to format the kernel consumer's sub-directory in rotate session command"); - ret = -LTTNG_ERR_UNK; - goto end; + cmd_ret = LTTNG_ERR_UNK; + goto error; } /* * Create the new chunk folder, before the rotation begins so we don't @@ -4688,13 +4692,12 @@ int cmd_rotate_session(struct ltt_session *session, if (ret) { ERR("Failed to create kernel session tracing path at %s", session->kernel_session->consumer->chunk_path); - ret = -LTTNG_ERR_CREATE_DIR_FAIL; - goto end; + cmd_ret = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; } - ret = kernel_rotate_session(session); - if (ret != LTTNG_OK) { - ret = -ret; - goto end; + cmd_ret = kernel_rotate_session(session); + if (cmd_ret != LTTNG_OK) { + goto error; } } if (session->ust_session) { @@ -4704,16 +4707,16 @@ int cmd_rotate_session(struct ltt_session *session, datetime, session->current_archive_id + 1); if (ret < 0) { ERR("Failed to format active UST tracing path in rotate session command"); - ret = -LTTNG_ERR_UNK; - goto end; + cmd_ret = LTTNG_ERR_UNK; + goto error; } ret = snprintf(session->ust_session->consumer->chunk_path, PATH_MAX, "/%s-%" PRIu64, datetime, session->current_archive_id + 1); if (ret < 0) { ERR("Failed to format the UST consumer's sub-directory in rotate session command"); - ret = -LTTNG_ERR_UNK; - goto end; + cmd_ret = LTTNG_ERR_UNK; + goto error; } /* * Create the new chunk folder, before the rotation begins so we don't @@ -4723,19 +4726,24 @@ int cmd_rotate_session(struct ltt_session *session, session->ust_session->uid, session->ust_session->gid); if (ret) { - ret = -LTTNG_ERR_CREATE_DIR_FAIL; - goto end; + cmd_ret = LTTNG_ERR_CREATE_DIR_FAIL; + goto error; } - ret = ust_app_rotate_session(session); - if (ret != LTTNG_OK) { - goto end; + /* + * TODO: ust_app_rotate_session must be adapted to return + * an lttng_error_code, like its kernel counterpart. + */ + cmd_ret = ust_app_rotate_session(session); + if (cmd_ret != LTTNG_OK) { + goto error; } } ret = timer_session_rotation_pending_check_start(session, DEFAULT_ROTATE_PENDING_TIMER); if (ret) { - goto end; + cmd_ret = LTTNG_ERR_UNK; + goto error; } if (!session->active) { @@ -4746,12 +4754,30 @@ int cmd_rotate_session(struct ltt_session *session, rotate_return->rotation_id = session->current_archive_id; } + ret = notification_thread_command_session_rotation_ongoing( + notification_thread_handle, + session->name, session->uid, session->gid, + session->current_archive_id - 1); + if (ret != LTTNG_OK) { + ERR("Failed to notify notification thread that a session rotation is ongoing for session %s", + session->name); + cmd_ret = ret; + } + DBG("Cmd rotate session %s, archive_id %" PRIu64 " sent", session->name, session->current_archive_id - 1); - ret = LTTNG_OK; - end: + ret = (cmd_ret == LTTNG_OK) ? cmd_ret : -((int) cmd_ret); return ret; +error: + session->last_chunk_start_ts = original_last_chunk_start_ts; + session->current_archive_id = original_current_chunk_start_ts; + if (session_reset_rotation_state(session, + LTTNG_ROTATION_STATE_NO_ROTATION)) { + ERR("Failed to reset rotation state of session \"%s\"", + session->name); + } + goto end; } /*