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