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