X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsession.c;h=88bbe1309c4a1270cbbf418a97af3d5aeee57fb5;hb=875b29bfdafecb38a552264b0775478eaef0cae1;hp=ee71533f9ff790e60e11fac522ac2c82c2f4e3c6;hpb=5da88b0f58d7f838068037ea449ddfb25d3e85ad;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/session.c b/src/bin/lttng-sessiond/session.c index ee71533f9..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; } @@ -662,9 +686,9 @@ error: goto end; } -int session_close_trace_chunk(const struct ltt_session *session, +int session_close_trace_chunk(struct ltt_session *session, struct lttng_trace_chunk *trace_chunk, - const enum lttng_trace_chunk_command_type *close_command, + enum lttng_trace_chunk_command_type close_command, char *closed_trace_chunk_path) { int ret = 0; @@ -673,14 +697,13 @@ int session_close_trace_chunk(const 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; - if (close_command) { - chunk_status = lttng_trace_chunk_set_close_command( - trace_chunk, *close_command); - if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { - ret = -1; - goto end; - } + chunk_status = lttng_trace_chunk_set_close_command( + trace_chunk, close_command); + if (chunk_status != LTTNG_TRACE_CHUNK_STATUS_OK) { + ret = -1; + goto end; } if (chunk_close_timestamp == (time_t) -1) { @@ -689,6 +712,44 @@ int session_close_trace_chunk(const 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) { @@ -771,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) { @@ -833,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); @@ -901,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 @@ -992,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); @@ -1186,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; }