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