X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fmi-lttng.c;h=b790f793afba832272edc1461de6f6a1c78fcf60;hp=72b0791527eddf25ba89fb1a7ed4b27197fc9101;hb=f895927f329180ca1e6f4426e9d3c6250ae698ba;hpb=54f097faebfa13b13e8523c1ff9fafaf74ddda75 diff --git a/src/common/mi-lttng.c b/src/common/mi-lttng.c index 72b079152..b790f793a 100644 --- a/src/common/mi-lttng.c +++ b/src/common/mi-lttng.c @@ -1,32 +1,24 @@ /* - * Copyright (C) 2014 - Jonathan Rajotte - * - Olivier Cotte - * Copyright (C) 2016 - Jérémie Galarneau + * Copyright (C) 2014 Jonathan Rajotte + * Copyright (C) 2014 Olivier Cotte + * 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 "lttng/tracker.h" #define _LGPL_SOURCE +#include "mi-lttng.h" #include #include +#include +#include #include -#include "mi-lttng.h" -#include -#define MI_SCHEMA_MAJOR_VERSION 3 -#define MI_SCHEMA_MINOR_VERSION 0 +#define MI_SCHEMA_MAJOR_VERSION 4 +#define MI_SCHEMA_MINOR_VERSION 1 /* Machine interface namespace URI */ const char * const mi_lttng_xmlns = "xmlns"; @@ -35,7 +27,7 @@ const char * const mi_lttng_w3_schema_uri = "http://www.w3.org/2001/XMLSchema-in const char * const mi_lttng_schema_location = "xsi:schemaLocation"; const char * const mi_lttng_schema_location_uri = DEFAULT_LTTNG_MI_NAMESPACE " " - "http://lttng.org/xml/schemas/lttng-mi/" XSTR(MI_SCHEMA_MAJOR_VERSION) + "https://lttng.org/xml/schemas/lttng-mi/" XSTR(MI_SCHEMA_MAJOR_VERSION) "/lttng-mi-" XSTR(MI_SCHEMA_MAJOR_VERSION) "." XSTR(MI_SCHEMA_MINOR_VERSION) ".xsd"; const char * const mi_lttng_schema_version = "schemaVersion"; @@ -46,7 +38,7 @@ const char * const mi_lttng_schema_version_value = XSTR(MI_SCHEMA_MAJOR_VERSION) const char * const mi_lttng_element_command = "command"; const char * const mi_lttng_element_command_action = "snapshot_action"; const char * const mi_lttng_element_command_add_context = "add-context"; -const char * const mi_lttng_element_command_calibrate = "calibrate"; +const char *const mi_lttng_element_command_add_trigger = "add-trigger"; const char * const mi_lttng_element_command_create = "create"; const char * const mi_lttng_element_command_destroy = "destroy"; const char * const mi_lttng_element_command_disable_channel = "disable-channel"; @@ -54,9 +46,15 @@ const char * const mi_lttng_element_command_disable_event = "disable-event"; const char * const mi_lttng_element_command_enable_channels = "enable-channel"; const char * const mi_lttng_element_command_enable_event = "enable-event"; const char * const mi_lttng_element_command_list = "list"; +const char *const mi_lttng_element_command_list_trigger = "list-trigger"; const char * const mi_lttng_element_command_load = "load"; +const char * const mi_lttng_element_command_metadata = "metadata"; +const char * const mi_lttng_element_command_metadata_action = "metadata_action"; +const char * const mi_lttng_element_command_regenerate = "regenerate"; +const char * const mi_lttng_element_command_regenerate_action = "regenerate_action"; const char * const mi_lttng_element_command_name = "name"; const char * const mi_lttng_element_command_output = "output"; +const char *const mi_lttng_element_command_remove_trigger = "remove-trigger"; const char * const mi_lttng_element_command_save = "save"; const char * const mi_lttng_element_command_set_session = "set-session"; const char * const mi_lttng_element_command_snapshot = "snapshot"; @@ -70,6 +68,10 @@ const char * const mi_lttng_element_command_success = "success"; const char * const mi_lttng_element_command_track = "track"; const char * const mi_lttng_element_command_untrack = "untrack"; const char * const mi_lttng_element_command_version = "version"; +const char * const mi_lttng_element_command_rotate = "rotate"; +const char * const mi_lttng_element_command_enable_rotation = "enable-rotation"; +const char * const mi_lttng_element_command_disable_rotation = "disable-rotation"; +const char * const mi_lttng_element_command_clear = "clear"; /* Strings related to version command */ const char * const mi_lttng_element_version = "version"; @@ -97,6 +99,8 @@ const char * const mi_lttng_element_save = "save"; /* Strings related to load command */ const char * const mi_lttng_element_load = "load"; +const char * const mi_lttng_element_load_overrides = "overrides"; +const char * const mi_lttng_element_load_override_url = "url"; /* General elements of mi_lttng */ const char * const mi_lttng_element_empty = ""; @@ -162,10 +166,6 @@ const char * const mi_lttng_loglevel_type_range = "RANGE"; const char * const mi_lttng_loglevel_type_single = "SINGLE"; const char * const mi_lttng_loglevel_type_unknown = "UNKNOWN"; -/* String related to lttng_calibrate */ -const char * const mi_lttng_element_calibrate = "calibrate"; -const char * const mi_lttng_element_calibrate_function = "FUNCTION"; - /* String related to a lttng_snapshot_output */ const char * const mi_lttng_element_snapshot_ctrl_url = "ctrl_url"; const char * const mi_lttng_element_snapshot_data_url = "data_url"; @@ -177,12 +177,277 @@ const char * const mi_lttng_element_snapshots = "snapshots"; /* String related to track/untrack command */ const char * const mi_lttng_element_track_untrack_all_wildcard = "*"; +const char * const mi_lttng_element_session_name = "session_name"; + +/* String related to rotate command */ +const char * const mi_lttng_element_rotation = "rotation"; +const char * const mi_lttng_element_rotate_status = "status"; +const char * const mi_lttng_element_rotation_schedule = "rotation_schedule"; +const char * const mi_lttng_element_rotation_schedules = "rotation_schedules"; +const char * const mi_lttng_element_rotation_schedule_result = "rotation_schedule_result"; +const char * const mi_lttng_element_rotation_schedule_results = "rotation_schedule_results"; +const char * const mi_lttng_element_rotation_schedule_periodic = "periodic"; +const char * const mi_lttng_element_rotation_schedule_periodic_time_us = "time_us"; +const char * const mi_lttng_element_rotation_schedule_size_threshold = "size_threshold"; +const char * const mi_lttng_element_rotation_schedule_size_threshold_bytes = "bytes"; +const char * const mi_lttng_element_rotation_state = "state"; +const char * const mi_lttng_element_rotation_location = "location"; +const char * const mi_lttng_element_rotation_location_local = "local"; +const char * const mi_lttng_element_rotation_location_local_absolute_path = "absolute_path"; +const char * const mi_lttng_element_rotation_location_relay = "relay"; +const char * const mi_lttng_element_rotation_location_relay_host = "host"; +const char * const mi_lttng_element_rotation_location_relay_control_port = "control_port"; +const char * const mi_lttng_element_rotation_location_relay_data_port = "data_port"; +const char * const mi_lttng_element_rotation_location_relay_protocol = "protocol"; +const char * const mi_lttng_element_rotation_location_relay_relative_path = "relative_path"; + +/* String related to enum lttng_rotation_state */ +const char * const mi_lttng_rotation_state_str_ongoing = "ONGOING"; +const char * const mi_lttng_rotation_state_str_completed = "COMPLETED"; +const char * const mi_lttng_rotation_state_str_expired = "EXPIRED"; +const char * const mi_lttng_rotation_state_str_error = "ERROR"; + +/* String related to enum lttng_trace_archive_location_relay_protocol_type */ +const char * const mi_lttng_rotation_location_relay_protocol_str_tcp = "TCP"; + +/* String related to rate_policy elements */ +const char *const mi_lttng_element_rate_policy = "rate_policy"; +const char *const mi_lttng_element_rate_policy_every_n = + "rate_policy_every_n"; +const char *const mi_lttng_element_rate_policy_once_after_n = + "rate_policy_once_after_n"; + +const char *const mi_lttng_element_rate_policy_every_n_interval = + "interval"; +const char + *const mi_lttng_element_rate_policy_once_after_n_threshold = + "threshold"; + +/* String related to action elements */ +const char *const mi_lttng_element_action = "action"; +const char *const mi_lttng_element_action_list = "action_list"; +const char *const mi_lttng_element_action_notify = "action_notify"; +const char *const mi_lttng_element_action_start_session = + "action_start_session"; +const char *const mi_lttng_element_action_stop_session = + "action_stop_session"; +const char *const mi_lttng_element_action_rotate_session = + "action_rotate_session"; +const char *const mi_lttng_element_action_snapshot_session = + "action_snapshot_session"; +const char *const mi_lttng_element_action_snapshot_session_output = + "output"; + +/* String related to condition */ +const char *const mi_lttng_element_condition = "condition"; +const char *const mi_lttng_element_condition_buffer_usage_high = + "condition_buffer_usage_high"; +const char *const mi_lttng_element_condition_buffer_usage_low = + "condition_buffer_usage_low"; +const char *const mi_lttng_element_condition_event_rule_matches = + "condition_event_rule_matches"; +const char *const mi_lttng_element_condition_session_consumed_size = + "condition_session_consumed_size"; +const char *const mi_lttng_element_condition_session_rotation = + "condition_session_rotation"; +const char + *const mi_lttng_element_condition_session_rotation_completed = + "condition_session_rotation_completed"; +const char + *const mi_lttng_element_condition_session_rotation_ongoing = + "condition_session_rotation_ongoing"; + +const char *const mi_lttng_element_condition_channel_name = + "channel_name"; +const char *const mi_lttng_element_condition_threshold_bytes = + "threshold_bytes"; +const char *const mi_lttng_element_condition_threshold_ratio = + "threshold_ratio"; + +/* String related to capture descriptor */ +const char *const mi_lttng_element_capture_descriptor = + "capture_descriptor"; +const char *const mi_lttng_element_capture_descriptors = + "capture_descriptors"; + +/* String related to event expression */ +const char *const mi_lttng_element_event_expr = "event_expr"; +const char *const mi_lttng_element_event_expr_payload_field = + "event_expr_payload_field"; +const char *const mi_lttng_element_event_expr_channel_context_field = + "event_expr_channel_context_field"; +const char + *const mi_lttng_element_event_expr_app_specific_context_field = + "event_expr_app_specific_context_field"; +const char *const mi_lttng_element_event_expr_array_field_element = + "event_expr_array_field_element"; +const char *const mi_lttng_element_event_expr_provider_name = + "provider_name"; +const char *const mi_lttng_element_event_expr_type_name = + "type_name"; +const char *const mi_lttng_element_event_expr_index = "index"; + +/* String related to event rule */ +const char *const mi_lttng_element_event_rule = "event_rule"; + +/* String related to lttng_event_rule_type */ +const char *const mi_lttng_element_event_rule_event_name = + "event_name"; +const char *const mi_lttng_element_event_rule_name_pattern = + "name_pattern"; +const char *const mi_lttng_element_event_rule_filter_expression = + "filter_expression"; + +const char *const mi_lttng_element_event_rule_jul_logging = + "event_rule_jul_logging"; +const char *const mi_lttng_element_event_rule_kernel_kprobe = + "event_rule_kernel_kprobe"; +const char *const mi_lttng_element_event_rule_kernel_syscall = + "event_rule_kernel_syscall"; +const char *const mi_lttng_element_event_rule_kernel_tracepoint = + "event_rule_kernel_tracepoint"; +const char *const mi_lttng_element_event_rule_kernel_uprobe = + "event_rule_kernel_uprobe"; +const char *const mi_lttng_element_event_rule_log4j_logging = + "event_rule_log4j_logging"; +const char *const mi_lttng_element_event_rule_python_logging = + "event_rule_python_logging"; +const char *const mi_lttng_element_event_rule_user_tracepoint = + "event_rule_user_tracepoint"; + +/* String related to lttng_event_rule_kernel_syscall. */ +const char *const + mi_lttng_element_event_rule_kernel_syscall_emission_site = + "emission_site"; + +/* String related to enum lttng_event_rule_kernel_syscall_emission_site. */ +const char *const + mi_lttng_event_rule_kernel_syscall_emission_site_entry_exit = + "entry+exit"; +const char + *const mi_lttng_event_rule_kernel_syscall_emission_site_entry = + "entry"; +const char *const + mi_lttng_event_rule_kernel_syscall_emission_site_exit = "exit"; + +/* String related to lttng_event_rule_user_tracepoint */ +const char *const + mi_lttng_element_event_rule_user_tracepoint_name_pattern_exclusions = + "name_pattern_exclusions"; +const char *const + mi_lttng_element_event_rule_user_tracepoint_name_pattern_exclusion = + "name_pattern_exclusion"; + +/* String related to log level rule. */ +const char *const mi_lttng_element_log_level_rule = + "log_level_rule"; +const char *const mi_lttng_element_log_level_rule_exactly = + "log_level_rule_exactly"; +const char + *const mi_lttng_element_log_level_rule_at_least_as_severe_as = + "log_level_rule_at_least_as_severe_as"; +const char *const mi_lttng_element_log_level_rule_level = "level"; + +/* String related to kernel probe location. */ +const char *const mi_lttng_element_kernel_probe_location = + "kernel_probe_location"; +const char + *const mi_lttng_element_kernel_probe_location_symbol_offset = + "kernel_probe_location_symbol_offset"; +const char *const + mi_lttng_element_kernel_probe_location_symbol_offset_name = + "name"; +const char *const + mi_lttng_element_kernel_probe_location_symbol_offset_offset = + "offset"; + +const char *const mi_lttng_element_kernel_probe_location_address = + "kernel_probe_location_address"; +const char + *const mi_lttng_element_kernel_probe_location_address_address = + "address"; + +/* String related to userspace probe location. */ +const char *const mi_lttng_element_userspace_probe_location = + "userspace_probe_location"; +const char + *const mi_lttng_element_userspace_probe_location_binary_path = + "binary_path"; +const char + *const mi_lttng_element_userspace_probe_location_function = + "userspace_probe_location_function"; +const char + *const mi_lttng_element_userspace_probe_location_function_name = + "name"; +const char + *const mi_lttng_element_userspace_probe_location_lookup_method = + "userspace_probe_location_lookup_method"; +const char *const + mi_lttng_element_userspace_probe_location_lookup_method_function_default = + "userspace_probe_location_lookup_method_function_default"; +const char *const + mi_lttng_element_userspace_probe_location_lookup_method_function_elf = + "userspace_probe_location_lookup_method_function_elf"; +const char *const + mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt = + "userspace_probe_location_lookup_method_tracepoint_sdt"; +const char + *const mi_lttng_element_userspace_probe_location_tracepoint = + "userspace_probe_location_tracepoint"; +const char *const + mi_lttng_element_userspace_probe_location_tracepoint_probe_name = + "probe_name"; +const char *const + mi_lttng_element_userspace_probe_location_tracepoint_provider_name = + "provider_name"; + +/* String related to enum + * lttng_userspace_probe_location_function_instrumentation_type */ +const char *const + mi_lttng_element_userspace_probe_location_function_instrumentation_type = + "instrumentation_type"; +const char *const + mi_lttng_userspace_probe_location_function_instrumentation_type_entry = + "ENTRY"; + +/* String related to trigger */ +const char *const mi_lttng_element_triggers = "triggers"; +const char *const mi_lttng_element_trigger = "trigger"; +const char *const mi_lttng_element_trigger_owner_uid = "owner_uid"; + +/* String related to error_query. */ +const char *const mi_lttng_element_error_query_result = + "error_query_result"; +const char *const mi_lttng_element_error_query_result_counter = + "error_query_result_counter"; +const char *const + mi_lttng_element_error_query_result_counter_value = "value"; +const char *const mi_lttng_element_error_query_result_description = + "description"; +const char *const mi_lttng_element_error_query_result_name = + "name"; +const char *const mi_lttng_element_error_query_result_type = + "type"; +const char *const mi_lttng_element_error_query_results = + "error_query_results"; + +/* String related to add-context command */ +const char * const mi_lttng_element_context_symbol = "symbol"; + +/* Deprecated symbols preserved for ABI compatibility. */ +const char * const mi_lttng_context_type_perf_counter; +const char * const mi_lttng_context_type_perf_cpu_counter; +const char * const mi_lttng_context_type_perf_thread_counter; +const char * const mi_lttng_element_track_untrack_pid_target; +const char * const mi_lttng_element_track_untrack_targets; +const char * const mi_lttng_element_calibrate; +const char * const mi_lttng_element_calibrate_function; +const char * const mi_lttng_element_command_calibrate; /* This is a merge of jul loglevel and regular loglevel * Those should never overlap by definition * (see struct lttng_event loglevel) */ -LTTNG_HIDDEN const char *mi_lttng_loglevel_string(int value, enum lttng_domain_type domain) { switch (domain) { @@ -293,13 +558,11 @@ const char *mi_lttng_loglevel_string(int value, enum lttng_domain_type domain) return mi_lttng_loglevel_str_unknown; } break; + default: + return mi_lttng_loglevel_str_unknown; } - - /* Reaching this means the domain is unknown. */ - return mi_lttng_loglevel_str_unknown; } -LTTNG_HIDDEN const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value) { switch (value) { @@ -314,7 +577,7 @@ const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value) } } -LTTNG_HIDDEN +static const char *mi_lttng_eventtype_string(enum lttng_event_type value) { switch (value) { @@ -324,6 +587,8 @@ const char *mi_lttng_eventtype_string(enum lttng_event_type value) return config_event_type_tracepoint; case LTTNG_EVENT_PROBE: return config_event_type_probe; + case LTTNG_EVENT_USERSPACE_PROBE: + return config_event_type_userspace_probe; case LTTNG_EVENT_FUNCTION: return config_event_type_function; case LTTNG_EVENT_FUNCTION_ENTRY: @@ -365,12 +630,63 @@ const char *mi_lttng_event_contexttype_string(enum lttng_event_context_type val) return config_event_context_hostname; case LTTNG_EVENT_CONTEXT_IP: return config_event_context_ip; + case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE: + return config_event_context_interruptible; + case LTTNG_EVENT_CONTEXT_PREEMPTIBLE: + return config_event_context_preemptible; + case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE: + return config_event_context_need_reschedule; + case LTTNG_EVENT_CONTEXT_MIGRATABLE: + return config_event_context_migratable; + case LTTNG_EVENT_CONTEXT_CALLSTACK_USER: + return config_event_context_callstack_user; + case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL: + return config_event_context_callstack_kernel; + case LTTNG_EVENT_CONTEXT_CGROUP_NS: + return config_event_context_cgroup_ns; + case LTTNG_EVENT_CONTEXT_IPC_NS: + return config_event_context_ipc_ns; + case LTTNG_EVENT_CONTEXT_MNT_NS: + return config_event_context_mnt_ns; + case LTTNG_EVENT_CONTEXT_NET_NS: + return config_event_context_net_ns; + case LTTNG_EVENT_CONTEXT_PID_NS: + return config_event_context_pid_ns; + case LTTNG_EVENT_CONTEXT_TIME_NS: + return config_event_context_time_ns; + case LTTNG_EVENT_CONTEXT_USER_NS: + return config_event_context_user_ns; + case LTTNG_EVENT_CONTEXT_UTS_NS: + return config_event_context_uts_ns; + case LTTNG_EVENT_CONTEXT_UID: + return config_event_context_uid; + case LTTNG_EVENT_CONTEXT_EUID: + return config_event_context_euid; + case LTTNG_EVENT_CONTEXT_SUID: + return config_event_context_suid; + case LTTNG_EVENT_CONTEXT_GID: + return config_event_context_gid; + case LTTNG_EVENT_CONTEXT_EGID: + return config_event_context_egid; + case LTTNG_EVENT_CONTEXT_SGID: + return config_event_context_sgid; + case LTTNG_EVENT_CONTEXT_VUID: + return config_event_context_vuid; + case LTTNG_EVENT_CONTEXT_VEUID: + return config_event_context_veuid; + case LTTNG_EVENT_CONTEXT_VSUID: + return config_event_context_vsuid; + case LTTNG_EVENT_CONTEXT_VGID: + return config_event_context_vgid; + case LTTNG_EVENT_CONTEXT_VEGID: + return config_event_context_vegid; + case LTTNG_EVENT_CONTEXT_VSGID: + return config_event_context_vsgid; default: return NULL; } } -LTTNG_HIDDEN const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val) { switch (val) { @@ -387,10 +703,8 @@ const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val) } } -LTTNG_HIDDEN const char *mi_lttng_domaintype_string(enum lttng_domain_type value) { - /* Note: This is a *duplicate* of get_domain_str from bin/lttng/utils.c */ switch (value) { case LTTNG_DOMAIN_KERNEL: return config_domain_type_kernel; @@ -404,12 +718,11 @@ const char *mi_lttng_domaintype_string(enum lttng_domain_type value) return config_domain_type_python; default: /* Should not have an unknown domain */ - assert(0); + abort(); return NULL; } } -LTTNG_HIDDEN const char *mi_lttng_buffertype_string(enum lttng_buffer_type value) { switch (value) { @@ -421,28 +734,42 @@ const char *mi_lttng_buffertype_string(enum lttng_buffer_type value) return config_buffer_type_global; default: /* Should not have an unknow buffer type */ - assert(0); + abort(); return NULL; } } -LTTNG_HIDDEN -const char *mi_lttng_calibratetype_string(enum lttng_calibrate_type val) +const char *mi_lttng_rotation_state_string(enum lttng_rotation_state value) { - const char *ret; + switch (value) { + case LTTNG_ROTATION_STATE_ONGOING: + return mi_lttng_rotation_state_str_ongoing; + case LTTNG_ROTATION_STATE_COMPLETED: + return mi_lttng_rotation_state_str_completed; + case LTTNG_ROTATION_STATE_EXPIRED: + return mi_lttng_rotation_state_str_expired; + case LTTNG_ROTATION_STATE_ERROR: + return mi_lttng_rotation_state_str_error; + default: + /* Should not have an unknow rotation state. */ + abort(); + return NULL; + } +} - switch (val) { - case LTTNG_CALIBRATE_FUNCTION: - ret = mi_lttng_element_calibrate_function; - break; +const char *mi_lttng_trace_archive_location_relay_protocol_type_string( + enum lttng_trace_archive_location_relay_protocol_type value) +{ + switch (value) { + case LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP: + return mi_lttng_rotation_location_relay_protocol_str_tcp; default: - ret = mi_lttng_element_empty; - break; + /* Should not have an unknown relay protocol. */ + abort(); + return NULL; } - return ret; } -LTTNG_HIDDEN struct mi_writer *mi_lttng_writer_create(int fd_output, int mi_output_type) { struct mi_writer *mi_writer; @@ -470,7 +797,6 @@ err_destroy: return NULL; } -LTTNG_HIDDEN int mi_lttng_writer_destroy(struct mi_writer *writer) { int ret; @@ -490,7 +816,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_writer_command_open(struct mi_writer *writer, const char *command) { int ret; @@ -537,26 +862,22 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_writer_command_close(struct mi_writer *writer) { return mi_lttng_writer_close_element(writer); } -LTTNG_HIDDEN int mi_lttng_writer_open_element(struct mi_writer *writer, const char *element_name) { return config_writer_open_element(writer->writer, element_name); } -LTTNG_HIDDEN int mi_lttng_writer_close_element(struct mi_writer *writer) { return config_writer_close_element(writer->writer); } -LTTNG_HIDDEN int mi_lttng_close_multi_element(struct mi_writer *writer, unsigned int nb_element) { @@ -576,7 +897,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_writer_write_element_unsigned_int(struct mi_writer *writer, const char *element_name, uint64_t value) { @@ -584,7 +904,6 @@ int mi_lttng_writer_write_element_unsigned_int(struct mi_writer *writer, element_name, value); } -LTTNG_HIDDEN int mi_lttng_writer_write_element_signed_int(struct mi_writer *writer, const char *element_name, int64_t value) { @@ -592,7 +911,6 @@ int mi_lttng_writer_write_element_signed_int(struct mi_writer *writer, element_name, value); } -LTTNG_HIDDEN int mi_lttng_writer_write_element_bool(struct mi_writer *writer, const char *element_name, int value) { @@ -600,7 +918,6 @@ int mi_lttng_writer_write_element_bool(struct mi_writer *writer, element_name, value); } -LTTNG_HIDDEN int mi_lttng_writer_write_element_string(struct mi_writer *writer, const char *element_name, const char *value) { @@ -608,8 +925,15 @@ int mi_lttng_writer_write_element_string(struct mi_writer *writer, element_name, value); } -LTTNG_HIDDEN -int mi_lttng_version(struct mi_writer *writer, struct mi_lttng_version *version, +int mi_lttng_writer_write_element_double(struct mi_writer *writer, + const char *element_name, + double value) +{ + return config_writer_write_element_double( + writer->writer, element_name, value); +} + +int mi_lttng_version(struct mi_writer *writer, struct mi_lttng_version_data *version, const char *lttng_description, const char *lttng_license) { int ret; @@ -690,19 +1014,17 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_sessions_open(struct mi_writer *writer) { return mi_lttng_writer_open_element(writer, config_element_sessions); } -LTTNG_HIDDEN int mi_lttng_session(struct mi_writer *writer, struct lttng_session *session, int is_open) { int ret; - assert(session); + LTTNG_ASSERT(session); /* Open sessions element */ ret = mi_lttng_writer_open_element(writer, @@ -756,13 +1078,11 @@ end: } -LTTNG_HIDDEN int mi_lttng_domains_open(struct mi_writer *writer) { return mi_lttng_writer_open_element(writer, config_element_domains); } -LTTNG_HIDDEN int mi_lttng_domain(struct mi_writer *writer, struct lttng_domain *domain, int is_open) { @@ -770,7 +1090,7 @@ int mi_lttng_domain(struct mi_writer *writer, const char *str_domain; const char *str_buffer; - assert(domain); + LTTNG_ASSERT(domain); /* Open domain element */ ret = mi_lttng_writer_open_element(writer, config_element_domain); @@ -810,19 +1130,17 @@ end: } -LTTNG_HIDDEN int mi_lttng_channels_open(struct mi_writer *writer) { return mi_lttng_writer_open_element(writer, config_element_channels); } -LTTNG_HIDDEN int mi_lttng_channel(struct mi_writer *writer, struct lttng_channel *channel, int is_open) { int ret = 0; - assert(channel); + LTTNG_ASSERT(channel); /* Opening channel element */ ret = mi_lttng_writer_open_element(writer, config_element_channel); @@ -861,13 +1179,38 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_channel_attr(struct mi_writer *writer, struct lttng_channel_attr *attr) { int ret = 0; + struct lttng_channel *chan = caa_container_of(attr, + struct lttng_channel, attr); + uint64_t discarded_events, lost_packets, monitor_timer_interval; + int64_t blocking_timeout; + + LTTNG_ASSERT(attr); + + ret = lttng_channel_get_discarded_event_count(chan, &discarded_events); + if (ret) { + goto end; + } + + ret = lttng_channel_get_lost_packet_count(chan, &lost_packets); + if (ret) { + goto end; + } + + ret = lttng_channel_get_monitor_timer_interval(chan, + &monitor_timer_interval); + if (ret) { + goto end; + } - assert(attr); + ret = lttng_channel_get_blocking_timeout(chan, + &blocking_timeout); + if (ret) { + goto end; + } /* Opening Attributes */ ret = mi_lttng_writer_open_element(writer, config_element_attributes); @@ -915,6 +1258,22 @@ int mi_lttng_channel_attr(struct mi_writer *writer, goto end; } + /* Monitor timer interval in usec */ + ret = mi_lttng_writer_write_element_unsigned_int(writer, + config_element_monitor_timer_interval, + monitor_timer_interval); + if (ret) { + goto end; + } + + /* Retry timeout in usec */ + ret = mi_lttng_writer_write_element_signed_int(writer, + config_element_blocking_timeout, + blocking_timeout); + if (ret) { + goto end; + } + /* Event output */ ret = mi_lttng_writer_write_element_string(writer, config_element_output_type, @@ -947,6 +1306,22 @@ int mi_lttng_channel_attr(struct mi_writer *writer, goto end; } + /* Discarded events */ + ret = mi_lttng_writer_write_element_unsigned_int(writer, + config_element_discarded_events, + discarded_events); + if (ret) { + goto end; + } + + /* Lost packets */ + ret = mi_lttng_writer_write_element_unsigned_int(writer, + config_element_lost_packets, + lost_packets); + if (ret) { + goto end; + } + /* Closing attributes */ ret = mi_lttng_writer_close_element(writer); if (ret) { @@ -957,7 +1332,6 @@ end: } -LTTNG_HIDDEN int mi_lttng_event_common_attributes(struct mi_writer *writer, struct lttng_event *event) { @@ -992,7 +1366,7 @@ int mi_lttng_event_common_attributes(struct mi_writer *writer, } /* Event filter expression */ - ret = lttng_event_get_filter_string(event, &filter_expression); + ret = lttng_event_get_filter_expression(event, &filter_expression); if (ret) { goto end; } @@ -1055,7 +1429,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer, struct lttng_event *event, enum lttng_domain_type domain) { @@ -1084,7 +1457,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer, struct lttng_event *event) { @@ -1092,7 +1464,6 @@ int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer, return write_event_exclusions(writer, event); } -LTTNG_HIDDEN int mi_lttng_event_function_probe(struct mi_writer *writer, struct lttng_event *event) { @@ -1137,7 +1508,141 @@ end: return ret; } -LTTNG_HIDDEN +static +int mi_lttng_event_userspace_probe(struct mi_writer *writer, + struct lttng_event *event) +{ + int ret; + const struct lttng_userspace_probe_location *location; + const struct lttng_userspace_probe_location_lookup_method *lookup_method; + enum lttng_userspace_probe_location_lookup_method_type lookup_type; + + location = lttng_event_get_userspace_probe_location(event); + if (!location) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + lookup_method = lttng_userspace_probe_location_get_lookup_method(location); + if (!lookup_method) { + ret = -LTTNG_ERR_INVALID; + goto end; + } + + lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method); + + ret = mi_lttng_writer_open_element(writer, config_element_attributes); + if (ret) { + goto end; + } + + switch (lttng_userspace_probe_location_get_type(location)) { + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION: + { + const char *function_name; + const char *binary_path; + + ret = mi_lttng_writer_open_element(writer, + config_element_userspace_probe_function_attributes); + if (ret) { + goto end; + } + + switch (lookup_type) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF: + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_lookup, + config_element_userspace_probe_lookup_function_elf); + if (ret) { + goto end; + } + break; + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT: + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_lookup, + config_element_userspace_probe_lookup_function_default); + if (ret) { + goto end; + } + break; + default: + goto end; + } + + binary_path = lttng_userspace_probe_location_function_get_binary_path(location); + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_location_binary_path, binary_path); + if (ret) { + goto end; + } + + function_name = lttng_userspace_probe_location_function_get_function_name(location); + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_function_location_function_name, + function_name); + if (ret) { + goto end; + } + + break; + } + case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT: + { + const char *probe_name, *provider_name; + const char *binary_path; + + ret = mi_lttng_writer_open_element(writer, + config_element_userspace_probe_function_attributes); + if (ret) { + goto end; + } + + switch (lookup_type) { + case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT: + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_lookup, + config_element_userspace_probe_lookup_tracepoint_sdt); + if (ret) { + goto end; + } + break; + default: + goto end; + } + + binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path(location); + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_location_binary_path, + binary_path); + if (ret) { + goto end; + } + + provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name(location); + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_tracepoint_location_provider_name, + provider_name); + if (ret) { + goto end; + } + + probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name(location); + ret = mi_lttng_writer_write_element_string(writer, + config_element_userspace_probe_tracepoint_location_probe_name, probe_name); + if (ret) { + goto end; + } + break; + } + default: + ERR("Invalid probe type encountered"); + } + /* Close probe_attributes and attributes */ + ret = mi_lttng_close_multi_element(writer, 2); +end: + return ret; +} + int mi_lttng_event_function_entry(struct mi_writer *writer, struct lttng_event *event) { @@ -1166,13 +1671,11 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_events_open(struct mi_writer *writer) { return mi_lttng_writer_open_element(writer, config_element_events); } -LTTNG_HIDDEN int mi_lttng_event(struct mi_writer *writer, struct lttng_event *event, int is_open, enum lttng_domain_type domain) { @@ -1201,12 +1704,19 @@ int mi_lttng_event(struct mi_writer *writer, case LTTNG_EVENT_FUNCTION_ENTRY: ret = mi_lttng_event_function_entry(writer, event); break; + case LTTNG_EVENT_USERSPACE_PROBE: + ret = mi_lttng_event_userspace_probe(writer, event); + break; case LTTNG_EVENT_ALL: /* Fallthrough */ default: break; } + if (ret) { + goto end; + } + if (!is_open) { ret = mi_lttng_writer_close_element(writer); } @@ -1215,30 +1725,85 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_trackers_open(struct mi_writer *writer) { - return mi_lttng_writer_open_element(writer, config_element_trackers); + return mi_lttng_writer_open_element( + writer, config_element_process_attr_trackers); +} + +static int get_tracker_elements(enum lttng_process_attr process_attr, + const char **element_process_attr_tracker, + const char **element_process_attr_value) +{ + int ret = 0; + + switch (process_attr) { + case LTTNG_PROCESS_ATTR_PROCESS_ID: + *element_process_attr_tracker = + config_element_process_attr_tracker_pid; + *element_process_attr_value = + config_element_process_attr_pid_value; + break; + case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID: + *element_process_attr_tracker = + config_element_process_attr_tracker_vpid; + *element_process_attr_value = + config_element_process_attr_vpid_value; + break; + case LTTNG_PROCESS_ATTR_USER_ID: + *element_process_attr_tracker = + config_element_process_attr_tracker_uid; + *element_process_attr_value = + config_element_process_attr_uid_value; + break; + case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID: + *element_process_attr_tracker = + config_element_process_attr_tracker_vuid; + *element_process_attr_value = + config_element_process_attr_vuid_value; + break; + case LTTNG_PROCESS_ATTR_GROUP_ID: + *element_process_attr_tracker = + config_element_process_attr_tracker_gid; + *element_process_attr_value = + config_element_process_attr_gid_value; + break; + case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID: + *element_process_attr_tracker = + config_element_process_attr_tracker_vgid; + *element_process_attr_value = + config_element_process_attr_vgid_value; + break; + default: + ret = LTTNG_ERR_SAVE_IO_FAIL; + } + return ret; } -LTTNG_HIDDEN -int mi_lttng_pid_tracker_open(struct mi_writer *writer) +int mi_lttng_process_attribute_tracker_open( + struct mi_writer *writer, enum lttng_process_attr process_attr) { int ret; + const char *element_tracker, *element_value; + + ret = get_tracker_elements( + process_attr, &element_tracker, &element_value); + if (ret) { + return ret; + } - /* Open element pid_tracker */ - ret = mi_lttng_writer_open_element(writer, config_element_pid_tracker); + /* Open process attribute tracker element */ + ret = mi_lttng_writer_open_element(writer, element_tracker); if (ret) { goto end; } - /* Open targets element */ - ret = mi_lttng_targets_open(writer); + /* Open values element */ + ret = mi_lttng_process_attr_values_open(writer); end: return ret; } -LTTNG_HIDDEN int mi_lttng_pids_open(struct mi_writer *writer) { return mi_lttng_writer_open_element(writer, config_element_pids); @@ -1248,8 +1813,9 @@ int mi_lttng_pids_open(struct mi_writer *writer) * TODO: move the listing of pid for user agent to process semantic on * mi api bump. The use of process element break the mi api. */ -LTTNG_HIDDEN -int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *name, +int mi_lttng_pid(struct mi_writer *writer, + pid_t pid, + const char *name, int is_open) { int ret; @@ -1285,36 +1851,133 @@ end: return ret; } -LTTNG_HIDDEN -int mi_lttng_targets_open(struct mi_writer *writer) +int mi_lttng_process_attr_values_open(struct mi_writer *writer) { - return mi_lttng_writer_open_element(writer, - config_element_targets); + return mi_lttng_writer_open_element( + writer, config_element_process_attr_values); } -LTTNG_HIDDEN -int mi_lttng_pid_target(struct mi_writer *writer, pid_t pid, int is_open) +int mi_lttng_all_process_attribute_value(struct mi_writer *writer, + enum lttng_process_attr process_attr, + bool is_open) { int ret; + const char *element_id_tracker, *element_target_id; - ret = mi_lttng_writer_open_element(writer, - config_element_target_pid); + ret = get_tracker_elements( + process_attr, &element_id_tracker, &element_target_id); + if (ret) { + return ret; + } + + ret = mi_lttng_writer_open_element(writer, element_target_id); if (ret) { goto end; } - /* Writing pid number - * Special case for element all on track untrack command - * All pid is represented as wildcard * - */ - if ((int) pid == -1) { - ret = mi_lttng_writer_write_element_string(writer, - config_element_pid, - mi_lttng_element_track_untrack_all_wildcard); - } else { - ret = mi_lttng_writer_write_element_signed_int(writer, - config_element_pid, (int) pid); + ret = mi_lttng_writer_open_element(writer, config_element_type); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_bool(writer, config_element_all, 1); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + + if (!is_open) { + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + } +end: + return ret; +} + +int mi_lttng_integral_process_attribute_value(struct mi_writer *writer, + enum lttng_process_attr process_attr, + int64_t value, + bool is_open) +{ + int ret; + const char *element_id_tracker, *element_target_id; + + ret = get_tracker_elements( + process_attr, &element_id_tracker, &element_target_id); + if (ret) { + return ret; + } + + ret = mi_lttng_writer_open_element(writer, element_target_id); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_open_element(writer, config_element_type); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_signed_int( + writer, config_element_process_attr_id, value); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + + if (!is_open) { + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + } + +end: + return ret; +} + +int mi_lttng_string_process_attribute_value(struct mi_writer *writer, + enum lttng_process_attr process_attr, + const char *value, + bool is_open) + +{ + int ret; + const char *element_id_tracker, *element_target_id; + + ret = get_tracker_elements( + process_attr, &element_id_tracker, &element_target_id); + if (ret) { + return ret; } + + ret = mi_lttng_writer_open_element(writer, element_target_id); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_open_element(writer, config_element_type); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string( + writer, config_element_name, value); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_close_element(writer); if (ret) { goto end; } @@ -1330,13 +1993,11 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_event_fields_open(struct mi_writer *writer) { return mi_lttng_writer_open_element(writer, mi_lttng_element_event_fields); } -LTTNG_HIDDEN int mi_lttng_event_field(struct mi_writer *writer, struct lttng_event_field *field) { @@ -1386,32 +2047,6 @@ end: return ret; } -LTTNG_HIDDEN -int mi_lttng_calibrate(struct mi_writer *writer, - struct lttng_calibrate *calibrate) -{ - int ret; - - /* Open calibrate element */ - ret = mi_lttng_writer_open_element(writer, mi_lttng_element_calibrate); - if (ret) { - goto end; - } - - /* Calibration type */ - ret = mi_lttng_writer_write_element_string(writer, config_element_type, - mi_lttng_calibratetype_string(calibrate->type)); - if (ret) { - goto end; - } - - /* Closing calibrate element */ - ret = mi_lttng_writer_close_element(writer); -end: - return ret; -} - -LTTNG_HIDDEN int mi_lttng_perf_counter_context(struct mi_writer *writer, struct lttng_event_perf_counter_ctx *perf_context) { @@ -1485,7 +2120,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_context(struct mi_writer *writer, struct lttng_event_context *context, int is_open) { @@ -1547,7 +2181,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_snapshot_output_session_name(struct mi_writer *writer, const char *session_name) { @@ -1576,9 +2209,8 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_snapshot_list_output(struct mi_writer *writer, - struct lttng_snapshot_output *output) + const struct lttng_snapshot_output *output) { int ret; @@ -1631,7 +2263,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_snapshot_del_output(struct mi_writer *writer, int id, const char *name, const char *current_session_name) { @@ -1682,7 +2313,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_snapshot_add_output(struct mi_writer *writer, const char *current_session_name, const char *n_ptr, struct lttng_snapshot_output *output) @@ -1738,7 +2368,6 @@ end: return ret; } -LTTNG_HIDDEN int mi_lttng_snapshot_record(struct mi_writer *writer, const char *current_session_name, const char *url, const char *cmdline_ctrl_url, const char *cmdline_data_url) @@ -1784,3 +2413,306 @@ int mi_lttng_snapshot_record(struct mi_writer *writer, end: return ret; } + +int mi_lttng_rotation_schedule(struct mi_writer *writer, + const struct lttng_rotation_schedule *schedule) +{ + int ret = 0; + enum lttng_rotation_status status; + uint64_t value; + const char *element_name; + const char *value_name; + bool empty_schedule = false; + + switch (lttng_rotation_schedule_get_type(schedule)) { + case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC: + status = lttng_rotation_schedule_periodic_get_period(schedule, + &value); + element_name = mi_lttng_element_rotation_schedule_periodic; + value_name = mi_lttng_element_rotation_schedule_periodic_time_us; + break; + case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD: + status = lttng_rotation_schedule_size_threshold_get_threshold( + schedule, &value); + element_name = mi_lttng_element_rotation_schedule_size_threshold; + value_name = mi_lttng_element_rotation_schedule_size_threshold_bytes; + break; + default: + ret = -1; + goto end; + } + + if (status != LTTNG_ROTATION_STATUS_OK) { + if (status == LTTNG_ROTATION_STATUS_UNAVAILABLE) { + empty_schedule = true; + } else { + ret = -1; + goto end; + } + } + + ret = mi_lttng_writer_open_element(writer, element_name); + if (ret) { + goto end; + } + + if (!empty_schedule) { + ret = mi_lttng_writer_write_element_unsigned_int(writer, + value_name, value); + if (ret) { + goto end; + } + } + + /* Close schedule descriptor element. */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } +end: + return ret; +} + +int mi_lttng_rotation_schedule_result(struct mi_writer *writer, + const struct lttng_rotation_schedule *schedule, + bool success) +{ + int ret = 0; + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_schedule_result); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_schedule); + if (ret) { + goto end; + } + + ret = mi_lttng_rotation_schedule(writer, schedule); + if (ret) { + goto end; + } + + /* Close rotation_schedule element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_bool(writer, + mi_lttng_element_command_success, success); + if (ret) { + goto end; + } + + /* Close rotation_schedule_result element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } +end: + return ret; +} + +static +int mi_lttng_location(struct mi_writer *writer, + const struct lttng_trace_archive_location *location) +{ + int ret = 0; + enum lttng_trace_archive_location_type location_type; + enum lttng_trace_archive_location_status status; + + location_type = lttng_trace_archive_location_get_type(location); + + switch (location_type) { + case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL: + { + const char *absolute_path; + + status = lttng_trace_archive_location_local_get_absolute_path( + location, &absolute_path); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_location_local); + if (ret) { + goto end; + } + + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_local_absolute_path, + absolute_path); + if (ret) { + goto end; + } + + /* Close local element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + break; + } + case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY: + { + uint16_t control_port, data_port; + const char *host, *relative_path; + enum lttng_trace_archive_location_relay_protocol_type protocol; + + /* Fetch all relay location parameters. */ + status = lttng_trace_archive_location_relay_get_protocol_type( + location, &protocol); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_host( + location, &host); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_control_port( + location, &control_port); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_data_port( + location, &data_port); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + status = lttng_trace_archive_location_relay_get_relative_path( + location, &relative_path); + if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) { + ret = -1; + goto end; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_location_relay); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_relay_host, + host); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_unsigned_int(writer, + mi_lttng_element_rotation_location_relay_control_port, + control_port); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_unsigned_int(writer, + mi_lttng_element_rotation_location_relay_data_port, + data_port); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_relay_protocol, + mi_lttng_trace_archive_location_relay_protocol_type_string(protocol)); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_location_relay_relative_path, + relative_path); + if (ret) { + goto end; + } + + /* Close relay element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + break; + } + default: + abort(); + } +end: + return ret; +} + +int mi_lttng_rotate(struct mi_writer *writer, + const char *session_name, + enum lttng_rotation_state rotation_state, + const struct lttng_trace_archive_location *location) +{ + int ret; + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_session_name, + session_name); + if (ret) { + goto end; + } + + ret = mi_lttng_writer_write_element_string(writer, + mi_lttng_element_rotation_state, + mi_lttng_rotation_state_string(rotation_state)); + if (ret) { + goto end; + } + + if (!location) { + /* Not a serialization error. */ + goto close_rotation; + } + + ret = mi_lttng_writer_open_element(writer, + mi_lttng_element_rotation_location); + if (ret) { + goto end; + } + + ret = mi_lttng_location(writer, location); + if (ret) { + goto close_location; + } + +close_location: + /* Close location element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } + +close_rotation: + /* Close rotation element */ + ret = mi_lttng_writer_close_element(writer); + if (ret) { + goto end; + } +end: + return ret; +}