Add kernel and UST time namespace context
[lttng-tools.git] / src / bin / lttng-sessiond / save.c
1 /*
2 * Copyright (C) 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include <assert.h>
10 #include <inttypes.h>
11 #include <string.h>
12 #include <urcu/uatomic.h>
13 #include <unistd.h>
14
15 #include <common/defaults.h>
16 #include <common/error.h>
17 #include <common/config/session-config.h>
18 #include <common/utils.h>
19 #include <common/runas.h>
20 #include <lttng/save-internal.h>
21
22 #include "kernel.h"
23 #include "save.h"
24 #include "session.h"
25 #include "lttng-syscall.h"
26 #include "trace-ust.h"
27 #include "agent.h"
28
29 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
30 static
31 int save_kernel_channel_attributes(struct config_writer *writer,
32 struct lttng_channel_attr *attr)
33 {
34 int ret;
35
36 ret = config_writer_write_element_string(writer,
37 config_element_overwrite_mode,
38 attr->overwrite ? config_overwrite_mode_overwrite :
39 config_overwrite_mode_discard);
40 if (ret) {
41 ret = LTTNG_ERR_SAVE_IO_FAIL;
42 goto end;
43 }
44
45 ret = config_writer_write_element_unsigned_int(writer,
46 config_element_subbuf_size, attr->subbuf_size);
47 if (ret) {
48 ret = LTTNG_ERR_SAVE_IO_FAIL;
49 goto end;
50 }
51
52 ret = config_writer_write_element_unsigned_int(writer,
53 config_element_num_subbuf,
54 attr->num_subbuf);
55 if (ret) {
56 ret = LTTNG_ERR_SAVE_IO_FAIL;
57 goto end;
58 }
59
60 ret = config_writer_write_element_unsigned_int(writer,
61 config_element_switch_timer_interval,
62 attr->switch_timer_interval);
63 if (ret) {
64 ret = LTTNG_ERR_SAVE_IO_FAIL;
65 goto end;
66 }
67
68 ret = config_writer_write_element_unsigned_int(writer,
69 config_element_read_timer_interval,
70 attr->read_timer_interval);
71 if (ret) {
72 ret = LTTNG_ERR_SAVE_IO_FAIL;
73 goto end;
74 }
75
76 ret = config_writer_write_element_string(writer,
77 config_element_output_type,
78 attr->output == LTTNG_EVENT_SPLICE ?
79 config_output_type_splice : config_output_type_mmap);
80 if (ret) {
81 ret = LTTNG_ERR_SAVE_IO_FAIL;
82 goto end;
83 }
84
85 ret = config_writer_write_element_unsigned_int(writer,
86 config_element_tracefile_size, attr->tracefile_size);
87 if (ret) {
88 ret = LTTNG_ERR_SAVE_IO_FAIL;
89 goto end;
90 }
91
92 ret = config_writer_write_element_unsigned_int(writer,
93 config_element_tracefile_count,
94 attr->tracefile_count);
95 if (ret) {
96 ret = LTTNG_ERR_SAVE_IO_FAIL;
97 goto end;
98 }
99
100 ret = config_writer_write_element_unsigned_int(writer,
101 config_element_live_timer_interval,
102 attr->live_timer_interval);
103 if (ret) {
104 ret = LTTNG_ERR_SAVE_IO_FAIL;
105 goto end;
106 }
107
108 if (attr->extended.ptr) {
109 struct lttng_channel_extended *ext = NULL;
110
111 ext = (struct lttng_channel_extended *) attr->extended.ptr;
112 ret = config_writer_write_element_unsigned_int(writer,
113 config_element_monitor_timer_interval,
114 ext->monitor_timer_interval);
115 if (ret) {
116 ret = LTTNG_ERR_SAVE_IO_FAIL;
117 goto end;
118 }
119
120 ret = config_writer_write_element_signed_int(writer,
121 config_element_blocking_timeout,
122 ext->blocking_timeout);
123 if (ret) {
124 ret = LTTNG_ERR_SAVE_IO_FAIL;
125 goto end;
126 }
127 }
128
129 ret = LTTNG_OK;
130 end:
131 return ret;
132 }
133
134 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
135 static
136 int save_ust_channel_attributes(struct config_writer *writer,
137 struct lttng_ust_channel_attr *attr)
138 {
139 int ret;
140 struct ltt_ust_channel *channel = NULL;
141
142 ret = config_writer_write_element_string(writer,
143 config_element_overwrite_mode,
144 attr->overwrite ? config_overwrite_mode_overwrite :
145 config_overwrite_mode_discard);
146 if (ret) {
147 ret = LTTNG_ERR_SAVE_IO_FAIL;
148 goto end;
149 }
150
151 ret = config_writer_write_element_unsigned_int(writer,
152 config_element_subbuf_size, attr->subbuf_size);
153 if (ret) {
154 ret = LTTNG_ERR_SAVE_IO_FAIL;
155 goto end;
156 }
157
158 ret = config_writer_write_element_unsigned_int(writer,
159 config_element_num_subbuf,
160 attr->num_subbuf);
161 if (ret) {
162 ret = LTTNG_ERR_SAVE_IO_FAIL;
163 goto end;
164 }
165
166 ret = config_writer_write_element_unsigned_int(writer,
167 config_element_switch_timer_interval,
168 attr->switch_timer_interval);
169 if (ret) {
170 ret = LTTNG_ERR_SAVE_IO_FAIL;
171 goto end;
172 }
173
174 ret = config_writer_write_element_unsigned_int(writer,
175 config_element_read_timer_interval,
176 attr->read_timer_interval);
177 if (ret) {
178 ret = LTTNG_ERR_SAVE_IO_FAIL;
179 goto end;
180 }
181
182 ret = config_writer_write_element_string(writer,
183 config_element_output_type,
184 attr->output == LTTNG_UST_MMAP ?
185 config_output_type_mmap : config_output_type_splice);
186 if (ret) {
187 ret = LTTNG_ERR_SAVE_IO_FAIL;
188 goto end;
189 }
190
191 ret = config_writer_write_element_signed_int(writer,
192 config_element_blocking_timeout,
193 attr->u.s.blocking_timeout);
194 if (ret) {
195 ret = LTTNG_ERR_SAVE_IO_FAIL;
196 goto end;
197 }
198
199 /*
200 * Fetch the monitor timer which is located in the parent of
201 * lttng_ust_channel_attr
202 */
203 channel = caa_container_of(attr, struct ltt_ust_channel, attr);
204 ret = config_writer_write_element_unsigned_int(writer,
205 config_element_monitor_timer_interval,
206 channel->monitor_timer_interval);
207 if (ret) {
208 ret = LTTNG_ERR_SAVE_IO_FAIL;
209 goto end;
210 }
211
212 ret = LTTNG_OK;
213 end:
214 return ret;
215 }
216
217 static
218 const char *get_kernel_instrumentation_string(
219 enum lttng_kernel_instrumentation instrumentation)
220 {
221 const char *instrumentation_string;
222
223 switch (instrumentation) {
224 case LTTNG_KERNEL_ALL:
225 instrumentation_string = config_event_type_all;
226 break;
227 case LTTNG_KERNEL_TRACEPOINT:
228 instrumentation_string = config_event_type_tracepoint;
229 break;
230 case LTTNG_KERNEL_KPROBE:
231 instrumentation_string = config_event_type_probe;
232 break;
233 case LTTNG_KERNEL_UPROBE:
234 instrumentation_string = config_event_type_userspace_probe;
235 break;
236 case LTTNG_KERNEL_FUNCTION:
237 instrumentation_string = config_event_type_function_entry;
238 break;
239 case LTTNG_KERNEL_KRETPROBE:
240 instrumentation_string = config_event_type_function;
241 break;
242 case LTTNG_KERNEL_NOOP:
243 instrumentation_string = config_event_type_noop;
244 break;
245 case LTTNG_KERNEL_SYSCALL:
246 instrumentation_string = config_event_type_syscall;
247 break;
248 default:
249 instrumentation_string = NULL;
250 }
251
252 return instrumentation_string;
253 }
254
255 static
256 const char *get_kernel_context_type_string(
257 enum lttng_kernel_context_type context_type)
258 {
259 const char *context_type_string;
260
261 switch (context_type) {
262 case LTTNG_KERNEL_CONTEXT_PID:
263 context_type_string = config_event_context_pid;
264 break;
265 case LTTNG_KERNEL_CONTEXT_PROCNAME:
266 context_type_string = config_event_context_procname;
267 break;
268 case LTTNG_KERNEL_CONTEXT_PRIO:
269 context_type_string = config_event_context_prio;
270 break;
271 case LTTNG_KERNEL_CONTEXT_NICE:
272 context_type_string = config_event_context_nice;
273 break;
274 case LTTNG_KERNEL_CONTEXT_VPID:
275 context_type_string = config_event_context_vpid;
276 break;
277 case LTTNG_KERNEL_CONTEXT_TID:
278 context_type_string = config_event_context_tid;
279 break;
280 case LTTNG_KERNEL_CONTEXT_VTID:
281 context_type_string = config_event_context_vtid;
282 break;
283 case LTTNG_KERNEL_CONTEXT_PPID:
284 context_type_string = config_event_context_ppid;
285 break;
286 case LTTNG_KERNEL_CONTEXT_VPPID:
287 context_type_string = config_event_context_vppid;
288 break;
289 case LTTNG_KERNEL_CONTEXT_HOSTNAME:
290 context_type_string = config_event_context_hostname;
291 break;
292 case LTTNG_KERNEL_CONTEXT_INTERRUPTIBLE:
293 context_type_string = config_event_context_interruptible;
294 break;
295 case LTTNG_KERNEL_CONTEXT_PREEMPTIBLE:
296 context_type_string = config_event_context_preemptible;
297 break;
298 case LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE:
299 context_type_string = config_event_context_need_reschedule;
300 break;
301 case LTTNG_KERNEL_CONTEXT_MIGRATABLE:
302 context_type_string = config_event_context_migratable;
303 break;
304 case LTTNG_KERNEL_CONTEXT_CALLSTACK_USER:
305 context_type_string = config_event_context_callstack_user;
306 break;
307 case LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL:
308 context_type_string = config_event_context_callstack_kernel;
309 break;
310 case LTTNG_KERNEL_CONTEXT_CGROUP_NS:
311 context_type_string = config_event_context_cgroup_ns;
312 break;
313 case LTTNG_KERNEL_CONTEXT_IPC_NS:
314 context_type_string = config_event_context_ipc_ns;
315 break;
316 case LTTNG_KERNEL_CONTEXT_MNT_NS:
317 context_type_string = config_event_context_mnt_ns;
318 break;
319 case LTTNG_KERNEL_CONTEXT_NET_NS:
320 context_type_string = config_event_context_net_ns;
321 break;
322 case LTTNG_KERNEL_CONTEXT_PID_NS:
323 context_type_string = config_event_context_pid_ns;
324 break;
325 case LTTNG_KERNEL_CONTEXT_TIME_NS:
326 context_type_string = config_event_context_time_ns;
327 break;
328 case LTTNG_KERNEL_CONTEXT_USER_NS:
329 context_type_string = config_event_context_user_ns;
330 break;
331 case LTTNG_KERNEL_CONTEXT_UTS_NS:
332 context_type_string = config_event_context_uts_ns;
333 break;
334 case LTTNG_KERNEL_CONTEXT_UID:
335 context_type_string = config_event_context_uid;
336 break;
337 case LTTNG_KERNEL_CONTEXT_EUID:
338 context_type_string = config_event_context_euid;
339 break;
340 case LTTNG_KERNEL_CONTEXT_SUID:
341 context_type_string = config_event_context_suid;
342 break;
343 case LTTNG_KERNEL_CONTEXT_GID:
344 context_type_string = config_event_context_gid;
345 break;
346 case LTTNG_KERNEL_CONTEXT_EGID:
347 context_type_string = config_event_context_egid;
348 break;
349 case LTTNG_KERNEL_CONTEXT_SGID:
350 context_type_string = config_event_context_sgid;
351 break;
352 case LTTNG_KERNEL_CONTEXT_VUID:
353 context_type_string = config_event_context_vuid;
354 break;
355 case LTTNG_KERNEL_CONTEXT_VEUID:
356 context_type_string = config_event_context_veuid;
357 break;
358 case LTTNG_KERNEL_CONTEXT_VSUID:
359 context_type_string = config_event_context_vsuid;
360 break;
361 case LTTNG_KERNEL_CONTEXT_VGID:
362 context_type_string = config_event_context_vgid;
363 break;
364 case LTTNG_KERNEL_CONTEXT_VEGID:
365 context_type_string = config_event_context_vegid;
366 break;
367 case LTTNG_KERNEL_CONTEXT_VSGID:
368 context_type_string = config_event_context_vsgid;
369 break;
370 default:
371 context_type_string = NULL;
372 }
373
374 return context_type_string;
375 }
376
377 static
378 const char *get_ust_context_type_string(
379 enum lttng_ust_context_type context_type)
380 {
381 const char *context_type_string;
382
383 switch (context_type) {
384 case LTTNG_UST_CONTEXT_PROCNAME:
385 context_type_string = config_event_context_procname;
386 break;
387 case LTTNG_UST_CONTEXT_VPID:
388 context_type_string = config_event_context_vpid;
389 break;
390 case LTTNG_UST_CONTEXT_VTID:
391 context_type_string = config_event_context_vtid;
392 break;
393 case LTTNG_UST_CONTEXT_IP:
394 context_type_string = config_event_context_ip;
395 break;
396 case LTTNG_UST_CONTEXT_PTHREAD_ID:
397 context_type_string = config_event_context_pthread_id;
398 break;
399 case LTTNG_UST_CONTEXT_APP_CONTEXT:
400 context_type_string = config_event_context_app;
401 break;
402 case LTTNG_UST_CONTEXT_CGROUP_NS:
403 context_type_string = config_event_context_cgroup_ns;
404 break;
405 case LTTNG_UST_CONTEXT_IPC_NS:
406 context_type_string = config_event_context_ipc_ns;
407 break;
408 case LTTNG_UST_CONTEXT_MNT_NS:
409 context_type_string = config_event_context_mnt_ns;
410 break;
411 case LTTNG_UST_CONTEXT_NET_NS:
412 context_type_string = config_event_context_net_ns;
413 break;
414 case LTTNG_UST_CONTEXT_TIME_NS:
415 context_type_string = config_event_context_time_ns;
416 break;
417 case LTTNG_UST_CONTEXT_PID_NS:
418 context_type_string = config_event_context_pid_ns;
419 break;
420 case LTTNG_UST_CONTEXT_USER_NS:
421 context_type_string = config_event_context_user_ns;
422 break;
423 case LTTNG_UST_CONTEXT_UTS_NS:
424 context_type_string = config_event_context_uts_ns;
425 break;
426 case LTTNG_UST_CONTEXT_VUID:
427 context_type_string = config_event_context_vuid;
428 break;
429 case LTTNG_UST_CONTEXT_VEUID:
430 context_type_string = config_event_context_veuid;
431 break;
432 case LTTNG_UST_CONTEXT_VSUID:
433 context_type_string = config_event_context_vsuid;
434 break;
435 case LTTNG_UST_CONTEXT_VGID:
436 context_type_string = config_event_context_vgid;
437 break;
438 case LTTNG_UST_CONTEXT_VEGID:
439 context_type_string = config_event_context_vegid;
440 break;
441 case LTTNG_UST_CONTEXT_VSGID:
442 context_type_string = config_event_context_vsgid;
443 break;
444 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
445 /*
446 * Error, should not be stored in the XML, perf contexts
447 * are stored as a node of type event_perf_context_type.
448 */
449 default:
450 context_type_string = NULL;
451 break;
452 }
453
454 return context_type_string;
455 }
456
457 static
458 const char *get_buffer_type_string(
459 enum lttng_buffer_type buffer_type)
460 {
461 const char *buffer_type_string;
462
463 switch (buffer_type) {
464 case LTTNG_BUFFER_PER_PID:
465 buffer_type_string = config_buffer_type_per_pid;
466 break;
467 case LTTNG_BUFFER_PER_UID:
468 buffer_type_string = config_buffer_type_per_uid;
469 break;
470 case LTTNG_BUFFER_GLOBAL:
471 buffer_type_string = config_buffer_type_global;
472 break;
473 default:
474 buffer_type_string = NULL;
475 }
476
477 return buffer_type_string;
478 }
479
480 static
481 const char *get_loglevel_type_string(
482 enum lttng_ust_loglevel_type loglevel_type)
483 {
484 const char *loglevel_type_string;
485
486 switch (loglevel_type) {
487 case LTTNG_UST_LOGLEVEL_ALL:
488 loglevel_type_string = config_loglevel_type_all;
489 break;
490 case LTTNG_UST_LOGLEVEL_RANGE:
491 loglevel_type_string = config_loglevel_type_range;
492 break;
493 case LTTNG_UST_LOGLEVEL_SINGLE:
494 loglevel_type_string = config_loglevel_type_single;
495 break;
496 default:
497 loglevel_type_string = NULL;
498 }
499
500 return loglevel_type_string;
501 }
502
503 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
504 static
505 int save_kernel_function_event(struct config_writer *writer,
506 struct ltt_kernel_event *event)
507 {
508 int ret;
509
510 ret = config_writer_open_element(writer, config_element_function_attributes);
511 if (ret) {
512 ret = LTTNG_ERR_SAVE_IO_FAIL;
513 goto end;
514 }
515
516 ret = config_writer_write_element_string(writer, config_element_name,
517 event->event->u.ftrace.symbol_name);
518 if (ret) {
519 ret = LTTNG_ERR_SAVE_IO_FAIL;
520 goto end;
521 }
522
523 /* /function attributes */
524 ret = config_writer_close_element(writer);
525 if (ret) {
526 ret = LTTNG_ERR_SAVE_IO_FAIL;
527 goto end;
528 }
529 end:
530 return ret;
531 }
532
533 static
534 int save_kernel_kprobe_event(struct config_writer *writer,
535 struct ltt_kernel_event *event)
536 {
537 int ret;
538 const char *symbol_name;
539 uint64_t addr;
540 uint64_t offset;
541
542 switch (event->event->instrumentation) {
543 case LTTNG_KERNEL_KPROBE:
544 /*
545 * Comments in lttng-kernel.h mention that
546 * either addr or symbol_name are set, not both.
547 */
548 addr = event->event->u.kprobe.addr;
549 offset = event->event->u.kprobe.offset;
550 symbol_name = addr ? NULL : event->event->u.kprobe.symbol_name;
551 break;
552 case LTTNG_KERNEL_KRETPROBE:
553 addr = event->event->u.kretprobe.addr;
554 offset = event->event->u.kretprobe.offset;
555 symbol_name = addr ? NULL : event->event->u.kretprobe.symbol_name;
556 break;
557 default:
558 assert(1);
559 ERR("Unsupported kernel instrumentation type.");
560 ret = LTTNG_ERR_INVALID;
561 goto end;
562 }
563
564 ret = config_writer_open_element(writer, config_element_probe_attributes);
565 if (ret) {
566 ret = LTTNG_ERR_SAVE_IO_FAIL;
567 goto end;
568 }
569
570 if (addr) {
571 ret = config_writer_write_element_unsigned_int( writer,
572 config_element_address, addr);
573 if (ret) {
574 ret = LTTNG_ERR_SAVE_IO_FAIL;
575 goto end;
576 }
577 } else if (symbol_name) {
578 ret = config_writer_write_element_string(writer,
579 config_element_symbol_name, symbol_name);
580 if (ret) {
581 ret = LTTNG_ERR_SAVE_IO_FAIL;
582 goto end;
583 }
584 /* If the offset is non-zero, write it.*/
585 if (offset) {
586 ret = config_writer_write_element_unsigned_int(writer,
587 config_element_offset, offset);
588 if (ret) {
589 ret = LTTNG_ERR_SAVE_IO_FAIL;
590 goto end;
591 }
592 }
593 } else {
594 /*
595 * This really should not happen as we are either setting the
596 * address or the symbol above.
597 */
598 ERR("Invalid probe/function description.");
599 ret = LTTNG_ERR_INVALID;
600 goto end;
601 }
602
603
604 ret = config_writer_close_element(writer);
605 if (ret) {
606 ret = LTTNG_ERR_SAVE_IO_FAIL;
607 goto end;
608 }
609 end:
610 return ret;
611 }
612
613 /*
614 * Save the userspace probe tracepoint event associated with the event to the
615 * config writer.
616 */
617 static
618 int save_kernel_userspace_probe_tracepoint_event(struct config_writer *writer,
619 struct ltt_kernel_event *event)
620 {
621 int ret = 0;
622 const char *probe_name, *provider_name, *binary_path;
623 const struct lttng_userspace_probe_location *userspace_probe_location;
624 const struct lttng_userspace_probe_location_lookup_method *lookup_method;
625 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
626
627 /* Get userspace probe location from the event. */
628 userspace_probe_location = event->userspace_probe_location;
629 if (!userspace_probe_location) {
630 ret = LTTNG_ERR_SAVE_IO_FAIL;
631 goto end;
632 }
633
634 /* Get lookup method and lookup method type. */
635 lookup_method = lttng_userspace_probe_location_get_lookup_method(userspace_probe_location);
636 if (!lookup_method) {
637 ret = LTTNG_ERR_SAVE_IO_FAIL;
638 goto end;
639 }
640
641 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
642
643 /* Get the binary path, probe name and provider name. */
644 binary_path =
645 lttng_userspace_probe_location_tracepoint_get_binary_path(
646 userspace_probe_location);
647 if (!binary_path) {
648 ret = LTTNG_ERR_SAVE_IO_FAIL;
649 goto end;
650 }
651
652 probe_name =
653 lttng_userspace_probe_location_tracepoint_get_probe_name(
654 userspace_probe_location);
655 if (!probe_name) {
656 ret = LTTNG_ERR_SAVE_IO_FAIL;
657 goto end;
658 }
659
660 provider_name =
661 lttng_userspace_probe_location_tracepoint_get_provider_name(
662 userspace_probe_location);
663 if (!provider_name) {
664 ret = LTTNG_ERR_SAVE_IO_FAIL;
665 goto end;
666 }
667
668 /* Open a userspace probe tracepoint attribute. */
669 ret = config_writer_open_element(writer, config_element_userspace_probe_tracepoint_attributes);
670 if (ret) {
671 ret = LTTNG_ERR_SAVE_IO_FAIL;
672 goto end;
673 }
674
675 switch (lookup_type) {
676 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
677 ret = config_writer_write_element_string(writer,
678 config_element_userspace_probe_lookup,
679 config_element_userspace_probe_lookup_tracepoint_sdt);
680 if (ret) {
681 ret = LTTNG_ERR_SAVE_IO_FAIL;
682 goto end;
683 }
684 break;
685 default:
686 ERR("Unsupported kernel userspace probe tracepoint lookup method.");
687 ret = LTTNG_ERR_INVALID;
688 goto end;
689 }
690
691 /* Write the binary path, provider name and the probe name. */
692 ret = config_writer_write_element_string(writer,
693 config_element_userspace_probe_location_binary_path,
694 binary_path);
695 if (ret) {
696 ret = LTTNG_ERR_SAVE_IO_FAIL;
697 goto end;
698 }
699
700 ret = config_writer_write_element_string(writer,
701 config_element_userspace_probe_tracepoint_location_provider_name,
702 provider_name);
703 if (ret) {
704 ret = LTTNG_ERR_SAVE_IO_FAIL;
705 goto end;
706 }
707
708 ret = config_writer_write_element_string(writer,
709 config_element_userspace_probe_tracepoint_location_probe_name,
710 probe_name);
711 if (ret) {
712 ret = LTTNG_ERR_SAVE_IO_FAIL;
713 goto end;
714 }
715
716 /* Close the userspace probe tracepoint attribute. */
717 ret = config_writer_close_element(writer);
718 if (ret) {
719 ret = LTTNG_ERR_SAVE_IO_FAIL;
720 goto end;
721 }
722
723 end:
724 return ret;
725 }
726
727 /*
728 * Save the userspace probe function event associated with the event to the
729 * config writer.
730 */
731 static
732 int save_kernel_userspace_probe_function_event(struct config_writer *writer,
733 struct ltt_kernel_event *event)
734 {
735 int ret = 0;
736 const char *function_name, *binary_path;
737 const struct lttng_userspace_probe_location *userspace_probe_location;
738 const struct lttng_userspace_probe_location_lookup_method *lookup_method;
739 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
740
741 /* Get userspace probe location from the event. */
742 userspace_probe_location = event->userspace_probe_location;
743 if (!userspace_probe_location) {
744 ret = LTTNG_ERR_SAVE_IO_FAIL;
745 goto end;
746 }
747
748 /* Get lookup method and lookup method type. */
749 lookup_method = lttng_userspace_probe_location_get_lookup_method(
750 userspace_probe_location);
751 if (!lookup_method) {
752 ret = LTTNG_ERR_SAVE_IO_FAIL;
753 goto end;
754 }
755
756 /* Get the binary path and the function name. */
757 binary_path =
758 lttng_userspace_probe_location_function_get_binary_path(
759 userspace_probe_location);
760 if (!binary_path) {
761 ret = LTTNG_ERR_SAVE_IO_FAIL;
762 goto end;
763 }
764
765 function_name =
766 lttng_userspace_probe_location_function_get_function_name(
767 userspace_probe_location);
768 if (!function_name) {
769 ret = LTTNG_ERR_SAVE_IO_FAIL;
770 goto end;
771 }
772
773 /* Open a userspace probe function attribute. */
774 ret = config_writer_open_element(writer,
775 config_element_userspace_probe_function_attributes);
776 if (ret) {
777 ret = LTTNG_ERR_SAVE_IO_FAIL;
778 goto end;
779 }
780
781 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
782 switch (lookup_type) {
783 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
784 ret = config_writer_write_element_string(writer,
785 config_element_userspace_probe_lookup,
786 config_element_userspace_probe_lookup_function_elf);
787 if (ret) {
788 ret = LTTNG_ERR_SAVE_IO_FAIL;
789 goto end;
790 }
791 break;
792 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT:
793 ret = config_writer_write_element_string(writer,
794 config_element_userspace_probe_lookup,
795 config_element_userspace_probe_lookup_function_default);
796 if (ret) {
797 ret = LTTNG_ERR_SAVE_IO_FAIL;
798 goto end;
799 }
800 break;
801 default:
802 ERR("Unsupported kernel userspace probe function lookup method.");
803 ret = LTTNG_ERR_INVALID;
804 goto end;
805 }
806
807 /* Write the binary path and the function name. */
808 ret = config_writer_write_element_string(writer,
809 config_element_userspace_probe_location_binary_path,
810 binary_path);
811 if (ret) {
812 ret = LTTNG_ERR_SAVE_IO_FAIL;
813 goto end;
814 }
815
816 ret = config_writer_write_element_string(writer,
817 config_element_userspace_probe_function_location_function_name,
818 function_name);
819 if (ret) {
820 ret = LTTNG_ERR_SAVE_IO_FAIL;
821 goto end;
822 }
823
824 /* Close the userspace probe function attribute. */
825 ret = config_writer_close_element(writer);
826 if (ret) {
827 ret = LTTNG_ERR_SAVE_IO_FAIL;
828 goto end;
829 }
830
831 end:
832 return ret;
833 }
834
835 static
836 int save_kernel_userspace_probe_event(struct config_writer *writer,
837 struct ltt_kernel_event *event)
838 {
839 int ret;
840 struct lttng_userspace_probe_location *userspace_probe_location;
841
842 /* Get userspace probe location from the event. */
843 userspace_probe_location = event->userspace_probe_location;
844 if (!userspace_probe_location) {
845 ret = LTTNG_ERR_SAVE_IO_FAIL;
846 goto end;
847 }
848
849 switch(lttng_userspace_probe_location_get_type(userspace_probe_location)) {
850 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
851 {
852 ret = save_kernel_userspace_probe_function_event(writer, event);
853 if (ret) {
854 ret = LTTNG_ERR_SAVE_IO_FAIL;
855 goto end;
856 }
857 break;
858 }
859 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
860 {
861 ret = save_kernel_userspace_probe_tracepoint_event(writer, event);
862 if (ret) {
863 ret = LTTNG_ERR_SAVE_IO_FAIL;
864 goto end;
865 }
866 break;
867 }
868 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN:
869 default:
870 ERR("Unsupported kernel userspace probe location type.");
871 ret = LTTNG_ERR_INVALID;
872 goto end;
873 }
874
875 end:
876 return ret;
877 }
878
879 static
880 int save_kernel_event(struct config_writer *writer,
881 struct ltt_kernel_event *event)
882 {
883 int ret;
884 const char *instrumentation_type;
885
886 ret = config_writer_open_element(writer, config_element_event);
887 if (ret) {
888 ret = LTTNG_ERR_SAVE_IO_FAIL;
889 goto end;
890 }
891
892 if (event->event->name[0]) {
893 ret = config_writer_write_element_string(writer,
894 config_element_name, event->event->name);
895 if (ret) {
896 ret = LTTNG_ERR_SAVE_IO_FAIL;
897 goto end;
898 }
899 }
900
901 ret = config_writer_write_element_bool(writer, config_element_enabled,
902 event->enabled);
903 if (ret) {
904 ret = LTTNG_ERR_SAVE_IO_FAIL;
905 goto end;
906 }
907
908 instrumentation_type = get_kernel_instrumentation_string(
909 event->event->instrumentation);
910 if (!instrumentation_type) {
911 ret = LTTNG_ERR_INVALID;
912 goto end;
913 }
914
915 ret = config_writer_write_element_string(writer, config_element_type,
916 instrumentation_type);
917 if (ret) {
918 ret = LTTNG_ERR_SAVE_IO_FAIL;
919 goto end;
920 }
921
922 if (event->filter_expression) {
923 ret = config_writer_write_element_string(writer,
924 config_element_filter,
925 event->filter_expression);
926 if (ret) {
927 ret = LTTNG_ERR_SAVE_IO_FAIL;
928 goto end;
929 }
930 }
931
932 if (event->event->instrumentation == LTTNG_KERNEL_FUNCTION ||
933 event->event->instrumentation == LTTNG_KERNEL_KPROBE ||
934 event->event->instrumentation == LTTNG_KERNEL_UPROBE ||
935 event->event->instrumentation == LTTNG_KERNEL_KRETPROBE) {
936
937 ret = config_writer_open_element(writer,
938 config_element_attributes);
939 if (ret) {
940 ret = LTTNG_ERR_SAVE_IO_FAIL;
941 goto end;
942 }
943
944 switch (event->event->instrumentation) {
945 case LTTNG_KERNEL_SYSCALL:
946 case LTTNG_KERNEL_FUNCTION:
947 ret = save_kernel_function_event(writer, event);
948 if (ret) {
949 goto end;
950 }
951 break;
952 case LTTNG_KERNEL_KPROBE:
953 case LTTNG_KERNEL_KRETPROBE:
954 ret = save_kernel_kprobe_event(writer, event);
955 if (ret) {
956 goto end;
957 }
958 break;
959 case LTTNG_KERNEL_UPROBE:
960 ret = save_kernel_userspace_probe_event(writer, event);
961 if (ret) {
962 goto end;
963 }
964 break;
965 default:
966 ERR("Unsupported kernel instrumentation type.");
967 ret = LTTNG_ERR_INVALID;
968 goto end;
969 }
970
971 /* /attributes */
972 ret = config_writer_close_element(writer);
973 if (ret) {
974 ret = LTTNG_ERR_SAVE_IO_FAIL;
975 goto end;
976 }
977 }
978
979 /* /event */
980 ret = config_writer_close_element(writer);
981 if (ret) {
982 ret = LTTNG_ERR_SAVE_IO_FAIL;
983 goto end;
984 }
985
986 ret = LTTNG_OK;
987 end:
988 return ret;
989 }
990
991 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
992 static
993 int save_kernel_events(struct config_writer *writer,
994 struct ltt_kernel_channel *kchan)
995 {
996 int ret;
997 struct ltt_kernel_event *event;
998
999 ret = config_writer_open_element(writer, config_element_events);
1000 if (ret) {
1001 ret = LTTNG_ERR_SAVE_IO_FAIL;
1002 goto end;
1003 }
1004
1005 cds_list_for_each_entry(event, &kchan->events_list.head, list) {
1006 ret = save_kernel_event(writer, event);
1007 if (ret != LTTNG_OK) {
1008 goto end;
1009 }
1010 }
1011
1012 /* /events */
1013 ret = config_writer_close_element(writer);
1014 if (ret) {
1015 ret = LTTNG_ERR_SAVE_IO_FAIL;
1016 goto end;
1017 }
1018
1019 ret = LTTNG_OK;
1020 end:
1021 return ret;
1022 }
1023
1024 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1025 static
1026 int save_ust_event(struct config_writer *writer,
1027 struct ltt_ust_event *event)
1028 {
1029 int ret;
1030 const char *loglevel_type_string;
1031
1032 ret = config_writer_open_element(writer, config_element_event);
1033 if (ret) {
1034 ret = LTTNG_ERR_SAVE_IO_FAIL;
1035 goto end;
1036 }
1037
1038 if (event->attr.name[0]) {
1039 ret = config_writer_write_element_string(writer,
1040 config_element_name, event->attr.name);
1041 if (ret) {
1042 ret = LTTNG_ERR_SAVE_IO_FAIL;
1043 goto end;
1044 }
1045 }
1046
1047 ret = config_writer_write_element_bool(writer, config_element_enabled,
1048 event->enabled);
1049 if (ret) {
1050 ret = LTTNG_ERR_SAVE_IO_FAIL;
1051 goto end;
1052 }
1053
1054 if (event->attr.instrumentation != LTTNG_UST_TRACEPOINT) {
1055 ERR("Unsupported UST instrumentation type.");
1056 ret = LTTNG_ERR_INVALID;
1057 goto end;
1058 }
1059 ret = config_writer_write_element_string(writer, config_element_type,
1060 config_event_type_tracepoint);
1061 if (ret) {
1062 ret = LTTNG_ERR_SAVE_IO_FAIL;
1063 goto end;
1064 }
1065
1066 loglevel_type_string = get_loglevel_type_string(
1067 event->attr.loglevel_type);
1068 if (!loglevel_type_string) {
1069 ERR("Unsupported UST loglevel type.");
1070 ret = LTTNG_ERR_INVALID;
1071 goto end;
1072 }
1073
1074 ret = config_writer_write_element_string(writer,
1075 config_element_loglevel_type, loglevel_type_string);
1076 if (ret) {
1077 ret = LTTNG_ERR_SAVE_IO_FAIL;
1078 goto end;
1079 }
1080
1081 /* The log level is irrelevant if no "filtering" is enabled */
1082 if (event->attr.loglevel_type != LTTNG_UST_LOGLEVEL_ALL) {
1083 ret = config_writer_write_element_signed_int(writer,
1084 config_element_loglevel, event->attr.loglevel);
1085 if (ret) {
1086 ret = LTTNG_ERR_SAVE_IO_FAIL;
1087 goto end;
1088 }
1089 }
1090
1091 if (event->filter_expression) {
1092 ret = config_writer_write_element_string(writer,
1093 config_element_filter, event->filter_expression);
1094 if (ret) {
1095 ret = LTTNG_ERR_SAVE_IO_FAIL;
1096 goto end;
1097 }
1098 }
1099
1100 if (event->exclusion && event->exclusion->count) {
1101 uint32_t i;
1102
1103 ret = config_writer_open_element(writer,
1104 config_element_exclusions);
1105 if (ret) {
1106 ret = LTTNG_ERR_SAVE_IO_FAIL;
1107 goto end;
1108 }
1109
1110 for (i = 0; i < event->exclusion->count; i++) {
1111 ret = config_writer_write_element_string(writer,
1112 config_element_exclusion,
1113 LTTNG_EVENT_EXCLUSION_NAME_AT(
1114 event->exclusion, i));
1115 if (ret) {
1116 ret = LTTNG_ERR_SAVE_IO_FAIL;
1117 goto end;
1118 }
1119 }
1120
1121 /* /exclusions */
1122 ret = config_writer_close_element(writer);
1123 if (ret) {
1124 ret = LTTNG_ERR_SAVE_IO_FAIL;
1125 goto end;
1126 }
1127 }
1128
1129 /* /event */
1130 ret = config_writer_close_element(writer);
1131 if (ret) {
1132 ret = LTTNG_ERR_SAVE_IO_FAIL;
1133 goto end;
1134 }
1135
1136 ret = LTTNG_OK;
1137 end:
1138 return ret;
1139 }
1140
1141 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1142 static
1143 int save_ust_events(struct config_writer *writer,
1144 struct lttng_ht *events)
1145 {
1146 int ret;
1147 struct ltt_ust_event *event;
1148 struct lttng_ht_node_str *node;
1149 struct lttng_ht_iter iter;
1150
1151 ret = config_writer_open_element(writer, config_element_events);
1152 if (ret) {
1153 ret = LTTNG_ERR_SAVE_IO_FAIL;
1154 goto end;
1155 }
1156
1157 rcu_read_lock();
1158 cds_lfht_for_each_entry(events->ht, &iter.iter, node, node) {
1159 event = caa_container_of(node, struct ltt_ust_event, node);
1160
1161 if (event->internal) {
1162 /* Internal events must not be exposed to clients */
1163 continue;
1164 }
1165 ret = save_ust_event(writer, event);
1166 if (ret != LTTNG_OK) {
1167 rcu_read_unlock();
1168 goto end;
1169 }
1170 }
1171 rcu_read_unlock();
1172
1173 /* /events */
1174 ret = config_writer_close_element(writer);
1175 if (ret) {
1176 ret = LTTNG_ERR_SAVE_IO_FAIL;
1177 goto end;
1178 }
1179
1180 ret = LTTNG_OK;
1181 end:
1182 return ret;
1183 }
1184
1185 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1186 static
1187 int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event,
1188 struct agent_event *agent_event)
1189 {
1190 int ret;
1191 enum lttng_ust_loglevel_type ust_loglevel_type;
1192
1193 ust_event->enabled = agent_event->enabled;
1194 ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT;
1195 if (lttng_strncpy(ust_event->attr.name, agent_event->name,
1196 LTTNG_SYMBOL_NAME_LEN)) {
1197 ret = LTTNG_ERR_INVALID;
1198 goto end;
1199 }
1200 switch (agent_event->loglevel_type) {
1201 case LTTNG_EVENT_LOGLEVEL_ALL:
1202 ust_loglevel_type = LTTNG_UST_LOGLEVEL_ALL;
1203 break;
1204 case LTTNG_EVENT_LOGLEVEL_SINGLE:
1205 ust_loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE;
1206 break;
1207 case LTTNG_EVENT_LOGLEVEL_RANGE:
1208 ust_loglevel_type = LTTNG_UST_LOGLEVEL_RANGE;
1209 break;
1210 default:
1211 ERR("Invalid agent_event loglevel_type.");
1212 ret = LTTNG_ERR_INVALID;
1213 goto end;
1214 }
1215
1216 ust_event->attr.loglevel_type = ust_loglevel_type;
1217 ust_event->attr.loglevel = agent_event->loglevel_value;
1218 ust_event->filter_expression = agent_event->filter_expression;
1219 ust_event->exclusion = agent_event->exclusion;
1220
1221 ret = LTTNG_OK;
1222 end:
1223 return ret;
1224 }
1225
1226 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1227 static
1228 int save_agent_events(struct config_writer *writer,
1229 struct agent *agent)
1230 {
1231 int ret;
1232 struct lttng_ht_iter iter;
1233 struct lttng_ht_node_str *node;
1234
1235 ret = config_writer_open_element(writer, config_element_events);
1236 if (ret) {
1237 ret = LTTNG_ERR_SAVE_IO_FAIL;
1238 goto end;
1239 }
1240
1241 rcu_read_lock();
1242 cds_lfht_for_each_entry(agent->events->ht, &iter.iter, node, node) {
1243 int ret;
1244 struct agent_event *agent_event;
1245 struct ltt_ust_event fake_event;
1246
1247 memset(&fake_event, 0, sizeof(fake_event));
1248 agent_event = caa_container_of(node, struct agent_event, node);
1249
1250 /*
1251 * Initialize a fake ust event to reuse the same serialization
1252 * function since UST and agent events contain the same info
1253 * (and one could wonder why they don't reuse the same
1254 * structures...).
1255 */
1256 ret = init_ust_event_from_agent_event(&fake_event, agent_event);
1257 if (ret != LTTNG_OK) {
1258 rcu_read_unlock();
1259 goto end;
1260 }
1261 ret = save_ust_event(writer, &fake_event);
1262 if (ret != LTTNG_OK) {
1263 rcu_read_unlock();
1264 goto end;
1265 }
1266 }
1267 rcu_read_unlock();
1268
1269 /* /events */
1270 ret = config_writer_close_element(writer);
1271 if (ret) {
1272 ret = LTTNG_ERR_SAVE_IO_FAIL;
1273 goto end;
1274 }
1275
1276 ret = LTTNG_OK;
1277 end:
1278 return ret;
1279 }
1280
1281 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1282 static
1283 int save_kernel_context(struct config_writer *writer,
1284 struct lttng_kernel_context *ctx)
1285 {
1286 int ret = LTTNG_OK;
1287
1288 if (!ctx) {
1289 goto end;
1290 }
1291
1292 ret = config_writer_open_element(writer, config_element_context);
1293 if (ret) {
1294 ret = LTTNG_ERR_SAVE_IO_FAIL;
1295 goto end;
1296 }
1297
1298 if (ctx->ctx == LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER) {
1299 ret = config_writer_open_element(writer,
1300 config_element_context_perf);
1301 if (ret) {
1302 ret = LTTNG_ERR_SAVE_IO_FAIL;
1303 goto end;
1304 }
1305
1306 ret = config_writer_write_element_unsigned_int(writer,
1307 config_element_type, ctx->u.perf_counter.type);
1308 if (ret) {
1309 ret = LTTNG_ERR_SAVE_IO_FAIL;
1310 goto end;
1311 }
1312
1313 ret = config_writer_write_element_unsigned_int(writer,
1314 config_element_config, ctx->u.perf_counter.config);
1315 if (ret) {
1316 ret = LTTNG_ERR_SAVE_IO_FAIL;
1317 goto end;
1318 }
1319
1320 ret = config_writer_write_element_string(writer,
1321 config_element_name, ctx->u.perf_counter.name);
1322 if (ret) {
1323 ret = LTTNG_ERR_SAVE_IO_FAIL;
1324 goto end;
1325 }
1326
1327 /* /perf */
1328 ret = config_writer_close_element(writer);
1329 if (ret) {
1330 ret = LTTNG_ERR_SAVE_IO_FAIL;
1331 goto end;
1332 }
1333 } else {
1334 const char *context_type_string =
1335 get_kernel_context_type_string(ctx->ctx);
1336
1337 if (!context_type_string) {
1338 ERR("Unsupported kernel context type.");
1339 ret = LTTNG_ERR_INVALID;
1340 goto end;
1341 }
1342
1343 ret = config_writer_write_element_string(writer,
1344 config_element_type, context_type_string);
1345 if (ret) {
1346 ret = LTTNG_ERR_SAVE_IO_FAIL;
1347 goto end;
1348 }
1349 }
1350
1351 /* /context */
1352 ret = config_writer_close_element(writer);
1353 if (ret) {
1354 ret = LTTNG_ERR_SAVE_IO_FAIL;
1355 goto end;
1356 }
1357
1358 ret = LTTNG_OK;
1359 end:
1360 return ret;
1361 }
1362
1363 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1364 static
1365 int save_kernel_contexts(struct config_writer *writer,
1366 struct ltt_kernel_channel *kchan)
1367 {
1368 int ret;
1369 struct ltt_kernel_context *ctx;
1370
1371 if (cds_list_empty(&kchan->ctx_list)) {
1372 ret = LTTNG_OK;
1373 goto end;
1374 }
1375
1376 ret = config_writer_open_element(writer, config_element_contexts);
1377 if (ret) {
1378 ret = LTTNG_ERR_SAVE_IO_FAIL;
1379 goto end;
1380 }
1381
1382 cds_list_for_each_entry(ctx, &kchan->ctx_list, list) {
1383 ret = save_kernel_context(writer, &ctx->ctx);
1384 if (ret != LTTNG_OK) {
1385 goto end;
1386 }
1387 }
1388
1389 /* /contexts */
1390 ret = config_writer_close_element(writer);
1391 if (ret) {
1392 ret = LTTNG_ERR_SAVE_IO_FAIL;
1393 goto end;
1394 }
1395
1396 ret = LTTNG_OK;
1397 end:
1398 return ret;
1399 }
1400
1401 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1402 static
1403 int save_ust_context_perf_thread_counter(struct config_writer *writer,
1404 struct ltt_ust_context *ctx)
1405 {
1406 int ret;
1407
1408 assert(writer);
1409 assert(ctx);
1410
1411 /* Perf contexts are saved as event_perf_context_type */
1412 ret = config_writer_open_element(writer, config_element_context_perf);
1413 if (ret) {
1414 ret = LTTNG_ERR_SAVE_IO_FAIL;
1415 goto end;
1416 }
1417
1418 ret = config_writer_write_element_unsigned_int(writer,
1419 config_element_type, ctx->ctx.u.perf_counter.type);
1420 if (ret) {
1421 ret = LTTNG_ERR_SAVE_IO_FAIL;
1422 goto end;
1423 }
1424
1425 ret = config_writer_write_element_unsigned_int(writer,
1426 config_element_config, ctx->ctx.u.perf_counter.config);
1427 if (ret) {
1428 ret = LTTNG_ERR_SAVE_IO_FAIL;
1429 goto end;
1430 }
1431
1432 ret = config_writer_write_element_string(writer, config_element_name,
1433 ctx->ctx.u.perf_counter.name);
1434 if (ret) {
1435 ret = LTTNG_ERR_SAVE_IO_FAIL;
1436 goto end;
1437 }
1438
1439 /* /perf */
1440 ret = config_writer_close_element(writer);
1441 if (ret) {
1442 ret = LTTNG_ERR_SAVE_IO_FAIL;
1443 goto end;
1444 }
1445
1446 ret = LTTNG_OK;
1447 end:
1448 return ret;
1449 }
1450
1451 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1452 static
1453 int save_ust_context_app_ctx(struct config_writer *writer,
1454 struct ltt_ust_context *ctx)
1455 {
1456 int ret;
1457
1458 assert(writer);
1459 assert(ctx);
1460
1461 /* Application contexts are saved as application_context_type */
1462 ret = config_writer_open_element(writer, config_element_context_app);
1463 if (ret) {
1464 ret = LTTNG_ERR_SAVE_IO_FAIL;
1465 goto end;
1466 }
1467
1468 ret = config_writer_write_element_string(writer,
1469 config_element_context_app_provider_name,
1470 ctx->ctx.u.app_ctx.provider_name);
1471 if (ret) {
1472 ret = LTTNG_ERR_SAVE_IO_FAIL;
1473 goto end;
1474 }
1475
1476 ret = config_writer_write_element_string(writer,
1477 config_element_context_app_ctx_name,
1478 ctx->ctx.u.app_ctx.ctx_name);
1479 if (ret) {
1480 ret = LTTNG_ERR_SAVE_IO_FAIL;
1481 goto end;
1482 }
1483
1484 /* /app */
1485 ret = config_writer_close_element(writer);
1486 if (ret) {
1487 ret = LTTNG_ERR_SAVE_IO_FAIL;
1488 goto end;
1489 }
1490
1491 ret = LTTNG_OK;
1492 end:
1493 return ret;
1494 }
1495
1496 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1497 static
1498 int save_ust_context_generic(struct config_writer *writer,
1499 struct ltt_ust_context *ctx)
1500 {
1501 int ret;
1502 const char *context_type_string;
1503
1504 assert(writer);
1505 assert(ctx);
1506
1507 /* Save context as event_context_type_type */
1508 context_type_string = get_ust_context_type_string(
1509 ctx->ctx.ctx);
1510 if (!context_type_string) {
1511 ERR("Unsupported UST context type.");
1512 ret = LTTNG_ERR_SAVE_IO_FAIL;
1513 goto end;
1514 }
1515
1516 ret = config_writer_write_element_string(writer,
1517 config_element_type, context_type_string);
1518 if (ret) {
1519 ret = LTTNG_ERR_SAVE_IO_FAIL;
1520 goto end;
1521 }
1522
1523 ret = LTTNG_OK;
1524 end:
1525 return ret;
1526 }
1527
1528 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1529 static
1530 int save_ust_context(struct config_writer *writer,
1531 struct cds_list_head *ctx_list)
1532 {
1533 int ret;
1534 struct ltt_ust_context *ctx;
1535
1536 assert(writer);
1537 assert(ctx_list);
1538
1539 ret = config_writer_open_element(writer, config_element_contexts);
1540 if (ret) {
1541 ret = LTTNG_ERR_SAVE_IO_FAIL;
1542 goto end;
1543 }
1544
1545 cds_list_for_each_entry(ctx, ctx_list, list) {
1546 ret = config_writer_open_element(writer,
1547 config_element_context);
1548 if (ret) {
1549 ret = LTTNG_ERR_SAVE_IO_FAIL;
1550 goto end;
1551 }
1552
1553 switch (ctx->ctx.ctx) {
1554 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
1555 ret = save_ust_context_perf_thread_counter(writer, ctx);
1556 break;
1557 case LTTNG_UST_CONTEXT_APP_CONTEXT:
1558 ret = save_ust_context_app_ctx(writer, ctx);
1559 break;
1560 default:
1561 /* Save generic context. */
1562 ret = save_ust_context_generic(writer, ctx);
1563 }
1564 if (ret != LTTNG_OK) {
1565 goto end;
1566 }
1567
1568 /* /context */
1569 ret = config_writer_close_element(writer);
1570 if (ret) {
1571 ret = LTTNG_ERR_SAVE_IO_FAIL;
1572 goto end;
1573 }
1574 }
1575
1576 /* /contexts */
1577 ret = config_writer_close_element(writer);
1578 if (ret) {
1579 ret = LTTNG_ERR_SAVE_IO_FAIL;
1580 goto end;
1581 }
1582
1583 ret = LTTNG_OK;
1584 end:
1585 return ret;
1586 }
1587
1588 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1589 static
1590 int save_kernel_channel(struct config_writer *writer,
1591 struct ltt_kernel_channel *kchan)
1592 {
1593 int ret;
1594
1595 assert(writer);
1596 assert(kchan);
1597
1598 ret = config_writer_open_element(writer, config_element_channel);
1599 if (ret) {
1600 ret = LTTNG_ERR_SAVE_IO_FAIL;
1601 goto end;
1602 }
1603
1604 ret = config_writer_write_element_string(writer, config_element_name,
1605 kchan->channel->name);
1606 if (ret) {
1607 ret = LTTNG_ERR_SAVE_IO_FAIL;
1608 goto end;
1609 }
1610
1611 ret = config_writer_write_element_bool(writer, config_element_enabled,
1612 kchan->channel->enabled);
1613 if (ret) {
1614 ret = LTTNG_ERR_SAVE_IO_FAIL;
1615 goto end;
1616 }
1617
1618 ret = save_kernel_channel_attributes(writer, &kchan->channel->attr);
1619 if (ret != LTTNG_OK) {
1620 goto end;
1621 }
1622
1623 ret = save_kernel_events(writer, kchan);
1624 if (ret != LTTNG_OK) {
1625 goto end;
1626 }
1627
1628 ret = save_kernel_contexts(writer, kchan);
1629 if (ret != LTTNG_OK) {
1630 goto end;
1631 }
1632
1633 /* /channel */
1634 ret = config_writer_close_element(writer);
1635 if (ret) {
1636 ret = LTTNG_ERR_SAVE_IO_FAIL;
1637 goto end;
1638 }
1639
1640 ret = LTTNG_OK;
1641 end:
1642 return ret;
1643 }
1644
1645 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1646 static
1647 int save_ust_channel(struct config_writer *writer,
1648 struct ltt_ust_channel *ust_chan,
1649 struct ltt_ust_session *session)
1650 {
1651 int ret;
1652
1653 assert(writer);
1654 assert(ust_chan);
1655 assert(session);
1656
1657 ret = config_writer_open_element(writer, config_element_channel);
1658 if (ret) {
1659 ret = LTTNG_ERR_SAVE_IO_FAIL;
1660 goto end;
1661 }
1662
1663 ret = config_writer_write_element_string(writer, config_element_name,
1664 ust_chan->name);
1665 if (ret) {
1666 ret = LTTNG_ERR_SAVE_IO_FAIL;
1667 goto end;
1668 }
1669
1670 ret = config_writer_write_element_bool(writer, config_element_enabled,
1671 ust_chan->enabled);
1672 if (ret) {
1673 ret = LTTNG_ERR_SAVE_IO_FAIL;
1674 goto end;
1675 }
1676
1677 ret = save_ust_channel_attributes(writer, &ust_chan->attr);
1678 if (ret != LTTNG_OK) {
1679 goto end;
1680 }
1681
1682 ret = config_writer_write_element_unsigned_int(writer,
1683 config_element_tracefile_size, ust_chan->tracefile_size);
1684 if (ret) {
1685 ret = LTTNG_ERR_SAVE_IO_FAIL;
1686 goto end;
1687 }
1688
1689 ret = config_writer_write_element_unsigned_int(writer,
1690 config_element_tracefile_count, ust_chan->tracefile_count);
1691 if (ret) {
1692 ret = LTTNG_ERR_SAVE_IO_FAIL;
1693 goto end;
1694 }
1695
1696 ret = config_writer_write_element_unsigned_int(writer,
1697 config_element_live_timer_interval,
1698 session->live_timer_interval);
1699 if (ret) {
1700 ret = LTTNG_ERR_SAVE_IO_FAIL;
1701 goto end;
1702 }
1703
1704 if (ust_chan->domain == LTTNG_DOMAIN_UST) {
1705 ret = save_ust_events(writer, ust_chan->events);
1706 if (ret != LTTNG_OK) {
1707 goto end;
1708 }
1709 } else {
1710 struct agent *agent = NULL;
1711
1712 agent = trace_ust_find_agent(session, ust_chan->domain);
1713 if (!agent) {
1714 ret = LTTNG_ERR_SAVE_IO_FAIL;
1715 ERR("Could not find agent associated to UST subdomain");
1716 goto end;
1717 }
1718
1719 /*
1720 * Channels associated with a UST sub-domain (such as JUL, Log4j
1721 * or Python) don't have any non-internal events. We retrieve
1722 * the "agent" events associated with this channel and serialize
1723 * them.
1724 */
1725 ret = save_agent_events(writer, agent);
1726 if (ret != LTTNG_OK) {
1727 goto end;
1728 }
1729 }
1730
1731 ret = save_ust_context(writer, &ust_chan->ctx_list);
1732 if (ret != LTTNG_OK) {
1733 goto end;
1734 }
1735
1736 /* /channel */
1737 ret = config_writer_close_element(writer);
1738 if (ret) {
1739 ret = LTTNG_ERR_SAVE_IO_FAIL;
1740 goto end;
1741 }
1742
1743 ret = LTTNG_OK;
1744 end:
1745 return ret;
1746 }
1747
1748 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1749 static
1750 int save_kernel_session(struct config_writer *writer,
1751 struct ltt_session *session)
1752 {
1753 int ret;
1754 struct ltt_kernel_channel *kchan;
1755
1756 assert(writer);
1757 assert(session);
1758
1759 ret = config_writer_write_element_string(writer, config_element_type,
1760 config_domain_type_kernel);
1761 if (ret) {
1762 ret = LTTNG_ERR_SAVE_IO_FAIL;
1763 goto end;
1764 }
1765
1766 ret = config_writer_write_element_string(writer,
1767 config_element_buffer_type, config_buffer_type_global);
1768 if (ret) {
1769 ret = LTTNG_ERR_SAVE_IO_FAIL;
1770 goto end;
1771 }
1772
1773 ret = config_writer_open_element(writer,
1774 config_element_channels);
1775 if (ret) {
1776 ret = LTTNG_ERR_SAVE_IO_FAIL;
1777 goto end;
1778 }
1779
1780 cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head,
1781 list) {
1782 ret = save_kernel_channel(writer, kchan);
1783 if (ret != LTTNG_OK) {
1784 goto end;
1785 }
1786 }
1787
1788 /* /channels */
1789 ret = config_writer_close_element(writer);
1790 if (ret) {
1791 ret = LTTNG_ERR_SAVE_IO_FAIL;
1792 goto end;
1793 }
1794
1795 ret = LTTNG_OK;
1796 end:
1797 return ret;
1798 }
1799
1800 static
1801 const char *get_config_domain_str(enum lttng_domain_type domain)
1802 {
1803 const char *str_dom;
1804
1805 switch (domain) {
1806 case LTTNG_DOMAIN_KERNEL:
1807 str_dom = config_domain_type_kernel;
1808 break;
1809 case LTTNG_DOMAIN_UST:
1810 str_dom = config_domain_type_ust;
1811 break;
1812 case LTTNG_DOMAIN_JUL:
1813 str_dom = config_domain_type_jul;
1814 break;
1815 case LTTNG_DOMAIN_LOG4J:
1816 str_dom = config_domain_type_log4j;
1817 break;
1818 case LTTNG_DOMAIN_PYTHON:
1819 str_dom = config_domain_type_python;
1820 break;
1821 default:
1822 assert(0);
1823 }
1824
1825 return str_dom;
1826 }
1827
1828 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1829 static int save_process_attr_tracker(struct config_writer *writer,
1830 struct ltt_session *sess,
1831 int domain,
1832 enum lttng_process_attr process_attr)
1833 {
1834 int ret = LTTNG_OK;
1835 const char *element_id_tracker, *element_target_id, *element_id;
1836 const struct process_attr_tracker *tracker;
1837 enum lttng_tracking_policy tracking_policy;
1838 struct lttng_process_attr_values *values = NULL;
1839
1840 switch (process_attr) {
1841 case LTTNG_PROCESS_ATTR_PROCESS_ID:
1842 element_id_tracker = config_element_process_attr_tracker_pid;
1843 element_target_id = config_element_process_attr_pid_value;
1844 element_id = config_element_process_attr_id;
1845 break;
1846 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1847 element_id_tracker = config_element_process_attr_tracker_vpid;
1848 element_target_id = config_element_process_attr_vpid_value;
1849 element_id = config_element_process_attr_id;
1850 break;
1851 case LTTNG_PROCESS_ATTR_USER_ID:
1852 element_id_tracker = config_element_process_attr_tracker_uid;
1853 element_target_id = config_element_process_attr_uid_value;
1854 element_id = config_element_process_attr_id;
1855 break;
1856 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
1857 element_id_tracker = config_element_process_attr_tracker_vuid;
1858 element_target_id = config_element_process_attr_vuid_value;
1859 element_id = config_element_process_attr_id;
1860 break;
1861 case LTTNG_PROCESS_ATTR_GROUP_ID:
1862 element_id_tracker = config_element_process_attr_tracker_gid;
1863 element_target_id = config_element_process_attr_gid_value;
1864 element_id = config_element_process_attr_id;
1865 break;
1866 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
1867 element_id_tracker = config_element_process_attr_tracker_vgid;
1868 element_target_id = config_element_process_attr_vgid_value;
1869 element_id = config_element_process_attr_id;
1870 break;
1871 default:
1872 ret = LTTNG_ERR_SAVE_IO_FAIL;
1873 goto end;
1874 }
1875
1876 switch (domain) {
1877 case LTTNG_DOMAIN_KERNEL:
1878 {
1879 tracker = kernel_get_process_attr_tracker(
1880 sess->kernel_session, process_attr);
1881 assert(tracker);
1882 break;
1883 }
1884 case LTTNG_DOMAIN_UST:
1885 {
1886 tracker = trace_ust_get_process_attr_tracker(
1887 sess->ust_session, process_attr);
1888 assert(tracker);
1889 break;
1890 }
1891 case LTTNG_DOMAIN_JUL:
1892 case LTTNG_DOMAIN_LOG4J:
1893 case LTTNG_DOMAIN_PYTHON:
1894 default:
1895 ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
1896 goto end;
1897 }
1898
1899 tracking_policy = process_attr_tracker_get_tracking_policy(tracker);
1900 if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_ALL) {
1901 /* Tracking all, nothing to output. */
1902 ret = LTTNG_OK;
1903 goto end;
1904 }
1905
1906 ret = config_writer_open_element(writer, element_id_tracker);
1907 if (ret) {
1908 ret = LTTNG_ERR_SAVE_IO_FAIL;
1909 goto end;
1910 }
1911
1912 ret = config_writer_open_element(
1913 writer, config_element_process_attr_values);
1914 if (ret) {
1915 ret = LTTNG_ERR_SAVE_IO_FAIL;
1916 goto end;
1917 }
1918
1919 if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_SET) {
1920 unsigned int i, count;
1921 enum process_attr_tracker_status status =
1922 process_attr_tracker_get_inclusion_set(
1923 tracker, &values);
1924
1925 if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
1926 ret = LTTNG_ERR_NOMEM;
1927 goto end;
1928 }
1929
1930 count = _lttng_process_attr_values_get_count(values);
1931
1932 for (i = 0; i < count; i++) {
1933 unsigned int integral_value = UINT_MAX;
1934 const char *name = NULL;
1935 const struct process_attr_value *value =
1936 lttng_process_attr_tracker_values_get_at_index(
1937 values, i);
1938
1939 assert(value);
1940 ret = config_writer_open_element(
1941 writer, element_target_id);
1942 if (ret) {
1943 ret = LTTNG_ERR_SAVE_IO_FAIL;
1944 goto end;
1945 }
1946
1947 switch (value->type) {
1948 case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
1949 integral_value =
1950 (unsigned int) value->value.pid;
1951 break;
1952 case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
1953 integral_value =
1954 (unsigned int) value->value.uid;
1955 break;
1956 case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
1957 integral_value =
1958 (unsigned int) value->value.gid;
1959 break;
1960 case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
1961 name = value->value.user_name;
1962 assert(name);
1963 break;
1964 case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
1965 name = value->value.group_name;
1966 assert(name);
1967 break;
1968 default:
1969 abort();
1970 }
1971
1972 if (name) {
1973 ret = config_writer_write_element_string(writer,
1974 config_element_name, name);
1975 } else {
1976 ret = config_writer_write_element_unsigned_int(
1977 writer, element_id,
1978 integral_value);
1979 }
1980
1981 if (ret) {
1982 ret = LTTNG_ERR_SAVE_IO_FAIL;
1983 goto end;
1984 }
1985
1986 /* /$element_target_id */
1987 ret = config_writer_close_element(writer);
1988 if (ret) {
1989 ret = LTTNG_ERR_SAVE_IO_FAIL;
1990 goto end;
1991 }
1992 }
1993 }
1994
1995 /* /values */
1996 ret = config_writer_close_element(writer);
1997 if (ret) {
1998 ret = LTTNG_ERR_SAVE_IO_FAIL;
1999 goto end;
2000 }
2001
2002 /* /$element_id_tracker */
2003 ret = config_writer_close_element(writer);
2004 if (ret) {
2005 ret = LTTNG_ERR_SAVE_IO_FAIL;
2006 goto end;
2007 }
2008
2009 ret = LTTNG_OK;
2010 end:
2011 lttng_process_attr_values_destroy(values);
2012 return ret;
2013 }
2014
2015 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2016 static int save_process_attr_trackers(struct config_writer *writer,
2017 struct ltt_session *sess,
2018 int domain)
2019 {
2020 int ret;
2021
2022 switch (domain) {
2023 case LTTNG_DOMAIN_KERNEL:
2024 ret = save_process_attr_tracker(writer, sess, domain,
2025 LTTNG_PROCESS_ATTR_PROCESS_ID);
2026 if (ret != LTTNG_OK) {
2027 goto end;
2028 }
2029 ret = save_process_attr_tracker(writer, sess, domain,
2030 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
2031 if (ret != LTTNG_OK) {
2032 goto end;
2033 }
2034 ret = save_process_attr_tracker(writer, sess, domain,
2035 LTTNG_PROCESS_ATTR_USER_ID);
2036 if (ret != LTTNG_OK) {
2037 goto end;
2038 }
2039 ret = save_process_attr_tracker(writer, sess, domain,
2040 LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
2041 if (ret != LTTNG_OK) {
2042 goto end;
2043 }
2044 ret = save_process_attr_tracker(writer, sess, domain,
2045 LTTNG_PROCESS_ATTR_GROUP_ID);
2046 if (ret != LTTNG_OK) {
2047 goto end;
2048 }
2049 ret = save_process_attr_tracker(writer, sess, domain,
2050 LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
2051 if (ret != LTTNG_OK) {
2052 goto end;
2053 }
2054 break;
2055 case LTTNG_DOMAIN_UST:
2056 ret = save_process_attr_tracker(writer, sess, domain,
2057 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
2058 if (ret != LTTNG_OK) {
2059 goto end;
2060 }
2061 ret = save_process_attr_tracker(writer, sess, domain,
2062 LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
2063 if (ret != LTTNG_OK) {
2064 goto end;
2065 }
2066 ret = save_process_attr_tracker(writer, sess, domain,
2067 LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
2068 if (ret != LTTNG_OK) {
2069 goto end;
2070 }
2071 break;
2072 default:
2073 ret = LTTNG_ERR_INVALID;
2074 goto end;
2075 }
2076 ret = LTTNG_OK;
2077 end:
2078 return ret;
2079 }
2080
2081 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2082 static
2083 int save_ust_domain(struct config_writer *writer,
2084 struct ltt_session *session, enum lttng_domain_type domain)
2085 {
2086 int ret;
2087 struct ltt_ust_channel *ust_chan;
2088 const char *buffer_type_string;
2089 struct lttng_ht_node_str *node;
2090 struct lttng_ht_iter iter;
2091 const char *config_domain_name;
2092
2093 assert(writer);
2094 assert(session);
2095
2096 ret = config_writer_open_element(writer,
2097 config_element_domain);
2098 if (ret) {
2099 ret = LTTNG_ERR_SAVE_IO_FAIL;
2100 goto end;
2101 }
2102
2103 config_domain_name = get_config_domain_str(domain);
2104 if (!config_domain_name) {
2105 ret = LTTNG_ERR_INVALID;
2106 goto end;
2107 }
2108
2109 ret = config_writer_write_element_string(writer,
2110 config_element_type, config_domain_name);
2111 if (ret) {
2112 ret = LTTNG_ERR_SAVE_IO_FAIL;
2113 goto end;
2114 }
2115
2116 buffer_type_string = get_buffer_type_string(
2117 session->ust_session->buffer_type);
2118 if (!buffer_type_string) {
2119 ERR("Unsupported buffer type.");
2120 ret = LTTNG_ERR_INVALID;
2121 goto end;
2122 }
2123
2124 ret = config_writer_write_element_string(writer,
2125 config_element_buffer_type, buffer_type_string);
2126 if (ret) {
2127 ret = LTTNG_ERR_SAVE_IO_FAIL;
2128 goto end;
2129 }
2130
2131 ret = config_writer_open_element(writer, config_element_channels);
2132 if (ret) {
2133 ret = LTTNG_ERR_SAVE_IO_FAIL;
2134 goto end;
2135 }
2136
2137 rcu_read_lock();
2138 cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht,
2139 &iter.iter, node, node) {
2140 ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
2141 if (domain == ust_chan->domain) {
2142 ret = save_ust_channel(writer, ust_chan, session->ust_session);
2143 if (ret != LTTNG_OK) {
2144 rcu_read_unlock();
2145 goto end;
2146 }
2147 }
2148 }
2149 rcu_read_unlock();
2150
2151 /* /channels */
2152 ret = config_writer_close_element(writer);
2153 if (ret) {
2154 ret = LTTNG_ERR_SAVE_IO_FAIL;
2155 goto end;
2156 }
2157
2158 if (domain == LTTNG_DOMAIN_UST) {
2159 ret = config_writer_open_element(
2160 writer, config_element_process_attr_trackers);
2161 if (ret) {
2162 ret = LTTNG_ERR_SAVE_IO_FAIL;
2163 goto end;
2164 }
2165
2166 ret = save_process_attr_trackers(
2167 writer, session, LTTNG_DOMAIN_UST);
2168 if (ret != LTTNG_OK) {
2169 goto end;
2170 }
2171
2172 /* /trackers */
2173 ret = config_writer_close_element(writer);
2174 if (ret) {
2175 ret = LTTNG_ERR_SAVE_IO_FAIL;
2176 goto end;
2177 }
2178 }
2179
2180 /* /domain */
2181 ret = config_writer_close_element(writer);
2182 if (ret) {
2183 ret = LTTNG_ERR_SAVE_IO_FAIL;
2184 goto end;
2185 }
2186
2187 ret = LTTNG_OK;
2188 end:
2189 return ret;
2190 }
2191
2192 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2193 static
2194 int save_domains(struct config_writer *writer, struct ltt_session *session)
2195 {
2196 int ret = LTTNG_OK;
2197
2198 assert(writer);
2199 assert(session);
2200
2201 if (!session->kernel_session && !session->ust_session) {
2202 goto end;
2203 }
2204
2205 ret = config_writer_open_element(writer, config_element_domains);
2206 if (ret) {
2207 ret = LTTNG_ERR_SAVE_IO_FAIL;
2208 goto end;
2209 }
2210
2211 if (session->kernel_session) {
2212 ret = config_writer_open_element(writer,
2213 config_element_domain);
2214 if (ret) {
2215 ret = LTTNG_ERR_SAVE_IO_FAIL;
2216 goto end;
2217 }
2218
2219 ret = save_kernel_session(writer, session);
2220 if (ret != LTTNG_OK) {
2221 goto end;
2222 }
2223
2224 ret = config_writer_open_element(
2225 writer, config_element_process_attr_trackers);
2226 if (ret) {
2227 ret = LTTNG_ERR_SAVE_IO_FAIL;
2228 goto end;
2229 }
2230
2231 ret = save_process_attr_trackers(
2232 writer, session, LTTNG_DOMAIN_KERNEL);
2233 if (ret != LTTNG_OK) {
2234 goto end;
2235 }
2236
2237 /* /trackers */
2238 ret = config_writer_close_element(writer);
2239 if (ret) {
2240 ret = LTTNG_ERR_SAVE_IO_FAIL;
2241 goto end;
2242 }
2243 /* /domain */
2244 ret = config_writer_close_element(writer);
2245 if (ret) {
2246 ret = LTTNG_ERR_SAVE_IO_FAIL;
2247 goto end;
2248 }
2249 }
2250
2251 if (session->ust_session) {
2252 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST);
2253 if (ret != LTTNG_OK) {
2254 goto end;
2255 }
2256
2257 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL);
2258 if (ret != LTTNG_OK) {
2259 goto end;
2260 }
2261
2262 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J);
2263 if (ret != LTTNG_OK) {
2264 goto end;
2265 }
2266
2267 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
2268 if (ret != LTTNG_OK) {
2269 goto end;
2270 }
2271 }
2272
2273 /* /domains */
2274 ret = config_writer_close_element(writer);
2275 if (ret) {
2276 ret = LTTNG_ERR_SAVE_IO_FAIL;
2277 goto end;
2278 }
2279
2280 ret = LTTNG_OK;
2281 end:
2282 return ret;
2283 }
2284
2285 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2286 static
2287 int save_consumer_output(struct config_writer *writer,
2288 struct consumer_output *output)
2289 {
2290 int ret;
2291
2292 assert(writer);
2293 assert(output);
2294
2295 ret = config_writer_open_element(writer, config_element_consumer_output);
2296 if (ret) {
2297 ret = LTTNG_ERR_SAVE_IO_FAIL;
2298 goto end;
2299 }
2300
2301 ret = config_writer_write_element_bool(writer, config_element_enabled,
2302 output->enabled);
2303 if (ret) {
2304 ret = LTTNG_ERR_SAVE_IO_FAIL;
2305 goto end;
2306 }
2307
2308 ret = config_writer_open_element(writer, config_element_destination);
2309 if (ret) {
2310 ret = LTTNG_ERR_SAVE_IO_FAIL;
2311 goto end;
2312 }
2313
2314 switch (output->type) {
2315 case CONSUMER_DST_LOCAL:
2316 ret = config_writer_write_element_string(writer,
2317 config_element_path, output->dst.session_root_path);
2318 if (ret) {
2319 ret = LTTNG_ERR_SAVE_IO_FAIL;
2320 goto end;
2321 }
2322 break;
2323 case CONSUMER_DST_NET:
2324 {
2325 char *uri;
2326
2327 uri = zmalloc(PATH_MAX);
2328 if (!uri) {
2329 ret = LTTNG_ERR_NOMEM;
2330 goto end;
2331 }
2332
2333 ret = config_writer_open_element(writer, config_element_net_output);
2334 if (ret) {
2335 ret = LTTNG_ERR_SAVE_IO_FAIL;
2336 goto end_net_output;
2337 }
2338
2339 if (output->dst.net.control_isset &&
2340 output->dst.net.data_isset) {
2341 ret = uri_to_str_url(&output->dst.net.control, uri, PATH_MAX);
2342 if (ret < 0) {
2343 ret = LTTNG_ERR_INVALID;
2344 goto end_net_output;
2345 }
2346
2347 ret = config_writer_write_element_string(writer,
2348 config_element_control_uri, uri);
2349 if (ret) {
2350 ret = LTTNG_ERR_SAVE_IO_FAIL;
2351 goto end_net_output;
2352 }
2353
2354 ret = uri_to_str_url(&output->dst.net.data, uri, PATH_MAX);
2355 if (ret < 0) {
2356 ret = LTTNG_ERR_INVALID;
2357 goto end_net_output;
2358 }
2359
2360 ret = config_writer_write_element_string(writer,
2361 config_element_data_uri, uri);
2362 if (ret) {
2363 ret = LTTNG_ERR_SAVE_IO_FAIL;
2364 goto end_net_output;
2365 }
2366 ret = LTTNG_OK;
2367 end_net_output:
2368 free(uri);
2369 if (ret != LTTNG_OK) {
2370 goto end;
2371 }
2372 } else {
2373 ret = !output->dst.net.control_isset ?
2374 LTTNG_ERR_URL_CTRL_MISS :
2375 LTTNG_ERR_URL_DATA_MISS;
2376 free(uri);
2377 goto end;
2378 }
2379
2380 ret = config_writer_close_element(writer);
2381 if (ret) {
2382 ret = LTTNG_ERR_SAVE_IO_FAIL;
2383 goto end;
2384 }
2385 break;
2386 }
2387 default:
2388 ERR("Unsupported consumer output type.");
2389 ret = LTTNG_ERR_INVALID;
2390 goto end;
2391 }
2392
2393 /* /destination */
2394 ret = config_writer_close_element(writer);
2395 if (ret) {
2396 ret = LTTNG_ERR_SAVE_IO_FAIL;
2397 goto end;
2398 }
2399
2400 /* /consumer_output */
2401 ret = config_writer_close_element(writer);
2402 if (ret) {
2403 ret = LTTNG_ERR_SAVE_IO_FAIL;
2404 goto end;
2405 }
2406
2407 ret = LTTNG_OK;
2408 end:
2409 return ret;
2410 }
2411
2412 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2413 static
2414 int save_snapshot_outputs(struct config_writer *writer,
2415 struct snapshot *snapshot)
2416 {
2417 int ret;
2418 struct lttng_ht_iter iter;
2419 struct snapshot_output *output;
2420
2421 assert(writer);
2422 assert(snapshot);
2423
2424 ret = config_writer_open_element(writer, config_element_snapshot_outputs);
2425 if (ret) {
2426 ret = LTTNG_ERR_SAVE_IO_FAIL;
2427 goto end;
2428 }
2429
2430 rcu_read_lock();
2431 cds_lfht_for_each_entry(snapshot->output_ht->ht, &iter.iter, output,
2432 node.node) {
2433 ret = config_writer_open_element(writer,
2434 config_element_output);
2435 if (ret) {
2436 ret = LTTNG_ERR_SAVE_IO_FAIL;
2437 goto end_unlock;
2438 }
2439
2440 ret = config_writer_write_element_string(writer,
2441 config_element_name, output->name);
2442 if (ret) {
2443 ret = LTTNG_ERR_SAVE_IO_FAIL;
2444 goto end_unlock;
2445 }
2446
2447 ret = config_writer_write_element_unsigned_int(writer,
2448 config_element_max_size, output->max_size);
2449 if (ret) {
2450 ret = LTTNG_ERR_SAVE_IO_FAIL;
2451 goto end_unlock;
2452 }
2453
2454 ret = save_consumer_output(writer, output->consumer);
2455 if (ret != LTTNG_OK) {
2456 goto end_unlock;
2457 }
2458
2459 /* /output */
2460 ret = config_writer_close_element(writer);
2461 if (ret) {
2462 ret = LTTNG_ERR_SAVE_IO_FAIL;
2463 goto end_unlock;
2464 }
2465 }
2466 rcu_read_unlock();
2467
2468 /* /snapshot_outputs */
2469 ret = config_writer_close_element(writer);
2470 if (ret) {
2471 ret = LTTNG_ERR_SAVE_IO_FAIL;
2472 goto end;
2473 }
2474
2475 ret = LTTNG_OK;
2476 end:
2477 return ret;
2478 end_unlock:
2479 rcu_read_unlock();
2480 return ret;
2481 }
2482
2483 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2484 static
2485 int save_session_output(struct config_writer *writer,
2486 struct ltt_session *session)
2487 {
2488 int ret;
2489
2490 assert(writer);
2491 assert(session);
2492
2493 if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
2494 (!session->snapshot_mode && !session->consumer)) {
2495 /* Session is in no output mode */
2496 ret = LTTNG_OK;
2497 goto end;
2498 }
2499
2500 ret = config_writer_open_element(writer, config_element_output);
2501 if (ret) {
2502 ret = LTTNG_ERR_SAVE_IO_FAIL;
2503 goto end;
2504 }
2505
2506 if (session->snapshot_mode) {
2507 ret = save_snapshot_outputs(writer, &session->snapshot);
2508 if (ret != LTTNG_OK) {
2509 goto end;
2510 }
2511 } else {
2512 if (session->consumer) {
2513 ret = save_consumer_output(writer, session->consumer);
2514 if (ret != LTTNG_OK) {
2515 goto end;
2516 }
2517 }
2518 }
2519
2520 /* /output */
2521 ret = config_writer_close_element(writer);
2522 if (ret) {
2523 ret = LTTNG_ERR_SAVE_IO_FAIL;
2524 goto end;
2525 }
2526 ret = LTTNG_OK;
2527 end:
2528 return ret;
2529 }
2530
2531 static
2532 int save_session_rotation_schedule(struct config_writer *writer,
2533 enum lttng_rotation_schedule_type type, uint64_t value)
2534 {
2535 int ret = 0;
2536 const char *element_name;
2537 const char *value_name;
2538
2539 switch (type) {
2540 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
2541 element_name = config_element_rotation_schedule_periodic;
2542 value_name = config_element_rotation_schedule_periodic_time_us;
2543 break;
2544 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
2545 element_name = config_element_rotation_schedule_size_threshold;
2546 value_name = config_element_rotation_schedule_size_threshold_bytes;
2547 break;
2548 default:
2549 ret = -1;
2550 goto end;
2551 }
2552
2553 ret = config_writer_open_element(writer, element_name);
2554 if (ret) {
2555 goto end;
2556 }
2557
2558 ret = config_writer_write_element_unsigned_int(writer,
2559 value_name, value);
2560 if (ret) {
2561 goto end;
2562 }
2563
2564 /* Close schedule descriptor element. */
2565 ret = config_writer_close_element(writer);
2566 if (ret) {
2567 goto end;
2568 }
2569 end:
2570 return ret;
2571 }
2572
2573 static
2574 int save_session_rotation_schedules(struct config_writer *writer,
2575 struct ltt_session *session)
2576 {
2577 int ret;
2578
2579 ret = config_writer_open_element(writer,
2580 config_element_rotation_schedules);
2581 if (ret) {
2582 goto end;
2583 }
2584 if (session->rotate_timer_period) {
2585 ret = save_session_rotation_schedule(writer,
2586 LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC,
2587 session->rotate_timer_period);
2588 if (ret) {
2589 goto close_schedules;
2590 }
2591 }
2592 if (session->rotate_size) {
2593 ret = save_session_rotation_schedule(writer,
2594 LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD,
2595 session->rotate_size);
2596 if (ret) {
2597 goto close_schedules;
2598 }
2599 }
2600
2601 close_schedules:
2602 /* Close rotation schedules element. */
2603 ret = config_writer_close_element(writer);
2604 if (ret) {
2605 goto end;
2606 }
2607 end:
2608 return ret;
2609 }
2610
2611 /*
2612 * Save the given session.
2613 *
2614 * Return LTTNG_OK on success else a LTTNG_ERR* code.
2615 */
2616 static
2617 int save_session(struct ltt_session *session,
2618 struct lttng_save_session_attr *attr, lttng_sock_cred *creds)
2619 {
2620 int ret, fd = -1;
2621 char config_file_path[LTTNG_PATH_MAX];
2622 size_t len;
2623 struct config_writer *writer = NULL;
2624 size_t session_name_len;
2625 const char *provided_path;
2626 int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC;
2627
2628 assert(session);
2629 assert(attr);
2630 assert(creds);
2631
2632 session_name_len = strlen(session->name);
2633 memset(config_file_path, 0, sizeof(config_file_path));
2634
2635 if (!session_access_ok(session,
2636 LTTNG_SOCK_GET_UID_CRED(creds),
2637 LTTNG_SOCK_GET_GID_CRED(creds)) || session->destroyed) {
2638 ret = LTTNG_ERR_EPERM;
2639 goto end;
2640 }
2641
2642 provided_path = lttng_save_session_attr_get_output_url(attr);
2643 if (provided_path) {
2644 DBG3("Save session in provided path %s", provided_path);
2645 len = strlen(provided_path);
2646 if (len >= sizeof(config_file_path)) {
2647 ret = LTTNG_ERR_SET_URL;
2648 goto end;
2649 }
2650 strncpy(config_file_path, provided_path, sizeof(config_file_path));
2651 } else {
2652 ssize_t ret_len;
2653 char *home_dir = utils_get_user_home_dir(
2654 LTTNG_SOCK_GET_UID_CRED(creds));
2655 if (!home_dir) {
2656 ret = LTTNG_ERR_SET_URL;
2657 goto end;
2658 }
2659
2660 ret_len = snprintf(config_file_path, sizeof(config_file_path),
2661 DEFAULT_SESSION_HOME_CONFIGPATH, home_dir);
2662 free(home_dir);
2663 if (ret_len < 0) {
2664 PERROR("snprintf save session");
2665 ret = LTTNG_ERR_SET_URL;
2666 goto end;
2667 }
2668 len = ret_len;
2669 }
2670
2671 /*
2672 * Check the path fits in the config file path dst including the '/'
2673 * followed by trailing .lttng extension and the NULL terminated string.
2674 */
2675 if ((len + session_name_len + 2 +
2676 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION))
2677 > sizeof(config_file_path)) {
2678 ret = LTTNG_ERR_SET_URL;
2679 goto end;
2680 }
2681
2682 ret = run_as_mkdir_recursive(config_file_path, S_IRWXU | S_IRWXG,
2683 LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds));
2684 if (ret) {
2685 ret = LTTNG_ERR_SET_URL;
2686 goto end;
2687 }
2688
2689 /*
2690 * At this point, we know that everything fits in the buffer. Validation
2691 * was done just above.
2692 */
2693 config_file_path[len++] = '/';
2694 strncpy(config_file_path + len, session->name, sizeof(config_file_path) - len);
2695 len += session_name_len;
2696 strcpy(config_file_path + len, DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
2697 len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
2698 config_file_path[len] = '\0';
2699
2700 if (!attr->overwrite) {
2701 file_open_flags |= O_EXCL;
2702 }
2703
2704 fd = run_as_open(config_file_path, file_open_flags,
2705 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
2706 LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds));
2707 if (fd < 0) {
2708 PERROR("Could not create configuration file");
2709 switch (errno) {
2710 case EEXIST:
2711 ret = LTTNG_ERR_SAVE_FILE_EXIST;
2712 break;
2713 case EACCES:
2714 ret = LTTNG_ERR_EPERM;
2715 break;
2716 default:
2717 ret = LTTNG_ERR_SAVE_IO_FAIL;
2718 break;
2719 }
2720 goto end;
2721 }
2722
2723 writer = config_writer_create(fd, 1);
2724 if (!writer) {
2725 ret = LTTNG_ERR_NOMEM;
2726 goto end;
2727 }
2728
2729 ret = config_writer_open_element(writer, config_element_sessions);
2730 if (ret) {
2731 ret = LTTNG_ERR_SAVE_IO_FAIL;
2732 goto end;
2733 }
2734
2735 ret = config_writer_open_element(writer, config_element_session);
2736 if (ret) {
2737 ret = LTTNG_ERR_SAVE_IO_FAIL;
2738 goto end;
2739 }
2740
2741 ret = config_writer_write_element_string(writer, config_element_name,
2742 session->name);
2743 if (ret) {
2744 ret = LTTNG_ERR_SAVE_IO_FAIL;
2745 goto end;
2746 }
2747
2748 if (session->shm_path[0] != '\0') {
2749 ret = config_writer_write_element_string(writer,
2750 config_element_shared_memory_path,
2751 session->shm_path);
2752 if (ret) {
2753 ret = LTTNG_ERR_SAVE_IO_FAIL;
2754 goto end;
2755 }
2756 }
2757
2758 ret = save_domains(writer, session);
2759 if (ret != LTTNG_OK) {
2760 goto end;
2761 }
2762
2763 ret = config_writer_write_element_bool(writer, config_element_started,
2764 session->active);
2765 if (ret) {
2766 ret = LTTNG_ERR_SAVE_IO_FAIL;
2767 goto end;
2768 }
2769
2770 if (session->snapshot_mode || session->live_timer ||
2771 session->rotate_timer_period || session->rotate_size) {
2772 ret = config_writer_open_element(writer, config_element_attributes);
2773 if (ret) {
2774 ret = LTTNG_ERR_SAVE_IO_FAIL;
2775 goto end;
2776 }
2777
2778 if (session->snapshot_mode) {
2779 ret = config_writer_write_element_bool(writer,
2780 config_element_snapshot_mode, 1);
2781 if (ret) {
2782 ret = LTTNG_ERR_SAVE_IO_FAIL;
2783 goto end;
2784 }
2785 } else if (session->live_timer) {
2786 ret = config_writer_write_element_unsigned_int(writer,
2787 config_element_live_timer_interval, session->live_timer);
2788 if (ret) {
2789 ret = LTTNG_ERR_SAVE_IO_FAIL;
2790 goto end;
2791 }
2792 }
2793 if (session->rotate_timer_period || session->rotate_size) {
2794 ret = save_session_rotation_schedules(writer,
2795 session);
2796 if (ret) {
2797 ret = LTTNG_ERR_SAVE_IO_FAIL;
2798 goto end;
2799 }
2800 }
2801
2802 /* /attributes */
2803 ret = config_writer_close_element(writer);
2804 if (ret) {
2805 ret = LTTNG_ERR_SAVE_IO_FAIL;
2806 goto end;
2807 }
2808 }
2809
2810 ret = save_session_output(writer, session);
2811 if (ret != LTTNG_OK) {
2812 goto end;
2813 }
2814
2815 /* /session */
2816 ret = config_writer_close_element(writer);
2817 if (ret) {
2818 ret = LTTNG_ERR_SAVE_IO_FAIL;
2819 goto end;
2820 }
2821
2822 /* /sessions */
2823 ret = config_writer_close_element(writer);
2824 if (ret) {
2825 ret = LTTNG_ERR_SAVE_IO_FAIL;
2826 goto end;
2827 }
2828
2829 ret = LTTNG_OK;
2830 end:
2831 if (writer && config_writer_destroy(writer)) {
2832 /* Preserve the original error code */
2833 ret = ret != LTTNG_OK ? ret : LTTNG_ERR_SAVE_IO_FAIL;
2834 }
2835 if (ret != LTTNG_OK) {
2836 /* Delete file in case of error */
2837 if ((fd >= 0) && unlink(config_file_path)) {
2838 PERROR("Unlinking XML session configuration.");
2839 }
2840 }
2841
2842 if (fd >= 0) {
2843 int closeret;
2844
2845 closeret = close(fd);
2846 if (closeret) {
2847 PERROR("Closing XML session configuration");
2848 }
2849 }
2850
2851 return ret;
2852 }
2853
2854 int cmd_save_sessions(struct lttng_save_session_attr *attr,
2855 lttng_sock_cred *creds)
2856 {
2857 int ret;
2858 const char *session_name;
2859 struct ltt_session *session;
2860
2861 session_lock_list();
2862
2863 session_name = lttng_save_session_attr_get_session_name(attr);
2864 if (session_name) {
2865 session = session_find_by_name(session_name);
2866 if (!session) {
2867 ret = LTTNG_ERR_SESS_NOT_FOUND;
2868 goto end;
2869 }
2870
2871 session_lock(session);
2872 ret = save_session(session, attr, creds);
2873 session_unlock(session);
2874 session_put(session);
2875 if (ret != LTTNG_OK) {
2876 goto end;
2877 }
2878 } else {
2879 struct ltt_session_list *list = session_get_list();
2880
2881 cds_list_for_each_entry(session, &list->head, list) {
2882 if (!session_get(session)) {
2883 continue;
2884 }
2885 session_lock(session);
2886 ret = save_session(session, attr, creds);
2887 session_unlock(session);
2888 session_put(session);
2889 /* Don't abort if we don't have the required permissions. */
2890 if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) {
2891 goto end;
2892 }
2893 }
2894 }
2895 ret = LTTNG_OK;
2896
2897 end:
2898 session_unlock_list();
2899 return ret;
2900 }
This page took 0.161135 seconds and 4 git commands to generate.