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