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