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