Fix: lttng: remove-trigger: null dereference on MI initialization error
[lttng-tools.git] / src / common / mi-lttng.c
... / ...
CommitLineData
1/*
2 * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
3 * Copyright (C) 2014 Olivier Cotte <olivier.cotte@polymtl.ca>
4 * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * SPDX-License-Identifier: GPL-2.0-only
7 *
8 */
9
10#include "lttng/tracker.h"
11#define _LGPL_SOURCE
12#include "mi-lttng.h"
13#include <common/config/session-config.h>
14#include <common/defaults.h>
15#include <common/tracker.h>
16#include <lttng/channel.h>
17#include <lttng/snapshot-internal.h>
18
19#include <assert.h>
20
21#define MI_SCHEMA_MAJOR_VERSION 4
22#define MI_SCHEMA_MINOR_VERSION 1
23
24/* Machine interface namespace URI */
25LTTNG_HIDDEN const char * const mi_lttng_xmlns = "xmlns";
26LTTNG_HIDDEN const char * const mi_lttng_xmlns_xsi = "xmlns:xsi";
27LTTNG_HIDDEN const char * const mi_lttng_w3_schema_uri = "http://www.w3.org/2001/XMLSchema-instance";
28LTTNG_HIDDEN const char * const mi_lttng_schema_location = "xsi:schemaLocation";
29LTTNG_HIDDEN const char * const mi_lttng_schema_location_uri =
30 DEFAULT_LTTNG_MI_NAMESPACE " "
31 "https://lttng.org/xml/schemas/lttng-mi/" XSTR(MI_SCHEMA_MAJOR_VERSION)
32 "/lttng-mi-" XSTR(MI_SCHEMA_MAJOR_VERSION) "."
33 XSTR(MI_SCHEMA_MINOR_VERSION) ".xsd";
34LTTNG_HIDDEN const char * const mi_lttng_schema_version = "schemaVersion";
35LTTNG_HIDDEN const char * const mi_lttng_schema_version_value = XSTR(MI_SCHEMA_MAJOR_VERSION)
36 "." XSTR(MI_SCHEMA_MINOR_VERSION);
37
38/* Strings related to command */
39const char * const mi_lttng_element_command = "command";
40const char * const mi_lttng_element_command_action = "snapshot_action";
41const char * const mi_lttng_element_command_add_context = "add-context";
42const char *const mi_lttng_element_command_add_trigger = "add-trigger";
43const char * const mi_lttng_element_command_create = "create";
44const char * const mi_lttng_element_command_destroy = "destroy";
45const char * const mi_lttng_element_command_disable_channel = "disable-channel";
46const char * const mi_lttng_element_command_disable_event = "disable-event";
47const char * const mi_lttng_element_command_enable_channels = "enable-channel";
48const char * const mi_lttng_element_command_enable_event = "enable-event";
49const char * const mi_lttng_element_command_list = "list";
50const char *const mi_lttng_element_command_list_trigger = "list-trigger";
51const char * const mi_lttng_element_command_load = "load";
52LTTNG_HIDDEN const char * const mi_lttng_element_command_metadata = "metadata";
53LTTNG_HIDDEN const char * const mi_lttng_element_command_metadata_action = "metadata_action";
54LTTNG_HIDDEN const char * const mi_lttng_element_command_regenerate = "regenerate";
55LTTNG_HIDDEN const char * const mi_lttng_element_command_regenerate_action = "regenerate_action";
56const char * const mi_lttng_element_command_name = "name";
57const char * const mi_lttng_element_command_output = "output";
58const char *const mi_lttng_element_command_remove_trigger = "remove-trigger";
59const char * const mi_lttng_element_command_save = "save";
60const char * const mi_lttng_element_command_set_session = "set-session";
61const char * const mi_lttng_element_command_snapshot = "snapshot";
62const char * const mi_lttng_element_command_snapshot_add = "add_snapshot";
63const char * const mi_lttng_element_command_snapshot_del = "del_snapshot";
64const char * const mi_lttng_element_command_snapshot_list = "list_snapshot";
65const char * const mi_lttng_element_command_snapshot_record = "record_snapshot";
66const char * const mi_lttng_element_command_start = "start";
67const char * const mi_lttng_element_command_stop = "stop";
68const char * const mi_lttng_element_command_success = "success";
69const char * const mi_lttng_element_command_track = "track";
70const char * const mi_lttng_element_command_untrack = "untrack";
71const char * const mi_lttng_element_command_version = "version";
72LTTNG_HIDDEN const char * const mi_lttng_element_command_rotate = "rotate";
73LTTNG_HIDDEN const char * const mi_lttng_element_command_enable_rotation = "enable-rotation";
74LTTNG_HIDDEN const char * const mi_lttng_element_command_disable_rotation = "disable-rotation";
75LTTNG_HIDDEN const char * const mi_lttng_element_command_clear = "clear";
76
77/* Strings related to version command */
78const char * const mi_lttng_element_version = "version";
79const char * const mi_lttng_element_version_commit = "commit";
80const char * const mi_lttng_element_version_description = "description";
81const char * const mi_lttng_element_version_license = "license";
82const char * const mi_lttng_element_version_major = "major";
83const char * const mi_lttng_element_version_minor = "minor";
84const char * const mi_lttng_element_version_patch_level = "patchLevel";
85const char * const mi_lttng_element_version_str = "string";
86const char * const mi_lttng_element_version_web = "url";
87
88/* String related to a lttng_event_field */
89const char * const mi_lttng_element_event_field = "event_field";
90const char * const mi_lttng_element_event_fields = "event_fields";
91
92/* String related to lttng_event_perf_counter_ctx */
93const char * const mi_lttng_element_perf_counter_context = "perf";
94
95/* Strings related to pid */
96const char * const mi_lttng_element_pid_id = "id";
97
98/* Strings related to save command */
99const char * const mi_lttng_element_save = "save";
100
101/* Strings related to load command */
102const char * const mi_lttng_element_load = "load";
103LTTNG_HIDDEN const char * const mi_lttng_element_load_overrides = "overrides";
104LTTNG_HIDDEN const char * const mi_lttng_element_load_override_url = "url";
105
106/* General elements of mi_lttng */
107const char * const mi_lttng_element_empty = "";
108const char * const mi_lttng_element_id = "id";
109const char * const mi_lttng_element_nowrite = "nowrite";
110const char * const mi_lttng_element_success = "success";
111const char * const mi_lttng_element_type_enum = "ENUM";
112const char * const mi_lttng_element_type_float = "FLOAT";
113const char * const mi_lttng_element_type_integer = "INTEGER";
114const char * const mi_lttng_element_type_other = "OTHER";
115const char * const mi_lttng_element_type_string = "STRING";
116
117/* String related to loglevel */
118const char * const mi_lttng_loglevel_str_alert = "TRACE_ALERT";
119const char * const mi_lttng_loglevel_str_crit = "TRACE_CRIT";
120const char * const mi_lttng_loglevel_str_debug = "TRACE_DEBUG";
121const char * const mi_lttng_loglevel_str_debug_function = "TRACE_DEBUG_FUNCTION";
122const char * const mi_lttng_loglevel_str_debug_line = "TRACE_DEBUG_LINE";
123const char * const mi_lttng_loglevel_str_debug_module = "TRACE_DEBUG_MODULE";
124const char * const mi_lttng_loglevel_str_debug_process = "TRACE_DEBUG_PROCESS";
125const char * const mi_lttng_loglevel_str_debug_program = "TRACE_DEBUG_PROGRAM";
126const char * const mi_lttng_loglevel_str_debug_system = "TRACE_DEBUG_SYSTEM";
127const char * const mi_lttng_loglevel_str_debug_unit = "TRACE_DEBUG_UNIT";
128const char * const mi_lttng_loglevel_str_emerg = "TRACE_EMERG";
129const char * const mi_lttng_loglevel_str_err = "TRACE_ERR";
130const char * const mi_lttng_loglevel_str_info = "TRACE_INFO";
131const char * const mi_lttng_loglevel_str_notice = "TRACE_NOTICE";
132const char * const mi_lttng_loglevel_str_unknown = "UNKNOWN";
133const char * const mi_lttng_loglevel_str_warning = "TRACE_WARNING";
134
135/* String related to loglevel JUL */
136const char * const mi_lttng_loglevel_str_jul_all = "JUL_ALL";
137const char * const mi_lttng_loglevel_str_jul_config = "JUL_CONFIG";
138const char * const mi_lttng_loglevel_str_jul_fine = "JUL_FINE";
139const char * const mi_lttng_loglevel_str_jul_finer = "JUL_FINER";
140const char * const mi_lttng_loglevel_str_jul_finest = "JUL_FINEST";
141const char * const mi_lttng_loglevel_str_jul_info = "JUL_INFO";
142const char * const mi_lttng_loglevel_str_jul_off = "JUL_OFF";
143const char * const mi_lttng_loglevel_str_jul_severe = "JUL_SEVERE";
144const char * const mi_lttng_loglevel_str_jul_warning = "JUL_WARNING";
145
146/* String related to loglevel LOG4J */
147const char * const mi_lttng_loglevel_str_log4j_off = "LOG4J_OFF";
148const char * const mi_lttng_loglevel_str_log4j_fatal = "LOG4J_FATAL";
149const char * const mi_lttng_loglevel_str_log4j_error = "LOG4J_ERROR";
150const char * const mi_lttng_loglevel_str_log4j_warn = "LOG4J_WARN";
151const char * const mi_lttng_loglevel_str_log4j_info = "LOG4J_INFO";
152const char * const mi_lttng_loglevel_str_log4j_debug = "LOG4J_DEBUG";
153const char * const mi_lttng_loglevel_str_log4j_trace = "LOG4J_TRACE";
154const char * const mi_lttng_loglevel_str_log4j_all = "LOG4J_ALL";
155
156/* String related to loglevel Python */
157const char * const mi_lttng_loglevel_str_python_critical = "PYTHON_CRITICAL";
158const char * const mi_lttng_loglevel_str_python_error = "PYTHON_ERROR";
159const char * const mi_lttng_loglevel_str_python_warning = "PYTHON_WARNING";
160const char * const mi_lttng_loglevel_str_python_info = "PYTHON_INFO";
161const char * const mi_lttng_loglevel_str_python_debug = "PYTHON_DEBUG";
162const char * const mi_lttng_loglevel_str_python_notset = "PYTHON_NOTSET";
163
164/* String related to loglevel type */
165const char * const mi_lttng_loglevel_type_all = "ALL";
166const char * const mi_lttng_loglevel_type_range = "RANGE";
167const char * const mi_lttng_loglevel_type_single = "SINGLE";
168const char * const mi_lttng_loglevel_type_unknown = "UNKNOWN";
169
170/* String related to a lttng_snapshot_output */
171const char * const mi_lttng_element_snapshot_ctrl_url = "ctrl_url";
172const char * const mi_lttng_element_snapshot_data_url = "data_url";
173const char * const mi_lttng_element_snapshot_max_size = "max_size";
174const char * const mi_lttng_element_snapshot_n_ptr = "n_ptr";
175const char * const mi_lttng_element_snapshot_session_name = "session_name";
176const char * const mi_lttng_element_snapshots = "snapshots";
177
178/* String related to track/untrack command */
179const char * const mi_lttng_element_track_untrack_all_wildcard = "*";
180
181LTTNG_HIDDEN const char * const mi_lttng_element_session_name = "session_name";
182
183/* String related to rotate command */
184LTTNG_HIDDEN const char * const mi_lttng_element_rotation = "rotation";
185LTTNG_HIDDEN const char * const mi_lttng_element_rotate_status = "status";
186LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule = "rotation_schedule";
187LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedules = "rotation_schedules";
188LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_result = "rotation_schedule_result";
189LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_results = "rotation_schedule_results";
190LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_periodic = "periodic";
191LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_periodic_time_us = "time_us";
192LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_size_threshold = "size_threshold";
193LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule_size_threshold_bytes = "bytes";
194LTTNG_HIDDEN const char * const mi_lttng_element_rotation_state = "state";
195LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location = "location";
196LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_local = "local";
197LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_local_absolute_path = "absolute_path";
198LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay = "relay";
199LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_host = "host";
200LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_control_port = "control_port";
201LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_data_port = "data_port";
202LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_protocol = "protocol";
203LTTNG_HIDDEN const char * const mi_lttng_element_rotation_location_relay_relative_path = "relative_path";
204
205/* String related to enum lttng_rotation_state */
206LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_ongoing = "ONGOING";
207LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_completed = "COMPLETED";
208LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_expired = "EXPIRED";
209LTTNG_HIDDEN const char * const mi_lttng_rotation_state_str_error = "ERROR";
210
211/* String related to enum lttng_trace_archive_location_relay_protocol_type */
212LTTNG_HIDDEN const char * const mi_lttng_rotation_location_relay_protocol_str_tcp = "TCP";
213
214/* String related to rate_policy elements */
215LTTNG_HIDDEN const char *const mi_lttng_element_rate_policy = "rate_policy";
216LTTNG_HIDDEN const char *const mi_lttng_element_rate_policy_every_n =
217 "rate_policy_every_n";
218LTTNG_HIDDEN const char *const mi_lttng_element_rate_policy_once_after_n =
219 "rate_policy_once_after_n";
220
221LTTNG_HIDDEN const char *const mi_lttng_element_rate_policy_every_n_interval =
222 "interval";
223LTTNG_HIDDEN const char
224 *const mi_lttng_element_rate_policy_once_after_n_threshold =
225 "threshold";
226
227/* String related to action elements */
228LTTNG_HIDDEN const char *const mi_lttng_element_action = "action";
229LTTNG_HIDDEN const char *const mi_lttng_element_action_list = "action_list";
230LTTNG_HIDDEN const char *const mi_lttng_element_action_notify = "action_notify";
231LTTNG_HIDDEN const char *const mi_lttng_element_action_start_session =
232 "action_start_session";
233LTTNG_HIDDEN const char *const mi_lttng_element_action_stop_session =
234 "action_stop_session";
235LTTNG_HIDDEN const char *const mi_lttng_element_action_rotate_session =
236 "action_rotate_session";
237LTTNG_HIDDEN const char *const mi_lttng_element_action_snapshot_session =
238 "action_snapshot_session";
239LTTNG_HIDDEN const char *const mi_lttng_element_action_snapshot_session_output =
240 "output";
241
242/* String related to condition */
243LTTNG_HIDDEN const char *const mi_lttng_element_condition = "condition";
244LTTNG_HIDDEN const char *const mi_lttng_element_condition_buffer_usage_high =
245 "condition_buffer_usage_high";
246LTTNG_HIDDEN const char *const mi_lttng_element_condition_buffer_usage_low =
247 "condition_buffer_usage_low";
248LTTNG_HIDDEN const char *const mi_lttng_element_condition_event_rule_matches =
249 "condition_event_rule_matches";
250LTTNG_HIDDEN const char *const mi_lttng_element_condition_session_consumed_size =
251 "condition_session_consumed_size";
252LTTNG_HIDDEN const char *const mi_lttng_element_condition_session_rotation =
253 "condition_session_rotation";
254LTTNG_HIDDEN const char
255 *const mi_lttng_element_condition_session_rotation_completed =
256 "condition_session_rotation_completed";
257LTTNG_HIDDEN const char
258 *const mi_lttng_element_condition_session_rotation_ongoing =
259 "condition_session_rotation_ongoing";
260
261LTTNG_HIDDEN const char *const mi_lttng_element_condition_channel_name =
262 "channel_name";
263LTTNG_HIDDEN const char *const mi_lttng_element_condition_threshold_bytes =
264 "threshold_bytes";
265LTTNG_HIDDEN const char *const mi_lttng_element_condition_threshold_ratio =
266 "threshold_ratio";
267
268/* String related to capture descriptor */
269LTTNG_HIDDEN const char *const mi_lttng_element_capture_descriptor =
270 "capture_descriptor";
271LTTNG_HIDDEN const char *const mi_lttng_element_capture_descriptors =
272 "capture_descriptors";
273
274/* String related to event expression */
275LTTNG_HIDDEN const char *const mi_lttng_element_event_expr = "event_expr";
276LTTNG_HIDDEN const char *const mi_lttng_element_event_expr_payload_field =
277 "event_expr_payload_field";
278LTTNG_HIDDEN const char *const mi_lttng_element_event_expr_channel_context_field =
279 "event_expr_channel_context_field";
280LTTNG_HIDDEN const char
281 *const mi_lttng_element_event_expr_app_specific_context_field =
282 "event_expr_app_specific_context_field";
283LTTNG_HIDDEN const char *const mi_lttng_element_event_expr_array_field_element =
284 "event_expr_array_field_element";
285LTTNG_HIDDEN const char *const mi_lttng_element_event_expr_provider_name =
286 "provider_name";
287LTTNG_HIDDEN const char *const mi_lttng_element_event_expr_type_name =
288 "type_name";
289LTTNG_HIDDEN const char *const mi_lttng_element_event_expr_index = "index";
290
291/* String related to event rule */
292LTTNG_HIDDEN const char *const mi_lttng_element_event_rule = "event_rule";
293
294/* String related to lttng_event_rule_type */
295LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_event_name =
296 "event_name";
297LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_name_pattern =
298 "name_pattern";
299LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_filter_expression =
300 "filter_expression";
301
302LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_jul_logging =
303 "event_rule_jul_logging";
304LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_kernel_kprobe =
305 "event_rule_kernel_kprobe";
306LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_kernel_syscall =
307 "event_rule_kernel_syscall";
308LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_kernel_tracepoint =
309 "event_rule_kernel_tracepoint";
310LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_kernel_uprobe =
311 "event_rule_kernel_uprobe";
312LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_log4j_logging =
313 "event_rule_log4j_logging";
314LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_python_logging =
315 "event_rule_python_logging";
316LTTNG_HIDDEN const char *const mi_lttng_element_event_rule_user_tracepoint =
317 "event_rule_user_tracepoint";
318
319/* String related to lttng_event_rule_kernel_syscall. */
320LTTNG_HIDDEN const char *const
321 mi_lttng_element_event_rule_kernel_syscall_emission_site =
322 "emission_site";
323
324/* String related to enum lttng_event_rule_kernel_syscall_emission_site. */
325LTTNG_HIDDEN const char *const
326 mi_lttng_event_rule_kernel_syscall_emission_site_entry_exit =
327 "entry+exit";
328LTTNG_HIDDEN const char
329 *const mi_lttng_event_rule_kernel_syscall_emission_site_entry =
330 "entry";
331LTTNG_HIDDEN const char *const
332 mi_lttng_event_rule_kernel_syscall_emission_site_exit = "exit";
333
334/* String related to lttng_event_rule_user_tracepoint */
335LTTNG_HIDDEN const char *const
336 mi_lttng_element_event_rule_user_tracepoint_name_pattern_exclusions =
337 "name_pattern_exclusions";
338LTTNG_HIDDEN const char *const
339 mi_lttng_element_event_rule_user_tracepoint_name_pattern_exclusion =
340 "name_pattern_exclusion";
341
342/* String related to log level rule. */
343LTTNG_HIDDEN const char *const mi_lttng_element_log_level_rule =
344 "log_level_rule";
345LTTNG_HIDDEN const char *const mi_lttng_element_log_level_rule_exactly =
346 "log_level_rule_exactly";
347LTTNG_HIDDEN const char
348 *const mi_lttng_element_log_level_rule_at_least_as_severe_as =
349 "log_level_rule_at_least_as_severe_as";
350LTTNG_HIDDEN const char *const mi_lttng_element_log_level_rule_level = "level";
351
352/* String related to kernel probe location. */
353LTTNG_HIDDEN const char *const mi_lttng_element_kernel_probe_location =
354 "kernel_probe_location";
355LTTNG_HIDDEN const char
356 *const mi_lttng_element_kernel_probe_location_symbol_offset =
357 "kernel_probe_location_symbol_offset";
358LTTNG_HIDDEN const char *const
359 mi_lttng_element_kernel_probe_location_symbol_offset_name =
360 "name";
361LTTNG_HIDDEN const char *const
362 mi_lttng_element_kernel_probe_location_symbol_offset_offset =
363 "offset";
364
365LTTNG_HIDDEN const char *const mi_lttng_element_kernel_probe_location_address =
366 "kernel_probe_location_address";
367LTTNG_HIDDEN const char
368 *const mi_lttng_element_kernel_probe_location_address_address =
369 "address";
370
371/* String related to userspace probe location. */
372LTTNG_HIDDEN const char *const mi_lttng_element_userspace_probe_location =
373 "userspace_probe_location";
374LTTNG_HIDDEN const char
375 *const mi_lttng_element_userspace_probe_location_binary_path =
376 "binary_path";
377LTTNG_HIDDEN const char
378 *const mi_lttng_element_userspace_probe_location_function =
379 "userspace_probe_location_function";
380LTTNG_HIDDEN const char
381 *const mi_lttng_element_userspace_probe_location_function_name =
382 "name";
383LTTNG_HIDDEN const char
384 *const mi_lttng_element_userspace_probe_location_lookup_method =
385 "userspace_probe_location_lookup_method";
386LTTNG_HIDDEN const char *const
387 mi_lttng_element_userspace_probe_location_lookup_method_function_default =
388 "userspace_probe_location_lookup_method_function_default";
389LTTNG_HIDDEN const char *const
390 mi_lttng_element_userspace_probe_location_lookup_method_function_elf =
391 "userspace_probe_location_lookup_method_function_elf";
392LTTNG_HIDDEN const char *const
393 mi_lttng_element_userspace_probe_location_lookup_method_tracepoint_sdt =
394 "userspace_probe_location_lookup_method_tracepoint_sdt";
395LTTNG_HIDDEN const char
396 *const mi_lttng_element_userspace_probe_location_tracepoint =
397 "userspace_probe_location_tracepoint";
398LTTNG_HIDDEN const char *const
399 mi_lttng_element_userspace_probe_location_tracepoint_probe_name =
400 "probe_name";
401LTTNG_HIDDEN const char *const
402 mi_lttng_element_userspace_probe_location_tracepoint_provider_name =
403 "provider_name";
404
405/* String related to enum
406 * lttng_userspace_probe_location_function_instrumentation_type */
407LTTNG_HIDDEN const char *const
408 mi_lttng_element_userspace_probe_location_function_instrumentation_type =
409 "instrumentation_type";
410LTTNG_HIDDEN const char *const
411 mi_lttng_userspace_probe_location_function_instrumentation_type_entry =
412 "ENTRY";
413
414/* String related to trigger */
415LTTNG_HIDDEN const char *const mi_lttng_element_triggers = "triggers";
416LTTNG_HIDDEN const char *const mi_lttng_element_trigger = "trigger";
417LTTNG_HIDDEN const char *const mi_lttng_element_trigger_owner_uid = "owner_uid";
418
419/* String related to error_query. */
420LTTNG_HIDDEN const char *const mi_lttng_element_error_query_result =
421 "error_query_result";
422LTTNG_HIDDEN const char *const mi_lttng_element_error_query_result_counter =
423 "error_query_result_counter";
424LTTNG_HIDDEN const char *const
425 mi_lttng_element_error_query_result_counter_value = "value";
426LTTNG_HIDDEN const char *const mi_lttng_element_error_query_result_description =
427 "description";
428LTTNG_HIDDEN const char *const mi_lttng_element_error_query_result_name =
429 "name";
430LTTNG_HIDDEN const char *const mi_lttng_element_error_query_result_type =
431 "type";
432LTTNG_HIDDEN const char *const mi_lttng_element_error_query_results =
433 "error_query_results";
434
435/* String related to add-context command */
436LTTNG_HIDDEN const char * const mi_lttng_element_context_symbol = "symbol";
437
438/* Deprecated symbols preserved for ABI compatibility. */
439const char * const mi_lttng_context_type_perf_counter;
440const char * const mi_lttng_context_type_perf_cpu_counter;
441const char * const mi_lttng_context_type_perf_thread_counter;
442const char * const mi_lttng_element_track_untrack_pid_target;
443const char * const mi_lttng_element_track_untrack_targets;
444const char * const mi_lttng_element_calibrate;
445const char * const mi_lttng_element_calibrate_function;
446const char * const mi_lttng_element_command_calibrate;
447
448/* This is a merge of jul loglevel and regular loglevel
449 * Those should never overlap by definition
450 * (see struct lttng_event loglevel)
451 */
452LTTNG_HIDDEN
453const char *mi_lttng_loglevel_string(int value, enum lttng_domain_type domain)
454{
455 switch (domain) {
456 case LTTNG_DOMAIN_KERNEL:
457 case LTTNG_DOMAIN_UST:
458 switch (value) {
459 case -1:
460 return mi_lttng_element_empty;
461 case LTTNG_LOGLEVEL_EMERG:
462 return mi_lttng_loglevel_str_emerg;
463 case LTTNG_LOGLEVEL_ALERT:
464 return mi_lttng_loglevel_str_alert;
465 case LTTNG_LOGLEVEL_CRIT:
466 return mi_lttng_loglevel_str_crit;
467 case LTTNG_LOGLEVEL_ERR:
468 return mi_lttng_loglevel_str_err;
469 case LTTNG_LOGLEVEL_WARNING:
470 return mi_lttng_loglevel_str_warning;
471 case LTTNG_LOGLEVEL_NOTICE:
472 return mi_lttng_loglevel_str_notice;
473 case LTTNG_LOGLEVEL_INFO:
474 return mi_lttng_loglevel_str_info;
475 case LTTNG_LOGLEVEL_DEBUG_SYSTEM:
476 return mi_lttng_loglevel_str_debug_system;
477 case LTTNG_LOGLEVEL_DEBUG_PROGRAM:
478 return mi_lttng_loglevel_str_debug_program;
479 case LTTNG_LOGLEVEL_DEBUG_PROCESS:
480 return mi_lttng_loglevel_str_debug_process;
481 case LTTNG_LOGLEVEL_DEBUG_MODULE:
482 return mi_lttng_loglevel_str_debug_module;
483 case LTTNG_LOGLEVEL_DEBUG_UNIT:
484 return mi_lttng_loglevel_str_debug_unit;
485 case LTTNG_LOGLEVEL_DEBUG_FUNCTION:
486 return mi_lttng_loglevel_str_debug_function;
487 case LTTNG_LOGLEVEL_DEBUG_LINE:
488 return mi_lttng_loglevel_str_debug_line;
489 case LTTNG_LOGLEVEL_DEBUG:
490 return mi_lttng_loglevel_str_debug;
491 default:
492 return mi_lttng_loglevel_str_unknown;
493 }
494 break;
495 case LTTNG_DOMAIN_LOG4J:
496 switch (value) {
497 case -1:
498 return mi_lttng_element_empty;
499 case LTTNG_LOGLEVEL_LOG4J_OFF:
500 return mi_lttng_loglevel_str_log4j_off;
501 case LTTNG_LOGLEVEL_LOG4J_FATAL:
502 return mi_lttng_loglevel_str_log4j_fatal;
503 case LTTNG_LOGLEVEL_LOG4J_ERROR:
504 return mi_lttng_loglevel_str_log4j_error;
505 case LTTNG_LOGLEVEL_LOG4J_WARN:
506 return mi_lttng_loglevel_str_log4j_warn;
507 case LTTNG_LOGLEVEL_LOG4J_INFO:
508 return mi_lttng_loglevel_str_log4j_info;
509 case LTTNG_LOGLEVEL_LOG4J_DEBUG:
510 return mi_lttng_loglevel_str_log4j_debug;
511 case LTTNG_LOGLEVEL_LOG4J_TRACE:
512 return mi_lttng_loglevel_str_log4j_trace;
513 case LTTNG_LOGLEVEL_LOG4J_ALL:
514 return mi_lttng_loglevel_str_log4j_all;
515 default:
516 return mi_lttng_loglevel_str_unknown;
517 }
518 break;
519 case LTTNG_DOMAIN_JUL:
520 switch (value) {
521 case -1:
522 return mi_lttng_element_empty;
523 case LTTNG_LOGLEVEL_JUL_OFF:
524 return mi_lttng_loglevel_str_jul_off;
525 case LTTNG_LOGLEVEL_JUL_SEVERE:
526 return mi_lttng_loglevel_str_jul_severe;
527 case LTTNG_LOGLEVEL_JUL_WARNING:
528 return mi_lttng_loglevel_str_jul_warning;
529 case LTTNG_LOGLEVEL_JUL_INFO:
530 return mi_lttng_loglevel_str_jul_info;
531 case LTTNG_LOGLEVEL_JUL_CONFIG:
532 return mi_lttng_loglevel_str_jul_config;
533 case LTTNG_LOGLEVEL_JUL_FINE:
534 return mi_lttng_loglevel_str_jul_fine;
535 case LTTNG_LOGLEVEL_JUL_FINER:
536 return mi_lttng_loglevel_str_jul_finer;
537 case LTTNG_LOGLEVEL_JUL_FINEST:
538 return mi_lttng_loglevel_str_jul_finest;
539 case LTTNG_LOGLEVEL_JUL_ALL:
540 return mi_lttng_loglevel_str_jul_all;
541 default:
542 return mi_lttng_loglevel_str_unknown;
543 }
544 break;
545 case LTTNG_DOMAIN_PYTHON:
546 switch (value) {
547 case LTTNG_LOGLEVEL_PYTHON_CRITICAL:
548 return mi_lttng_loglevel_str_python_critical;
549 case LTTNG_LOGLEVEL_PYTHON_ERROR:
550 return mi_lttng_loglevel_str_python_error;
551 case LTTNG_LOGLEVEL_PYTHON_WARNING:
552 return mi_lttng_loglevel_str_python_warning;
553 case LTTNG_LOGLEVEL_PYTHON_INFO:
554 return mi_lttng_loglevel_str_python_info;
555 case LTTNG_LOGLEVEL_PYTHON_DEBUG:
556 return mi_lttng_loglevel_str_python_debug;
557 case LTTNG_LOGLEVEL_PYTHON_NOTSET:
558 return mi_lttng_loglevel_str_python_notset;
559 default:
560 return mi_lttng_loglevel_str_unknown;
561 }
562 break;
563 default:
564 return mi_lttng_loglevel_str_unknown;
565 }
566}
567
568LTTNG_HIDDEN
569const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value)
570{
571 switch (value) {
572 case LTTNG_EVENT_LOGLEVEL_ALL:
573 return mi_lttng_loglevel_type_all;
574 case LTTNG_EVENT_LOGLEVEL_RANGE:
575 return mi_lttng_loglevel_type_range;
576 case LTTNG_EVENT_LOGLEVEL_SINGLE:
577 return mi_lttng_loglevel_type_single;
578 default:
579 return mi_lttng_loglevel_type_unknown;
580 }
581}
582
583static
584const char *mi_lttng_eventtype_string(enum lttng_event_type value)
585{
586 switch (value) {
587 case LTTNG_EVENT_ALL:
588 return config_event_type_all;
589 case LTTNG_EVENT_TRACEPOINT:
590 return config_event_type_tracepoint;
591 case LTTNG_EVENT_PROBE:
592 return config_event_type_probe;
593 case LTTNG_EVENT_USERSPACE_PROBE:
594 return config_event_type_userspace_probe;
595 case LTTNG_EVENT_FUNCTION:
596 return config_event_type_function;
597 case LTTNG_EVENT_FUNCTION_ENTRY:
598 return config_event_type_function_entry;
599 case LTTNG_EVENT_SYSCALL:
600 return config_event_type_syscall;
601 case LTTNG_EVENT_NOOP:
602 return config_event_type_noop;
603 default:
604 return mi_lttng_element_empty;
605 }
606}
607
608static
609const char *mi_lttng_event_contexttype_string(enum lttng_event_context_type val)
610{
611 switch (val) {
612 case LTTNG_EVENT_CONTEXT_PID:
613 return config_event_context_pid;
614 case LTTNG_EVENT_CONTEXT_PROCNAME:
615 return config_event_context_procname;
616 case LTTNG_EVENT_CONTEXT_PRIO:
617 return config_event_context_prio;
618 case LTTNG_EVENT_CONTEXT_NICE:
619 return config_event_context_nice;
620 case LTTNG_EVENT_CONTEXT_VPID:
621 return config_event_context_vpid;
622 case LTTNG_EVENT_CONTEXT_TID:
623 return config_event_context_tid;
624 case LTTNG_EVENT_CONTEXT_VTID:
625 return config_event_context_vtid;
626 case LTTNG_EVENT_CONTEXT_PPID:
627 return config_event_context_ppid;
628 case LTTNG_EVENT_CONTEXT_VPPID:
629 return config_event_context_vppid;
630 case LTTNG_EVENT_CONTEXT_PTHREAD_ID:
631 return config_event_context_pthread_id;
632 case LTTNG_EVENT_CONTEXT_HOSTNAME:
633 return config_event_context_hostname;
634 case LTTNG_EVENT_CONTEXT_IP:
635 return config_event_context_ip;
636 case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE:
637 return config_event_context_interruptible;
638 case LTTNG_EVENT_CONTEXT_PREEMPTIBLE:
639 return config_event_context_preemptible;
640 case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE:
641 return config_event_context_need_reschedule;
642 case LTTNG_EVENT_CONTEXT_MIGRATABLE:
643 return config_event_context_migratable;
644 case LTTNG_EVENT_CONTEXT_CALLSTACK_USER:
645 return config_event_context_callstack_user;
646 case LTTNG_EVENT_CONTEXT_CALLSTACK_KERNEL:
647 return config_event_context_callstack_kernel;
648 case LTTNG_EVENT_CONTEXT_CGROUP_NS:
649 return config_event_context_cgroup_ns;
650 case LTTNG_EVENT_CONTEXT_IPC_NS:
651 return config_event_context_ipc_ns;
652 case LTTNG_EVENT_CONTEXT_MNT_NS:
653 return config_event_context_mnt_ns;
654 case LTTNG_EVENT_CONTEXT_NET_NS:
655 return config_event_context_net_ns;
656 case LTTNG_EVENT_CONTEXT_PID_NS:
657 return config_event_context_pid_ns;
658 case LTTNG_EVENT_CONTEXT_TIME_NS:
659 return config_event_context_time_ns;
660 case LTTNG_EVENT_CONTEXT_USER_NS:
661 return config_event_context_user_ns;
662 case LTTNG_EVENT_CONTEXT_UTS_NS:
663 return config_event_context_uts_ns;
664 case LTTNG_EVENT_CONTEXT_UID:
665 return config_event_context_uid;
666 case LTTNG_EVENT_CONTEXT_EUID:
667 return config_event_context_euid;
668 case LTTNG_EVENT_CONTEXT_SUID:
669 return config_event_context_suid;
670 case LTTNG_EVENT_CONTEXT_GID:
671 return config_event_context_gid;
672 case LTTNG_EVENT_CONTEXT_EGID:
673 return config_event_context_egid;
674 case LTTNG_EVENT_CONTEXT_SGID:
675 return config_event_context_sgid;
676 case LTTNG_EVENT_CONTEXT_VUID:
677 return config_event_context_vuid;
678 case LTTNG_EVENT_CONTEXT_VEUID:
679 return config_event_context_veuid;
680 case LTTNG_EVENT_CONTEXT_VSUID:
681 return config_event_context_vsuid;
682 case LTTNG_EVENT_CONTEXT_VGID:
683 return config_event_context_vgid;
684 case LTTNG_EVENT_CONTEXT_VEGID:
685 return config_event_context_vegid;
686 case LTTNG_EVENT_CONTEXT_VSGID:
687 return config_event_context_vsgid;
688 default:
689 return NULL;
690 }
691}
692
693LTTNG_HIDDEN
694const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val)
695{
696 switch (val) {
697 case(LTTNG_EVENT_FIELD_INTEGER):
698 return mi_lttng_element_type_integer;
699 case(LTTNG_EVENT_FIELD_ENUM):
700 return mi_lttng_element_type_enum;
701 case(LTTNG_EVENT_FIELD_FLOAT):
702 return mi_lttng_element_type_float;
703 case(LTTNG_EVENT_FIELD_STRING):
704 return mi_lttng_element_type_string;
705 default:
706 return mi_lttng_element_type_other;
707 }
708}
709
710LTTNG_HIDDEN
711const char *mi_lttng_domaintype_string(enum lttng_domain_type value)
712{
713 /* Note: This is a *duplicate* of get_domain_str from bin/lttng/utils.c */
714 switch (value) {
715 case LTTNG_DOMAIN_KERNEL:
716 return config_domain_type_kernel;
717 case LTTNG_DOMAIN_UST:
718 return config_domain_type_ust;
719 case LTTNG_DOMAIN_JUL:
720 return config_domain_type_jul;
721 case LTTNG_DOMAIN_LOG4J:
722 return config_domain_type_log4j;
723 case LTTNG_DOMAIN_PYTHON:
724 return config_domain_type_python;
725 default:
726 /* Should not have an unknown domain */
727 assert(0);
728 return NULL;
729 }
730}
731
732LTTNG_HIDDEN
733const char *mi_lttng_buffertype_string(enum lttng_buffer_type value)
734{
735 switch (value) {
736 case LTTNG_BUFFER_PER_PID:
737 return config_buffer_type_per_pid;
738 case LTTNG_BUFFER_PER_UID:
739 return config_buffer_type_per_uid;
740 case LTTNG_BUFFER_GLOBAL:
741 return config_buffer_type_global;
742 default:
743 /* Should not have an unknow buffer type */
744 assert(0);
745 return NULL;
746 }
747}
748
749LTTNG_HIDDEN
750const char *mi_lttng_rotation_state_string(enum lttng_rotation_state value)
751{
752 switch (value) {
753 case LTTNG_ROTATION_STATE_ONGOING:
754 return mi_lttng_rotation_state_str_ongoing;
755 case LTTNG_ROTATION_STATE_COMPLETED:
756 return mi_lttng_rotation_state_str_completed;
757 case LTTNG_ROTATION_STATE_EXPIRED:
758 return mi_lttng_rotation_state_str_expired;
759 case LTTNG_ROTATION_STATE_ERROR:
760 return mi_lttng_rotation_state_str_error;
761 default:
762 /* Should not have an unknow rotation state. */
763 assert(0);
764 return NULL;
765 }
766}
767
768LTTNG_HIDDEN
769const char *mi_lttng_trace_archive_location_relay_protocol_type_string(
770 enum lttng_trace_archive_location_relay_protocol_type value)
771{
772 switch (value) {
773 case LTTNG_TRACE_ARCHIVE_LOCATION_RELAY_PROTOCOL_TYPE_TCP:
774 return mi_lttng_rotation_location_relay_protocol_str_tcp;
775 default:
776 /* Should not have an unknown relay protocol. */
777 assert(0);
778 return NULL;
779 }
780}
781
782LTTNG_HIDDEN
783struct mi_writer *mi_lttng_writer_create(int fd_output, int mi_output_type)
784{
785 struct mi_writer *mi_writer;
786
787 mi_writer = zmalloc(sizeof(struct mi_writer));
788 if (!mi_writer) {
789 PERROR("zmalloc mi_writer_create");
790 goto end;
791 }
792 if (mi_output_type == LTTNG_MI_XML) {
793 mi_writer->writer = config_writer_create(fd_output, 0);
794 if (!mi_writer->writer) {
795 goto err_destroy;
796 }
797 mi_writer->type = LTTNG_MI_XML;
798 } else {
799 goto err_destroy;
800 }
801
802end:
803 return mi_writer;
804
805err_destroy:
806 free(mi_writer);
807 return NULL;
808}
809
810LTTNG_HIDDEN
811int mi_lttng_writer_destroy(struct mi_writer *writer)
812{
813 int ret;
814
815 if (!writer) {
816 ret = -EINVAL;
817 goto end;
818 }
819
820 ret = config_writer_destroy(writer->writer);
821 if (ret < 0) {
822 goto end;
823 }
824
825 free(writer);
826end:
827 return ret;
828}
829
830LTTNG_HIDDEN
831int mi_lttng_writer_command_open(struct mi_writer *writer, const char *command)
832{
833 int ret;
834
835 /*
836 * A command is always the MI's root node, it must declare the current
837 * namespace and schema URIs and the schema's version.
838 */
839 ret = config_writer_open_element(writer->writer,
840 mi_lttng_element_command);
841 if (ret) {
842 goto end;
843 }
844
845 ret = config_writer_write_attribute(writer->writer,
846 mi_lttng_xmlns, DEFAULT_LTTNG_MI_NAMESPACE);
847 if (ret) {
848 goto end;
849 }
850
851 ret = config_writer_write_attribute(writer->writer,
852 mi_lttng_xmlns_xsi, mi_lttng_w3_schema_uri);
853 if (ret) {
854 goto end;
855 }
856
857 ret = config_writer_write_attribute(writer->writer,
858 mi_lttng_schema_location,
859 mi_lttng_schema_location_uri);
860 if (ret) {
861 goto end;
862 }
863
864 ret = config_writer_write_attribute(writer->writer,
865 mi_lttng_schema_version,
866 mi_lttng_schema_version_value);
867 if (ret) {
868 goto end;
869 }
870
871 ret = mi_lttng_writer_write_element_string(writer,
872 mi_lttng_element_command_name, command);
873end:
874 return ret;
875}
876
877LTTNG_HIDDEN
878int mi_lttng_writer_command_close(struct mi_writer *writer)
879{
880 return mi_lttng_writer_close_element(writer);
881}
882
883LTTNG_HIDDEN
884int mi_lttng_writer_open_element(struct mi_writer *writer,
885 const char *element_name)
886{
887 return config_writer_open_element(writer->writer, element_name);
888}
889
890LTTNG_HIDDEN
891int mi_lttng_writer_close_element(struct mi_writer *writer)
892{
893 return config_writer_close_element(writer->writer);
894}
895
896LTTNG_HIDDEN
897int mi_lttng_close_multi_element(struct mi_writer *writer,
898 unsigned int nb_element)
899{
900 int ret, i;
901
902 if (nb_element < 1) {
903 ret = 0;
904 goto end;
905 }
906 for (i = 0; i < nb_element; i++) {
907 ret = mi_lttng_writer_close_element(writer);
908 if (ret) {
909 goto end;
910 }
911 }
912end:
913 return ret;
914}
915
916LTTNG_HIDDEN
917int mi_lttng_writer_write_element_unsigned_int(struct mi_writer *writer,
918 const char *element_name, uint64_t value)
919{
920 return config_writer_write_element_unsigned_int(writer->writer,
921 element_name, value);
922}
923
924LTTNG_HIDDEN
925int mi_lttng_writer_write_element_signed_int(struct mi_writer *writer,
926 const char *element_name, int64_t value)
927{
928 return config_writer_write_element_signed_int(writer->writer,
929 element_name, value);
930}
931
932LTTNG_HIDDEN
933int mi_lttng_writer_write_element_bool(struct mi_writer *writer,
934 const char *element_name, int value)
935{
936 return config_writer_write_element_bool(writer->writer,
937 element_name, value);
938}
939
940LTTNG_HIDDEN
941int mi_lttng_writer_write_element_string(struct mi_writer *writer,
942 const char *element_name, const char *value)
943{
944 return config_writer_write_element_string(writer->writer,
945 element_name, value);
946}
947
948LTTNG_HIDDEN
949int mi_lttng_writer_write_element_double(struct mi_writer *writer,
950 const char *element_name,
951 double value)
952{
953 return config_writer_write_element_double(
954 writer->writer, element_name, value);
955}
956
957LTTNG_HIDDEN
958int mi_lttng_version(struct mi_writer *writer, struct mi_lttng_version *version,
959 const char *lttng_description, const char *lttng_license)
960{
961 int ret;
962
963 /* Open version */
964 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_version);
965 if (ret) {
966 goto end;
967 }
968
969 /* Version string (contain info like rc etc.) */
970 ret = mi_lttng_writer_write_element_string(writer,
971 mi_lttng_element_version_str, version->version);
972 if (ret) {
973 goto end;
974 }
975
976 /* Major version number */
977 ret = mi_lttng_writer_write_element_unsigned_int(writer,
978 mi_lttng_element_version_major, version->version_major);
979 if (ret) {
980 goto end;
981 }
982
983 /* Minor version number */
984 ret = mi_lttng_writer_write_element_unsigned_int(writer,
985 mi_lttng_element_version_minor, version->version_minor);
986 if (ret) {
987 goto end;
988 }
989
990 /* Commit version number */
991 ret = mi_lttng_writer_write_element_string(writer,
992 mi_lttng_element_version_commit, version->version_commit);
993 if (ret) {
994 goto end;
995 }
996
997 /* Patch number */
998 ret = mi_lttng_writer_write_element_unsigned_int(writer,
999 mi_lttng_element_version_patch_level, version->version_patchlevel);
1000 if (ret) {
1001 goto end;
1002 }
1003
1004 /* Name of the version */
1005 ret = mi_lttng_writer_write_element_string(writer,
1006 config_element_name, version->version_name);
1007 if (ret) {
1008 goto end;
1009 }
1010
1011 /* Description mostly related to beer... */
1012 ret = mi_lttng_writer_write_element_string(writer,
1013 mi_lttng_element_version_description, lttng_description);
1014 if (ret) {
1015 goto end;
1016 }
1017
1018 /* url */
1019 ret = mi_lttng_writer_write_element_string(writer,
1020 mi_lttng_element_version_web, version->package_url);
1021 if (ret) {
1022 goto end;
1023 }
1024
1025 /* License: free as in free beer...no...*speech* */
1026 ret = mi_lttng_writer_write_element_string(writer,
1027 mi_lttng_element_version_license, lttng_license);
1028 if (ret) {
1029 goto end;
1030 }
1031
1032 /* Close version element */
1033 ret = mi_lttng_writer_close_element(writer);
1034
1035end:
1036 return ret;
1037}
1038
1039LTTNG_HIDDEN
1040int mi_lttng_sessions_open(struct mi_writer *writer)
1041{
1042 return mi_lttng_writer_open_element(writer, config_element_sessions);
1043}
1044
1045LTTNG_HIDDEN
1046int mi_lttng_session(struct mi_writer *writer,
1047 struct lttng_session *session, int is_open)
1048{
1049 int ret;
1050
1051 assert(session);
1052
1053 /* Open sessions element */
1054 ret = mi_lttng_writer_open_element(writer,
1055 config_element_session);
1056 if (ret) {
1057 goto end;
1058 }
1059
1060 /* Name of the session */
1061 ret = mi_lttng_writer_write_element_string(writer,
1062 config_element_name, session->name);
1063 if (ret) {
1064 goto end;
1065 }
1066
1067 /* Path */
1068 ret = mi_lttng_writer_write_element_string(writer,
1069 config_element_path, session->path);
1070 if (ret) {
1071 goto end;
1072 }
1073
1074 /* Enabled ? */
1075 ret = mi_lttng_writer_write_element_bool(writer,
1076 config_element_enabled, session->enabled);
1077 if (ret) {
1078 goto end;
1079 }
1080
1081 /* Snapshot mode */
1082 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1083 config_element_snapshot_mode, session->snapshot_mode);
1084 if (ret) {
1085 goto end;
1086 }
1087
1088 /* Live timer interval in usec */
1089 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1090 config_element_live_timer_interval,
1091 session->live_timer_interval);
1092 if (ret) {
1093 goto end;
1094 }
1095
1096 if (!is_open) {
1097 /* Closing session element */
1098 ret = mi_lttng_writer_close_element(writer);
1099 }
1100end:
1101 return ret;
1102
1103}
1104
1105LTTNG_HIDDEN
1106int mi_lttng_domains_open(struct mi_writer *writer)
1107{
1108 return mi_lttng_writer_open_element(writer, config_element_domains);
1109}
1110
1111LTTNG_HIDDEN
1112int mi_lttng_domain(struct mi_writer *writer,
1113 struct lttng_domain *domain, int is_open)
1114{
1115 int ret = 0;
1116 const char *str_domain;
1117 const char *str_buffer;
1118
1119 assert(domain);
1120
1121 /* Open domain element */
1122 ret = mi_lttng_writer_open_element(writer, config_element_domain);
1123 if (ret) {
1124 goto end;
1125 }
1126
1127 /* Domain Type */
1128 str_domain = mi_lttng_domaintype_string(domain->type);
1129 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
1130 str_domain);
1131 if (ret) {
1132 goto end;
1133 }
1134
1135 /* Buffer Type */
1136 str_buffer= mi_lttng_buffertype_string(domain->buf_type);
1137 ret = mi_lttng_writer_write_element_string(writer,
1138 config_element_buffer_type, str_buffer);
1139 if (ret) {
1140 goto end;
1141 }
1142
1143 /* TODO: union attr
1144 * This union is not currently used and was added for
1145 * future ust domain support.
1146 * Date: 25-06-2014
1147 * */
1148
1149 if (!is_open) {
1150 /* Closing domain element */
1151 ret = mi_lttng_writer_close_element(writer);
1152 }
1153
1154end:
1155 return ret;
1156
1157}
1158
1159LTTNG_HIDDEN
1160int mi_lttng_channels_open(struct mi_writer *writer)
1161{
1162 return mi_lttng_writer_open_element(writer, config_element_channels);
1163}
1164
1165LTTNG_HIDDEN
1166int mi_lttng_channel(struct mi_writer *writer,
1167 struct lttng_channel *channel, int is_open)
1168{
1169 int ret = 0;
1170
1171 assert(channel);
1172
1173 /* Opening channel element */
1174 ret = mi_lttng_writer_open_element(writer, config_element_channel);
1175 if (ret) {
1176 goto end;
1177 }
1178
1179 /* Name */
1180 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1181 channel->name);
1182 if (ret) {
1183 goto end;
1184 }
1185
1186 /* Enabled ? */
1187 ret = mi_lttng_writer_write_element_bool(writer,
1188 config_element_enabled, channel->enabled);
1189 if (ret) {
1190 goto end;
1191 }
1192
1193 /* Attribute */
1194 ret = mi_lttng_channel_attr(writer, &channel->attr);
1195 if (ret) {
1196 goto end;
1197 }
1198
1199 if (!is_open) {
1200 /* Closing channel element */
1201 ret = mi_lttng_writer_close_element(writer);
1202 if (ret) {
1203 goto end;
1204 }
1205 }
1206end:
1207 return ret;
1208}
1209
1210LTTNG_HIDDEN
1211int mi_lttng_channel_attr(struct mi_writer *writer,
1212 struct lttng_channel_attr *attr)
1213{
1214 int ret = 0;
1215 struct lttng_channel *chan = caa_container_of(attr,
1216 struct lttng_channel, attr);
1217 uint64_t discarded_events, lost_packets, monitor_timer_interval;
1218 int64_t blocking_timeout;
1219
1220 assert(attr);
1221
1222 ret = lttng_channel_get_discarded_event_count(chan, &discarded_events);
1223 if (ret) {
1224 goto end;
1225 }
1226
1227 ret = lttng_channel_get_lost_packet_count(chan, &lost_packets);
1228 if (ret) {
1229 goto end;
1230 }
1231
1232 ret = lttng_channel_get_monitor_timer_interval(chan,
1233 &monitor_timer_interval);
1234 if (ret) {
1235 goto end;
1236 }
1237
1238 ret = lttng_channel_get_blocking_timeout(chan,
1239 &blocking_timeout);
1240 if (ret) {
1241 goto end;
1242 }
1243
1244 /* Opening Attributes */
1245 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1246 if (ret) {
1247 goto end;
1248 }
1249
1250 /* Overwrite */
1251 ret = mi_lttng_writer_write_element_string(writer,
1252 config_element_overwrite_mode,
1253 attr->overwrite ? config_overwrite_mode_overwrite :
1254 config_overwrite_mode_discard);
1255 if (ret) {
1256 goto end;
1257 }
1258
1259 /* Sub buffer size in byte */
1260 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1261 config_element_subbuf_size, attr->subbuf_size);
1262 if (ret) {
1263 goto end;
1264 }
1265
1266 /* Number of subbuffer (power of two) */
1267 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1268 config_element_num_subbuf,
1269 attr->num_subbuf);
1270 if (ret) {
1271 goto end;
1272 }
1273
1274 /* Switch timer interval in usec */
1275 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1276 config_element_switch_timer_interval,
1277 attr->switch_timer_interval);
1278 if (ret) {
1279 goto end;
1280 }
1281
1282 /* Read timer interval in usec */
1283 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1284 config_element_read_timer_interval,
1285 attr->read_timer_interval);
1286 if (ret) {
1287 goto end;
1288 }
1289
1290 /* Monitor timer interval in usec */
1291 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1292 config_element_monitor_timer_interval,
1293 monitor_timer_interval);
1294 if (ret) {
1295 goto end;
1296 }
1297
1298 /* Retry timeout in usec */
1299 ret = mi_lttng_writer_write_element_signed_int(writer,
1300 config_element_blocking_timeout,
1301 blocking_timeout);
1302 if (ret) {
1303 goto end;
1304 }
1305
1306 /* Event output */
1307 ret = mi_lttng_writer_write_element_string(writer,
1308 config_element_output_type,
1309 attr->output == LTTNG_EVENT_SPLICE ?
1310 config_output_type_splice : config_output_type_mmap);
1311 if (ret) {
1312 goto end;
1313 }
1314
1315 /* Tracefile size in bytes */
1316 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1317 config_element_tracefile_size, attr->tracefile_size);
1318 if (ret) {
1319 goto end;
1320 }
1321
1322 /* Count of tracefiles */
1323 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1324 config_element_tracefile_count,
1325 attr->tracefile_count);
1326 if (ret) {
1327 goto end;
1328 }
1329
1330 /* Live timer interval in usec*/
1331 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1332 config_element_live_timer_interval,
1333 attr->live_timer_interval);
1334 if (ret) {
1335 goto end;
1336 }
1337
1338 /* Discarded events */
1339 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1340 config_element_discarded_events,
1341 discarded_events);
1342 if (ret) {
1343 goto end;
1344 }
1345
1346 /* Lost packets */
1347 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1348 config_element_lost_packets,
1349 lost_packets);
1350 if (ret) {
1351 goto end;
1352 }
1353
1354 /* Closing attributes */
1355 ret = mi_lttng_writer_close_element(writer);
1356 if (ret) {
1357 goto end;
1358 }
1359end:
1360 return ret;
1361
1362}
1363
1364LTTNG_HIDDEN
1365int mi_lttng_event_common_attributes(struct mi_writer *writer,
1366 struct lttng_event *event)
1367{
1368 int ret;
1369 const char *filter_expression;
1370
1371 /* Open event element */
1372 ret = mi_lttng_writer_open_element(writer, config_element_event);
1373 if (ret) {
1374 goto end;
1375 }
1376
1377 /* Event name */
1378 ret = mi_lttng_writer_write_element_string(writer,
1379 config_element_name, event->name);
1380 if (ret) {
1381 goto end;
1382 }
1383
1384 /* Event type */
1385 ret = mi_lttng_writer_write_element_string(writer,
1386 config_element_type, mi_lttng_eventtype_string(event->type));
1387 if (ret) {
1388 goto end;
1389 }
1390
1391 /* Is event enabled */
1392 ret = mi_lttng_writer_write_element_bool(writer,
1393 config_element_enabled, event->enabled);
1394 if (ret) {
1395 goto end;
1396 }
1397
1398 /* Event filter expression */
1399 ret = lttng_event_get_filter_expression(event, &filter_expression);
1400 if (ret) {
1401 goto end;
1402 }
1403
1404 if (filter_expression) {
1405 ret = mi_lttng_writer_write_element_string(writer,
1406 config_element_filter_expression,
1407 filter_expression);
1408 if (ret) {
1409 goto end;
1410 }
1411 }
1412
1413end:
1414 return ret;
1415}
1416
1417static int write_event_exclusions(struct mi_writer *writer,
1418 struct lttng_event *event)
1419{
1420 int i;
1421 int ret;
1422 int exclusion_count;
1423
1424 /* Open event exclusions */
1425 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
1426 if (ret) {
1427 goto end;
1428 }
1429
1430 exclusion_count = lttng_event_get_exclusion_name_count(event);
1431 if (exclusion_count < 0) {
1432 ret = exclusion_count;
1433 goto end;
1434 }
1435
1436 for (i = 0; i < exclusion_count; i++) {
1437 const char *name;
1438
1439 ret = lttng_event_get_exclusion_name(event, i, &name);
1440 if (ret) {
1441 /* Close exclusions */
1442 mi_lttng_writer_close_element(writer);
1443 goto end;
1444 }
1445
1446 ret = mi_lttng_writer_write_element_string(writer,
1447 config_element_exclusion, name);
1448 if (ret) {
1449 /* Close exclusions */
1450 mi_lttng_writer_close_element(writer);
1451 goto end;
1452 }
1453 }
1454
1455 /* Close exclusions */
1456 ret = mi_lttng_writer_close_element(writer);
1457
1458end:
1459 return ret;
1460}
1461
1462LTTNG_HIDDEN
1463int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer,
1464 struct lttng_event *event, enum lttng_domain_type domain)
1465{
1466 int ret;
1467
1468 /* Event loglevel */
1469 ret = mi_lttng_writer_write_element_string(writer,
1470 config_element_loglevel,
1471 mi_lttng_loglevel_string(event->loglevel, domain));
1472 if (ret) {
1473 goto end;
1474 }
1475
1476 /* Log level type */
1477 ret = mi_lttng_writer_write_element_string(writer,
1478 config_element_loglevel_type,
1479 mi_lttng_logleveltype_string(event->loglevel_type));
1480 if (ret) {
1481 goto end;
1482 }
1483
1484 /* Event exclusions */
1485 ret = write_event_exclusions(writer, event);
1486
1487end:
1488 return ret;
1489}
1490
1491LTTNG_HIDDEN
1492int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer,
1493 struct lttng_event *event)
1494{
1495 /* event exclusion filter */
1496 return write_event_exclusions(writer, event);
1497}
1498
1499LTTNG_HIDDEN
1500int mi_lttng_event_function_probe(struct mi_writer *writer,
1501 struct lttng_event *event)
1502{
1503 int ret;
1504
1505 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1506 if (ret) {
1507 goto end;
1508 }
1509
1510 ret = mi_lttng_writer_open_element(writer, config_element_probe_attributes);
1511 if (ret) {
1512 goto end;
1513 }
1514
1515 if (event->attr.probe.addr != 0) {
1516 /* event probe address */
1517 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1518 config_element_address, event->attr.probe.addr);
1519 if (ret) {
1520 goto end;
1521 }
1522 } else {
1523 /* event probe offset */
1524 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1525 config_element_offset, event->attr.probe.offset);
1526 if (ret) {
1527 goto end;
1528 }
1529
1530 /* event probe symbol_name */
1531 ret = mi_lttng_writer_write_element_string(writer,
1532 config_element_symbol_name, event->attr.probe.symbol_name);
1533 if (ret) {
1534 goto end;
1535 }
1536 }
1537
1538 /* Close probe_attributes and attributes */
1539 ret = mi_lttng_close_multi_element(writer, 2);
1540end:
1541 return ret;
1542}
1543
1544static
1545int mi_lttng_event_userspace_probe(struct mi_writer *writer,
1546 struct lttng_event *event)
1547{
1548 int ret;
1549 const struct lttng_userspace_probe_location *location;
1550 const struct lttng_userspace_probe_location_lookup_method *lookup_method;
1551 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
1552
1553 location = lttng_event_get_userspace_probe_location(event);
1554 if (!location) {
1555 ret = -LTTNG_ERR_INVALID;
1556 goto end;
1557 }
1558
1559 lookup_method = lttng_userspace_probe_location_get_lookup_method(location);
1560 if (!lookup_method) {
1561 ret = -LTTNG_ERR_INVALID;
1562 goto end;
1563 }
1564
1565 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
1566
1567 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1568 if (ret) {
1569 goto end;
1570 }
1571
1572 switch (lttng_userspace_probe_location_get_type(location)) {
1573 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
1574 {
1575 const char *function_name;
1576 const char *binary_path;
1577
1578 ret = mi_lttng_writer_open_element(writer,
1579 config_element_userspace_probe_function_attributes);
1580 if (ret) {
1581 goto end;
1582 }
1583
1584 switch (lookup_type) {
1585 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
1586 ret = mi_lttng_writer_write_element_string(writer,
1587 config_element_userspace_probe_lookup,
1588 config_element_userspace_probe_lookup_function_elf);
1589 if (ret) {
1590 goto end;
1591 }
1592 break;
1593 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT:
1594 ret = mi_lttng_writer_write_element_string(writer,
1595 config_element_userspace_probe_lookup,
1596 config_element_userspace_probe_lookup_function_default);
1597 if (ret) {
1598 goto end;
1599 }
1600 break;
1601 default:
1602 goto end;
1603 }
1604
1605 binary_path = lttng_userspace_probe_location_function_get_binary_path(location);
1606 ret = mi_lttng_writer_write_element_string(writer,
1607 config_element_userspace_probe_location_binary_path, binary_path);
1608 if (ret) {
1609 goto end;
1610 }
1611
1612 function_name = lttng_userspace_probe_location_function_get_function_name(location);
1613 ret = mi_lttng_writer_write_element_string(writer,
1614 config_element_userspace_probe_function_location_function_name,
1615 function_name);
1616 if (ret) {
1617 goto end;
1618 }
1619
1620 break;
1621 }
1622 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
1623 {
1624 const char *probe_name, *provider_name;
1625 const char *binary_path;
1626
1627 ret = mi_lttng_writer_open_element(writer,
1628 config_element_userspace_probe_function_attributes);
1629 if (ret) {
1630 goto end;
1631 }
1632
1633 switch (lookup_type) {
1634 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
1635 ret = mi_lttng_writer_write_element_string(writer,
1636 config_element_userspace_probe_lookup,
1637 config_element_userspace_probe_lookup_tracepoint_sdt);
1638 if (ret) {
1639 goto end;
1640 }
1641 break;
1642 default:
1643 goto end;
1644 }
1645
1646 binary_path = lttng_userspace_probe_location_tracepoint_get_binary_path(location);
1647 ret = mi_lttng_writer_write_element_string(writer,
1648 config_element_userspace_probe_location_binary_path,
1649 binary_path);
1650 if (ret) {
1651 goto end;
1652 }
1653
1654 provider_name = lttng_userspace_probe_location_tracepoint_get_provider_name(location);
1655 ret = mi_lttng_writer_write_element_string(writer,
1656 config_element_userspace_probe_tracepoint_location_provider_name,
1657 provider_name);
1658 if (ret) {
1659 goto end;
1660 }
1661
1662 probe_name = lttng_userspace_probe_location_tracepoint_get_probe_name(location);
1663 ret = mi_lttng_writer_write_element_string(writer,
1664 config_element_userspace_probe_tracepoint_location_probe_name, probe_name);
1665 if (ret) {
1666 goto end;
1667 }
1668 break;
1669 }
1670 default:
1671 ERR("Invalid probe type encountered");
1672 }
1673 /* Close probe_attributes and attributes */
1674 ret = mi_lttng_close_multi_element(writer, 2);
1675end:
1676 return ret;
1677}
1678
1679LTTNG_HIDDEN
1680int mi_lttng_event_function_entry(struct mi_writer *writer,
1681 struct lttng_event *event)
1682{
1683 int ret;
1684
1685 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1686 if (ret) {
1687 goto end;
1688 }
1689
1690 ret = mi_lttng_writer_open_element(writer, config_element_probe_attributes);
1691 if (ret) {
1692 goto end;
1693 }
1694
1695 /* event probe symbol_name */
1696 ret = mi_lttng_writer_write_element_string(writer,
1697 config_element_symbol_name, event->attr.ftrace.symbol_name);
1698 if (ret) {
1699 goto end;
1700 }
1701
1702 /* Close function_attributes and attributes */
1703 ret = mi_lttng_close_multi_element(writer, 2);
1704end:
1705 return ret;
1706}
1707
1708LTTNG_HIDDEN
1709int mi_lttng_events_open(struct mi_writer *writer)
1710{
1711 return mi_lttng_writer_open_element(writer, config_element_events);
1712}
1713
1714LTTNG_HIDDEN
1715int mi_lttng_event(struct mi_writer *writer,
1716 struct lttng_event *event, int is_open, enum lttng_domain_type domain)
1717{
1718 int ret;
1719
1720 ret = mi_lttng_event_common_attributes(writer, event);
1721 if (ret) {
1722 goto end;
1723 }
1724
1725 switch (event->type) {
1726 case LTTNG_EVENT_TRACEPOINT:
1727 {
1728 if (event->loglevel != -1) {
1729 ret = mi_lttng_event_tracepoint_loglevel(writer, event, domain);
1730 } else {
1731 ret = mi_lttng_event_tracepoint_no_loglevel(writer, event);
1732 }
1733 break;
1734 }
1735 case LTTNG_EVENT_FUNCTION:
1736 /* Fallthrough */
1737 case LTTNG_EVENT_PROBE:
1738 ret = mi_lttng_event_function_probe(writer, event);
1739 break;
1740 case LTTNG_EVENT_FUNCTION_ENTRY:
1741 ret = mi_lttng_event_function_entry(writer, event);
1742 break;
1743 case LTTNG_EVENT_USERSPACE_PROBE:
1744 ret = mi_lttng_event_userspace_probe(writer, event);
1745 break;
1746 case LTTNG_EVENT_ALL:
1747 /* Fallthrough */
1748 default:
1749 break;
1750 }
1751
1752 if (ret) {
1753 goto end;
1754 }
1755
1756 if (!is_open) {
1757 ret = mi_lttng_writer_close_element(writer);
1758 }
1759
1760end:
1761 return ret;
1762}
1763
1764LTTNG_HIDDEN
1765int mi_lttng_trackers_open(struct mi_writer *writer)
1766{
1767 return mi_lttng_writer_open_element(
1768 writer, config_element_process_attr_trackers);
1769}
1770
1771static int get_tracker_elements(enum lttng_process_attr process_attr,
1772 const char **element_process_attr_tracker,
1773 const char **element_process_attr_value)
1774{
1775 int ret = 0;
1776
1777 switch (process_attr) {
1778 case LTTNG_PROCESS_ATTR_PROCESS_ID:
1779 *element_process_attr_tracker =
1780 config_element_process_attr_tracker_pid;
1781 *element_process_attr_value =
1782 config_element_process_attr_pid_value;
1783 break;
1784 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1785 *element_process_attr_tracker =
1786 config_element_process_attr_tracker_vpid;
1787 *element_process_attr_value =
1788 config_element_process_attr_vpid_value;
1789 break;
1790 case LTTNG_PROCESS_ATTR_USER_ID:
1791 *element_process_attr_tracker =
1792 config_element_process_attr_tracker_uid;
1793 *element_process_attr_value =
1794 config_element_process_attr_uid_value;
1795 break;
1796 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
1797 *element_process_attr_tracker =
1798 config_element_process_attr_tracker_vuid;
1799 *element_process_attr_value =
1800 config_element_process_attr_vuid_value;
1801 break;
1802 case LTTNG_PROCESS_ATTR_GROUP_ID:
1803 *element_process_attr_tracker =
1804 config_element_process_attr_tracker_gid;
1805 *element_process_attr_value =
1806 config_element_process_attr_gid_value;
1807 break;
1808 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
1809 *element_process_attr_tracker =
1810 config_element_process_attr_tracker_vgid;
1811 *element_process_attr_value =
1812 config_element_process_attr_vgid_value;
1813 break;
1814 default:
1815 ret = LTTNG_ERR_SAVE_IO_FAIL;
1816 }
1817 return ret;
1818}
1819
1820LTTNG_HIDDEN
1821int mi_lttng_process_attribute_tracker_open(
1822 struct mi_writer *writer, enum lttng_process_attr process_attr)
1823{
1824 int ret;
1825 const char *element_tracker, *element_value;
1826
1827 ret = get_tracker_elements(
1828 process_attr, &element_tracker, &element_value);
1829 if (ret) {
1830 return ret;
1831 }
1832
1833 /* Open process attribute tracker element */
1834 ret = mi_lttng_writer_open_element(writer, element_tracker);
1835 if (ret) {
1836 goto end;
1837 }
1838
1839 /* Open values element */
1840 ret = mi_lttng_process_attr_values_open(writer);
1841end:
1842 return ret;
1843}
1844
1845LTTNG_HIDDEN
1846int mi_lttng_pids_open(struct mi_writer *writer)
1847{
1848 return mi_lttng_writer_open_element(writer, config_element_pids);
1849}
1850
1851/*
1852 * TODO: move the listing of pid for user agent to process semantic on
1853 * mi api bump. The use of process element break the mi api.
1854 */
1855LTTNG_HIDDEN
1856int mi_lttng_pid(struct mi_writer *writer,
1857 pid_t pid,
1858 const char *name,
1859 int is_open)
1860{
1861 int ret;
1862
1863 /* Open pid process */
1864 ret = mi_lttng_writer_open_element(writer, config_element_pid);
1865 if (ret) {
1866 goto end;
1867 }
1868
1869 /* Writing pid number */
1870 ret = mi_lttng_writer_write_element_signed_int(writer,
1871 mi_lttng_element_pid_id, (int)pid);
1872 if (ret) {
1873 goto end;
1874 }
1875
1876 /* Writing name of the process */
1877 if (name) {
1878 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1879 name);
1880 if (ret) {
1881 goto end;
1882 }
1883 }
1884
1885 if (!is_open) {
1886 /* Closing Pid */
1887 ret = mi_lttng_writer_close_element(writer);
1888 }
1889
1890end:
1891 return ret;
1892}
1893
1894LTTNG_HIDDEN
1895int mi_lttng_process_attr_values_open(struct mi_writer *writer)
1896{
1897 return mi_lttng_writer_open_element(
1898 writer, config_element_process_attr_values);
1899}
1900
1901LTTNG_HIDDEN
1902int mi_lttng_all_process_attribute_value(struct mi_writer *writer,
1903 enum lttng_process_attr process_attr,
1904 bool is_open)
1905{
1906 int ret;
1907 const char *element_id_tracker, *element_target_id;
1908
1909 ret = get_tracker_elements(
1910 process_attr, &element_id_tracker, &element_target_id);
1911 if (ret) {
1912 return ret;
1913 }
1914
1915 ret = mi_lttng_writer_open_element(writer, element_target_id);
1916 if (ret) {
1917 goto end;
1918 }
1919
1920 ret = mi_lttng_writer_open_element(writer, config_element_type);
1921 if (ret) {
1922 goto end;
1923 }
1924
1925 ret = mi_lttng_writer_write_element_bool(writer, config_element_all, 1);
1926 if (ret) {
1927 goto end;
1928 }
1929
1930 ret = mi_lttng_writer_close_element(writer);
1931 if (ret) {
1932 goto end;
1933 }
1934
1935 if (!is_open) {
1936 ret = mi_lttng_writer_close_element(writer);
1937 if (ret) {
1938 goto end;
1939 }
1940 }
1941end:
1942 return ret;
1943}
1944
1945LTTNG_HIDDEN
1946int mi_lttng_integral_process_attribute_value(struct mi_writer *writer,
1947 enum lttng_process_attr process_attr,
1948 int64_t value,
1949 bool is_open)
1950{
1951 int ret;
1952 const char *element_id_tracker, *element_target_id;
1953
1954 ret = get_tracker_elements(
1955 process_attr, &element_id_tracker, &element_target_id);
1956 if (ret) {
1957 return ret;
1958 }
1959
1960 ret = mi_lttng_writer_open_element(writer, element_target_id);
1961 if (ret) {
1962 goto end;
1963 }
1964
1965 ret = mi_lttng_writer_open_element(writer, config_element_type);
1966 if (ret) {
1967 goto end;
1968 }
1969
1970 ret = mi_lttng_writer_write_element_signed_int(
1971 writer, config_element_process_attr_id, value);
1972 if (ret) {
1973 goto end;
1974 }
1975
1976 ret = mi_lttng_writer_close_element(writer);
1977 if (ret) {
1978 goto end;
1979 }
1980
1981 if (!is_open) {
1982 ret = mi_lttng_writer_close_element(writer);
1983 if (ret) {
1984 goto end;
1985 }
1986 }
1987
1988end:
1989 return ret;
1990}
1991
1992LTTNG_HIDDEN
1993int mi_lttng_string_process_attribute_value(struct mi_writer *writer,
1994 enum lttng_process_attr process_attr,
1995 const char *value,
1996 bool is_open)
1997
1998{
1999 int ret;
2000 const char *element_id_tracker, *element_target_id;
2001
2002 ret = get_tracker_elements(
2003 process_attr, &element_id_tracker, &element_target_id);
2004 if (ret) {
2005 return ret;
2006 }
2007
2008 ret = mi_lttng_writer_open_element(writer, element_target_id);
2009 if (ret) {
2010 goto end;
2011 }
2012
2013 ret = mi_lttng_writer_open_element(writer, config_element_type);
2014 if (ret) {
2015 goto end;
2016 }
2017
2018 ret = mi_lttng_writer_write_element_string(
2019 writer, config_element_name, value);
2020 if (ret) {
2021 goto end;
2022 }
2023
2024 ret = mi_lttng_writer_close_element(writer);
2025 if (ret) {
2026 goto end;
2027 }
2028
2029 if (!is_open) {
2030 ret = mi_lttng_writer_close_element(writer);
2031 if (ret) {
2032 goto end;
2033 }
2034 }
2035
2036end:
2037 return ret;
2038}
2039
2040LTTNG_HIDDEN
2041int mi_lttng_event_fields_open(struct mi_writer *writer)
2042{
2043 return mi_lttng_writer_open_element(writer, mi_lttng_element_event_fields);
2044}
2045
2046LTTNG_HIDDEN
2047int mi_lttng_event_field(struct mi_writer *writer,
2048 struct lttng_event_field *field)
2049{
2050 int ret;
2051
2052 if (!field->field_name[0]) {
2053 ret = 0;
2054 goto end;
2055 }
2056
2057 /* Open field */
2058 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_field);
2059 if (ret) {
2060 goto end;
2061 }
2062
2063 if (!field->field_name[0]) {
2064 goto close;
2065 }
2066
2067 /* Name */
2068 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
2069 field->field_name);
2070 if (ret) {
2071 goto end;
2072 }
2073
2074 /* Type */
2075 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
2076 mi_lttng_eventfieldtype_string(field->type));
2077 if (ret) {
2078 goto end;
2079 }
2080
2081 /* nowrite */
2082 ret = mi_lttng_writer_write_element_signed_int(writer,
2083 mi_lttng_element_nowrite, field->nowrite);
2084 if (ret) {
2085 goto end;
2086 }
2087
2088close:
2089 /* Close field element */
2090 ret = mi_lttng_writer_close_element(writer);
2091
2092end:
2093 return ret;
2094}
2095
2096LTTNG_HIDDEN
2097int mi_lttng_perf_counter_context(struct mi_writer *writer,
2098 struct lttng_event_perf_counter_ctx *perf_context)
2099{
2100 int ret;
2101
2102 /* Open perf_counter_context */
2103 ret = mi_lttng_writer_open_element(writer,
2104 mi_lttng_element_perf_counter_context);
2105 if (ret) {
2106 goto end;
2107 }
2108
2109 /* Type */
2110 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2111 config_element_type, perf_context->type);
2112 if (ret) {
2113 goto end;
2114 }
2115
2116 /* Config */
2117 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2118 config_element_config, perf_context->config);
2119 if (ret) {
2120 goto end;
2121 }
2122
2123 /* Name of the perf counter */
2124 ret = mi_lttng_writer_write_element_string(writer,
2125 config_element_name, perf_context->name);
2126 if (ret) {
2127 goto end;
2128 }
2129
2130 /* Close perf_counter_context */
2131 ret = mi_lttng_writer_close_element(writer);
2132end:
2133 return ret;
2134}
2135
2136static
2137int mi_lttng_app_context(struct mi_writer *writer,
2138 const char *provider_name, const char *ctx_name)
2139{
2140 int ret;
2141
2142 /* Open app */
2143 ret = mi_lttng_writer_open_element(writer,
2144 config_element_context_app);
2145 if (ret) {
2146 goto end;
2147 }
2148
2149 /* provider_name */
2150 ret = mi_lttng_writer_write_element_string(writer,
2151 config_element_context_app_provider_name,
2152 provider_name);
2153 if (ret) {
2154 goto end;
2155 }
2156
2157 /* ctx_name */
2158 ret = mi_lttng_writer_write_element_string(writer,
2159 config_element_context_app_ctx_name, ctx_name);
2160 if (ret) {
2161 goto end;
2162 }
2163
2164 /* Close app */
2165 ret = mi_lttng_writer_close_element(writer);
2166end:
2167 return ret;
2168}
2169
2170LTTNG_HIDDEN
2171int mi_lttng_context(struct mi_writer *writer,
2172 struct lttng_event_context *context, int is_open)
2173{
2174 int ret;
2175
2176 /* Open context */
2177 ret = mi_lttng_writer_open_element(writer , config_element_context);
2178 if (ret) {
2179 goto end;
2180 }
2181
2182 /* Special case for PERF_*_COUNTER
2183 * print the lttng_event_perf_counter_ctx*/
2184 switch (context->ctx) {
2185 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
2186 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
2187 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
2188 {
2189 struct lttng_event_perf_counter_ctx *perf_context =
2190 &context->u.perf_counter;
2191 ret = mi_lttng_perf_counter_context(writer, perf_context);
2192 if (ret) {
2193 goto end;
2194 }
2195 break;
2196 }
2197 case LTTNG_EVENT_CONTEXT_APP_CONTEXT:
2198 {
2199 ret = mi_lttng_app_context(writer,
2200 context->u.app_ctx.provider_name,
2201 context->u.app_ctx.ctx_name);
2202 if (ret) {
2203 goto end;
2204 }
2205 break;
2206 }
2207 default:
2208 {
2209 const char *type_string = mi_lttng_event_contexttype_string(
2210 context->ctx);
2211 if (!type_string) {
2212 ret = -LTTNG_ERR_INVALID;
2213 goto end;
2214 }
2215
2216 /* Print context type */
2217 ret = mi_lttng_writer_write_element_string(writer,
2218 config_element_type, type_string);
2219 break;
2220 }
2221 }
2222
2223 /* Close context */
2224 if (!is_open) {
2225 ret = mi_lttng_writer_close_element(writer);
2226 }
2227
2228end:
2229 return ret;
2230}
2231
2232LTTNG_HIDDEN
2233int mi_lttng_snapshot_output_session_name(struct mi_writer *writer,
2234 const char *session_name)
2235{
2236 int ret;
2237
2238 /* Open session element */
2239 ret = mi_lttng_writer_open_element(writer, config_element_session);
2240 if (ret) {
2241 goto end;
2242 }
2243
2244 /* Snapshot output list for current session name */
2245 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
2246 session_name);
2247 if (ret) {
2248 goto end;
2249 }
2250
2251 /* Open element snapshots (sequence one snapshot) */
2252 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_snapshots);
2253 if (ret) {
2254 goto end;
2255 }
2256
2257end:
2258 return ret;
2259}
2260
2261LTTNG_HIDDEN
2262int mi_lttng_snapshot_list_output(struct mi_writer *writer,
2263 const struct lttng_snapshot_output *output)
2264{
2265 int ret;
2266
2267 /* Open element snapshot output */
2268 ret = mi_lttng_writer_open_element(writer,
2269 mi_lttng_element_command_snapshot);
2270 if (ret) {
2271 goto end;
2272 }
2273
2274 /* ID of the snapshot output */
2275 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2276 mi_lttng_element_id, output->id);
2277 if (ret) {
2278 goto end;
2279 }
2280
2281 /* Name of the output */
2282 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
2283 output->name);
2284 if (ret) {
2285 goto end;
2286 }
2287
2288 /* Destination of the output (ctrl_url)*/
2289 ret = mi_lttng_writer_write_element_string(writer,
2290 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
2291 if (ret) {
2292 goto end;
2293 }
2294
2295 /* Destination of the output (data_url) */
2296 ret = mi_lttng_writer_write_element_string(writer,
2297 mi_lttng_element_snapshot_data_url, output->data_url);
2298 if (ret) {
2299 goto end;
2300 }
2301
2302 /* total size of all stream combined */
2303 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2304 mi_lttng_element_snapshot_max_size, output->max_size);
2305 if (ret) {
2306 goto end;
2307 }
2308
2309 /* Close snapshot output element */
2310 ret = mi_lttng_writer_close_element(writer);
2311
2312end:
2313 return ret;
2314}
2315
2316LTTNG_HIDDEN
2317int mi_lttng_snapshot_del_output(struct mi_writer *writer, int id,
2318 const char *name, const char *current_session_name)
2319{
2320 int ret;
2321
2322 /* Open element del_snapshot */
2323 ret = mi_lttng_writer_open_element(writer,
2324 mi_lttng_element_command_snapshot);
2325 if (ret) {
2326 goto end;
2327 }
2328
2329
2330 if (id != UINT32_MAX) {
2331 /* "Snapshot output "id" successfully deleted
2332 * for "current_session_name"
2333 * ID of the snapshot output
2334 */
2335 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2336 mi_lttng_element_id, id);
2337 if (ret) {
2338 goto end;
2339 }
2340 } else {
2341 /* "Snapshot output "name" successfully deleted
2342 * for session "current_session_name"
2343 * Name of the output
2344 */
2345 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
2346 name);
2347 if (ret) {
2348 goto end;
2349 }
2350 }
2351
2352 /* Snapshot was deleted for session "current_session_name"*/
2353 ret = mi_lttng_writer_write_element_string(writer,
2354 mi_lttng_element_snapshot_session_name,
2355 current_session_name);
2356 if (ret) {
2357 goto end;
2358 }
2359
2360 /* Close snapshot element */
2361 ret = mi_lttng_writer_close_element(writer);
2362
2363end:
2364 return ret;
2365}
2366
2367LTTNG_HIDDEN
2368int mi_lttng_snapshot_add_output(struct mi_writer *writer,
2369 const char *current_session_name, const char *n_ptr,
2370 struct lttng_snapshot_output *output)
2371{
2372 int ret;
2373
2374 /* Open element snapshot */
2375 ret = mi_lttng_writer_open_element(writer,
2376 mi_lttng_element_command_snapshot);
2377 if (ret) {
2378 goto end;
2379 }
2380
2381 /* Snapshot output id */
2382 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2383 mi_lttng_element_id, output->id);
2384 if (ret) {
2385 goto end;
2386 }
2387
2388 /* Snapshot output names */
2389 ret = mi_lttng_writer_write_element_string(writer,
2390 config_element_name, n_ptr);
2391 if (ret) {
2392 goto end;
2393 }
2394
2395 /* Destination of the output (ctrl_url)*/
2396 ret = mi_lttng_writer_write_element_string(writer,
2397 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
2398 if (ret) {
2399 goto end;
2400 }
2401
2402 /* Snapshot added for session "current_session_name"*/
2403 ret = mi_lttng_writer_write_element_string(writer,
2404 mi_lttng_element_snapshot_session_name, current_session_name);
2405 if (ret) {
2406 goto end;
2407 }
2408
2409 /* total size of all stream combined */
2410 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2411 mi_lttng_element_snapshot_max_size, output->max_size);
2412 if (ret) {
2413 goto end;
2414 }
2415
2416 /* Close snapshot element */
2417 ret = mi_lttng_writer_close_element(writer);
2418
2419end:
2420 return ret;
2421}
2422
2423LTTNG_HIDDEN
2424int mi_lttng_snapshot_record(struct mi_writer *writer,
2425 const char *current_session_name, const char *url,
2426 const char *cmdline_ctrl_url, const char *cmdline_data_url)
2427{
2428 int ret;
2429
2430 /* Open element snapshot */
2431 ret = mi_lttng_writer_open_element(writer,
2432 mi_lttng_element_command_snapshot);
2433 if (ret) {
2434 goto end;
2435 }
2436
2437 /*
2438 * If a valid an URL was given, serialize it,
2439 * else take the command line data and ctrl urls*/
2440 if (url) {
2441 /* Destination of the output (ctrl_url)*/
2442 ret = mi_lttng_writer_write_element_string(writer,
2443 mi_lttng_element_snapshot_ctrl_url, url);
2444 if (ret) {
2445 goto end;
2446 }
2447 } else if (cmdline_ctrl_url) {
2448 /* Destination of the output (ctrl_url)*/
2449 ret = mi_lttng_writer_write_element_string(writer,
2450 mi_lttng_element_snapshot_ctrl_url, cmdline_ctrl_url);
2451 if (ret) {
2452 goto end;
2453 }
2454
2455 /* Destination of the output (data_url) */
2456 ret = mi_lttng_writer_write_element_string(writer,
2457 mi_lttng_element_snapshot_data_url, cmdline_data_url);
2458 if (ret) {
2459 goto end;
2460 }
2461 }
2462
2463 /* Close record_snapshot element */
2464 ret = mi_lttng_writer_close_element(writer);
2465
2466end:
2467 return ret;
2468}
2469
2470LTTNG_HIDDEN
2471int mi_lttng_rotation_schedule(struct mi_writer *writer,
2472 const struct lttng_rotation_schedule *schedule)
2473{
2474 int ret = 0;
2475 enum lttng_rotation_status status;
2476 uint64_t value;
2477 const char *element_name;
2478 const char *value_name;
2479 bool empty_schedule = false;
2480
2481 switch (lttng_rotation_schedule_get_type(schedule)) {
2482 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
2483 status = lttng_rotation_schedule_periodic_get_period(schedule,
2484 &value);
2485 element_name = mi_lttng_element_rotation_schedule_periodic;
2486 value_name = mi_lttng_element_rotation_schedule_periodic_time_us;
2487 break;
2488 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
2489 status = lttng_rotation_schedule_size_threshold_get_threshold(
2490 schedule, &value);
2491 element_name = mi_lttng_element_rotation_schedule_size_threshold;
2492 value_name = mi_lttng_element_rotation_schedule_size_threshold_bytes;
2493 break;
2494 default:
2495 ret = -1;
2496 goto end;
2497 }
2498
2499 if (status != LTTNG_ROTATION_STATUS_OK) {
2500 if (status == LTTNG_ROTATION_STATUS_UNAVAILABLE) {
2501 empty_schedule = true;
2502 } else {
2503 ret = -1;
2504 goto end;
2505 }
2506 }
2507
2508 ret = mi_lttng_writer_open_element(writer, element_name);
2509 if (ret) {
2510 goto end;
2511 }
2512
2513 if (!empty_schedule) {
2514 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2515 value_name, value);
2516 if (ret) {
2517 goto end;
2518 }
2519 }
2520
2521 /* Close schedule descriptor element. */
2522 ret = mi_lttng_writer_close_element(writer);
2523 if (ret) {
2524 goto end;
2525 }
2526end:
2527 return ret;
2528}
2529
2530LTTNG_HIDDEN
2531int mi_lttng_rotation_schedule_result(struct mi_writer *writer,
2532 const struct lttng_rotation_schedule *schedule,
2533 bool success)
2534{
2535 int ret = 0;
2536
2537 ret = mi_lttng_writer_open_element(writer,
2538 mi_lttng_element_rotation_schedule_result);
2539 if (ret) {
2540 goto end;
2541 }
2542
2543 ret = mi_lttng_writer_open_element(writer,
2544 mi_lttng_element_rotation_schedule);
2545 if (ret) {
2546 goto end;
2547 }
2548
2549 ret = mi_lttng_rotation_schedule(writer, schedule);
2550 if (ret) {
2551 goto end;
2552 }
2553
2554 /* Close rotation_schedule element */
2555 ret = mi_lttng_writer_close_element(writer);
2556 if (ret) {
2557 goto end;
2558 }
2559
2560 ret = mi_lttng_writer_write_element_bool(writer,
2561 mi_lttng_element_command_success, success);
2562 if (ret) {
2563 goto end;
2564 }
2565
2566 /* Close rotation_schedule_result element */
2567 ret = mi_lttng_writer_close_element(writer);
2568 if (ret) {
2569 goto end;
2570 }
2571end:
2572 return ret;
2573}
2574
2575static
2576int mi_lttng_location(struct mi_writer *writer,
2577 const struct lttng_trace_archive_location *location)
2578{
2579 int ret = 0;
2580 enum lttng_trace_archive_location_type location_type;
2581 enum lttng_trace_archive_location_status status;
2582
2583 location_type = lttng_trace_archive_location_get_type(location);
2584
2585 switch (location_type) {
2586 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
2587 {
2588 const char *absolute_path;
2589
2590 status = lttng_trace_archive_location_local_get_absolute_path(
2591 location, &absolute_path);
2592 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
2593 ret = -1;
2594 goto end;
2595 }
2596
2597 ret = mi_lttng_writer_open_element(writer,
2598 mi_lttng_element_rotation_location_local);
2599 if (ret) {
2600 goto end;
2601 }
2602
2603
2604 ret = mi_lttng_writer_write_element_string(writer,
2605 mi_lttng_element_rotation_location_local_absolute_path,
2606 absolute_path);
2607 if (ret) {
2608 goto end;
2609 }
2610
2611 /* Close local element */
2612 ret = mi_lttng_writer_close_element(writer);
2613 if (ret) {
2614 goto end;
2615 }
2616 break;
2617 }
2618 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
2619 {
2620 uint16_t control_port, data_port;
2621 const char *host, *relative_path;
2622 enum lttng_trace_archive_location_relay_protocol_type protocol;
2623
2624 /* Fetch all relay location parameters. */
2625 status = lttng_trace_archive_location_relay_get_protocol_type(
2626 location, &protocol);
2627 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
2628 ret = -1;
2629 goto end;
2630 }
2631
2632 status = lttng_trace_archive_location_relay_get_host(
2633 location, &host);
2634 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
2635 ret = -1;
2636 goto end;
2637 }
2638
2639 status = lttng_trace_archive_location_relay_get_control_port(
2640 location, &control_port);
2641 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
2642 ret = -1;
2643 goto end;
2644 }
2645
2646 status = lttng_trace_archive_location_relay_get_data_port(
2647 location, &data_port);
2648 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
2649 ret = -1;
2650 goto end;
2651 }
2652
2653 status = lttng_trace_archive_location_relay_get_relative_path(
2654 location, &relative_path);
2655 if (status != LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK) {
2656 ret = -1;
2657 goto end;
2658 }
2659
2660 ret = mi_lttng_writer_open_element(writer,
2661 mi_lttng_element_rotation_location_relay);
2662 if (ret) {
2663 goto end;
2664 }
2665
2666 ret = mi_lttng_writer_write_element_string(writer,
2667 mi_lttng_element_rotation_location_relay_host,
2668 host);
2669 if (ret) {
2670 goto end;
2671 }
2672
2673 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2674 mi_lttng_element_rotation_location_relay_control_port,
2675 control_port);
2676 if (ret) {
2677 goto end;
2678 }
2679
2680 ret = mi_lttng_writer_write_element_unsigned_int(writer,
2681 mi_lttng_element_rotation_location_relay_data_port,
2682 data_port);
2683 if (ret) {
2684 goto end;
2685 }
2686
2687 ret = mi_lttng_writer_write_element_string(writer,
2688 mi_lttng_element_rotation_location_relay_protocol,
2689 mi_lttng_trace_archive_location_relay_protocol_type_string(protocol));
2690 if (ret) {
2691 goto end;
2692 }
2693
2694 ret = mi_lttng_writer_write_element_string(writer,
2695 mi_lttng_element_rotation_location_relay_relative_path,
2696 relative_path);
2697 if (ret) {
2698 goto end;
2699 }
2700
2701 /* Close relay element */
2702 ret = mi_lttng_writer_close_element(writer);
2703 if (ret) {
2704 goto end;
2705 }
2706 break;
2707 }
2708 default:
2709 abort();
2710 }
2711end:
2712 return ret;
2713}
2714
2715LTTNG_HIDDEN
2716int mi_lttng_rotate(struct mi_writer *writer,
2717 const char *session_name,
2718 enum lttng_rotation_state rotation_state,
2719 const struct lttng_trace_archive_location *location)
2720{
2721 int ret;
2722
2723 ret = mi_lttng_writer_open_element(writer,
2724 mi_lttng_element_rotation);
2725 if (ret) {
2726 goto end;
2727 }
2728
2729 ret = mi_lttng_writer_write_element_string(writer,
2730 mi_lttng_element_session_name,
2731 session_name);
2732 if (ret) {
2733 goto end;
2734 }
2735
2736 ret = mi_lttng_writer_write_element_string(writer,
2737 mi_lttng_element_rotation_state,
2738 mi_lttng_rotation_state_string(rotation_state));
2739 if (ret) {
2740 goto end;
2741 }
2742
2743 if (!location) {
2744 /* Not a serialization error. */
2745 goto close_rotation;
2746 }
2747
2748 ret = mi_lttng_writer_open_element(writer,
2749 mi_lttng_element_rotation_location);
2750 if (ret) {
2751 goto end;
2752 }
2753
2754 ret = mi_lttng_location(writer, location);
2755 if (ret) {
2756 goto close_location;
2757 }
2758
2759close_location:
2760 /* Close location element */
2761 ret = mi_lttng_writer_close_element(writer);
2762 if (ret) {
2763 goto end;
2764 }
2765
2766close_rotation:
2767 /* Close rotation element */
2768 ret = mi_lttng_writer_close_element(writer);
2769 if (ret) {
2770 goto end;
2771 }
2772end:
2773 return ret;
2774}
This page took 0.031765 seconds and 4 git commands to generate.