bc0778d2fb405362e608a4d305709b42934b1493
[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 "http://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_rotations = "rotations";
190 LTTNG_HIDDEN const char * const mi_lttng_element_rotate_status = "status";
191 LTTNG_HIDDEN const char * const mi_lttng_element_rotation_schedule = "rotation_schedule";
192
193 /* Deprecated symbols preserved for ABI compatibility. */
194 const char * const mi_lttng_context_type_perf_counter;
195 const char * const mi_lttng_context_type_perf_cpu_counter;
196 const char * const mi_lttng_context_type_perf_thread_counter;
197 const char * const mi_lttng_element_track_untrack_pid_target;
198 const char * const mi_lttng_element_track_untrack_targets;
199 const char * const mi_lttng_element_calibrate;
200 const char * const mi_lttng_element_calibrate_function;
201 const char * const mi_lttng_element_command_calibrate;
202
203 /* This is a merge of jul loglevel and regular loglevel
204 * Those should never overlap by definition
205 * (see struct lttng_event loglevel)
206 */
207 LTTNG_HIDDEN
208 const char *mi_lttng_loglevel_string(int value, enum lttng_domain_type domain)
209 {
210 switch (domain) {
211 case LTTNG_DOMAIN_KERNEL:
212 case LTTNG_DOMAIN_UST:
213 switch (value) {
214 case -1:
215 return mi_lttng_element_empty;
216 case LTTNG_LOGLEVEL_EMERG:
217 return mi_lttng_loglevel_str_emerg;
218 case LTTNG_LOGLEVEL_ALERT:
219 return mi_lttng_loglevel_str_alert;
220 case LTTNG_LOGLEVEL_CRIT:
221 return mi_lttng_loglevel_str_crit;
222 case LTTNG_LOGLEVEL_ERR:
223 return mi_lttng_loglevel_str_err;
224 case LTTNG_LOGLEVEL_WARNING:
225 return mi_lttng_loglevel_str_warning;
226 case LTTNG_LOGLEVEL_NOTICE:
227 return mi_lttng_loglevel_str_notice;
228 case LTTNG_LOGLEVEL_INFO:
229 return mi_lttng_loglevel_str_info;
230 case LTTNG_LOGLEVEL_DEBUG_SYSTEM:
231 return mi_lttng_loglevel_str_debug_system;
232 case LTTNG_LOGLEVEL_DEBUG_PROGRAM:
233 return mi_lttng_loglevel_str_debug_program;
234 case LTTNG_LOGLEVEL_DEBUG_PROCESS:
235 return mi_lttng_loglevel_str_debug_process;
236 case LTTNG_LOGLEVEL_DEBUG_MODULE:
237 return mi_lttng_loglevel_str_debug_module;
238 case LTTNG_LOGLEVEL_DEBUG_UNIT:
239 return mi_lttng_loglevel_str_debug_unit;
240 case LTTNG_LOGLEVEL_DEBUG_FUNCTION:
241 return mi_lttng_loglevel_str_debug_function;
242 case LTTNG_LOGLEVEL_DEBUG_LINE:
243 return mi_lttng_loglevel_str_debug_line;
244 case LTTNG_LOGLEVEL_DEBUG:
245 return mi_lttng_loglevel_str_debug;
246 default:
247 return mi_lttng_loglevel_str_unknown;
248 }
249 break;
250 case LTTNG_DOMAIN_LOG4J:
251 switch (value) {
252 case -1:
253 return mi_lttng_element_empty;
254 case LTTNG_LOGLEVEL_LOG4J_OFF:
255 return mi_lttng_loglevel_str_log4j_off;
256 case LTTNG_LOGLEVEL_LOG4J_FATAL:
257 return mi_lttng_loglevel_str_log4j_fatal;
258 case LTTNG_LOGLEVEL_LOG4J_ERROR:
259 return mi_lttng_loglevel_str_log4j_error;
260 case LTTNG_LOGLEVEL_LOG4J_WARN:
261 return mi_lttng_loglevel_str_log4j_warn;
262 case LTTNG_LOGLEVEL_LOG4J_INFO:
263 return mi_lttng_loglevel_str_log4j_info;
264 case LTTNG_LOGLEVEL_LOG4J_DEBUG:
265 return mi_lttng_loglevel_str_log4j_debug;
266 case LTTNG_LOGLEVEL_LOG4J_TRACE:
267 return mi_lttng_loglevel_str_log4j_trace;
268 case LTTNG_LOGLEVEL_LOG4J_ALL:
269 return mi_lttng_loglevel_str_log4j_all;
270 default:
271 return mi_lttng_loglevel_str_unknown;
272 }
273 break;
274 case LTTNG_DOMAIN_JUL:
275 switch (value) {
276 case -1:
277 return mi_lttng_element_empty;
278 case LTTNG_LOGLEVEL_JUL_OFF:
279 return mi_lttng_loglevel_str_jul_off;
280 case LTTNG_LOGLEVEL_JUL_SEVERE:
281 return mi_lttng_loglevel_str_jul_severe;
282 case LTTNG_LOGLEVEL_JUL_WARNING:
283 return mi_lttng_loglevel_str_jul_warning;
284 case LTTNG_LOGLEVEL_JUL_INFO:
285 return mi_lttng_loglevel_str_jul_info;
286 case LTTNG_LOGLEVEL_JUL_CONFIG:
287 return mi_lttng_loglevel_str_jul_config;
288 case LTTNG_LOGLEVEL_JUL_FINE:
289 return mi_lttng_loglevel_str_jul_fine;
290 case LTTNG_LOGLEVEL_JUL_FINER:
291 return mi_lttng_loglevel_str_jul_finer;
292 case LTTNG_LOGLEVEL_JUL_FINEST:
293 return mi_lttng_loglevel_str_jul_finest;
294 case LTTNG_LOGLEVEL_JUL_ALL:
295 return mi_lttng_loglevel_str_jul_all;
296 default:
297 return mi_lttng_loglevel_str_unknown;
298 }
299 break;
300 case LTTNG_DOMAIN_PYTHON:
301 switch (value) {
302 case LTTNG_LOGLEVEL_PYTHON_CRITICAL:
303 return mi_lttng_loglevel_str_python_critical;
304 case LTTNG_LOGLEVEL_PYTHON_ERROR:
305 return mi_lttng_loglevel_str_python_error;
306 case LTTNG_LOGLEVEL_PYTHON_WARNING:
307 return mi_lttng_loglevel_str_python_warning;
308 case LTTNG_LOGLEVEL_PYTHON_INFO:
309 return mi_lttng_loglevel_str_python_info;
310 case LTTNG_LOGLEVEL_PYTHON_DEBUG:
311 return mi_lttng_loglevel_str_python_debug;
312 case LTTNG_LOGLEVEL_PYTHON_NOTSET:
313 return mi_lttng_loglevel_str_python_notset;
314 default:
315 return mi_lttng_loglevel_str_unknown;
316 }
317 break;
318 default:
319 return mi_lttng_loglevel_str_unknown;
320 }
321 }
322
323 LTTNG_HIDDEN
324 const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value)
325 {
326 switch (value) {
327 case LTTNG_EVENT_LOGLEVEL_ALL:
328 return mi_lttng_loglevel_type_all;
329 case LTTNG_EVENT_LOGLEVEL_RANGE:
330 return mi_lttng_loglevel_type_range;
331 case LTTNG_EVENT_LOGLEVEL_SINGLE:
332 return mi_lttng_loglevel_type_single;
333 default:
334 return mi_lttng_loglevel_type_unknown;
335 }
336 }
337
338 LTTNG_HIDDEN
339 const char *mi_lttng_eventtype_string(enum lttng_event_type value)
340 {
341 switch (value) {
342 case LTTNG_EVENT_ALL:
343 return config_event_type_all;
344 case LTTNG_EVENT_TRACEPOINT:
345 return config_event_type_tracepoint;
346 case LTTNG_EVENT_PROBE:
347 return config_event_type_probe;
348 case LTTNG_EVENT_FUNCTION:
349 return config_event_type_function;
350 case LTTNG_EVENT_FUNCTION_ENTRY:
351 return config_event_type_function_entry;
352 case LTTNG_EVENT_SYSCALL:
353 return config_event_type_syscall;
354 case LTTNG_EVENT_NOOP:
355 return config_event_type_noop;
356 default:
357 return mi_lttng_element_empty;
358 }
359 }
360
361 static
362 const char *mi_lttng_event_contexttype_string(enum lttng_event_context_type val)
363 {
364 switch (val) {
365 case LTTNG_EVENT_CONTEXT_PID:
366 return config_event_context_pid;
367 case LTTNG_EVENT_CONTEXT_PROCNAME:
368 return config_event_context_procname;
369 case LTTNG_EVENT_CONTEXT_PRIO:
370 return config_event_context_prio;
371 case LTTNG_EVENT_CONTEXT_NICE:
372 return config_event_context_nice;
373 case LTTNG_EVENT_CONTEXT_VPID:
374 return config_event_context_vpid;
375 case LTTNG_EVENT_CONTEXT_TID:
376 return config_event_context_tid;
377 case LTTNG_EVENT_CONTEXT_VTID:
378 return config_event_context_vtid;
379 case LTTNG_EVENT_CONTEXT_PPID:
380 return config_event_context_ppid;
381 case LTTNG_EVENT_CONTEXT_VPPID:
382 return config_event_context_vppid;
383 case LTTNG_EVENT_CONTEXT_PTHREAD_ID:
384 return config_event_context_pthread_id;
385 case LTTNG_EVENT_CONTEXT_HOSTNAME:
386 return config_event_context_hostname;
387 case LTTNG_EVENT_CONTEXT_IP:
388 return config_event_context_ip;
389 case LTTNG_EVENT_CONTEXT_INTERRUPTIBLE:
390 return config_event_context_interruptible;
391 case LTTNG_EVENT_CONTEXT_PREEMPTIBLE:
392 return config_event_context_preemptible;
393 case LTTNG_EVENT_CONTEXT_NEED_RESCHEDULE:
394 return config_event_context_need_reschedule;
395 case LTTNG_EVENT_CONTEXT_MIGRATABLE:
396 return config_event_context_migratable;
397 default:
398 return NULL;
399 }
400 }
401
402 LTTNG_HIDDEN
403 const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val)
404 {
405 switch (val) {
406 case(LTTNG_EVENT_FIELD_INTEGER):
407 return mi_lttng_element_type_integer;
408 case(LTTNG_EVENT_FIELD_ENUM):
409 return mi_lttng_element_type_enum;
410 case(LTTNG_EVENT_FIELD_FLOAT):
411 return mi_lttng_element_type_float;
412 case(LTTNG_EVENT_FIELD_STRING):
413 return mi_lttng_element_type_string;
414 default:
415 return mi_lttng_element_type_other;
416 }
417 }
418
419 LTTNG_HIDDEN
420 const char *mi_lttng_domaintype_string(enum lttng_domain_type value)
421 {
422 /* Note: This is a *duplicate* of get_domain_str from bin/lttng/utils.c */
423 switch (value) {
424 case LTTNG_DOMAIN_KERNEL:
425 return config_domain_type_kernel;
426 case LTTNG_DOMAIN_UST:
427 return config_domain_type_ust;
428 case LTTNG_DOMAIN_JUL:
429 return config_domain_type_jul;
430 case LTTNG_DOMAIN_LOG4J:
431 return config_domain_type_log4j;
432 case LTTNG_DOMAIN_PYTHON:
433 return config_domain_type_python;
434 default:
435 /* Should not have an unknown domain */
436 assert(0);
437 return NULL;
438 }
439 }
440
441 LTTNG_HIDDEN
442 const char *mi_lttng_buffertype_string(enum lttng_buffer_type value)
443 {
444 switch (value) {
445 case LTTNG_BUFFER_PER_PID:
446 return config_buffer_type_per_pid;
447 case LTTNG_BUFFER_PER_UID:
448 return config_buffer_type_per_uid;
449 case LTTNG_BUFFER_GLOBAL:
450 return config_buffer_type_global;
451 default:
452 /* Should not have an unknow buffer type */
453 assert(0);
454 return NULL;
455 }
456 }
457
458 LTTNG_HIDDEN
459 struct mi_writer *mi_lttng_writer_create(int fd_output, int mi_output_type)
460 {
461 struct mi_writer *mi_writer;
462
463 mi_writer = zmalloc(sizeof(struct mi_writer));
464 if (!mi_writer) {
465 PERROR("zmalloc mi_writer_create");
466 goto end;
467 }
468 if (mi_output_type == LTTNG_MI_XML) {
469 mi_writer->writer = config_writer_create(fd_output, 0);
470 if (!mi_writer->writer) {
471 goto err_destroy;
472 }
473 mi_writer->type = LTTNG_MI_XML;
474 } else {
475 goto err_destroy;
476 }
477
478 end:
479 return mi_writer;
480
481 err_destroy:
482 free(mi_writer);
483 return NULL;
484 }
485
486 LTTNG_HIDDEN
487 int mi_lttng_writer_destroy(struct mi_writer *writer)
488 {
489 int ret;
490
491 if (!writer) {
492 ret = -EINVAL;
493 goto end;
494 }
495
496 ret = config_writer_destroy(writer->writer);
497 if (ret < 0) {
498 goto end;
499 }
500
501 free(writer);
502 end:
503 return ret;
504 }
505
506 LTTNG_HIDDEN
507 int mi_lttng_writer_command_open(struct mi_writer *writer, const char *command)
508 {
509 int ret;
510
511 /*
512 * A command is always the MI's root node, it must declare the current
513 * namespace and schema URIs and the schema's version.
514 */
515 ret = config_writer_open_element(writer->writer,
516 mi_lttng_element_command);
517 if (ret) {
518 goto end;
519 }
520
521 ret = config_writer_write_attribute(writer->writer,
522 mi_lttng_xmlns, DEFAULT_LTTNG_MI_NAMESPACE);
523 if (ret) {
524 goto end;
525 }
526
527 ret = config_writer_write_attribute(writer->writer,
528 mi_lttng_xmlns_xsi, mi_lttng_w3_schema_uri);
529 if (ret) {
530 goto end;
531 }
532
533 ret = config_writer_write_attribute(writer->writer,
534 mi_lttng_schema_location,
535 mi_lttng_schema_location_uri);
536 if (ret) {
537 goto end;
538 }
539
540 ret = config_writer_write_attribute(writer->writer,
541 mi_lttng_schema_version,
542 mi_lttng_schema_version_value);
543 if (ret) {
544 goto end;
545 }
546
547 ret = mi_lttng_writer_write_element_string(writer,
548 mi_lttng_element_command_name, command);
549 end:
550 return ret;
551 }
552
553 LTTNG_HIDDEN
554 int mi_lttng_writer_command_close(struct mi_writer *writer)
555 {
556 return mi_lttng_writer_close_element(writer);
557 }
558
559 LTTNG_HIDDEN
560 int mi_lttng_writer_open_element(struct mi_writer *writer,
561 const char *element_name)
562 {
563 return config_writer_open_element(writer->writer, element_name);
564 }
565
566 LTTNG_HIDDEN
567 int mi_lttng_writer_close_element(struct mi_writer *writer)
568 {
569 return config_writer_close_element(writer->writer);
570 }
571
572 LTTNG_HIDDEN
573 int mi_lttng_close_multi_element(struct mi_writer *writer,
574 unsigned int nb_element)
575 {
576 int ret, i;
577
578 if (nb_element < 1) {
579 ret = 0;
580 goto end;
581 }
582 for (i = 0; i < nb_element; i++) {
583 ret = mi_lttng_writer_close_element(writer);
584 if (ret) {
585 goto end;
586 }
587 }
588 end:
589 return ret;
590 }
591
592 LTTNG_HIDDEN
593 int mi_lttng_writer_write_element_unsigned_int(struct mi_writer *writer,
594 const char *element_name, uint64_t value)
595 {
596 return config_writer_write_element_unsigned_int(writer->writer,
597 element_name, value);
598 }
599
600 LTTNG_HIDDEN
601 int mi_lttng_writer_write_element_signed_int(struct mi_writer *writer,
602 const char *element_name, int64_t value)
603 {
604 return config_writer_write_element_signed_int(writer->writer,
605 element_name, value);
606 }
607
608 LTTNG_HIDDEN
609 int mi_lttng_writer_write_element_bool(struct mi_writer *writer,
610 const char *element_name, int value)
611 {
612 return config_writer_write_element_bool(writer->writer,
613 element_name, value);
614 }
615
616 LTTNG_HIDDEN
617 int mi_lttng_writer_write_element_string(struct mi_writer *writer,
618 const char *element_name, const char *value)
619 {
620 return config_writer_write_element_string(writer->writer,
621 element_name, value);
622 }
623
624 LTTNG_HIDDEN
625 int mi_lttng_version(struct mi_writer *writer, struct mi_lttng_version *version,
626 const char *lttng_description, const char *lttng_license)
627 {
628 int ret;
629
630 /* Open version */
631 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_version);
632 if (ret) {
633 goto end;
634 }
635
636 /* Version string (contain info like rc etc.) */
637 ret = mi_lttng_writer_write_element_string(writer,
638 mi_lttng_element_version_str, version->version);
639 if (ret) {
640 goto end;
641 }
642
643 /* Major version number */
644 ret = mi_lttng_writer_write_element_unsigned_int(writer,
645 mi_lttng_element_version_major, version->version_major);
646 if (ret) {
647 goto end;
648 }
649
650 /* Minor version number */
651 ret = mi_lttng_writer_write_element_unsigned_int(writer,
652 mi_lttng_element_version_minor, version->version_minor);
653 if (ret) {
654 goto end;
655 }
656
657 /* Commit version number */
658 ret = mi_lttng_writer_write_element_string(writer,
659 mi_lttng_element_version_commit, version->version_commit);
660 if (ret) {
661 goto end;
662 }
663
664 /* Patch number */
665 ret = mi_lttng_writer_write_element_unsigned_int(writer,
666 mi_lttng_element_version_patch_level, version->version_patchlevel);
667 if (ret) {
668 goto end;
669 }
670
671 /* Name of the version */
672 ret = mi_lttng_writer_write_element_string(writer,
673 config_element_name, version->version_name);
674 if (ret) {
675 goto end;
676 }
677
678 /* Description mostly related to beer... */
679 ret = mi_lttng_writer_write_element_string(writer,
680 mi_lttng_element_version_description, lttng_description);
681 if (ret) {
682 goto end;
683 }
684
685 /* url */
686 ret = mi_lttng_writer_write_element_string(writer,
687 mi_lttng_element_version_web, version->package_url);
688 if (ret) {
689 goto end;
690 }
691
692 /* License: free as in free beer...no...*speech* */
693 ret = mi_lttng_writer_write_element_string(writer,
694 mi_lttng_element_version_license, lttng_license);
695 if (ret) {
696 goto end;
697 }
698
699 /* Close version element */
700 ret = mi_lttng_writer_close_element(writer);
701
702 end:
703 return ret;
704 }
705
706 LTTNG_HIDDEN
707 int mi_lttng_sessions_open(struct mi_writer *writer)
708 {
709 return mi_lttng_writer_open_element(writer, config_element_sessions);
710 }
711
712 LTTNG_HIDDEN
713 int mi_lttng_session(struct mi_writer *writer,
714 struct lttng_session *session, int is_open)
715 {
716 int ret;
717
718 assert(session);
719
720 /* Open sessions element */
721 ret = mi_lttng_writer_open_element(writer,
722 config_element_session);
723 if (ret) {
724 goto end;
725 }
726
727 /* Name of the session */
728 ret = mi_lttng_writer_write_element_string(writer,
729 config_element_name, session->name);
730 if (ret) {
731 goto end;
732 }
733
734 /* Path */
735 ret = mi_lttng_writer_write_element_string(writer,
736 config_element_path, session->path);
737 if (ret) {
738 goto end;
739 }
740
741 /* Enabled ? */
742 ret = mi_lttng_writer_write_element_bool(writer,
743 config_element_enabled, session->enabled);
744 if (ret) {
745 goto end;
746 }
747
748 /* Snapshot mode */
749 ret = mi_lttng_writer_write_element_unsigned_int(writer,
750 config_element_snapshot_mode, session->snapshot_mode);
751 if (ret) {
752 goto end;
753 }
754
755 /* Live timer interval in usec */
756 ret = mi_lttng_writer_write_element_unsigned_int(writer,
757 config_element_live_timer_interval,
758 session->live_timer_interval);
759 if (ret) {
760 goto end;
761 }
762
763 if (!is_open) {
764 /* Closing session element */
765 ret = mi_lttng_writer_close_element(writer);
766 }
767 end:
768 return ret;
769
770 }
771
772 LTTNG_HIDDEN
773 int mi_lttng_domains_open(struct mi_writer *writer)
774 {
775 return mi_lttng_writer_open_element(writer, config_element_domains);
776 }
777
778 LTTNG_HIDDEN
779 int mi_lttng_domain(struct mi_writer *writer,
780 struct lttng_domain *domain, int is_open)
781 {
782 int ret = 0;
783 const char *str_domain;
784 const char *str_buffer;
785
786 assert(domain);
787
788 /* Open domain element */
789 ret = mi_lttng_writer_open_element(writer, config_element_domain);
790 if (ret) {
791 goto end;
792 }
793
794 /* Domain Type */
795 str_domain = mi_lttng_domaintype_string(domain->type);
796 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
797 str_domain);
798 if (ret) {
799 goto end;
800 }
801
802 /* Buffer Type */
803 str_buffer= mi_lttng_buffertype_string(domain->buf_type);
804 ret = mi_lttng_writer_write_element_string(writer,
805 config_element_buffer_type, str_buffer);
806 if (ret) {
807 goto end;
808 }
809
810 /* TODO: union attr
811 * This union is not currently used and was added for
812 * future ust domain support.
813 * Date: 25-06-2014
814 * */
815
816 if (!is_open) {
817 /* Closing domain element */
818 ret = mi_lttng_writer_close_element(writer);
819 }
820
821 end:
822 return ret;
823
824 }
825
826 LTTNG_HIDDEN
827 int mi_lttng_channels_open(struct mi_writer *writer)
828 {
829 return mi_lttng_writer_open_element(writer, config_element_channels);
830 }
831
832 LTTNG_HIDDEN
833 int mi_lttng_channel(struct mi_writer *writer,
834 struct lttng_channel *channel, int is_open)
835 {
836 int ret = 0;
837
838 assert(channel);
839
840 /* Opening channel element */
841 ret = mi_lttng_writer_open_element(writer, config_element_channel);
842 if (ret) {
843 goto end;
844 }
845
846 /* Name */
847 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
848 channel->name);
849 if (ret) {
850 goto end;
851 }
852
853 /* Enabled ? */
854 ret = mi_lttng_writer_write_element_bool(writer,
855 config_element_enabled, channel->enabled);
856 if (ret) {
857 goto end;
858 }
859
860 /* Attribute */
861 ret = mi_lttng_channel_attr(writer, &channel->attr);
862 if (ret) {
863 goto end;
864 }
865
866 if (!is_open) {
867 /* Closing channel element */
868 ret = mi_lttng_writer_close_element(writer);
869 if (ret) {
870 goto end;
871 }
872 }
873 end:
874 return ret;
875 }
876
877 LTTNG_HIDDEN
878 int mi_lttng_channel_attr(struct mi_writer *writer,
879 struct lttng_channel_attr *attr)
880 {
881 int ret = 0;
882 struct lttng_channel *chan = caa_container_of(attr,
883 struct lttng_channel, attr);
884 uint64_t discarded_events, lost_packets, monitor_timer_interval;
885 int64_t blocking_timeout;
886
887 assert(attr);
888
889 ret = lttng_channel_get_discarded_event_count(chan, &discarded_events);
890 if (ret) {
891 goto end;
892 }
893
894 ret = lttng_channel_get_lost_packet_count(chan, &lost_packets);
895 if (ret) {
896 goto end;
897 }
898
899 ret = lttng_channel_get_monitor_timer_interval(chan,
900 &monitor_timer_interval);
901 if (ret) {
902 goto end;
903 }
904
905 ret = lttng_channel_get_blocking_timeout(chan,
906 &blocking_timeout);
907 if (ret) {
908 goto end;
909 }
910
911 /* Opening Attributes */
912 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
913 if (ret) {
914 goto end;
915 }
916
917 /* Overwrite */
918 ret = mi_lttng_writer_write_element_string(writer,
919 config_element_overwrite_mode,
920 attr->overwrite ? config_overwrite_mode_overwrite :
921 config_overwrite_mode_discard);
922 if (ret) {
923 goto end;
924 }
925
926 /* Sub buffer size in byte */
927 ret = mi_lttng_writer_write_element_unsigned_int(writer,
928 config_element_subbuf_size, attr->subbuf_size);
929 if (ret) {
930 goto end;
931 }
932
933 /* Number of subbuffer (power of two) */
934 ret = mi_lttng_writer_write_element_unsigned_int(writer,
935 config_element_num_subbuf,
936 attr->num_subbuf);
937 if (ret) {
938 goto end;
939 }
940
941 /* Switch timer interval in usec */
942 ret = mi_lttng_writer_write_element_unsigned_int(writer,
943 config_element_switch_timer_interval,
944 attr->switch_timer_interval);
945 if (ret) {
946 goto end;
947 }
948
949 /* Read timer interval in usec */
950 ret = mi_lttng_writer_write_element_unsigned_int(writer,
951 config_element_read_timer_interval,
952 attr->read_timer_interval);
953 if (ret) {
954 goto end;
955 }
956
957 /* Monitor timer interval in usec */
958 ret = mi_lttng_writer_write_element_unsigned_int(writer,
959 config_element_monitor_timer_interval,
960 monitor_timer_interval);
961 if (ret) {
962 goto end;
963 }
964
965 /* Retry timeout in usec */
966 ret = mi_lttng_writer_write_element_signed_int(writer,
967 config_element_blocking_timeout,
968 blocking_timeout);
969 if (ret) {
970 goto end;
971 }
972
973 /* Event output */
974 ret = mi_lttng_writer_write_element_string(writer,
975 config_element_output_type,
976 attr->output == LTTNG_EVENT_SPLICE ?
977 config_output_type_splice : config_output_type_mmap);
978 if (ret) {
979 goto end;
980 }
981
982 /* Tracefile size in bytes */
983 ret = mi_lttng_writer_write_element_unsigned_int(writer,
984 config_element_tracefile_size, attr->tracefile_size);
985 if (ret) {
986 goto end;
987 }
988
989 /* Count of tracefiles */
990 ret = mi_lttng_writer_write_element_unsigned_int(writer,
991 config_element_tracefile_count,
992 attr->tracefile_count);
993 if (ret) {
994 goto end;
995 }
996
997 /* Live timer interval in usec*/
998 ret = mi_lttng_writer_write_element_unsigned_int(writer,
999 config_element_live_timer_interval,
1000 attr->live_timer_interval);
1001 if (ret) {
1002 goto end;
1003 }
1004
1005 /* Discarded events */
1006 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1007 config_element_discarded_events,
1008 discarded_events);
1009 if (ret) {
1010 goto end;
1011 }
1012
1013 /* Lost packets */
1014 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1015 config_element_lost_packets,
1016 lost_packets);
1017 if (ret) {
1018 goto end;
1019 }
1020
1021 /* Closing attributes */
1022 ret = mi_lttng_writer_close_element(writer);
1023 if (ret) {
1024 goto end;
1025 }
1026 end:
1027 return ret;
1028
1029 }
1030
1031 LTTNG_HIDDEN
1032 int mi_lttng_event_common_attributes(struct mi_writer *writer,
1033 struct lttng_event *event)
1034 {
1035 int ret;
1036 const char *filter_expression;
1037
1038 /* Open event element */
1039 ret = mi_lttng_writer_open_element(writer, config_element_event);
1040 if (ret) {
1041 goto end;
1042 }
1043
1044 /* Event name */
1045 ret = mi_lttng_writer_write_element_string(writer,
1046 config_element_name, event->name);
1047 if (ret) {
1048 goto end;
1049 }
1050
1051 /* Event type */
1052 ret = mi_lttng_writer_write_element_string(writer,
1053 config_element_type, mi_lttng_eventtype_string(event->type));
1054 if (ret) {
1055 goto end;
1056 }
1057
1058 /* Is event enabled */
1059 ret = mi_lttng_writer_write_element_bool(writer,
1060 config_element_enabled, event->enabled);
1061 if (ret) {
1062 goto end;
1063 }
1064
1065 /* Event filter expression */
1066 ret = lttng_event_get_filter_expression(event, &filter_expression);
1067 if (ret) {
1068 goto end;
1069 }
1070
1071 if (filter_expression) {
1072 ret = mi_lttng_writer_write_element_string(writer,
1073 config_element_filter_expression,
1074 filter_expression);
1075 if (ret) {
1076 goto end;
1077 }
1078 }
1079
1080 end:
1081 return ret;
1082 }
1083
1084 static int write_event_exclusions(struct mi_writer *writer,
1085 struct lttng_event *event)
1086 {
1087 int i;
1088 int ret;
1089 int exclusion_count;
1090
1091 /* Open event exclusions */
1092 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
1093 if (ret) {
1094 goto end;
1095 }
1096
1097 exclusion_count = lttng_event_get_exclusion_name_count(event);
1098 if (exclusion_count < 0) {
1099 ret = exclusion_count;
1100 goto end;
1101 }
1102
1103 for (i = 0; i < exclusion_count; i++) {
1104 const char *name;
1105
1106 ret = lttng_event_get_exclusion_name(event, i, &name);
1107 if (ret) {
1108 /* Close exclusions */
1109 mi_lttng_writer_close_element(writer);
1110 goto end;
1111 }
1112
1113 ret = mi_lttng_writer_write_element_string(writer,
1114 config_element_exclusion, name);
1115 if (ret) {
1116 /* Close exclusions */
1117 mi_lttng_writer_close_element(writer);
1118 goto end;
1119 }
1120 }
1121
1122 /* Close exclusions */
1123 ret = mi_lttng_writer_close_element(writer);
1124
1125 end:
1126 return ret;
1127 }
1128
1129 LTTNG_HIDDEN
1130 int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer,
1131 struct lttng_event *event, enum lttng_domain_type domain)
1132 {
1133 int ret;
1134
1135 /* Event loglevel */
1136 ret = mi_lttng_writer_write_element_string(writer,
1137 config_element_loglevel,
1138 mi_lttng_loglevel_string(event->loglevel, domain));
1139 if (ret) {
1140 goto end;
1141 }
1142
1143 /* Log level type */
1144 ret = mi_lttng_writer_write_element_string(writer,
1145 config_element_loglevel_type,
1146 mi_lttng_logleveltype_string(event->loglevel_type));
1147 if (ret) {
1148 goto end;
1149 }
1150
1151 /* Event exclusions */
1152 ret = write_event_exclusions(writer, event);
1153
1154 end:
1155 return ret;
1156 }
1157
1158 LTTNG_HIDDEN
1159 int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer,
1160 struct lttng_event *event)
1161 {
1162 /* event exclusion filter */
1163 return write_event_exclusions(writer, event);
1164 }
1165
1166 LTTNG_HIDDEN
1167 int mi_lttng_event_function_probe(struct mi_writer *writer,
1168 struct lttng_event *event)
1169 {
1170 int ret;
1171
1172 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1173 if (ret) {
1174 goto end;
1175 }
1176
1177 ret = mi_lttng_writer_open_element(writer, config_element_probe_attributes);
1178 if (ret) {
1179 goto end;
1180 }
1181
1182 if (event->attr.probe.addr != 0) {
1183 /* event probe address */
1184 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1185 config_element_address, event->attr.probe.addr);
1186 if (ret) {
1187 goto end;
1188 }
1189 } else {
1190 /* event probe offset */
1191 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1192 config_element_offset, event->attr.probe.offset);
1193 if (ret) {
1194 goto end;
1195 }
1196
1197 /* event probe symbol_name */
1198 ret = mi_lttng_writer_write_element_string(writer,
1199 config_element_symbol_name, event->attr.probe.symbol_name);
1200 if (ret) {
1201 goto end;
1202 }
1203 }
1204
1205 /* Close probe_attributes and attributes */
1206 ret = mi_lttng_close_multi_element(writer, 2);
1207 end:
1208 return ret;
1209 }
1210
1211 LTTNG_HIDDEN
1212 int mi_lttng_event_function_entry(struct mi_writer *writer,
1213 struct lttng_event *event)
1214 {
1215 int ret;
1216
1217 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1218 if (ret) {
1219 goto end;
1220 }
1221
1222 ret = mi_lttng_writer_open_element(writer, config_element_probe_attributes);
1223 if (ret) {
1224 goto end;
1225 }
1226
1227 /* event probe symbol_name */
1228 ret = mi_lttng_writer_write_element_string(writer,
1229 config_element_symbol_name, event->attr.ftrace.symbol_name);
1230 if (ret) {
1231 goto end;
1232 }
1233
1234 /* Close function_attributes and attributes */
1235 ret = mi_lttng_close_multi_element(writer, 2);
1236 end:
1237 return ret;
1238 }
1239
1240 LTTNG_HIDDEN
1241 int mi_lttng_events_open(struct mi_writer *writer)
1242 {
1243 return mi_lttng_writer_open_element(writer, config_element_events);
1244 }
1245
1246 LTTNG_HIDDEN
1247 int mi_lttng_event(struct mi_writer *writer,
1248 struct lttng_event *event, int is_open, enum lttng_domain_type domain)
1249 {
1250 int ret;
1251
1252 ret = mi_lttng_event_common_attributes(writer, event);
1253 if (ret) {
1254 goto end;
1255 }
1256
1257 switch (event->type) {
1258 case LTTNG_EVENT_TRACEPOINT:
1259 {
1260 if (event->loglevel != -1) {
1261 ret = mi_lttng_event_tracepoint_loglevel(writer, event, domain);
1262 } else {
1263 ret = mi_lttng_event_tracepoint_no_loglevel(writer, event);
1264 }
1265 break;
1266 }
1267 case LTTNG_EVENT_FUNCTION:
1268 /* Fallthrough */
1269 case LTTNG_EVENT_PROBE:
1270 ret = mi_lttng_event_function_probe(writer, event);
1271 break;
1272 case LTTNG_EVENT_FUNCTION_ENTRY:
1273 ret = mi_lttng_event_function_entry(writer, event);
1274 break;
1275 case LTTNG_EVENT_ALL:
1276 /* Fallthrough */
1277 default:
1278 break;
1279 }
1280
1281 if (!is_open) {
1282 ret = mi_lttng_writer_close_element(writer);
1283 }
1284
1285 end:
1286 return ret;
1287 }
1288
1289 LTTNG_HIDDEN
1290 int mi_lttng_trackers_open(struct mi_writer *writer)
1291 {
1292 return mi_lttng_writer_open_element(writer, config_element_trackers);
1293 }
1294
1295 LTTNG_HIDDEN
1296 int mi_lttng_pid_tracker_open(struct mi_writer *writer)
1297 {
1298 int ret;
1299
1300 /* Open element pid_tracker */
1301 ret = mi_lttng_writer_open_element(writer, config_element_pid_tracker);
1302 if (ret) {
1303 goto end;
1304 }
1305
1306 /* Open targets element */
1307 ret = mi_lttng_targets_open(writer);
1308 end:
1309 return ret;
1310 }
1311
1312 LTTNG_HIDDEN
1313 int mi_lttng_pids_open(struct mi_writer *writer)
1314 {
1315 return mi_lttng_writer_open_element(writer, config_element_pids);
1316 }
1317
1318 /*
1319 * TODO: move the listing of pid for user agent to process semantic on
1320 * mi api bump. The use of process element break the mi api.
1321 */
1322 LTTNG_HIDDEN
1323 int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *name,
1324 int is_open)
1325 {
1326 int ret;
1327
1328 /* Open pid process */
1329 ret = mi_lttng_writer_open_element(writer, config_element_pid);
1330 if (ret) {
1331 goto end;
1332 }
1333
1334 /* Writing pid number */
1335 ret = mi_lttng_writer_write_element_signed_int(writer,
1336 mi_lttng_element_pid_id, (int)pid);
1337 if (ret) {
1338 goto end;
1339 }
1340
1341 /* Writing name of the process */
1342 if (name) {
1343 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1344 name);
1345 if (ret) {
1346 goto end;
1347 }
1348 }
1349
1350 if (!is_open) {
1351 /* Closing Pid */
1352 ret = mi_lttng_writer_close_element(writer);
1353 }
1354
1355 end:
1356 return ret;
1357 }
1358
1359 LTTNG_HIDDEN
1360 int mi_lttng_targets_open(struct mi_writer *writer)
1361 {
1362 return mi_lttng_writer_open_element(writer,
1363 config_element_targets);
1364 }
1365
1366 LTTNG_HIDDEN
1367 int mi_lttng_pid_target(struct mi_writer *writer, pid_t pid, int is_open)
1368 {
1369 int ret;
1370
1371 ret = mi_lttng_writer_open_element(writer,
1372 config_element_target_pid);
1373 if (ret) {
1374 goto end;
1375 }
1376
1377 /* Writing pid number
1378 * Special case for element all on track untrack command
1379 * All pid is represented as wildcard *
1380 */
1381 if ((int) pid == -1) {
1382 ret = mi_lttng_writer_write_element_string(writer,
1383 config_element_pid,
1384 mi_lttng_element_track_untrack_all_wildcard);
1385 } else {
1386 ret = mi_lttng_writer_write_element_signed_int(writer,
1387 config_element_pid, (int) pid);
1388 }
1389 if (ret) {
1390 goto end;
1391 }
1392
1393 if (!is_open) {
1394 ret = mi_lttng_writer_close_element(writer);
1395 if (ret) {
1396 goto end;
1397 }
1398 }
1399
1400 end:
1401 return ret;
1402 }
1403
1404 LTTNG_HIDDEN
1405 int mi_lttng_event_fields_open(struct mi_writer *writer)
1406 {
1407 return mi_lttng_writer_open_element(writer, mi_lttng_element_event_fields);
1408 }
1409
1410 LTTNG_HIDDEN
1411 int mi_lttng_event_field(struct mi_writer *writer,
1412 struct lttng_event_field *field)
1413 {
1414 int ret;
1415
1416 if (!field->field_name[0]) {
1417 ret = 0;
1418 goto end;
1419 }
1420
1421 /* Open field */
1422 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_field);
1423 if (ret) {
1424 goto end;
1425 }
1426
1427 if (!field->field_name[0]) {
1428 goto close;
1429 }
1430
1431 /* Name */
1432 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1433 field->field_name);
1434 if (ret) {
1435 goto end;
1436 }
1437
1438 /* Type */
1439 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
1440 mi_lttng_eventfieldtype_string(field->type));
1441 if (ret) {
1442 goto end;
1443 }
1444
1445 /* nowrite */
1446 ret = mi_lttng_writer_write_element_signed_int(writer,
1447 mi_lttng_element_nowrite, field->nowrite);
1448 if (ret) {
1449 goto end;
1450 }
1451
1452 close:
1453 /* Close field element */
1454 ret = mi_lttng_writer_close_element(writer);
1455
1456 end:
1457 return ret;
1458 }
1459
1460 LTTNG_HIDDEN
1461 int mi_lttng_perf_counter_context(struct mi_writer *writer,
1462 struct lttng_event_perf_counter_ctx *perf_context)
1463 {
1464 int ret;
1465
1466 /* Open perf_counter_context */
1467 ret = mi_lttng_writer_open_element(writer,
1468 mi_lttng_element_perf_counter_context);
1469 if (ret) {
1470 goto end;
1471 }
1472
1473 /* Type */
1474 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1475 config_element_type, perf_context->type);
1476 if (ret) {
1477 goto end;
1478 }
1479
1480 /* Config */
1481 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1482 config_element_config, perf_context->config);
1483 if (ret) {
1484 goto end;
1485 }
1486
1487 /* Name of the perf counter */
1488 ret = mi_lttng_writer_write_element_string(writer,
1489 config_element_name, perf_context->name);
1490 if (ret) {
1491 goto end;
1492 }
1493
1494 /* Close perf_counter_context */
1495 ret = mi_lttng_writer_close_element(writer);
1496 end:
1497 return ret;
1498 }
1499
1500 static
1501 int mi_lttng_app_context(struct mi_writer *writer,
1502 const char *provider_name, const char *ctx_name)
1503 {
1504 int ret;
1505
1506 /* Open app */
1507 ret = mi_lttng_writer_open_element(writer,
1508 config_element_context_app);
1509 if (ret) {
1510 goto end;
1511 }
1512
1513 /* provider_name */
1514 ret = mi_lttng_writer_write_element_string(writer,
1515 config_element_context_app_provider_name,
1516 provider_name);
1517 if (ret) {
1518 goto end;
1519 }
1520
1521 /* ctx_name */
1522 ret = mi_lttng_writer_write_element_string(writer,
1523 config_element_context_app_ctx_name, ctx_name);
1524 if (ret) {
1525 goto end;
1526 }
1527
1528 /* Close app */
1529 ret = mi_lttng_writer_close_element(writer);
1530 end:
1531 return ret;
1532 }
1533
1534 LTTNG_HIDDEN
1535 int mi_lttng_context(struct mi_writer *writer,
1536 struct lttng_event_context *context, int is_open)
1537 {
1538 int ret;
1539
1540 /* Open context */
1541 ret = mi_lttng_writer_open_element(writer , config_element_context);
1542 if (ret) {
1543 goto end;
1544 }
1545
1546 /* Special case for PERF_*_COUNTER
1547 * print the lttng_event_perf_counter_ctx*/
1548 switch (context->ctx) {
1549 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
1550 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
1551 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
1552 {
1553 struct lttng_event_perf_counter_ctx *perf_context =
1554 &context->u.perf_counter;
1555 ret = mi_lttng_perf_counter_context(writer, perf_context);
1556 if (ret) {
1557 goto end;
1558 }
1559 break;
1560 }
1561 case LTTNG_EVENT_CONTEXT_APP_CONTEXT:
1562 {
1563 ret = mi_lttng_app_context(writer,
1564 context->u.app_ctx.provider_name,
1565 context->u.app_ctx.ctx_name);
1566 if (ret) {
1567 goto end;
1568 }
1569 break;
1570 }
1571 default:
1572 {
1573 const char *type_string = mi_lttng_event_contexttype_string(
1574 context->ctx);
1575 if (!type_string) {
1576 ret = -LTTNG_ERR_INVALID;
1577 goto end;
1578 }
1579
1580 /* Print context type */
1581 ret = mi_lttng_writer_write_element_string(writer,
1582 config_element_type, type_string);
1583 break;
1584 }
1585 }
1586
1587 /* Close context */
1588 if (!is_open) {
1589 ret = mi_lttng_writer_close_element(writer);
1590 }
1591
1592 end:
1593 return ret;
1594 }
1595
1596 LTTNG_HIDDEN
1597 int mi_lttng_snapshot_output_session_name(struct mi_writer *writer,
1598 const char *session_name)
1599 {
1600 int ret;
1601
1602 /* Open session element */
1603 ret = mi_lttng_writer_open_element(writer, config_element_session);
1604 if (ret) {
1605 goto end;
1606 }
1607
1608 /* Snapshot output list for current session name */
1609 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1610 session_name);
1611 if (ret) {
1612 goto end;
1613 }
1614
1615 /* Open element snapshots (sequence one snapshot) */
1616 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_snapshots);
1617 if (ret) {
1618 goto end;
1619 }
1620
1621 end:
1622 return ret;
1623 }
1624
1625 LTTNG_HIDDEN
1626 int mi_lttng_snapshot_list_output(struct mi_writer *writer,
1627 struct lttng_snapshot_output *output)
1628 {
1629 int ret;
1630
1631 /* Open element snapshot output */
1632 ret = mi_lttng_writer_open_element(writer,
1633 mi_lttng_element_command_snapshot);
1634 if (ret) {
1635 goto end;
1636 }
1637
1638 /* ID of the snapshot output */
1639 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1640 mi_lttng_element_id, output->id);
1641 if (ret) {
1642 goto end;
1643 }
1644
1645 /* Name of the output */
1646 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1647 output->name);
1648 if (ret) {
1649 goto end;
1650 }
1651
1652 /* Destination of the output (ctrl_url)*/
1653 ret = mi_lttng_writer_write_element_string(writer,
1654 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
1655 if (ret) {
1656 goto end;
1657 }
1658
1659 /* Destination of the output (data_url) */
1660 ret = mi_lttng_writer_write_element_string(writer,
1661 mi_lttng_element_snapshot_data_url, output->data_url);
1662 if (ret) {
1663 goto end;
1664 }
1665
1666 /* total size of all stream combined */
1667 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1668 mi_lttng_element_snapshot_max_size, output->max_size);
1669 if (ret) {
1670 goto end;
1671 }
1672
1673 /* Close snapshot output element */
1674 ret = mi_lttng_writer_close_element(writer);
1675
1676 end:
1677 return ret;
1678 }
1679
1680 LTTNG_HIDDEN
1681 int mi_lttng_snapshot_del_output(struct mi_writer *writer, int id,
1682 const char *name, const char *current_session_name)
1683 {
1684 int ret;
1685
1686 /* Open element del_snapshot */
1687 ret = mi_lttng_writer_open_element(writer,
1688 mi_lttng_element_command_snapshot);
1689 if (ret) {
1690 goto end;
1691 }
1692
1693
1694 if (id != UINT32_MAX) {
1695 /* "Snapshot output "id" successfully deleted
1696 * for "current_session_name"
1697 * ID of the snapshot output
1698 */
1699 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1700 mi_lttng_element_id, id);
1701 if (ret) {
1702 goto end;
1703 }
1704 } else {
1705 /* "Snapshot output "name" successfully deleted
1706 * for session "current_session_name"
1707 * Name of the output
1708 */
1709 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1710 name);
1711 if (ret) {
1712 goto end;
1713 }
1714 }
1715
1716 /* Snapshot was deleted for session "current_session_name"*/
1717 ret = mi_lttng_writer_write_element_string(writer,
1718 mi_lttng_element_snapshot_session_name,
1719 current_session_name);
1720 if (ret) {
1721 goto end;
1722 }
1723
1724 /* Close snapshot element */
1725 ret = mi_lttng_writer_close_element(writer);
1726
1727 end:
1728 return ret;
1729 }
1730
1731 LTTNG_HIDDEN
1732 int mi_lttng_snapshot_add_output(struct mi_writer *writer,
1733 const char *current_session_name, const char *n_ptr,
1734 struct lttng_snapshot_output *output)
1735 {
1736 int ret;
1737
1738 /* Open element snapshot */
1739 ret = mi_lttng_writer_open_element(writer,
1740 mi_lttng_element_command_snapshot);
1741 if (ret) {
1742 goto end;
1743 }
1744
1745 /* Snapshot output id */
1746 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1747 mi_lttng_element_id, output->id);
1748 if (ret) {
1749 goto end;
1750 }
1751
1752 /* Snapshot output names */
1753 ret = mi_lttng_writer_write_element_string(writer,
1754 config_element_name, n_ptr);
1755 if (ret) {
1756 goto end;
1757 }
1758
1759 /* Destination of the output (ctrl_url)*/
1760 ret = mi_lttng_writer_write_element_string(writer,
1761 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
1762 if (ret) {
1763 goto end;
1764 }
1765
1766 /* Snapshot added for session "current_session_name"*/
1767 ret = mi_lttng_writer_write_element_string(writer,
1768 mi_lttng_element_snapshot_session_name, current_session_name);
1769 if (ret) {
1770 goto end;
1771 }
1772
1773 /* total size of all stream combined */
1774 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1775 mi_lttng_element_snapshot_max_size, output->max_size);
1776 if (ret) {
1777 goto end;
1778 }
1779
1780 /* Close snapshot element */
1781 ret = mi_lttng_writer_close_element(writer);
1782
1783 end:
1784 return ret;
1785 }
1786
1787 LTTNG_HIDDEN
1788 int mi_lttng_snapshot_record(struct mi_writer *writer,
1789 const char *current_session_name, const char *url,
1790 const char *cmdline_ctrl_url, const char *cmdline_data_url)
1791 {
1792 int ret;
1793
1794 /* Open element snapshot */
1795 ret = mi_lttng_writer_open_element(writer,
1796 mi_lttng_element_command_snapshot);
1797 if (ret) {
1798 goto end;
1799 }
1800
1801 /*
1802 * If a valid an URL was given, serialize it,
1803 * else take the command line data and ctrl urls*/
1804 if (url) {
1805 /* Destination of the output (ctrl_url)*/
1806 ret = mi_lttng_writer_write_element_string(writer,
1807 mi_lttng_element_snapshot_ctrl_url, url);
1808 if (ret) {
1809 goto end;
1810 }
1811 } else if (cmdline_ctrl_url) {
1812 /* Destination of the output (ctrl_url)*/
1813 ret = mi_lttng_writer_write_element_string(writer,
1814 mi_lttng_element_snapshot_ctrl_url, cmdline_ctrl_url);
1815 if (ret) {
1816 goto end;
1817 }
1818
1819 /* Destination of the output (data_url) */
1820 ret = mi_lttng_writer_write_element_string(writer,
1821 mi_lttng_element_snapshot_data_url, cmdline_data_url);
1822 if (ret) {
1823 goto end;
1824 }
1825 }
1826
1827 /* Close record_snapshot element */
1828 ret = mi_lttng_writer_close_element(writer);
1829
1830 end:
1831 return ret;
1832 }
This page took 0.081986 seconds and 3 git commands to generate.