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