MI: add <exclusions> (event exclusion names)
[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 /* event exclusion filter */
1021 ret = mi_lttng_writer_write_element_bool(writer,
1022 config_element_exclusion, event->exclusion);
1023 if (ret) {
1024 goto end;
1025 }
1026
1027 /* Open event exclusions */
1028 ret = mi_lttng_writer_open_element(writer, config_element_exclusions);
1029 if (ret) {
1030 goto end;
1031 }
1032
1033 exclusion_count = lttng_event_get_exclusion_name_count(event);
1034 if (exclusion_count < 0) {
1035 ret = exclusion_count;
1036 goto end;
1037 }
1038
1039 for (i = 0; i < exclusion_count; i++) {
1040 const char *name;
1041
1042 ret = lttng_event_get_exclusion_name(event, i, &name);
1043 if (ret) {
1044 /* Close exclusions */
1045 mi_lttng_writer_close_element(writer);
1046 goto end;
1047 }
1048
1049 ret = mi_lttng_writer_write_element_string(writer,
1050 config_element_exclusion, name);
1051 if (ret) {
1052 /* Close exclusions */
1053 mi_lttng_writer_close_element(writer);
1054 goto end;
1055 }
1056 }
1057
1058 /* Close exclusions */
1059 ret = mi_lttng_writer_close_element(writer);
1060
1061 end:
1062 return ret;
1063 }
1064
1065 LTTNG_HIDDEN
1066 int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer,
1067 struct lttng_event *event, enum lttng_domain_type domain)
1068 {
1069 int ret;
1070
1071 /* Event loglevel */
1072 ret = mi_lttng_writer_write_element_string(writer,
1073 config_element_loglevel,
1074 mi_lttng_loglevel_string(event->loglevel, domain));
1075 if (ret) {
1076 goto end;
1077 }
1078
1079 /* Log level type */
1080 ret = mi_lttng_writer_write_element_string(writer,
1081 config_element_loglevel_type,
1082 mi_lttng_logleveltype_string(event->loglevel_type));
1083 if (ret) {
1084 goto end;
1085 }
1086
1087 /* Event exclusions */
1088 ret = write_event_exclusions(writer, event);
1089
1090 end:
1091 return ret;
1092 }
1093
1094 LTTNG_HIDDEN
1095 int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer,
1096 struct lttng_event *event)
1097 {
1098 /* event exclusion filter */
1099 return write_event_exclusions(writer, event);
1100 }
1101
1102 LTTNG_HIDDEN
1103 int mi_lttng_event_function_probe(struct mi_writer *writer,
1104 struct lttng_event *event)
1105 {
1106 int ret;
1107
1108 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1109 if (ret) {
1110 goto end;
1111 }
1112
1113 ret = mi_lttng_writer_open_element(writer, config_element_probe_attributes);
1114 if (ret) {
1115 goto end;
1116 }
1117
1118 if (event->attr.probe.addr != 0) {
1119 /* event probe address */
1120 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1121 config_element_address, event->attr.probe.addr);
1122 if (ret) {
1123 goto end;
1124 }
1125 } else {
1126 /* event probe offset */
1127 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1128 config_element_offset, event->attr.probe.offset);
1129 if (ret) {
1130 goto end;
1131 }
1132
1133 /* event probe symbol_name */
1134 ret = mi_lttng_writer_write_element_string(writer,
1135 config_element_symbol_name, event->attr.probe.symbol_name);
1136 if (ret) {
1137 goto end;
1138 }
1139 }
1140
1141 /* Close probe_attributes and attributes */
1142 ret = mi_lttng_close_multi_element(writer, 2);
1143 end:
1144 return ret;
1145 }
1146
1147 LTTNG_HIDDEN
1148 int mi_lttng_event_function_entry(struct mi_writer *writer,
1149 struct lttng_event *event)
1150 {
1151 int ret;
1152
1153 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
1154 if (ret) {
1155 goto end;
1156 }
1157
1158 ret = mi_lttng_writer_open_element(writer, config_element_probe_attributes);
1159 if (ret) {
1160 goto end;
1161 }
1162
1163 /* event probe symbol_name */
1164 ret = mi_lttng_writer_write_element_string(writer,
1165 config_element_symbol_name, event->attr.ftrace.symbol_name);
1166 if (ret) {
1167 goto end;
1168 }
1169
1170 /* Close function_attributes and attributes */
1171 ret = mi_lttng_close_multi_element(writer, 2);
1172 end:
1173 return ret;
1174 }
1175
1176 LTTNG_HIDDEN
1177 int mi_lttng_events_open(struct mi_writer *writer)
1178 {
1179 return mi_lttng_writer_open_element(writer, config_element_events);
1180 }
1181
1182 LTTNG_HIDDEN
1183 int mi_lttng_event(struct mi_writer *writer,
1184 struct lttng_event *event, int is_open, enum lttng_domain_type domain)
1185 {
1186 int ret;
1187
1188 ret = mi_lttng_event_common_attributes(writer, event);
1189 if (ret) {
1190 goto end;
1191 }
1192
1193 switch (event->type) {
1194 case LTTNG_EVENT_TRACEPOINT:
1195 {
1196 if (event->loglevel != -1) {
1197 ret = mi_lttng_event_tracepoint_loglevel(writer, event, domain);
1198 } else {
1199 ret = mi_lttng_event_tracepoint_no_loglevel(writer, event);
1200 }
1201 break;
1202 }
1203 case LTTNG_EVENT_FUNCTION:
1204 /* Fallthrough */
1205 case LTTNG_EVENT_PROBE:
1206 ret = mi_lttng_event_function_probe(writer, event);
1207 break;
1208 case LTTNG_EVENT_FUNCTION_ENTRY:
1209 ret = mi_lttng_event_function_entry(writer, event);
1210 break;
1211 case LTTNG_EVENT_ALL:
1212 /* Fallthrough */
1213 default:
1214 break;
1215 }
1216
1217 if (!is_open) {
1218 ret = mi_lttng_writer_close_element(writer);
1219 }
1220
1221 end:
1222 return ret;
1223 }
1224
1225 LTTNG_HIDDEN
1226 int mi_lttng_trackers_open(struct mi_writer *writer)
1227 {
1228 return mi_lttng_writer_open_element(writer, config_element_trackers);
1229 }
1230
1231 LTTNG_HIDDEN
1232 int mi_lttng_pid_tracker_open(struct mi_writer *writer)
1233 {
1234 int ret;
1235
1236 /* Open element pid_tracker */
1237 ret = mi_lttng_writer_open_element(writer, config_element_pid_tracker);
1238 if (ret) {
1239 goto end;
1240 }
1241
1242 /* Open targets element */
1243 ret = mi_lttng_targets_open(writer);
1244 end:
1245 return ret;
1246 }
1247
1248 LTTNG_HIDDEN
1249 int mi_lttng_pids_open(struct mi_writer *writer)
1250 {
1251 return mi_lttng_writer_open_element(writer, config_element_pids);
1252 }
1253
1254 /*
1255 * TODO: move the listing of pid for user agent to process semantic on
1256 * mi api bump. The use of process element break the mi api.
1257 */
1258 LTTNG_HIDDEN
1259 int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *name,
1260 int is_open)
1261 {
1262 int ret;
1263
1264 /* Open pid process */
1265 ret = mi_lttng_writer_open_element(writer, config_element_pid);
1266 if (ret) {
1267 goto end;
1268 }
1269
1270 /* Writing pid number */
1271 ret = mi_lttng_writer_write_element_signed_int(writer,
1272 mi_lttng_element_pid_id, (int)pid);
1273 if (ret) {
1274 goto end;
1275 }
1276
1277 /* Writing name of the process */
1278 if (name) {
1279 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1280 name);
1281 if (ret) {
1282 goto end;
1283 }
1284 }
1285
1286 if (!is_open) {
1287 /* Closing Pid */
1288 ret = mi_lttng_writer_close_element(writer);
1289 }
1290
1291 end:
1292 return ret;
1293 }
1294
1295 LTTNG_HIDDEN
1296 int mi_lttng_targets_open(struct mi_writer *writer)
1297 {
1298 return mi_lttng_writer_open_element(writer,
1299 config_element_targets);
1300 }
1301
1302 LTTNG_HIDDEN
1303 int mi_lttng_pid_target(struct mi_writer *writer, pid_t pid, int is_open)
1304 {
1305 int ret;
1306
1307 ret = mi_lttng_writer_open_element(writer,
1308 config_element_target_pid);
1309 if (ret) {
1310 goto end;
1311 }
1312
1313 /* Writing pid number
1314 * Special case for element all on track untrack command
1315 * All pid is represented as wildcard *
1316 */
1317 if ((int) pid == -1) {
1318 ret = mi_lttng_writer_write_element_string(writer,
1319 config_element_pid,
1320 mi_lttng_element_track_untrack_all_wildcard);
1321 } else {
1322 ret = mi_lttng_writer_write_element_signed_int(writer,
1323 config_element_pid, (int) pid);
1324 }
1325 if (ret) {
1326 goto end;
1327 }
1328
1329 if (!is_open) {
1330 ret = mi_lttng_writer_close_element(writer);
1331 if (ret) {
1332 goto end;
1333 }
1334 }
1335
1336 end:
1337 return ret;
1338 }
1339
1340 LTTNG_HIDDEN
1341 int mi_lttng_event_fields_open(struct mi_writer *writer)
1342 {
1343 return mi_lttng_writer_open_element(writer, mi_lttng_element_event_fields);
1344 }
1345
1346 LTTNG_HIDDEN
1347 int mi_lttng_event_field(struct mi_writer *writer,
1348 struct lttng_event_field *field)
1349 {
1350 int ret;
1351
1352 if (!field->field_name[0]) {
1353 ret = 0;
1354 goto end;
1355 }
1356
1357 /* Open field */
1358 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_field);
1359 if (ret) {
1360 goto end;
1361 }
1362
1363 if (!field->field_name[0]) {
1364 goto close;
1365 }
1366
1367 /* Name */
1368 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1369 field->field_name);
1370 if (ret) {
1371 goto end;
1372 }
1373
1374 /* Type */
1375 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
1376 mi_lttng_eventfieldtype_string(field->type));
1377 if (ret) {
1378 goto end;
1379 }
1380
1381 /* nowrite */
1382 ret = mi_lttng_writer_write_element_signed_int(writer,
1383 mi_lttng_element_nowrite, field->nowrite);
1384 if (ret) {
1385 goto end;
1386 }
1387
1388 close:
1389 /* Close field element */
1390 ret = mi_lttng_writer_close_element(writer);
1391
1392 end:
1393 return ret;
1394 }
1395
1396 LTTNG_HIDDEN
1397 int mi_lttng_calibrate(struct mi_writer *writer,
1398 struct lttng_calibrate *calibrate)
1399 {
1400 int ret;
1401
1402 /* Open calibrate element */
1403 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_calibrate);
1404 if (ret) {
1405 goto end;
1406 }
1407
1408 /* Calibration type */
1409 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
1410 mi_lttng_calibratetype_string(calibrate->type));
1411 if (ret) {
1412 goto end;
1413 }
1414
1415 /* Closing calibrate element */
1416 ret = mi_lttng_writer_close_element(writer);
1417 end:
1418 return ret;
1419 }
1420
1421 LTTNG_HIDDEN
1422 int mi_lttng_perf_counter_context(struct mi_writer *writer,
1423 struct lttng_event_perf_counter_ctx *perf_context)
1424 {
1425 int ret;
1426
1427 /* Open perf_counter_context */
1428 ret = mi_lttng_writer_open_element(writer,
1429 mi_lttng_element_perf_counter_context);
1430 if (ret) {
1431 goto end;
1432 }
1433
1434 /* Type */
1435 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1436 config_element_type, perf_context->type);
1437 if (ret) {
1438 goto end;
1439 }
1440
1441 /* Config */
1442 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1443 config_element_config, perf_context->config);
1444 if (ret) {
1445 goto end;
1446 }
1447
1448 /* Name of the perf counter */
1449 ret = mi_lttng_writer_write_element_string(writer,
1450 config_element_name, perf_context->name);
1451 if (ret) {
1452 goto end;
1453 }
1454
1455 /* Close perf_counter_context */
1456 ret = mi_lttng_writer_close_element(writer);
1457 end:
1458 return ret;
1459 }
1460
1461 static
1462 int mi_lttng_app_context(struct mi_writer *writer,
1463 const char *provider_name, const char *ctx_name)
1464 {
1465 int ret;
1466
1467 /* Open app */
1468 ret = mi_lttng_writer_open_element(writer,
1469 config_element_context_app);
1470 if (ret) {
1471 goto end;
1472 }
1473
1474 /* provider_name */
1475 ret = mi_lttng_writer_write_element_string(writer,
1476 config_element_context_app_provider_name,
1477 provider_name);
1478 if (ret) {
1479 goto end;
1480 }
1481
1482 /* ctx_name */
1483 ret = mi_lttng_writer_write_element_string(writer,
1484 config_element_context_app_ctx_name, ctx_name);
1485 if (ret) {
1486 goto end;
1487 }
1488
1489 /* Close app */
1490 ret = mi_lttng_writer_close_element(writer);
1491 end:
1492 return ret;
1493 }
1494
1495 LTTNG_HIDDEN
1496 int mi_lttng_context(struct mi_writer *writer,
1497 struct lttng_event_context *context, int is_open)
1498 {
1499 int ret;
1500
1501 /* Open context */
1502 ret = mi_lttng_writer_open_element(writer , config_element_context);
1503 if (ret) {
1504 goto end;
1505 }
1506
1507 /* Special case for PERF_*_COUNTER
1508 * print the lttng_event_perf_counter_ctx*/
1509 switch (context->ctx) {
1510 case LTTNG_EVENT_CONTEXT_PERF_COUNTER:
1511 case LTTNG_EVENT_CONTEXT_PERF_THREAD_COUNTER:
1512 case LTTNG_EVENT_CONTEXT_PERF_CPU_COUNTER:
1513 {
1514 struct lttng_event_perf_counter_ctx *perf_context =
1515 &context->u.perf_counter;
1516 ret = mi_lttng_perf_counter_context(writer, perf_context);
1517 if (ret) {
1518 goto end;
1519 }
1520 break;
1521 }
1522 case LTTNG_EVENT_CONTEXT_APP_CONTEXT:
1523 {
1524 ret = mi_lttng_app_context(writer,
1525 context->u.app_ctx.provider_name,
1526 context->u.app_ctx.ctx_name);
1527 if (ret) {
1528 goto end;
1529 }
1530 break;
1531 }
1532 default:
1533 {
1534 const char *type_string = mi_lttng_event_contexttype_string(
1535 context->ctx);
1536 if (!type_string) {
1537 ret = -LTTNG_ERR_INVALID;
1538 goto end;
1539 }
1540
1541 /* Print context type */
1542 ret = mi_lttng_writer_write_element_string(writer,
1543 config_element_type, type_string);
1544 break;
1545 }
1546 }
1547
1548 /* Close context */
1549 if (!is_open) {
1550 ret = mi_lttng_writer_close_element(writer);
1551 }
1552
1553 end:
1554 return ret;
1555 }
1556
1557 LTTNG_HIDDEN
1558 int mi_lttng_snapshot_output_session_name(struct mi_writer *writer,
1559 const char *session_name)
1560 {
1561 int ret;
1562
1563 /* Open session element */
1564 ret = mi_lttng_writer_open_element(writer, config_element_session);
1565 if (ret) {
1566 goto end;
1567 }
1568
1569 /* Snapshot output list for current session name */
1570 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1571 session_name);
1572 if (ret) {
1573 goto end;
1574 }
1575
1576 /* Open element snapshots (sequence one snapshot) */
1577 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_snapshots);
1578 if (ret) {
1579 goto end;
1580 }
1581
1582 end:
1583 return ret;
1584 }
1585
1586 LTTNG_HIDDEN
1587 int mi_lttng_snapshot_list_output(struct mi_writer *writer,
1588 struct lttng_snapshot_output *output)
1589 {
1590 int ret;
1591
1592 /* Open element snapshot output */
1593 ret = mi_lttng_writer_open_element(writer,
1594 mi_lttng_element_command_snapshot);
1595 if (ret) {
1596 goto end;
1597 }
1598
1599 /* ID of the snapshot output */
1600 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1601 mi_lttng_element_id, output->id);
1602 if (ret) {
1603 goto end;
1604 }
1605
1606 /* Name of the output */
1607 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1608 output->name);
1609 if (ret) {
1610 goto end;
1611 }
1612
1613 /* Destination of the output (ctrl_url)*/
1614 ret = mi_lttng_writer_write_element_string(writer,
1615 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
1616 if (ret) {
1617 goto end;
1618 }
1619
1620 /* Destination of the output (data_url) */
1621 ret = mi_lttng_writer_write_element_string(writer,
1622 mi_lttng_element_snapshot_data_url, output->data_url);
1623 if (ret) {
1624 goto end;
1625 }
1626
1627 /* total size of all stream combined */
1628 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1629 mi_lttng_element_snapshot_max_size, output->max_size);
1630 if (ret) {
1631 goto end;
1632 }
1633
1634 /* Close snapshot output element */
1635 ret = mi_lttng_writer_close_element(writer);
1636
1637 end:
1638 return ret;
1639 }
1640
1641 LTTNG_HIDDEN
1642 int mi_lttng_snapshot_del_output(struct mi_writer *writer, int id,
1643 const char *name, const char *current_session_name)
1644 {
1645 int ret;
1646
1647 /* Open element del_snapshot */
1648 ret = mi_lttng_writer_open_element(writer,
1649 mi_lttng_element_command_snapshot);
1650 if (ret) {
1651 goto end;
1652 }
1653
1654
1655 if (id != UINT32_MAX) {
1656 /* "Snapshot output "id" successfully deleted
1657 * for "current_session_name"
1658 * ID of the snapshot output
1659 */
1660 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1661 mi_lttng_element_id, id);
1662 if (ret) {
1663 goto end;
1664 }
1665 } else {
1666 /* "Snapshot output "name" successfully deleted
1667 * for session "current_session_name"
1668 * Name of the output
1669 */
1670 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
1671 name);
1672 if (ret) {
1673 goto end;
1674 }
1675 }
1676
1677 /* Snapshot was deleted for session "current_session_name"*/
1678 ret = mi_lttng_writer_write_element_string(writer,
1679 mi_lttng_element_snapshot_session_name,
1680 current_session_name);
1681 if (ret) {
1682 goto end;
1683 }
1684
1685 /* Close snapshot element */
1686 ret = mi_lttng_writer_close_element(writer);
1687
1688 end:
1689 return ret;
1690 }
1691
1692 LTTNG_HIDDEN
1693 int mi_lttng_snapshot_add_output(struct mi_writer *writer,
1694 const char *current_session_name, const char *n_ptr,
1695 struct lttng_snapshot_output *output)
1696 {
1697 int ret;
1698
1699 /* Open element snapshot */
1700 ret = mi_lttng_writer_open_element(writer,
1701 mi_lttng_element_command_snapshot);
1702 if (ret) {
1703 goto end;
1704 }
1705
1706 /* Snapshot output id */
1707 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1708 mi_lttng_element_id, output->id);
1709 if (ret) {
1710 goto end;
1711 }
1712
1713 /* Snapshot output names */
1714 ret = mi_lttng_writer_write_element_string(writer,
1715 config_element_name, n_ptr);
1716 if (ret) {
1717 goto end;
1718 }
1719
1720 /* Destination of the output (ctrl_url)*/
1721 ret = mi_lttng_writer_write_element_string(writer,
1722 mi_lttng_element_snapshot_ctrl_url, output->ctrl_url);
1723 if (ret) {
1724 goto end;
1725 }
1726
1727 /* Snapshot added for session "current_session_name"*/
1728 ret = mi_lttng_writer_write_element_string(writer,
1729 mi_lttng_element_snapshot_session_name, current_session_name);
1730 if (ret) {
1731 goto end;
1732 }
1733
1734 /* total size of all stream combined */
1735 ret = mi_lttng_writer_write_element_unsigned_int(writer,
1736 mi_lttng_element_snapshot_max_size, output->max_size);
1737 if (ret) {
1738 goto end;
1739 }
1740
1741 /* Close snapshot element */
1742 ret = mi_lttng_writer_close_element(writer);
1743
1744 end:
1745 return ret;
1746 }
1747
1748 LTTNG_HIDDEN
1749 int mi_lttng_snapshot_record(struct mi_writer *writer,
1750 const char *current_session_name, const char *url,
1751 const char *cmdline_ctrl_url, const char *cmdline_data_url)
1752 {
1753 int ret;
1754
1755 /* Open element snapshot */
1756 ret = mi_lttng_writer_open_element(writer,
1757 mi_lttng_element_command_snapshot);
1758 if (ret) {
1759 goto end;
1760 }
1761
1762 /*
1763 * If a valid an URL was given, serialize it,
1764 * else take the command line data and ctrl urls*/
1765 if (url) {
1766 /* Destination of the output (ctrl_url)*/
1767 ret = mi_lttng_writer_write_element_string(writer,
1768 mi_lttng_element_snapshot_ctrl_url, url);
1769 if (ret) {
1770 goto end;
1771 }
1772 } else if (cmdline_ctrl_url) {
1773 /* Destination of the output (ctrl_url)*/
1774 ret = mi_lttng_writer_write_element_string(writer,
1775 mi_lttng_element_snapshot_ctrl_url, cmdline_ctrl_url);
1776 if (ret) {
1777 goto end;
1778 }
1779
1780 /* Destination of the output (data_url) */
1781 ret = mi_lttng_writer_write_element_string(writer,
1782 mi_lttng_element_snapshot_data_url, cmdline_data_url);
1783 if (ret) {
1784 goto end;
1785 }
1786 }
1787
1788 /* Close record_snapshot element */
1789 ret = mi_lttng_writer_close_element(writer);
1790
1791 end:
1792 return ret;
1793 }
This page took 0.114611 seconds and 4 git commands to generate.