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