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