X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fsession.c;h=f8134f8ad966a950b0c97f13bbb18f2ba12d89b9;hp=0da2058fdf28dbbef05f0d2490cfbf49a089a294;hb=d7b377ed1acd4043bde353d99122e0e56fa4e975;hpb=ccbdaca404a66cf124ec7e4926b1507327f6d165 diff --git a/src/bin/lttng-sessiond/session.c b/src/bin/lttng-sessiond/session.c index 0da2058fd..f8134f8ad 100644 --- a/src/bin/lttng-sessiond/session.c +++ b/src/bin/lttng-sessiond/session.c @@ -1,18 +1,8 @@ /* - * Copyright (C) 2011 - David Goulet + * Copyright (C) 2011 David Goulet * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2 only, - * as published by the Free Software Foundation. + * SPDX-License-Identifier: GPL-2.0-only * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define _LGPL_SOURCE @@ -481,7 +471,7 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, CONSUMER_DST_LOCAL; session->ust_session->current_trace_chunk = new_trace_chunk; - if (is_local_trace) { + if (is_local_trace) { enum lttng_error_code ret_error_code; ret_error_code = ust_app_create_channel_subdirectories( @@ -489,7 +479,7 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, if (ret_error_code != LTTNG_OK) { goto error; } - } + } cds_lfht_for_each_entry( session->ust_session->consumer->socks->ht, &iter, socket, node.node) { @@ -499,11 +489,11 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, session->id, new_trace_chunk, DEFAULT_UST_TRACE_DIR); pthread_mutex_unlock(socket->lock); - if (ret) { + if (ret) { goto error; - } - } - } + } + } + } if (session->kernel_session) { const uint64_t relayd_id = session->kernel_session->consumer->net_seq_index; @@ -520,7 +510,7 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, if (ret_error_code != LTTNG_OK) { goto error; } - } + } cds_lfht_for_each_entry( session->kernel_session->consumer->socks->ht, &iter, socket, node.node) { @@ -530,11 +520,11 @@ int _session_set_trace_chunk_no_lock_check(struct ltt_session *session, session->id, new_trace_chunk, DEFAULT_KERNEL_TRACE_DIR); pthread_mutex_unlock(socket->lock); - if (ret) { + if (ret) { goto error; - } - } - } + } + } + } /* * Update local current trace chunk state last, only if all remote @@ -558,7 +548,7 @@ error: if (session->kernel_session) { session->kernel_session->current_trace_chunk = NULL; } - /* + /* * Release references taken in the case where all references could not * be acquired. */ @@ -589,6 +579,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; @@ -612,8 +603,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; } @@ -678,6 +687,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); @@ -692,6 +702,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) { @@ -744,6 +792,83 @@ end: return ret; } +/* + * This function skips the metadata channel as the begin/end timestamps of a + * metadata packet are useless. + * + * Moreover, opening a packet after a "clear" will cause problems for live + * sessions as it will introduce padding that was not part of the first trace + * chunk. The relay daemon expects the content of the metadata stream of + * successive metadata trace chunks to be strict supersets of one another. + * + * For example, flushing a packet at the beginning of the metadata stream of + * a trace chunk resulting from a "clear" session command will cause the + * size of the metadata stream of the new trace chunk to not match the size of + * the metadata stream of the original chunk. This will confuse the relay + * daemon as the same "offset" in a metadata stream will no longer point + * to the same content. + */ +static +enum lttng_error_code session_kernel_open_packets(struct ltt_session *session) +{ + enum lttng_error_code ret = LTTNG_OK; + struct consumer_socket *socket; + struct lttng_ht_iter iter; + struct cds_lfht_node *node; + struct ltt_kernel_channel *chan; + + rcu_read_lock(); + + cds_lfht_first(session->kernel_session->consumer->socks->ht, &iter.iter); + node = cds_lfht_iter_get_node(&iter.iter); + socket = container_of(node, typeof(*socket), node.node); + + cds_list_for_each_entry(chan, + &session->kernel_session->channel_list.head, list) { + int open_ret; + + DBG("Open packet of kernel channel: channel key = %" PRIu64 + ", session name = %s, session_id = %" PRIu64, + chan->key, session->name, session->id); + + open_ret = consumer_open_channel_packets(socket, chan->key); + if (open_ret < 0) { + /* General error (no known error expected). */ + ret = LTTNG_ERR_UNK; + goto end; + } + } + +end: + rcu_read_unlock(); + return ret; +} + +enum lttng_error_code session_open_packets(struct ltt_session *session) +{ + enum lttng_error_code ret = LTTNG_OK; + + DBG("Opening packets of session channels: session name = %s, session id = %" PRIu64, + session->name, session->id); + + if (session->ust_session) { + ret = ust_app_open_packets(session); + if (ret != LTTNG_OK) { + goto end; + } + } + + if (session->kernel_session) { + ret = session_kernel_open_packets(session); + if (ret != LTTNG_OK) { + goto end; + } + } + +end: + return ret; +} + /* * Set a session's current trace chunk. * @@ -807,7 +932,7 @@ void session_release(struct urcu_ref *ref) usess = session->ust_session; ksess = session->kernel_session; - /* Clean kernel session teardown, keeping data for destroy notifier. */ + /* Clean kernel session teardown, keeping data for destroy notifier. */ kernel_destroy_session(ksess); /* UST session teardown, keeping data for destroy notifier. */ @@ -1171,18 +1296,13 @@ error: } /* - * Check if the UID or GID match the session. Root user has access to all + * Check if the UID matches the session. Root user has access to all * sessions. */ -int session_access_ok(struct ltt_session *session, uid_t uid, gid_t gid) +bool session_access_ok(struct ltt_session *session, uid_t uid) { assert(session); - - if (uid != session->uid && gid != session->gid && uid != 0) { - return 0; - } else { - return 1; - } + return (uid == session->uid) || uid == 0; } /*