X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fbin%2Flttng-sessiond%2Fcmd.c;h=03405bb7846277e3cb0ab3930d5b46e4e96e1cab;hb=06671f3490837e28032f3c5bc9375e32bd67f42e;hp=2c2ce285a676461238703f2cb77a285cdb5a66b6;hpb=7a24ece351f5be3d915e5c93201a4b9fcf1d486b;p=lttng-tools.git diff --git a/src/bin/lttng-sessiond/cmd.c b/src/bin/lttng-sessiond/cmd.c index 2c2ce285a..03405bb78 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,112 +1429,6 @@ error: return ret; } -/* - * Command LTTNG_TRACK_ID processed by the client thread. - * - * Called with session lock held. - */ -int cmd_track_id(struct ltt_session *session, - enum lttng_tracker_type tracker_type, - enum lttng_domain_type domain, - const struct lttng_tracker_id *id) -{ - int ret; - - rcu_read_lock(); - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - - ksess = session->kernel_session; - - ret = kernel_track_id(tracker_type, ksess, id); - 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_id(tracker_type, usess, id); - 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_ID processed by the client thread. - * - * Called with session lock held. - */ -int cmd_untrack_id(struct ltt_session *session, - enum lttng_tracker_type tracker_type, - enum lttng_domain_type domain, - const struct lttng_tracker_id *id) -{ - int ret; - - rcu_read_lock(); - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - - ksess = session->kernel_session; - - ret = kernel_untrack_id(tracker_type, ksess, id); - 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_id(tracker_type, usess, id); - 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. * @@ -1579,15 +1461,6 @@ int cmd_enable_channel(struct ltt_session *session, rcu_read_lock(); - /* - * Don't try to enable a channel if the session has been started at - * some point in time before. The tracer does not allow it. - */ - if (session->has_been_started) { - ret = LTTNG_ERR_TRACE_ALREADY_STARTED; - goto error; - } - /* * If the session is a live session, remove the switch timer, the * live timer does the same thing but sends also synchronisation @@ -1636,6 +1509,15 @@ int cmd_enable_channel(struct ltt_session *session, kchan = trace_kernel_get_channel_by_name(attr.name, session->kernel_session); if (kchan == NULL) { + /* + * Don't try to create a channel if the session has been started at + * some point in time before. The tracer does not allow it. + */ + if (session->has_been_started) { + ret = LTTNG_ERR_TRACE_ALREADY_STARTED; + goto error; + } + if (session->snapshot.nb_output > 0 || session->snapshot_mode) { /* Enforce mmap output for snapshot sessions. */ @@ -1695,6 +1577,15 @@ int cmd_enable_channel(struct ltt_session *session, uchan = trace_ust_find_channel_by_name(chan_ht, attr.name); if (uchan == NULL) { + /* + * Don't try to create a channel if the session has been started at + * some point in time before. The tracer does not allow it. + */ + if (session->has_been_started) { + ret = LTTNG_ERR_TRACE_ALREADY_STARTED; + goto error; + } + ret = channel_ust_create(usess, &attr, domain->buf_type); if (attr.name[0] != '\0') { usess->has_non_default_channel = 1; @@ -1718,6 +1609,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. */ @@ -2576,56 +2672,6 @@ ssize_t cmd_list_syscalls(struct lttng_event **events) return syscall_table_list(events); } -/* - * Command LTTNG_LIST_TRACKER_IDS processed by the client thread. - * - * Called with session lock held. - */ -int cmd_list_tracker_ids(enum lttng_tracker_type tracker_type, - struct ltt_session *session, - enum lttng_domain_type domain, - struct lttng_tracker_ids **ids) -{ - int ret = LTTNG_OK; - - switch (domain) { - case LTTNG_DOMAIN_KERNEL: - { - struct ltt_kernel_session *ksess; - - ksess = session->kernel_session; - ret = kernel_list_tracker_ids(tracker_type, ksess, ids); - if (ret != LTTNG_OK) { - ret = -LTTNG_ERR_KERN_LIST_FAIL; - goto error; - } - break; - } - case LTTNG_DOMAIN_UST: - { - struct ltt_ust_session *usess; - - usess = session->ust_session; - ret = trace_ust_list_tracker_ids(tracker_type, usess, ids); - if (ret != LTTNG_OK) { - 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; - } - -error: - /* Return negative value to differentiate return code */ - return ret; -} - /* * Command LTTNG_START_TRACE processed by the client thread. * @@ -2749,6 +2795,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. @@ -3256,6 +3312,7 @@ void cmd_destroy_session_reply(const struct ltt_session *session, payload_size_before_location = payload.size; comm_ret = lttng_trace_archive_location_serialize(location, &payload); + lttng_trace_archive_location_put(location); if (comm_ret < 0) { ERR("Failed to serialize the location of the trace archive produced during the destruction of session \"%s\"", session->name); @@ -3360,9 +3417,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; } } @@ -4584,7 +4649,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; } @@ -4631,6 +4696,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) { @@ -4653,6 +4723,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) { @@ -4697,7 +4772,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) { @@ -4705,7 +4780,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; } } @@ -4714,10 +4789,11 @@ 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; } } +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);