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