X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsession.c;h=88bbe1309c4a1270cbbf418a97af3d5aeee57fb5;hp=3a537e49e2179357298cb43813dfa17a6f63927d;hb=a7ceb342d473cc37e00d74c45b04b5378965e055;hpb=343defc2671db532be8a9eed84907fd2e4044f0e diff --git a/src/bin/lttng-sessiond/session.c b/src/bin/lttng-sessiond/session.c index 3a537e49e..88bbe1309 100644 --- a/src/bin/lttng-sessiond/session.c +++ b/src/bin/lttng-sessiond/session.c @@ -46,6 +46,11 @@ struct ltt_session_destroy_notifier_element { void *user_data; }; +struct ltt_session_clear_notifier_element { + ltt_session_clear_notifier notifier; + void *user_data; +}; + /* * NOTES: * @@ -584,6 +589,7 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( }; uint64_t next_chunk_id; const struct consumer_output *output; + const char *new_path; if (consumer_output_override) { output = consumer_output_override; @@ -607,8 +613,26 @@ struct lttng_trace_chunk *session_create_new_trace_chunk( next_chunk_id = session->most_recent_chunk_id.is_set ? session->most_recent_chunk_id.value + 1 : 0; + if (session->current_trace_chunk && + !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) { + chunk_status = lttng_trace_chunk_rename_path(session->current_trace_chunk, + DEFAULT_CHUNK_TMP_OLD_DIRECTORY); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + goto error; + } + } + if (!session->current_trace_chunk) { + if (!session->rotated) { + new_path = ""; + } else { + new_path = NULL; + } + } else { + new_path = DEFAULT_CHUNK_TMP_NEW_DIRECTORY; + } + trace_chunk = lttng_trace_chunk_create(next_chunk_id, - chunk_creation_ts); + chunk_creation_ts, new_path); if (!trace_chunk) { goto error; } @@ -673,6 +697,7 @@ int session_close_trace_chunk(struct ltt_session *session, struct consumer_socket *socket; enum lttng_trace_chunk_status chunk_status; const time_t chunk_close_timestamp = time(NULL); + const char *new_path; chunk_status = lttng_trace_chunk_set_close_command( trace_chunk, close_command); @@ -687,6 +712,44 @@ int session_close_trace_chunk(struct ltt_session *session, ret = -1; goto end; } + + if (close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_DELETE && !session->rotated) { + /* New chunk stays in session output directory. */ + new_path = ""; + } else { + /* Use chunk name for new chunk. */ + new_path = NULL; + } + if (session->current_trace_chunk && + !lttng_trace_chunk_get_name_overridden(session->current_trace_chunk)) { + /* Rename new chunk path. */ + chunk_status = lttng_trace_chunk_rename_path(session->current_trace_chunk, + new_path); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + ret = -1; + goto end; + } + } + if (!lttng_trace_chunk_get_name_overridden(trace_chunk) && + close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION) { + const char *old_path; + + if (!session->rotated) { + old_path = ""; + } else { + old_path = NULL; + } + /* We need to move back the .tmp_old_chunk to its rightful place. */ + chunk_status = lttng_trace_chunk_rename_path(trace_chunk, + old_path); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + ret = -1; + goto end; + } + } + if (close_command == LTTNG_TRACE_CHUNK_COMMAND_TYPE_MOVE_TO_COMPLETED) { + session->rotated = true; + } chunk_status = lttng_trace_chunk_set_close_timestamp(trace_chunk, chunk_close_timestamp); if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { @@ -769,6 +832,25 @@ void session_notify_destruction(const struct ltt_session *session) } } +/* + * Fire each clear notifier once, and remove them from the array. + */ +void session_notify_clear(struct ltt_session *session) +{ + size_t i; + const size_t count = lttng_dynamic_array_get_count( + &session->clear_notifiers); + + for (i = 0; i < count; i++) { + const struct ltt_session_clear_notifier_element *element = + lttng_dynamic_array_get_element( + &session->clear_notifiers, i); + + element->notifier(session, element->user_data); + } + lttng_dynamic_array_clear(&session->clear_notifiers); +} + static void session_release(struct urcu_ref *ref) { @@ -831,6 +913,7 @@ void session_release(struct urcu_ref *ref) session->ust_session = NULL; } lttng_dynamic_array_reset(&session->destroy_notifiers); + lttng_dynamic_array_reset(&session->clear_notifiers); free(session->last_archived_chunk_name); free(session->base_path); free(session); @@ -899,6 +982,18 @@ int session_add_destroy_notifier(struct ltt_session *session, &element); } +int session_add_clear_notifier(struct ltt_session *session, + ltt_session_clear_notifier notifier, void *user_data) +{ + const struct ltt_session_clear_notifier_element element = { + .notifier = notifier, + .user_data = user_data + }; + + return lttng_dynamic_array_add_element(&session->clear_notifiers, + &element); +} + /* * Return a ltt_session structure ptr that matches name. If no session found, * NULL is returned. This must be called with the session list lock held using @@ -990,6 +1085,9 @@ enum lttng_error_code session_create(const char *name, uid_t uid, gid_t gid, lttng_dynamic_array_init(&new_session->destroy_notifiers, sizeof(struct ltt_session_destroy_notifier_element), NULL); + lttng_dynamic_array_init(&new_session->clear_notifiers, + sizeof(struct ltt_session_clear_notifier_element), + NULL); urcu_ref_init(&new_session->ref); pthread_mutex_init(&new_session->lock, NULL); @@ -1184,6 +1282,11 @@ int session_reset_rotation_state(struct ltt_session *session, chunk_id); lttng_trace_chunk_put(session->chunk_being_archived); session->chunk_being_archived = NULL; + /* + * Fire the clear reply notifiers if we are completing a clear + * rotation. + */ + session_notify_clear(session); } return ret; }