X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=eb5da1b76c44b70dcaf9fa221cb07fef8d2b0cdd;hb=ca8331f78e8c57d8d699926c7b4948cad9905b2e;hp=7af855eacb14e13b204730cdd2848f888c3bc352;hpb=343defc2671db532be8a9eed84907fd2e4044f0e;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 7af855eac..eb5da1b76 100644 --- a/src/bin/lttng-sessiond/cmd.c +++ b/src/bin/lttng-sessiond/cmd.c @@ -1,21 +1,14 @@ /* - * Copyright (C) 2012 - David Goulet - * Copyright (C) 2016 - Jérémie Galarneau + * Copyright (C) 2012 David Goulet + * Copyright (C) 2016 Jérémie Galarneau * - * 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. */ +#include "bin/lttng-sessiond/tracker.h" +#include "lttng/lttng-error.h" +#include "lttng/tracker.h" #define _LGPL_SOURCE #include #include @@ -517,7 +510,6 @@ static int list_lttng_agent_events(struct agent *agt, rcu_read_lock(); nb_event = lttng_ht_get_count(agt->events); - rcu_read_unlock(); if (nb_event == 0) { ret = nb_event; *total_size = 0; @@ -531,7 +523,6 @@ static int list_lttng_agent_events(struct agent *agt, * This is only valid because the commands which add events are * processed in the same thread as the listing. */ - rcu_read_lock(); cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) { ret = increment_extended_len(event->filter_expression, NULL, NULL, &extended_len); @@ -541,7 +532,6 @@ static int list_lttng_agent_events(struct agent *agt, goto error; } } - rcu_read_unlock(); *total_size = nb_event * sizeof(*tmp_events) + extended_len; tmp_events = zmalloc(*total_size); @@ -554,7 +544,6 @@ static int list_lttng_agent_events(struct agent *agt, extended_at = ((uint8_t *) tmp_events) + nb_event * sizeof(struct lttng_event); - rcu_read_lock(); cds_lfht_for_each_entry(agt->events->ht, &iter.iter, event, node.node) { strncpy(tmp_events[i].name, event->name, sizeof(tmp_events[i].name)); tmp_events[i].name[sizeof(tmp_events[i].name) - 1] = '\0'; @@ -823,8 +812,7 @@ end: return nb_event; error: - /* Negate the error code to differentiate the size from an error */ - return -ret; + return ret; } /* @@ -1441,108 +1429,6 @@ error: return ret; } -/* - * Command LTTNG_TRACK_PID processed by the client thread. - * - * Called with session lock held. - */ -int cmd_track_pid(struct ltt_session *session, enum lttng_domain_type domain, - int pid) -{ - int ret; - - rcu_read_lock(); - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - - ksess = session->kernel_session; - - ret = kernel_track_pid(ksess, pid); - if (ret != LTTNG_OK) { - goto error; - } - - kernel_wait_quiescent(); - break; - } - case LTTNG_DOMAIN_UST: - { - struct ltt_ust_session *usess; - - usess = session->ust_session; - - ret = trace_ust_track_pid(usess, pid); - if (ret != LTTNG_OK) { - goto error; - } - break; - } - default: - ret = LTTNG_ERR_UNKNOWN_DOMAIN; - goto error; - } - - ret = LTTNG_OK; - -error: - rcu_read_unlock(); - return ret; -} - -/* - * Command LTTNG_UNTRACK_PID processed by the client thread. - * - * Called with session lock held. - */ -int cmd_untrack_pid(struct ltt_session *session, enum lttng_domain_type domain, - int pid) -{ - int ret; - - rcu_read_lock(); - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - - ksess = session->kernel_session; - - ret = kernel_untrack_pid(ksess, pid); - if (ret != LTTNG_OK) { - goto error; - } - - kernel_wait_quiescent(); - break; - } - case LTTNG_DOMAIN_UST: - { - struct ltt_ust_session *usess; - - usess = session->ust_session; - - ret = trace_ust_untrack_pid(usess, pid); - if (ret != LTTNG_OK) { - goto error; - } - break; - } - default: - ret = LTTNG_ERR_UNKNOWN_DOMAIN; - goto error; - } - - ret = LTTNG_OK; - -error: - rcu_read_unlock(); - return ret; -} - /* * Command LTTNG_ENABLE_CHANNEL processed by the client thread. * @@ -1714,6 +1600,211 @@ end: return ret; } +enum lttng_error_code cmd_process_attr_tracker_get_tracking_policy( + struct ltt_session *session, + enum lttng_domain_type domain, + enum lttng_process_attr process_attr, + enum lttng_tracking_policy *policy) +{ + enum lttng_error_code ret_code = LTTNG_OK; + const struct process_attr_tracker *tracker; + + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + if (!session->kernel_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + tracker = kernel_get_process_attr_tracker( + session->kernel_session, process_attr); + break; + case LTTNG_DOMAIN_UST: + if (!session->ust_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + tracker = trace_ust_get_process_attr_tracker( + session->ust_session, process_attr); + break; + default: + ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN; + goto end; + } + if (tracker) { + *policy = process_attr_tracker_get_tracking_policy(tracker); + } else { + ret_code = LTTNG_ERR_INVALID; + } +end: + return ret_code; +} + +enum lttng_error_code cmd_process_attr_tracker_set_tracking_policy( + struct ltt_session *session, + enum lttng_domain_type domain, + enum lttng_process_attr process_attr, + enum lttng_tracking_policy policy) +{ + enum lttng_error_code ret_code = LTTNG_OK; + + switch (policy) { + case LTTNG_TRACKING_POLICY_INCLUDE_SET: + case LTTNG_TRACKING_POLICY_EXCLUDE_ALL: + case LTTNG_TRACKING_POLICY_INCLUDE_ALL: + break; + default: + ret_code = LTTNG_ERR_INVALID; + goto end; + } + + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + if (!session->kernel_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + ret_code = kernel_process_attr_tracker_set_tracking_policy( + session->kernel_session, process_attr, policy); + break; + case LTTNG_DOMAIN_UST: + if (!session->ust_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + ret_code = trace_ust_process_attr_tracker_set_tracking_policy( + session->ust_session, process_attr, policy); + break; + default: + ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN; + break; + } +end: + return ret_code; +} + +enum lttng_error_code cmd_process_attr_tracker_inclusion_set_add_value( + struct ltt_session *session, + enum lttng_domain_type domain, + enum lttng_process_attr process_attr, + const struct process_attr_value *value) +{ + enum lttng_error_code ret_code = LTTNG_OK; + + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + if (!session->kernel_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + ret_code = kernel_process_attr_tracker_inclusion_set_add_value( + session->kernel_session, process_attr, value); + break; + case LTTNG_DOMAIN_UST: + if (!session->ust_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + ret_code = trace_ust_process_attr_tracker_inclusion_set_add_value( + session->ust_session, process_attr, value); + break; + default: + ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN; + break; + } +end: + return ret_code; +} + +enum lttng_error_code cmd_process_attr_tracker_inclusion_set_remove_value( + struct ltt_session *session, + enum lttng_domain_type domain, + enum lttng_process_attr process_attr, + const struct process_attr_value *value) +{ + enum lttng_error_code ret_code = LTTNG_OK; + + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + if (!session->kernel_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + ret_code = kernel_process_attr_tracker_inclusion_set_remove_value( + session->kernel_session, process_attr, value); + break; + case LTTNG_DOMAIN_UST: + if (!session->ust_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + ret_code = trace_ust_process_attr_tracker_inclusion_set_remove_value( + session->ust_session, process_attr, value); + break; + default: + ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN; + break; + } +end: + return ret_code; +} + +enum lttng_error_code cmd_process_attr_tracker_get_inclusion_set( + struct ltt_session *session, + enum lttng_domain_type domain, + enum lttng_process_attr process_attr, + struct lttng_process_attr_values **values) +{ + enum lttng_error_code ret_code = LTTNG_OK; + const struct process_attr_tracker *tracker; + enum process_attr_tracker_status status; + + switch (domain) { + case LTTNG_DOMAIN_KERNEL: + if (!session->kernel_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + tracker = kernel_get_process_attr_tracker( + session->kernel_session, process_attr); + break; + case LTTNG_DOMAIN_UST: + if (!session->ust_session) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + tracker = trace_ust_get_process_attr_tracker( + session->ust_session, process_attr); + break; + default: + ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN; + goto end; + } + + if (!tracker) { + ret_code = LTTNG_ERR_INVALID; + goto end; + } + + status = process_attr_tracker_get_inclusion_set(tracker, values); + switch (status) { + case PROCESS_ATTR_TRACKER_STATUS_OK: + ret_code = LTTNG_OK; + break; + case PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY: + ret_code = LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY; + break; + case PROCESS_ATTR_TRACKER_STATUS_ERROR: + ret_code = LTTNG_ERR_NOMEM; + break; + default: + ret_code = LTTNG_ERR_UNK; + break; + } + +end: + return ret_code; +} + /* * Command LTTNG_DISABLE_EVENT processed by the client thread. */ @@ -2572,57 +2663,6 @@ ssize_t cmd_list_syscalls(struct lttng_event **events) return syscall_table_list(events); } -/* - * Command LTTNG_LIST_TRACKER_PIDS processed by the client thread. - * - * Called with session lock held. - */ -ssize_t cmd_list_tracker_pids(struct ltt_session *session, - enum lttng_domain_type domain, int32_t **pids) -{ - int ret; - ssize_t nr_pids = 0; - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - - ksess = session->kernel_session; - nr_pids = kernel_list_tracker_pids(ksess, pids); - if (nr_pids < 0) { - ret = LTTNG_ERR_KERN_LIST_FAIL; - goto error; - } - break; - } - case LTTNG_DOMAIN_UST: - { - struct ltt_ust_session *usess; - - usess = session->ust_session; - nr_pids = trace_ust_list_tracker_pids(usess, pids); - if (nr_pids < 0) { - ret = LTTNG_ERR_UST_LIST_FAIL; - goto error; - } - break; - } - case LTTNG_DOMAIN_LOG4J: - case LTTNG_DOMAIN_JUL: - case LTTNG_DOMAIN_PYTHON: - default: - ret = LTTNG_ERR_UND; - goto error; - } - - return nr_pids; - -error: - /* Return negative value to differentiate return code */ - return -ret; -} - /* * Command LTTNG_START_TRACE processed by the client thread. * @@ -2636,6 +2676,8 @@ int cmd_start_trace(struct ltt_session *session) struct ltt_ust_session *usess; const bool session_rotated_after_last_stop = session->rotated_after_last_stop; + const bool session_cleared_after_last_stop = + session->cleared_after_last_stop; assert(session); @@ -2646,7 +2688,8 @@ int cmd_start_trace(struct ltt_session *session) /* Is the session already started? */ if (session->active) { ret = LTTNG_ERR_TRACE_ALREADY_STARTED; - goto error; + /* Perform nothing */ + goto end; } if (session->rotation_state == LTTNG_ROTATION_STATE_ONGOING && @@ -2682,6 +2725,7 @@ int cmd_start_trace(struct ltt_session *session) session->active = 1; session->rotated_after_last_stop = false; + session->cleared_after_last_stop = false; if (session->output_traces && !session->current_trace_chunk) { if (!session->has_been_started) { struct lttng_trace_chunk *trace_chunk; @@ -2742,6 +2786,16 @@ int cmd_start_trace(struct ltt_session *session) } } + /* + * Open a packet in every stream of the session to ensure that viewers + * can correctly identify the boundaries of the periods during which + * tracing was active for this session. + */ + ret = session_open_packets(session); + if (ret != LTTNG_OK) { + goto error; + } + /* * Clear the flag that indicates that a rotation was done while the * session was stopped. @@ -2770,7 +2824,10 @@ error: /* Restore initial state on error. */ session->rotated_after_last_stop = session_rotated_after_last_stop; + session->cleared_after_last_stop = + session_cleared_after_last_stop; } +end: return ret; } @@ -3323,9 +3380,7 @@ int cmd_destroy_session(struct ltt_session *session, session->rotate_size = 0; } - if (session->most_recent_chunk_id.is_set && - session->most_recent_chunk_id.value != 0 && - session->current_trace_chunk && session->output_traces) { + if (session->rotated && session->current_trace_chunk && session->output_traces) { /* * Perform a last rotation on destruction if rotations have * occurred during the session's lifetime. @@ -3352,9 +3407,17 @@ int cmd_destroy_session(struct ltt_session *session, */ ret = cmd_rotate_session(session, NULL, true, LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION); - if (ret != LTTNG_OK) { + /* + * Rotation operations may not be supported by the kernel + * tracer. Hence, do not consider this implicit rotation as + * a session destruction error. The library has already stopped + * the session and waited for pending data; there is nothing + * left to do but complete the destruction of the session. + */ + if (ret != LTTNG_OK && + ret != -LTTNG_ERR_ROTATION_NOT_AVAILABLE_KERNEL) { ERR("Failed to perform a quiet rotation as part of the destruction of session \"%s\": %s", - session->name, lttng_strerror(-ret)); + session->name, lttng_strerror(ret)); destruction_last_error = -ret; } } @@ -4576,7 +4639,7 @@ int64_t get_session_nb_packets_per_stream(const struct ltt_session *session, } cur_nb_packets++; } - if (!cur_nb_packets) { + if (!cur_nb_packets && size_left != max_size) { /* Not enough room to grab one packet of each stream, error. */ return -1; } @@ -4623,6 +4686,11 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, consumer_copy_output(snapshot_output->consumer); strcpy(snapshot_kernel_consumer_output->chunk_path, snapshot_chunk_name); + + /* Copy the original domain subdir. */ + strcpy(snapshot_kernel_consumer_output->domain_subdir, + original_kernel_consumer_output->domain_subdir); + ret = consumer_copy_sockets(snapshot_kernel_consumer_output, original_kernel_consumer_output); if (ret < 0) { @@ -4645,6 +4713,11 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, consumer_copy_output(snapshot_output->consumer); strcpy(snapshot_ust_consumer_output->chunk_path, snapshot_chunk_name); + + /* Copy the original domain subdir. */ + strcpy(snapshot_ust_consumer_output->domain_subdir, + original_ust_consumer_output->domain_subdir); + ret = consumer_copy_sockets(snapshot_ust_consumer_output, original_ust_consumer_output); if (ret < 0) { @@ -4689,7 +4762,7 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, snapshot_output->max_size); if (nb_packets_per_stream < 0) { ret_code = LTTNG_ERR_MAX_SIZE_INVALID; - goto error; + goto error_close_trace_chunk; } if (session->kernel_session) { @@ -4697,7 +4770,7 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, snapshot_kernel_consumer_output, session, wait, nb_packets_per_stream); if (ret_code != LTTNG_OK) { - goto error; + goto error_close_trace_chunk; } } @@ -4706,11 +4779,18 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, snapshot_ust_consumer_output, session, wait, nb_packets_per_stream); if (ret_code != LTTNG_OK) { - goto error; + goto error_close_trace_chunk; } } - if (session_close_trace_chunk(session, session->current_trace_chunk, +error_close_trace_chunk: + if (session_set_trace_chunk(session, NULL, &snapshot_trace_chunk)) { + ERR("Failed to release the current trace chunk of session \"%s\"", + session->name); + ret_code = LTTNG_ERR_UNK; + } + + if (session_close_trace_chunk(session, snapshot_trace_chunk, LTTNG_TRACE_CHUNK_COMMAND_TYPE_NO_OPERATION, NULL)) { /* * Don't goto end; make sure the chunk is closed for the session @@ -4720,11 +4800,6 @@ enum lttng_error_code snapshot_record(struct ltt_session *session, session->name); ret_code = LTTNG_ERR_CLOSE_TRACE_CHUNK_FAIL_CONSUMER; } - if (session_set_trace_chunk(session, NULL, NULL)) { - ERR("Failed to release the current trace chunk of session \"%s\"", - session->name); - ret_code = LTTNG_ERR_UNK; - } error: if (original_ust_consumer_output) { session->ust_session->consumer = original_ust_consumer_output; @@ -4967,6 +5042,18 @@ int cmd_rotate_session(struct ltt_session *session, cmd_ret = LTTNG_ERR_ROTATION_MULTIPLE_AFTER_STOP; goto end; } + + /* + * After a stop followed by a clear, disallow following rotations a they would + * generate empty chunks. + */ + if (session->cleared_after_last_stop) { + DBG("Session \"%s\" was already cleared after stop, refusing rotation", + session->name); + cmd_ret = LTTNG_ERR_ROTATION_AFTER_STOP_CLEAR; + goto end; + } + if (session->active) { new_trace_chunk = session_create_new_trace_chunk(session, NULL, NULL, NULL);