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