Mi save&load command: support and validation
[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
20 #include <include/config.h>
21 #include <common/config/config.h>
22 #include "mi-lttng.h"
23
24 #include <assert.h>
25
26 /* Strings related to command */
27 const char * const mi_lttng_element_command = "command";
28 const char * const mi_lttng_element_command_version = "version";
29 const char * const mi_lttng_element_command_list = "list";
30 const char * const mi_lttng_element_command_save = "save";
31 const char * const mi_lttng_element_command_load = "load";
32 const char * const mi_lttng_element_command_name = "name";
33 const char * const mi_lttng_element_command_output = "output";
34 const char * const mi_lttng_element_command_success = "success";
35
36 /* Strings related to version command */
37 const char * const mi_lttng_element_version = "version";
38 const char * const mi_lttng_element_version_str = "string";
39 const char * const mi_lttng_element_version_web = "url";
40 const char * const mi_lttng_element_version_major = "major";
41 const char * const mi_lttng_element_version_minor = "minor";
42 const char * const mi_lttng_element_version_commit = "commit";
43 const char * const mi_lttng_element_version_license = "license";
44 const char * const mi_lttng_element_version_patch_level = "patchLevel";
45 const char * const mi_lttng_element_version_description = "description";
46
47 /* Strings related to pid */
48 const char * const mi_lttng_element_pids = "pids";
49 const char * const mi_lttng_element_pid = "pid";
50 const char * const mi_lttng_element_pid_id = "id";
51
52 /* Strings related to save command */
53 const char * const mi_lttng_element_save = "save";
54
55 /* Strings related to load command */
56 const char * const mi_lttng_element_load = "load";
57
58 /* String related to a lttng_event_field */
59 const char * const mi_lttng_element_event_field = "event_field";
60 const char * const mi_lttng_element_event_fields = "event_fields";
61
62 /* General elements of mi_lttng */
63 const char * const mi_lttng_element_type_other = "OTHER";
64 const char * const mi_lttng_element_type_integer = "INTEGER";
65 const char * const mi_lttng_element_type_enum = "ENUM";
66 const char * const mi_lttng_element_type_float = "FLOAT";
67 const char * const mi_lttng_element_type_string = "STRING";
68 const char * const mi_lttng_element_nowrite = "nowrite";
69
70 /* String related to loglevel */
71 const char * const mi_lttng_loglevel_str_alert = "TRACE_ALERT";
72 const char * const mi_lttng_loglevel_str_crit = "TRACE_CRIT";
73 const char * const mi_lttng_loglevel_str_debug = "TRACE_DEBUG";
74 const char * const mi_lttng_loglevel_str_debug_function = "TRACE_DEBUG_FUNCTION";
75 const char * const mi_lttng_loglevel_str_debug_line = "TRACE_DEBUG_LINE";
76 const char * const mi_lttng_loglevel_str_debug_module = "TRACE_DEBUG_MODULE";
77 const char * const mi_lttng_loglevel_str_debug_process = "TRACE_DEBUG_PROCESS";
78 const char * const mi_lttng_loglevel_str_debug_program = "TRACE_DEBUG_PROGRAM";
79 const char * const mi_lttng_loglevel_str_debug_system = "TRACE_DEBUG_SYSTEM";
80 const char * const mi_lttng_loglevel_str_debug_unit = "TRACE_DEBUG_UNIT";
81 const char * const mi_lttng_loglevel_str_emerg = "TRACE_EMERG";
82 const char * const mi_lttng_loglevel_str_err = "TRACE_ERR";
83 const char * const mi_lttng_loglevel_str_info = "TRACE_INFO";
84 const char * const mi_lttng_loglevel_str_notice = "TRACE_NOTICE";
85 const char * const mi_lttng_loglevel_str_unknown = "UNKNOWN";
86 const char * const mi_lttng_loglevel_str_warning = "TRACE_WARNING";
87
88 /* String related to loglevel type */
89 const char * const mi_lttng_loglevel_type_all = "ALL";
90 const char * const mi_lttng_loglevel_type_range = "RANGE";
91 const char * const mi_lttng_loglevel_type_single = "SINGLE";
92 const char * const mi_lttng_loglevel_type_unknown = "UNKNOWN";
93
94 const char * const mi_lttng_element_empty = "";
95
96 const 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
136 const 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
150 const 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
172 const 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
188 const 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
204 const 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
219 LTTNG_HIDDEN
220 struct 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
239 end:
240 return mi_writer;
241
242 err_destroy:
243 free(mi_writer);
244 return NULL;
245 }
246
247 LTTNG_HIDDEN
248 int 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);
263 end:
264 return ret;
265 }
266
267 LTTNG_HIDDEN
268 int 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);
278 end:
279 return ret;
280 }
281
282 LTTNG_HIDDEN
283 int mi_lttng_writer_command_close(struct mi_writer *writer)
284 {
285 return mi_lttng_writer_close_element(writer);
286 }
287
288 LTTNG_HIDDEN
289 int 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
295 LTTNG_HIDDEN
296 int mi_lttng_writer_close_element(struct mi_writer *writer)
297 {
298 return config_writer_close_element(writer->writer);
299 }
300
301 LTTNG_HIDDEN
302 int 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 }
317 end:
318 return ret;
319 }
320
321 LTTNG_HIDDEN
322 int 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
329 LTTNG_HIDDEN
330 int 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
337 LTTNG_HIDDEN
338 int 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
345 LTTNG_HIDDEN
346 int 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
353 LTTNG_HIDDEN
354 int 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
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
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
431 end:
432 return ret;
433 }
434
435 LTTNG_HIDDEN
436 int mi_lttng_sessions_open(struct mi_writer *writer)
437 {
438 return mi_lttng_writer_open_element(writer, config_element_sessions);
439 }
440
441 LTTNG_HIDDEN
442 int mi_lttng_session(struct mi_writer *writer,
443 struct lttng_session *session, int is_open)
444 {
445 int ret;
446
447 assert(session);
448
449 /* Open sessions element */
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
463 /* Path */
464 ret = mi_lttng_writer_write_element_string(writer,
465 config_element_path, session->path);
466 if (ret) {
467 goto end;
468 }
469
470 /* Enabled ? */
471 ret = mi_lttng_writer_write_element_bool(writer,
472 config_element_enabled, session->enabled);
473 if (ret) {
474 goto end;
475 }
476
477 /* Snapshot mode */
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
484 /* Live timer interval in usec */
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 }
496 end:
497 return ret;
498
499 }
500
501 LTTNG_HIDDEN
502 int mi_lttng_domains_open(struct mi_writer *writer)
503 {
504 return mi_lttng_writer_open_element(writer, config_element_domains);
505 }
506
507 LTTNG_HIDDEN
508 int 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
546 end:
547 return ret;
548
549 }
550
551 LTTNG_HIDDEN
552 int mi_lttng_channels_open(struct mi_writer *writer)
553 {
554 return mi_lttng_writer_open_element(writer, config_element_channels);
555 }
556
557 LTTNG_HIDDEN
558 int 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 }
598 end:
599 return ret;
600 }
601
602 LTTNG_HIDDEN
603 int 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 }
693 end:
694 return ret;
695
696 }
697
698 LTTNG_HIDDEN
699 int 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
735 end:
736 return ret;
737 }
738
739 LTTNG_HIDDEN
740 int 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
766 end:
767 return ret;
768 }
769
770 LTTNG_HIDDEN
771 int 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
779 LTTNG_HIDDEN
780 int 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 }
807 end:
808 return ret;
809 }
810
811 LTTNG_HIDDEN
812 int 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
820 LTTNG_HIDDEN
821 int mi_lttng_events_open(struct mi_writer *writer)
822 {
823 return mi_lttng_writer_open_element(writer, config_element_events);
824 }
825
826 LTTNG_HIDDEN
827 int 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
865 end:
866 return ret;
867 }
868
869 LTTNG_HIDDEN
870 int mi_lttng_pids_open(struct mi_writer *writer)
871 {
872 return mi_lttng_writer_open_element(writer, mi_lttng_element_pids);
873 }
874
875 LTTNG_HIDDEN
876 int 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
906 end:
907 return ret;
908 }
909
910 LTTNG_HIDDEN
911 int 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
916 LTTNG_HIDDEN
917 int 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
961 close:
962 /* Close field element */
963 ret = mi_lttng_writer_close_element(writer);
964
965 end:
966 return ret;
967 }
This page took 0.048013 seconds and 5 git commands to generate.