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