Mi save&load command: support and validation
[lttng-tools.git] / src / common / mi-lttng.c
CommitLineData
c7e35b03
JR
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
5e18ec73 19
c7e35b03
JR
20#include <include/config.h>
21#include <common/config/config.h>
c7e35b03
JR
22#include "mi-lttng.h"
23
5e18ec73
JR
24#include <assert.h>
25
c7e35b03
JR
26/* Strings related to command */
27const char * const mi_lttng_element_command = "command";
28const char * const mi_lttng_element_command_version = "version";
29const char * const mi_lttng_element_command_list = "list";
1734c658
JRJ
30const char * const mi_lttng_element_command_save = "save";
31const char * const mi_lttng_element_command_load = "load";
c7e35b03
JR
32const char * const mi_lttng_element_command_name = "name";
33const char * const mi_lttng_element_command_output = "output";
1734c658 34const char * const mi_lttng_element_command_success = "success";
c7e35b03 35
1734c658 36/* Strings related to version command */
c7e35b03
JR
37const char * const mi_lttng_element_version = "version";
38const char * const mi_lttng_element_version_str = "string";
39const char * const mi_lttng_element_version_web = "url";
40const char * const mi_lttng_element_version_major = "major";
41const char * const mi_lttng_element_version_minor = "minor";
314d5222 42const char * const mi_lttng_element_version_commit = "commit";
c7e35b03
JR
43const char * const mi_lttng_element_version_license = "license";
44const char * const mi_lttng_element_version_patch_level = "patchLevel";
45const char * const mi_lttng_element_version_description = "description";
46
5e18ec73
JR
47/* Strings related to pid */
48const char * const mi_lttng_element_pids = "pids";
49const char * const mi_lttng_element_pid = "pid";
50const char * const mi_lttng_element_pid_id = "id";
51
1734c658
JRJ
52/* Strings related to save command */
53const char * const mi_lttng_element_save = "save";
54
55/* Strings related to load command */
56const char * const mi_lttng_element_load = "load";
57
5e18ec73
JR
58/* String related to a lttng_event_field */
59const char * const mi_lttng_element_event_field = "event_field";
60const char * const mi_lttng_element_event_fields = "event_fields";
61
62/* General elements of mi_lttng */
63const char * const mi_lttng_element_type_other = "OTHER";
64const char * const mi_lttng_element_type_integer = "INTEGER";
65const char * const mi_lttng_element_type_enum = "ENUM";
66const char * const mi_lttng_element_type_float = "FLOAT";
67const char * const mi_lttng_element_type_string = "STRING";
68const char * const mi_lttng_element_nowrite = "nowrite";
69
70/* String related to loglevel */
71const char * const mi_lttng_loglevel_str_alert = "TRACE_ALERT";
72const char * const mi_lttng_loglevel_str_crit = "TRACE_CRIT";
73const char * const mi_lttng_loglevel_str_debug = "TRACE_DEBUG";
74const char * const mi_lttng_loglevel_str_debug_function = "TRACE_DEBUG_FUNCTION";
75const char * const mi_lttng_loglevel_str_debug_line = "TRACE_DEBUG_LINE";
76const char * const mi_lttng_loglevel_str_debug_module = "TRACE_DEBUG_MODULE";
77const char * const mi_lttng_loglevel_str_debug_process = "TRACE_DEBUG_PROCESS";
78const char * const mi_lttng_loglevel_str_debug_program = "TRACE_DEBUG_PROGRAM";
79const char * const mi_lttng_loglevel_str_debug_system = "TRACE_DEBUG_SYSTEM";
80const char * const mi_lttng_loglevel_str_debug_unit = "TRACE_DEBUG_UNIT";
81const char * const mi_lttng_loglevel_str_emerg = "TRACE_EMERG";
82const char * const mi_lttng_loglevel_str_err = "TRACE_ERR";
83const char * const mi_lttng_loglevel_str_info = "TRACE_INFO";
84const char * const mi_lttng_loglevel_str_notice = "TRACE_NOTICE";
85const char * const mi_lttng_loglevel_str_unknown = "UNKNOWN";
86const char * const mi_lttng_loglevel_str_warning = "TRACE_WARNING";
87
1734c658 88/* String related to loglevel type */
5e18ec73
JR
89const char * const mi_lttng_loglevel_type_all = "ALL";
90const char * const mi_lttng_loglevel_type_range = "RANGE";
91const char * const mi_lttng_loglevel_type_single = "SINGLE";
92const char * const mi_lttng_loglevel_type_unknown = "UNKNOWN";
93
94const char * const mi_lttng_element_empty = "";
95
96const char *mi_lttng_loglevel_string(int value)
97{
98 switch (value) {
99 case -1:
100 return mi_lttng_element_empty;
101 case LTTNG_LOGLEVEL_EMERG:
102 return mi_lttng_loglevel_str_emerg;
103 case LTTNG_LOGLEVEL_ALERT:
104 return mi_lttng_loglevel_str_alert;
105 case LTTNG_LOGLEVEL_CRIT:
106 return mi_lttng_loglevel_str_crit;
107 case LTTNG_LOGLEVEL_ERR:
108 return mi_lttng_loglevel_str_err;
109 case LTTNG_LOGLEVEL_WARNING:
110 return mi_lttng_loglevel_str_warning;
111 case LTTNG_LOGLEVEL_NOTICE:
112 return mi_lttng_loglevel_str_notice;
113 case LTTNG_LOGLEVEL_INFO:
114 return mi_lttng_loglevel_str_info;
115 case LTTNG_LOGLEVEL_DEBUG_SYSTEM:
116 return mi_lttng_loglevel_str_debug_system;
117 case LTTNG_LOGLEVEL_DEBUG_PROGRAM:
118 return mi_lttng_loglevel_str_debug_program;
119 case LTTNG_LOGLEVEL_DEBUG_PROCESS:
120 return mi_lttng_loglevel_str_debug_process;
121 case LTTNG_LOGLEVEL_DEBUG_MODULE:
122 return mi_lttng_loglevel_str_debug_module;
123 case LTTNG_LOGLEVEL_DEBUG_UNIT:
124 return mi_lttng_loglevel_str_debug_unit;
125 case LTTNG_LOGLEVEL_DEBUG_FUNCTION:
126 return mi_lttng_loglevel_str_debug_function;
127 case LTTNG_LOGLEVEL_DEBUG_LINE:
128 return mi_lttng_loglevel_str_debug_line;
129 case LTTNG_LOGLEVEL_DEBUG:
130 return mi_lttng_loglevel_str_debug;
131 default:
132 return mi_lttng_loglevel_str_unknown;
133 }
134}
135
136const char *mi_lttng_logleveltype_string(enum lttng_loglevel_type value)
137{
138 switch (value) {
139 case LTTNG_EVENT_LOGLEVEL_ALL:
140 return mi_lttng_loglevel_type_all;
141 case LTTNG_EVENT_LOGLEVEL_RANGE:
142 return mi_lttng_loglevel_type_range;
143 case LTTNG_EVENT_LOGLEVEL_SINGLE:
144 return mi_lttng_loglevel_type_single;
145 default:
146 return mi_lttng_loglevel_type_unknown;
147 }
148}
149
150const char *mi_lttng_eventtype_string(enum lttng_event_type value)
151{
152 switch (value) {
153 case LTTNG_EVENT_ALL:
154 return config_event_type_all;
155 case LTTNG_EVENT_TRACEPOINT:
156 return config_event_type_tracepoint;
157 case LTTNG_EVENT_PROBE:
158 return config_event_type_probe;
159 case LTTNG_EVENT_FUNCTION:
160 return config_event_type_function;
161 case LTTNG_EVENT_FUNCTION_ENTRY:
162 return config_event_type_function_entry;
163 case LTTNG_EVENT_SYSCALL:
164 return config_event_type_syscall;
165 case LTTNG_EVENT_NOOP:
166 return config_event_type_noop;
167 default:
168 return mi_lttng_element_empty;
169 }
170}
171
172const char *mi_lttng_eventfieldtype_string(enum lttng_event_field_type val)
173{
174 switch (val) {
175 case(LTTNG_EVENT_FIELD_INTEGER):
176 return mi_lttng_element_type_integer;
177 case(LTTNG_EVENT_FIELD_ENUM):
178 return mi_lttng_element_type_enum;
179 case(LTTNG_EVENT_FIELD_FLOAT):
180 return mi_lttng_element_type_float;
181 case(LTTNG_EVENT_FIELD_STRING):
182 return mi_lttng_element_type_string;
183 default:
184 return mi_lttng_element_type_other;
185 }
186}
187
188const char *mi_lttng_domaintype_string(enum lttng_domain_type value)
189{
190 /* Note: This is a *duplicate* of get_domain_str from bin/lttng/utils.c */
191 switch (value) {
192 case LTTNG_DOMAIN_KERNEL:
193 return config_domain_type_kernel;
194 case LTTNG_DOMAIN_UST:
195 return config_domain_type_ust;
196 case LTTNG_DOMAIN_JUL:
197 return config_domain_type_jul;
198 default:
199 /* Should not have an unknown domain */
200 assert(0);
201 }
202}
203
204const char *mi_lttng_buffertype_string(enum lttng_buffer_type value)
205{
206 switch (value) {
207 case LTTNG_BUFFER_PER_PID:
208 return config_buffer_type_per_pid;
209 case LTTNG_BUFFER_PER_UID:
210 return config_buffer_type_per_uid;
211 case LTTNG_BUFFER_GLOBAL:
212 return config_buffer_type_global;
213 default:
214 /* Should not have an unknow buffer type */
215 assert(0);
216 }
217}
218
c7e35b03
JR
219LTTNG_HIDDEN
220struct mi_writer *mi_lttng_writer_create(int fd_output, int mi_output_type)
221{
222 struct mi_writer *mi_writer;
223
224 mi_writer = zmalloc(sizeof(struct mi_writer));
225 if (!mi_writer) {
226 PERROR("zmalloc mi_writer_create");
227 goto end;
228 }
229 if (mi_output_type == LTTNG_MI_XML) {
230 mi_writer->writer = config_writer_create(fd_output);
231 if (!mi_writer->writer) {
232 goto err_destroy;
233 }
234 mi_writer->type = LTTNG_MI_XML;
235 } else {
236 goto err_destroy;
237 }
238
239end:
240 return mi_writer;
241
242err_destroy:
243 free(mi_writer);
244 return NULL;
245}
246
247LTTNG_HIDDEN
248int mi_lttng_writer_destroy(struct mi_writer *writer)
249{
250 int ret;
251
252 if (!writer) {
253 ret = -EINVAL;
254 goto end;
255 }
256
257 ret = config_writer_destroy(writer->writer);
258 if (ret < 0) {
259 goto end;
260 }
261
262 free(writer);
263end:
264 return ret;
265}
266
267LTTNG_HIDDEN
268int mi_lttng_writer_command_open(struct mi_writer *writer, const char *command)
269{
270 int ret;
271
272 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command);
273 if (ret) {
274 goto end;
275 }
276 ret = mi_lttng_writer_write_element_string(writer,
277 mi_lttng_element_command_name, command);
278end:
279 return ret;
280}
281
282LTTNG_HIDDEN
283int mi_lttng_writer_command_close(struct mi_writer *writer)
284{
285 return mi_lttng_writer_close_element(writer);
286}
287
288LTTNG_HIDDEN
289int mi_lttng_writer_open_element(struct mi_writer *writer,
290 const char *element_name)
291{
292 return config_writer_open_element(writer->writer, element_name);
293}
294
295LTTNG_HIDDEN
296int mi_lttng_writer_close_element(struct mi_writer *writer)
297{
298 return config_writer_close_element(writer->writer);
299}
300
5e18ec73
JR
301LTTNG_HIDDEN
302int mi_lttng_close_multi_element(struct mi_writer *writer,
303 unsigned int nb_element)
304{
305 int ret, i;
306
307 if (nb_element < 1) {
308 ret = 0;
309 goto end;
310 }
311 for (i = 0; i < nb_element; i++) {
312 ret = mi_lttng_writer_close_element(writer);
313 if (ret) {
314 goto end;
315 }
316 }
317end:
318 return ret;
319}
320
c7e35b03
JR
321LTTNG_HIDDEN
322int mi_lttng_writer_write_element_unsigned_int(struct mi_writer *writer,
323 const char *element_name, uint64_t value)
324{
325 return config_writer_write_element_unsigned_int(writer->writer,
326 element_name, value);
327}
328
329LTTNG_HIDDEN
330int mi_lttng_writer_write_element_signed_int(struct mi_writer *writer,
331 const char *element_name, int64_t value)
332{
333 return config_writer_write_element_signed_int(writer->writer,
334 element_name, value);
335}
336
337LTTNG_HIDDEN
338int mi_lttng_writer_write_element_bool(struct mi_writer *writer,
339 const char *element_name, int value)
340{
341 return config_writer_write_element_bool(writer->writer,
342 element_name, value);
343}
344
345LTTNG_HIDDEN
346int mi_lttng_writer_write_element_string(struct mi_writer *writer,
347 const char *element_name, const char *value)
348{
349 return config_writer_write_element_string(writer->writer,
350 element_name, value);
351}
352
353LTTNG_HIDDEN
354int mi_lttng_version(struct mi_writer *writer, struct mi_lttng_version *version,
355 const char *lttng_description, const char *lttng_license)
356{
357 int ret;
358
359 /* Open version */
360 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_version);
361 if (ret) {
362 goto end;
363 }
364
365 /* Version string (contain info like rc etc.) */
366 ret = mi_lttng_writer_write_element_string(writer,
367 mi_lttng_element_version_str, VERSION);
368 if (ret) {
369 goto end;
370 }
371
372 /* Major version number */
373 ret = mi_lttng_writer_write_element_unsigned_int(writer,
374 mi_lttng_element_version_major, version->version_major);
375 if (ret) {
376 goto end;
377 }
378
379 /* Minor version number */
380 ret = mi_lttng_writer_write_element_unsigned_int(writer,
381 mi_lttng_element_version_minor, version->version_minor);
382 if (ret) {
383 goto end;
384 }
385
314d5222
JRJ
386 /* Commit version number */
387 ret = mi_lttng_writer_write_element_string(writer,
388 mi_lttng_element_version_commit, version->version_commit);
389 if (ret) {
390 goto end;
391 }
392
c7e35b03
JR
393 /* Patch number */
394 ret = mi_lttng_writer_write_element_unsigned_int(writer,
395 mi_lttng_element_version_patch_level, version->version_patchlevel);
396 if (ret) {
397 goto end;
398 }
399
400 /* Name of the version */
401 ret = mi_lttng_writer_write_element_string(writer,
402 config_element_name, version->version_name);
403 if (ret) {
404 goto end;
405 }
406
407 /* Description mostly related to beer... */
408 ret = mi_lttng_writer_write_element_string(writer,
409 mi_lttng_element_version_description, lttng_description);
410 if (ret) {
411 goto end;
412 }
413
414 /* url */
415 ret = mi_lttng_writer_write_element_string(writer,
416 mi_lttng_element_version_web, version->package_url);
417 if (ret) {
418 goto end;
419 }
420
421 /* License: free as in free beer...no...*speech* */
422 ret = mi_lttng_writer_write_element_string(writer,
423 mi_lttng_element_version_license, lttng_license);
424 if (ret) {
425 goto end;
426 }
427
428 /* Close version element */
429 ret = mi_lttng_writer_close_element(writer);
430
431end:
432 return ret;
433}
434
5e18ec73
JR
435LTTNG_HIDDEN
436int mi_lttng_sessions_open(struct mi_writer *writer)
437{
438 return mi_lttng_writer_open_element(writer, config_element_sessions);
439}
440
c7e35b03
JR
441LTTNG_HIDDEN
442int mi_lttng_session(struct mi_writer *writer,
443 struct lttng_session *session, int is_open)
444{
445 int ret;
446
5e18ec73
JR
447 assert(session);
448
449 /* Open sessions element */
c7e35b03
JR
450 ret = mi_lttng_writer_open_element(writer,
451 config_element_session);
452 if (ret) {
453 goto end;
454 }
455
456 /* Name of the session */
457 ret = mi_lttng_writer_write_element_string(writer,
458 config_element_name, session->name);
459 if (ret) {
460 goto end;
461 }
462
5e18ec73 463 /* Path */
c7e35b03
JR
464 ret = mi_lttng_writer_write_element_string(writer,
465 config_element_path, session->path);
466 if (ret) {
467 goto end;
468 }
469
5e18ec73
JR
470 /* Enabled ? */
471 ret = mi_lttng_writer_write_element_bool(writer,
c7e35b03
JR
472 config_element_enabled, session->enabled);
473 if (ret) {
474 goto end;
475 }
476
5e18ec73 477 /* Snapshot mode */
c7e35b03
JR
478 ret = mi_lttng_writer_write_element_unsigned_int(writer,
479 config_element_snapshot_mode, session->snapshot_mode);
480 if (ret) {
481 goto end;
482 }
483
5e18ec73 484 /* Live timer interval in usec */
c7e35b03
JR
485 ret = mi_lttng_writer_write_element_unsigned_int(writer,
486 config_element_live_timer_interval,
487 session->live_timer_interval);
488 if (ret) {
489 goto end;
490 }
491
492 if (!is_open) {
493 /* Closing session element */
494 ret = mi_lttng_writer_close_element(writer);
495 }
496end:
497 return ret;
498
499}
5e18ec73
JR
500
501LTTNG_HIDDEN
502int mi_lttng_domains_open(struct mi_writer *writer)
503{
504 return mi_lttng_writer_open_element(writer, config_element_domains);
505}
506
507LTTNG_HIDDEN
508int mi_lttng_domain(struct mi_writer *writer,
509 struct lttng_domain *domain, int is_open)
510{
511 int ret = 0;
512 const char *str_domain;
513 const char *str_buffer;
514
515 assert(domain);
516
517 /* Open domain element */
518 ret = mi_lttng_writer_open_element(writer, config_element_domain);
519 if (ret) {
520 goto end;
521 }
522
523 /* Domain Type */
524 str_domain = mi_lttng_domaintype_string(domain->type);
525 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
526 str_domain);
527 if (ret) {
528 goto end;
529 }
530
531 /* Buffer Type */
532 str_buffer= mi_lttng_buffertype_string(domain->buf_type);
533 ret = mi_lttng_writer_write_element_string(writer,
534 config_element_buffer_type, str_buffer);
535 if (ret) {
536 goto end;
537 }
538
539 /* TODO: attr... not sure how to use the union.... */
540
541 if (!is_open) {
542 /* Closing domain element */
543 ret = mi_lttng_writer_close_element(writer);
544 }
545
546end:
547 return ret;
548
549}
550
551LTTNG_HIDDEN
552int mi_lttng_channels_open(struct mi_writer *writer)
553{
554 return mi_lttng_writer_open_element(writer, config_element_channels);
555}
556
557LTTNG_HIDDEN
558int mi_lttng_channel(struct mi_writer *writer,
559 struct lttng_channel *channel, int is_open)
560{
561 int ret = 0;
562
563 assert(channel);
564
565 /* Opening channel element */
566 ret = mi_lttng_writer_open_element(writer, config_element_channel);
567 if (ret) {
568 goto end;
569 }
570
571 /* Name */
572 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
573 channel->name);
574 if (ret) {
575 goto end;
576 }
577
578 /* Enabled ? */
579 ret = mi_lttng_writer_write_element_bool(writer,
580 config_element_enabled, channel->enabled);
581 if (ret) {
582 goto end;
583 }
584
585 /* Attribute */
586 ret = mi_lttng_channel_attr(writer, &channel->attr);
587 if (ret) {
588 goto end;
589 }
590
591 if (!is_open) {
592 /* Closing channel element */
593 ret = mi_lttng_writer_close_element(writer);
594 if (ret) {
595 goto end;
596 }
597 }
598end:
599 return ret;
600}
601
602LTTNG_HIDDEN
603int mi_lttng_channel_attr(struct mi_writer *writer,
604 struct lttng_channel_attr *attr)
605{
606 int ret = 0;
607
608 assert(attr);
609
610 /* Opening Attributes */
611 ret = mi_lttng_writer_open_element(writer, config_element_attributes);
612 if (ret) {
613 goto end;
614 }
615
616 /* Overwrite */
617 ret = mi_lttng_writer_write_element_string(writer,
618 config_element_overwrite_mode,
619 attr->overwrite ? config_overwrite_mode_overwrite :
620 config_overwrite_mode_discard);
621 if (ret) {
622 goto end;
623 }
624
625 /* Sub buffer size in byte */
626 ret = mi_lttng_writer_write_element_unsigned_int(writer,
627 config_element_subbuf_size, attr->subbuf_size);
628 if (ret) {
629 goto end;
630 }
631
632 /* Number of subbuffer (power of two) */
633 ret = mi_lttng_writer_write_element_unsigned_int(writer,
634 config_element_num_subbuf,
635 attr->num_subbuf);
636 if (ret) {
637 goto end;
638 }
639
640 /* Switch timer interval in usec */
641 ret = mi_lttng_writer_write_element_unsigned_int(writer,
642 config_element_switch_timer_interval,
643 attr->switch_timer_interval);
644 if (ret) {
645 goto end;
646 }
647
648 /* Read timer interval in usec */
649 ret = mi_lttng_writer_write_element_unsigned_int(writer,
650 config_element_read_timer_interval,
651 attr->read_timer_interval);
652 if (ret) {
653 goto end;
654 }
655
656 /* Event output */
657 ret = mi_lttng_writer_write_element_string(writer,
658 config_element_output_type,
659 attr->output == LTTNG_EVENT_SPLICE ?
660 config_output_type_splice : config_output_type_mmap);
661 if (ret) {
662 goto end;
663 }
664
665 /* Tracefile size in bytes */
666 ret = mi_lttng_writer_write_element_unsigned_int(writer,
667 config_element_tracefile_size, attr->tracefile_size);
668 if (ret) {
669 goto end;
670 }
671
672 /* Count of tracefiles */
673 ret = mi_lttng_writer_write_element_unsigned_int(writer,
674 config_element_tracefile_count,
675 attr->tracefile_count);
676 if (ret) {
677 goto end;
678 }
679
680 /* Live timer interval in usec*/
681 ret = mi_lttng_writer_write_element_unsigned_int(writer,
682 config_element_live_timer_interval,
683 attr->live_timer_interval);
684 if (ret) {
685 goto end;
686 }
687
688 /* Closing attributes */
689 ret = mi_lttng_writer_close_element(writer);
690 if (ret) {
691 goto end;
692 }
693end:
694 return ret;
695
696}
697
698LTTNG_HIDDEN
699int mi_lttng_event_common_attributes(struct mi_writer *writer,
700 struct lttng_event *event)
701{
702 int ret;
703
704 /* Open event element */
705 ret = mi_lttng_writer_open_element(writer, config_element_event);
706 if (ret) {
707 goto end;
708 }
709
710 /* event name */
711 ret = mi_lttng_writer_write_element_string(writer,
712 config_element_name, event->name);
713 if (ret) {
714 goto end;
715 }
716
717 /* event type */
718 ret = mi_lttng_writer_write_element_string(writer,
719 config_element_type, mi_lttng_eventtype_string(event->type));
720 if (ret) {
721 goto end;
722 }
723
724 /* is event enabled */
725 ret = mi_lttng_writer_write_element_bool(writer,
726 config_element_enabled, event->enabled);
727 if (ret) {
728 goto end;
729 }
730
731 /* event filter enabled? */
732 ret = mi_lttng_writer_write_element_bool(writer,
733 config_element_filter, event->filter);
734
735end:
736 return ret;
737}
738
739LTTNG_HIDDEN
740int mi_lttng_event_tracepoint_loglevel(struct mi_writer *writer,
741 struct lttng_event *event)
742{
743 int ret;
744
745 /* event loglevel */
746 ret = mi_lttng_writer_write_element_string(writer,
747 config_element_loglevel, mi_lttng_loglevel_string(event->loglevel));
748 if (ret) {
749 goto end;
750 }
751
752 ret = mi_lttng_writer_write_element_string(writer,
753 config_element_loglevel_type,
754 mi_lttng_logleveltype_string(event->loglevel_type));
755 if (ret) {
756 goto end;
757 }
758
759 /* event exclusion filter */
760 ret = mi_lttng_writer_write_element_bool(writer,
761 config_element_exclusion, event->exclusion);
762 if (ret) {
763 goto end;
764 }
765
766end:
767 return ret;
768}
769
770LTTNG_HIDDEN
771int mi_lttng_event_tracepoint_no_loglevel(struct mi_writer *writer,
772 struct lttng_event *event)
773{
774 /* event exclusion filter */
775 return mi_lttng_writer_write_element_bool(writer,
776 config_element_exclusion, event->exclusion);
777}
778
779LTTNG_HIDDEN
780int mi_lttng_event_function_probe(struct mi_writer *writer,
781 struct lttng_event *event)
782{
783 int ret;
784
785 if (event->attr.probe.addr != 0) {
786 /* event probe address */
787 ret = mi_lttng_writer_write_element_unsigned_int(writer,
788 config_element_address, event->attr.probe.addr);
789 if (ret) {
790 goto end;
791 }
792 } else {
793 /* event probe offset */
794 ret = mi_lttng_writer_write_element_unsigned_int(writer,
795 config_element_offset, event->attr.probe.offset);
796 if (ret) {
797 goto end;
798 }
799
800 /* event probe symbol_name */
801 ret = mi_lttng_writer_write_element_string(writer,
802 config_element_symbol_name, event->attr.probe.symbol_name);
803 if (ret) {
804 goto end;
805 }
806 }
807end:
808 return ret;
809}
810
811LTTNG_HIDDEN
812int mi_lttng_event_function_entry(struct mi_writer *writer,
813 struct lttng_event *event)
814{
815 /* event probe symbol_name */
816 return mi_lttng_writer_write_element_string(writer,
817 config_element_symbol_name, event->attr.ftrace.symbol_name);
818}
819
820LTTNG_HIDDEN
821int mi_lttng_events_open(struct mi_writer *writer)
822{
823 return mi_lttng_writer_open_element(writer, config_element_events);
824}
825
826LTTNG_HIDDEN
827int mi_lttng_event(struct mi_writer *writer,
828 struct lttng_event *event, int is_open)
829{
830 int ret;
831
832 ret = mi_lttng_event_common_attributes(writer, event);
833 if (ret) {
834 goto end;
835 }
836
837 switch (event->type) {
838 case LTTNG_EVENT_ALL:
839 /* We should never have "all" events in list. */
840 assert(0);
841 break;
842 case LTTNG_EVENT_TRACEPOINT:
843 {
844 if (event->loglevel != -1) {
845 ret = mi_lttng_event_tracepoint_loglevel(writer, event);
846 } else {
847 ret = mi_lttng_event_tracepoint_no_loglevel(writer, event);
848 }
849 break;
850 }
851 case LTTNG_EVENT_PROBE:
852 ret = mi_lttng_event_function_probe(writer, event);
853 break;
854 case LTTNG_EVENT_FUNCTION_ENTRY:
855 ret = mi_lttng_event_function_entry(writer, event);
856 break;
857 default:
858 break;
859 }
860
861 if (!is_open) {
862 ret = mi_lttng_writer_close_element(writer);
863 }
864
865end:
866 return ret;
867}
868
869LTTNG_HIDDEN
870int mi_lttng_pids_open(struct mi_writer *writer)
871{
872 return mi_lttng_writer_open_element(writer, mi_lttng_element_pids);
873}
874
875LTTNG_HIDDEN
876int mi_lttng_pid(struct mi_writer *writer, pid_t pid , const char *cmdline,
877 int is_open)
878{
879 int ret;
880
881 /* Open element pid */
882 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_pid);
883 if (ret) {
884 goto end;
885 }
886
887 /* Writing pid number */
888 ret = mi_lttng_writer_write_element_signed_int(writer,
889 mi_lttng_element_pid_id, (int)pid);
890 if (ret) {
891 goto end;
892 }
893
894 /* Writing name of the process */
895 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
896 cmdline);
897 if (ret) {
898 goto end;
899 }
900
901 if (!is_open) {
902 /* Closing Pid */
903 ret = mi_lttng_writer_close_element(writer);
904 }
905
906end:
907 return ret;
908}
909
910LTTNG_HIDDEN
911int mi_lttng_event_fields_open(struct mi_writer *writer)
912{
913 return mi_lttng_writer_open_element(writer, mi_lttng_element_event_fields);
914}
915
916LTTNG_HIDDEN
917int mi_lttng_event_field(struct mi_writer *writer,
918 struct lttng_event_field *field)
919{
920 int ret;
921
922 if (!field->field_name[0]) {
923 /* To Review: not sure if legal david ?
924 * how should this be handle ?
925 */
926 ret = 0;
927 goto end;
928 }
929
930 /* Open field */
931 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_event_field);
932 if (ret) {
933 goto end;
934 }
935
936 if (!field->field_name[0]) {
937 goto close;
938 }
939
940 /* Name */
941 ret = mi_lttng_writer_write_element_string(writer, config_element_name,
942 field->field_name);
943 if (ret) {
944 goto end;
945 }
946
947 /* Type */
948 ret = mi_lttng_writer_write_element_string(writer, config_element_type,
949 mi_lttng_eventfieldtype_string(field->type));
950 if (ret) {
951 goto end;
952 }
953
954 /* nowrite */
955 ret = mi_lttng_writer_write_element_signed_int(writer,
956 mi_lttng_element_nowrite, field->nowrite);
957 if (ret) {
958 goto end;
959 }
960
961close:
962 /* Close field element */
963 ret = mi_lttng_writer_close_element(writer);
964
965end:
966 return ret;
967}
This page took 0.059015 seconds and 5 git commands to generate.