Replace explicit rcu_read_lock/unlock with lttng::urcu::read_lock_guard
[lttng-tools.git] / src / bin / lttng-sessiond / save.cpp
1 /*
2 * Copyright (C) 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include "agent.hpp"
10 #include "kernel.hpp"
11 #include "lttng-syscall.hpp"
12 #include "save.hpp"
13 #include "session.hpp"
14 #include "trace-ust.hpp"
15
16 #include <common/config/session-config.hpp>
17 #include <common/defaults.hpp>
18 #include <common/error.hpp>
19 #include <common/runas.hpp>
20 #include <common/urcu.hpp>
21 #include <common/utils.hpp>
22
23 #include <lttng/save-internal.hpp>
24
25 #include <inttypes.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <urcu/uatomic.h>
29
30 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
31 static int save_kernel_channel_attributes(struct config_writer *writer,
32 struct lttng_channel_attr *attr)
33 {
34 int ret;
35
36 ret = config_writer_write_element_string(writer,
37 config_element_overwrite_mode,
38 attr->overwrite ? config_overwrite_mode_overwrite :
39 config_overwrite_mode_discard);
40 if (ret) {
41 ret = LTTNG_ERR_SAVE_IO_FAIL;
42 goto end;
43 }
44
45 ret = config_writer_write_element_unsigned_int(
46 writer, config_element_subbuf_size, attr->subbuf_size);
47 if (ret) {
48 ret = LTTNG_ERR_SAVE_IO_FAIL;
49 goto end;
50 }
51
52 ret = config_writer_write_element_unsigned_int(
53 writer, config_element_num_subbuf, attr->num_subbuf);
54 if (ret) {
55 ret = LTTNG_ERR_SAVE_IO_FAIL;
56 goto end;
57 }
58
59 ret = config_writer_write_element_unsigned_int(
60 writer, config_element_switch_timer_interval, attr->switch_timer_interval);
61 if (ret) {
62 ret = LTTNG_ERR_SAVE_IO_FAIL;
63 goto end;
64 }
65
66 ret = config_writer_write_element_unsigned_int(
67 writer, config_element_read_timer_interval, attr->read_timer_interval);
68 if (ret) {
69 ret = LTTNG_ERR_SAVE_IO_FAIL;
70 goto end;
71 }
72
73 ret = config_writer_write_element_string(writer,
74 config_element_output_type,
75 attr->output == LTTNG_EVENT_SPLICE ?
76 config_output_type_splice :
77 config_output_type_mmap);
78 if (ret) {
79 ret = LTTNG_ERR_SAVE_IO_FAIL;
80 goto end;
81 }
82
83 ret = config_writer_write_element_unsigned_int(
84 writer, config_element_tracefile_size, attr->tracefile_size);
85 if (ret) {
86 ret = LTTNG_ERR_SAVE_IO_FAIL;
87 goto end;
88 }
89
90 ret = config_writer_write_element_unsigned_int(
91 writer, config_element_tracefile_count, attr->tracefile_count);
92 if (ret) {
93 ret = LTTNG_ERR_SAVE_IO_FAIL;
94 goto end;
95 }
96
97 ret = config_writer_write_element_unsigned_int(
98 writer, config_element_live_timer_interval, attr->live_timer_interval);
99 if (ret) {
100 ret = LTTNG_ERR_SAVE_IO_FAIL;
101 goto end;
102 }
103
104 if (attr->extended.ptr) {
105 struct lttng_channel_extended *ext = nullptr;
106
107 ext = (struct lttng_channel_extended *) attr->extended.ptr;
108 ret = config_writer_write_element_unsigned_int(
109 writer, config_element_monitor_timer_interval, ext->monitor_timer_interval);
110 if (ret) {
111 ret = LTTNG_ERR_SAVE_IO_FAIL;
112 goto end;
113 }
114
115 ret = config_writer_write_element_signed_int(
116 writer, config_element_blocking_timeout, ext->blocking_timeout);
117 if (ret) {
118 ret = LTTNG_ERR_SAVE_IO_FAIL;
119 goto end;
120 }
121 }
122
123 ret = LTTNG_OK;
124 end:
125 return ret;
126 }
127
128 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
129 static int save_ust_channel_attributes(struct config_writer *writer,
130 struct lttng_ust_abi_channel_attr *attr)
131 {
132 int ret;
133 struct ltt_ust_channel *channel = nullptr;
134
135 ret = config_writer_write_element_string(writer,
136 config_element_overwrite_mode,
137 attr->overwrite ? config_overwrite_mode_overwrite :
138 config_overwrite_mode_discard);
139 if (ret) {
140 ret = LTTNG_ERR_SAVE_IO_FAIL;
141 goto end;
142 }
143
144 ret = config_writer_write_element_unsigned_int(
145 writer, config_element_subbuf_size, attr->subbuf_size);
146 if (ret) {
147 ret = LTTNG_ERR_SAVE_IO_FAIL;
148 goto end;
149 }
150
151 ret = config_writer_write_element_unsigned_int(
152 writer, config_element_num_subbuf, attr->num_subbuf);
153 if (ret) {
154 ret = LTTNG_ERR_SAVE_IO_FAIL;
155 goto end;
156 }
157
158 ret = config_writer_write_element_unsigned_int(
159 writer, config_element_switch_timer_interval, attr->switch_timer_interval);
160 if (ret) {
161 ret = LTTNG_ERR_SAVE_IO_FAIL;
162 goto end;
163 }
164
165 ret = config_writer_write_element_unsigned_int(
166 writer, config_element_read_timer_interval, attr->read_timer_interval);
167 if (ret) {
168 ret = LTTNG_ERR_SAVE_IO_FAIL;
169 goto end;
170 }
171
172 ret = config_writer_write_element_string(writer,
173 config_element_output_type,
174 attr->output == LTTNG_UST_ABI_MMAP ?
175 config_output_type_mmap :
176 config_output_type_splice);
177 if (ret) {
178 ret = LTTNG_ERR_SAVE_IO_FAIL;
179 goto end;
180 }
181
182 ret = config_writer_write_element_signed_int(
183 writer, config_element_blocking_timeout, attr->u.s.blocking_timeout);
184 if (ret) {
185 ret = LTTNG_ERR_SAVE_IO_FAIL;
186 goto end;
187 }
188
189 /*
190 * Fetch the monitor timer which is located in the parent of
191 * lttng_ust_channel_attr
192 */
193 channel = lttng::utils::container_of(attr, &ltt_ust_channel::attr);
194 ret = config_writer_write_element_unsigned_int(
195 writer, config_element_monitor_timer_interval, channel->monitor_timer_interval);
196 if (ret) {
197 ret = LTTNG_ERR_SAVE_IO_FAIL;
198 goto end;
199 }
200
201 ret = LTTNG_OK;
202 end:
203 return ret;
204 }
205
206 static const char *
207 get_kernel_instrumentation_string(enum lttng_kernel_abi_instrumentation instrumentation)
208 {
209 const char *instrumentation_string;
210
211 switch (instrumentation) {
212 case LTTNG_KERNEL_ABI_ALL:
213 instrumentation_string = config_event_type_all;
214 break;
215 case LTTNG_KERNEL_ABI_TRACEPOINT:
216 instrumentation_string = config_event_type_tracepoint;
217 break;
218 case LTTNG_KERNEL_ABI_KPROBE:
219 instrumentation_string = config_event_type_probe;
220 break;
221 case LTTNG_KERNEL_ABI_UPROBE:
222 instrumentation_string = config_event_type_userspace_probe;
223 break;
224 case LTTNG_KERNEL_ABI_FUNCTION:
225 instrumentation_string = config_event_type_function_entry;
226 break;
227 case LTTNG_KERNEL_ABI_KRETPROBE:
228 instrumentation_string = config_event_type_function;
229 break;
230 case LTTNG_KERNEL_ABI_NOOP:
231 instrumentation_string = config_event_type_noop;
232 break;
233 case LTTNG_KERNEL_ABI_SYSCALL:
234 instrumentation_string = config_event_type_syscall;
235 break;
236 default:
237 instrumentation_string = nullptr;
238 }
239
240 return instrumentation_string;
241 }
242
243 static const char *get_kernel_context_type_string(enum lttng_kernel_abi_context_type context_type)
244 {
245 const char *context_type_string;
246
247 switch (context_type) {
248 case LTTNG_KERNEL_ABI_CONTEXT_PID:
249 context_type_string = config_event_context_pid;
250 break;
251 case LTTNG_KERNEL_ABI_CONTEXT_PROCNAME:
252 context_type_string = config_event_context_procname;
253 break;
254 case LTTNG_KERNEL_ABI_CONTEXT_PRIO:
255 context_type_string = config_event_context_prio;
256 break;
257 case LTTNG_KERNEL_ABI_CONTEXT_NICE:
258 context_type_string = config_event_context_nice;
259 break;
260 case LTTNG_KERNEL_ABI_CONTEXT_VPID:
261 context_type_string = config_event_context_vpid;
262 break;
263 case LTTNG_KERNEL_ABI_CONTEXT_TID:
264 context_type_string = config_event_context_tid;
265 break;
266 case LTTNG_KERNEL_ABI_CONTEXT_VTID:
267 context_type_string = config_event_context_vtid;
268 break;
269 case LTTNG_KERNEL_ABI_CONTEXT_PPID:
270 context_type_string = config_event_context_ppid;
271 break;
272 case LTTNG_KERNEL_ABI_CONTEXT_VPPID:
273 context_type_string = config_event_context_vppid;
274 break;
275 case LTTNG_KERNEL_ABI_CONTEXT_HOSTNAME:
276 context_type_string = config_event_context_hostname;
277 break;
278 case LTTNG_KERNEL_ABI_CONTEXT_INTERRUPTIBLE:
279 context_type_string = config_event_context_interruptible;
280 break;
281 case LTTNG_KERNEL_ABI_CONTEXT_PREEMPTIBLE:
282 context_type_string = config_event_context_preemptible;
283 break;
284 case LTTNG_KERNEL_ABI_CONTEXT_NEED_RESCHEDULE:
285 context_type_string = config_event_context_need_reschedule;
286 break;
287 case LTTNG_KERNEL_ABI_CONTEXT_MIGRATABLE:
288 context_type_string = config_event_context_migratable;
289 break;
290 case LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_USER:
291 context_type_string = config_event_context_callstack_user;
292 break;
293 case LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_KERNEL:
294 context_type_string = config_event_context_callstack_kernel;
295 break;
296 case LTTNG_KERNEL_ABI_CONTEXT_CGROUP_NS:
297 context_type_string = config_event_context_cgroup_ns;
298 break;
299 case LTTNG_KERNEL_ABI_CONTEXT_IPC_NS:
300 context_type_string = config_event_context_ipc_ns;
301 break;
302 case LTTNG_KERNEL_ABI_CONTEXT_MNT_NS:
303 context_type_string = config_event_context_mnt_ns;
304 break;
305 case LTTNG_KERNEL_ABI_CONTEXT_NET_NS:
306 context_type_string = config_event_context_net_ns;
307 break;
308 case LTTNG_KERNEL_ABI_CONTEXT_PID_NS:
309 context_type_string = config_event_context_pid_ns;
310 break;
311 case LTTNG_KERNEL_ABI_CONTEXT_TIME_NS:
312 context_type_string = config_event_context_time_ns;
313 break;
314 case LTTNG_KERNEL_ABI_CONTEXT_USER_NS:
315 context_type_string = config_event_context_user_ns;
316 break;
317 case LTTNG_KERNEL_ABI_CONTEXT_UTS_NS:
318 context_type_string = config_event_context_uts_ns;
319 break;
320 case LTTNG_KERNEL_ABI_CONTEXT_UID:
321 context_type_string = config_event_context_uid;
322 break;
323 case LTTNG_KERNEL_ABI_CONTEXT_EUID:
324 context_type_string = config_event_context_euid;
325 break;
326 case LTTNG_KERNEL_ABI_CONTEXT_SUID:
327 context_type_string = config_event_context_suid;
328 break;
329 case LTTNG_KERNEL_ABI_CONTEXT_GID:
330 context_type_string = config_event_context_gid;
331 break;
332 case LTTNG_KERNEL_ABI_CONTEXT_EGID:
333 context_type_string = config_event_context_egid;
334 break;
335 case LTTNG_KERNEL_ABI_CONTEXT_SGID:
336 context_type_string = config_event_context_sgid;
337 break;
338 case LTTNG_KERNEL_ABI_CONTEXT_VUID:
339 context_type_string = config_event_context_vuid;
340 break;
341 case LTTNG_KERNEL_ABI_CONTEXT_VEUID:
342 context_type_string = config_event_context_veuid;
343 break;
344 case LTTNG_KERNEL_ABI_CONTEXT_VSUID:
345 context_type_string = config_event_context_vsuid;
346 break;
347 case LTTNG_KERNEL_ABI_CONTEXT_VGID:
348 context_type_string = config_event_context_vgid;
349 break;
350 case LTTNG_KERNEL_ABI_CONTEXT_VEGID:
351 context_type_string = config_event_context_vegid;
352 break;
353 case LTTNG_KERNEL_ABI_CONTEXT_VSGID:
354 context_type_string = config_event_context_vsgid;
355 break;
356 default:
357 context_type_string = nullptr;
358 }
359
360 return context_type_string;
361 }
362
363 static const char *get_ust_context_type_string(enum lttng_ust_abi_context_type context_type)
364 {
365 const char *context_type_string;
366
367 switch (context_type) {
368 case LTTNG_UST_ABI_CONTEXT_PROCNAME:
369 context_type_string = config_event_context_procname;
370 break;
371 case LTTNG_UST_ABI_CONTEXT_VPID:
372 context_type_string = config_event_context_vpid;
373 break;
374 case LTTNG_UST_ABI_CONTEXT_VTID:
375 context_type_string = config_event_context_vtid;
376 break;
377 case LTTNG_UST_ABI_CONTEXT_IP:
378 context_type_string = config_event_context_ip;
379 break;
380 case LTTNG_UST_ABI_CONTEXT_PTHREAD_ID:
381 context_type_string = config_event_context_pthread_id;
382 break;
383 case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
384 context_type_string = config_event_context_app;
385 break;
386 case LTTNG_UST_ABI_CONTEXT_CGROUP_NS:
387 context_type_string = config_event_context_cgroup_ns;
388 break;
389 case LTTNG_UST_ABI_CONTEXT_IPC_NS:
390 context_type_string = config_event_context_ipc_ns;
391 break;
392 case LTTNG_UST_ABI_CONTEXT_MNT_NS:
393 context_type_string = config_event_context_mnt_ns;
394 break;
395 case LTTNG_UST_ABI_CONTEXT_NET_NS:
396 context_type_string = config_event_context_net_ns;
397 break;
398 case LTTNG_UST_ABI_CONTEXT_TIME_NS:
399 context_type_string = config_event_context_time_ns;
400 break;
401 case LTTNG_UST_ABI_CONTEXT_PID_NS:
402 context_type_string = config_event_context_pid_ns;
403 break;
404 case LTTNG_UST_ABI_CONTEXT_USER_NS:
405 context_type_string = config_event_context_user_ns;
406 break;
407 case LTTNG_UST_ABI_CONTEXT_UTS_NS:
408 context_type_string = config_event_context_uts_ns;
409 break;
410 case LTTNG_UST_ABI_CONTEXT_VUID:
411 context_type_string = config_event_context_vuid;
412 break;
413 case LTTNG_UST_ABI_CONTEXT_VEUID:
414 context_type_string = config_event_context_veuid;
415 break;
416 case LTTNG_UST_ABI_CONTEXT_VSUID:
417 context_type_string = config_event_context_vsuid;
418 break;
419 case LTTNG_UST_ABI_CONTEXT_VGID:
420 context_type_string = config_event_context_vgid;
421 break;
422 case LTTNG_UST_ABI_CONTEXT_VEGID:
423 context_type_string = config_event_context_vegid;
424 break;
425 case LTTNG_UST_ABI_CONTEXT_VSGID:
426 context_type_string = config_event_context_vsgid;
427 break;
428 case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
429 /*
430 * Error, should not be stored in the XML, perf contexts
431 * are stored as a node of type event_perf_context_type.
432 */
433 default:
434 context_type_string = nullptr;
435 break;
436 }
437
438 return context_type_string;
439 }
440
441 static const char *get_buffer_type_string(enum lttng_buffer_type buffer_type)
442 {
443 const char *buffer_type_string;
444
445 switch (buffer_type) {
446 case LTTNG_BUFFER_PER_PID:
447 buffer_type_string = config_buffer_type_per_pid;
448 break;
449 case LTTNG_BUFFER_PER_UID:
450 buffer_type_string = config_buffer_type_per_uid;
451 break;
452 case LTTNG_BUFFER_GLOBAL:
453 buffer_type_string = config_buffer_type_global;
454 break;
455 default:
456 buffer_type_string = nullptr;
457 }
458
459 return buffer_type_string;
460 }
461
462 static const char *get_loglevel_type_string(enum lttng_ust_abi_loglevel_type loglevel_type)
463 {
464 const char *loglevel_type_string;
465
466 switch (loglevel_type) {
467 case LTTNG_UST_ABI_LOGLEVEL_ALL:
468 loglevel_type_string = config_loglevel_type_all;
469 break;
470 case LTTNG_UST_ABI_LOGLEVEL_RANGE:
471 loglevel_type_string = config_loglevel_type_range;
472 break;
473 case LTTNG_UST_ABI_LOGLEVEL_SINGLE:
474 loglevel_type_string = config_loglevel_type_single;
475 break;
476 default:
477 loglevel_type_string = nullptr;
478 }
479
480 return loglevel_type_string;
481 }
482
483 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
484 static int save_kernel_function_event(struct config_writer *writer, struct ltt_kernel_event *event)
485 {
486 int ret;
487
488 ret = config_writer_open_element(writer, config_element_function_attributes);
489 if (ret) {
490 ret = LTTNG_ERR_SAVE_IO_FAIL;
491 goto end;
492 }
493
494 ret = config_writer_write_element_string(
495 writer, config_element_name, event->event->u.ftrace.symbol_name);
496 if (ret) {
497 ret = LTTNG_ERR_SAVE_IO_FAIL;
498 goto end;
499 }
500
501 /* /function attributes */
502 ret = config_writer_close_element(writer);
503 if (ret) {
504 ret = LTTNG_ERR_SAVE_IO_FAIL;
505 goto end;
506 }
507 end:
508 return ret;
509 }
510
511 static int save_kernel_kprobe_event(struct config_writer *writer, struct ltt_kernel_event *event)
512 {
513 int ret;
514 const char *symbol_name;
515 uint64_t addr;
516 uint64_t offset;
517
518 switch (event->event->instrumentation) {
519 case LTTNG_KERNEL_ABI_KPROBE:
520 /*
521 * Comments in lttng-kernel.h mention that
522 * either addr or symbol_name are set, not both.
523 */
524 addr = event->event->u.kprobe.addr;
525 offset = event->event->u.kprobe.offset;
526 symbol_name = addr ? nullptr : event->event->u.kprobe.symbol_name;
527 break;
528 case LTTNG_KERNEL_ABI_KRETPROBE:
529 addr = event->event->u.kretprobe.addr;
530 offset = event->event->u.kretprobe.offset;
531 symbol_name = addr ? nullptr : event->event->u.kretprobe.symbol_name;
532 break;
533 default:
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 {
1110 lttng::urcu::read_lock_guard read_lock;
1111
1112 cds_lfht_for_each_entry (events->ht, &iter.iter, node, node) {
1113 event = lttng::utils::container_of(node, &ltt_ust_event::node);
1114
1115 if (event->internal) {
1116 /* Internal events must not be exposed to clients */
1117 continue;
1118 }
1119 ret = save_ust_event(writer, event);
1120 if (ret != LTTNG_OK) {
1121 goto end;
1122 }
1123 }
1124 }
1125
1126 /* /events */
1127 ret = config_writer_close_element(writer);
1128 if (ret) {
1129 ret = LTTNG_ERR_SAVE_IO_FAIL;
1130 goto end;
1131 }
1132
1133 ret = LTTNG_OK;
1134 end:
1135 return ret;
1136 }
1137
1138 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1139 static int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event,
1140 struct agent_event *agent_event)
1141 {
1142 int ret;
1143 enum lttng_ust_abi_loglevel_type ust_loglevel_type;
1144
1145 ust_event->enabled = AGENT_EVENT_IS_ENABLED(agent_event);
1146 ust_event->attr.instrumentation = LTTNG_UST_ABI_TRACEPOINT;
1147 if (lttng_strncpy(ust_event->attr.name, agent_event->name, LTTNG_SYMBOL_NAME_LEN)) {
1148 ret = LTTNG_ERR_INVALID;
1149 goto end;
1150 }
1151 switch (agent_event->loglevel_type) {
1152 case LTTNG_EVENT_LOGLEVEL_ALL:
1153 ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL;
1154 break;
1155 case LTTNG_EVENT_LOGLEVEL_SINGLE:
1156 ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_SINGLE;
1157 break;
1158 case LTTNG_EVENT_LOGLEVEL_RANGE:
1159 ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_RANGE;
1160 break;
1161 default:
1162 ERR("Invalid agent_event loglevel_type.");
1163 ret = LTTNG_ERR_INVALID;
1164 goto end;
1165 }
1166
1167 ust_event->attr.loglevel_type = ust_loglevel_type;
1168 ust_event->attr.loglevel = agent_event->loglevel_value;
1169 ust_event->filter_expression = agent_event->filter_expression;
1170 ust_event->exclusion = agent_event->exclusion;
1171
1172 ret = LTTNG_OK;
1173 end:
1174 return ret;
1175 }
1176
1177 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1178 static int save_agent_events(struct config_writer *writer, struct agent *agent)
1179 {
1180 int ret;
1181 struct lttng_ht_iter iter;
1182 struct lttng_ht_node_str *node;
1183
1184 ret = config_writer_open_element(writer, config_element_events);
1185 if (ret) {
1186 ret = LTTNG_ERR_SAVE_IO_FAIL;
1187 goto end;
1188 }
1189
1190 {
1191 lttng::urcu::read_lock_guard read_lock;
1192
1193 cds_lfht_for_each_entry (agent->events->ht, &iter.iter, node, node) {
1194 struct agent_event *agent_event;
1195 struct ltt_ust_event fake_event;
1196
1197 memset(&fake_event, 0, sizeof(fake_event));
1198 agent_event = lttng::utils::container_of(node, &agent_event::node);
1199
1200 /*
1201 * Initialize a fake ust event to reuse the same serialization
1202 * function since UST and agent events contain the same info
1203 * (and one could wonder why they don't reuse the same
1204 * structures...).
1205 */
1206 ret = init_ust_event_from_agent_event(&fake_event, agent_event);
1207 if (ret != LTTNG_OK) {
1208 goto end;
1209 }
1210 ret = save_ust_event(writer, &fake_event);
1211 if (ret != LTTNG_OK) {
1212 goto end;
1213 }
1214 }
1215 }
1216
1217 /* /events */
1218 ret = config_writer_close_element(writer);
1219 if (ret) {
1220 ret = LTTNG_ERR_SAVE_IO_FAIL;
1221 goto end;
1222 }
1223
1224 ret = LTTNG_OK;
1225 end:
1226 return ret;
1227 }
1228
1229 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1230 static int save_kernel_context(struct config_writer *writer, struct lttng_kernel_abi_context *ctx)
1231 {
1232 int ret = LTTNG_OK;
1233
1234 if (!ctx) {
1235 goto end;
1236 }
1237
1238 ret = config_writer_open_element(writer, config_element_context);
1239 if (ret) {
1240 ret = LTTNG_ERR_SAVE_IO_FAIL;
1241 goto end;
1242 }
1243
1244 if (ctx->ctx == LTTNG_KERNEL_ABI_CONTEXT_PERF_CPU_COUNTER) {
1245 ret = config_writer_open_element(writer, config_element_context_perf);
1246 if (ret) {
1247 ret = LTTNG_ERR_SAVE_IO_FAIL;
1248 goto end;
1249 }
1250
1251 ret = config_writer_write_element_unsigned_int(
1252 writer, config_element_type, ctx->u.perf_counter.type);
1253 if (ret) {
1254 ret = LTTNG_ERR_SAVE_IO_FAIL;
1255 goto end;
1256 }
1257
1258 ret = config_writer_write_element_unsigned_int(
1259 writer, config_element_config, ctx->u.perf_counter.config);
1260 if (ret) {
1261 ret = LTTNG_ERR_SAVE_IO_FAIL;
1262 goto end;
1263 }
1264
1265 ret = config_writer_write_element_string(
1266 writer, config_element_name, ctx->u.perf_counter.name);
1267 if (ret) {
1268 ret = LTTNG_ERR_SAVE_IO_FAIL;
1269 goto end;
1270 }
1271
1272 /* /perf */
1273 ret = config_writer_close_element(writer);
1274 if (ret) {
1275 ret = LTTNG_ERR_SAVE_IO_FAIL;
1276 goto end;
1277 }
1278 } else {
1279 const char *context_type_string = get_kernel_context_type_string(ctx->ctx);
1280
1281 if (!context_type_string) {
1282 ERR("Unsupported kernel context type.");
1283 ret = LTTNG_ERR_INVALID;
1284 goto end;
1285 }
1286
1287 ret = config_writer_write_element_string(
1288 writer, config_element_type, context_type_string);
1289 if (ret) {
1290 ret = LTTNG_ERR_SAVE_IO_FAIL;
1291 goto end;
1292 }
1293 }
1294
1295 /* /context */
1296 ret = config_writer_close_element(writer);
1297 if (ret) {
1298 ret = LTTNG_ERR_SAVE_IO_FAIL;
1299 goto end;
1300 }
1301
1302 ret = LTTNG_OK;
1303 end:
1304 return ret;
1305 }
1306
1307 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1308 static int save_kernel_contexts(struct config_writer *writer, struct ltt_kernel_channel *kchan)
1309 {
1310 int ret;
1311 struct ltt_kernel_context *ctx;
1312
1313 if (cds_list_empty(&kchan->ctx_list)) {
1314 ret = LTTNG_OK;
1315 goto end;
1316 }
1317
1318 ret = config_writer_open_element(writer, config_element_contexts);
1319 if (ret) {
1320 ret = LTTNG_ERR_SAVE_IO_FAIL;
1321 goto end;
1322 }
1323
1324 cds_list_for_each_entry (ctx, &kchan->ctx_list, list) {
1325 ret = save_kernel_context(writer, &ctx->ctx);
1326 if (ret != LTTNG_OK) {
1327 goto end;
1328 }
1329 }
1330
1331 /* /contexts */
1332 ret = config_writer_close_element(writer);
1333 if (ret) {
1334 ret = LTTNG_ERR_SAVE_IO_FAIL;
1335 goto end;
1336 }
1337
1338 ret = LTTNG_OK;
1339 end:
1340 return ret;
1341 }
1342
1343 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1344 static int save_ust_context_perf_thread_counter(struct config_writer *writer,
1345 struct ltt_ust_context *ctx)
1346 {
1347 int ret;
1348
1349 LTTNG_ASSERT(writer);
1350 LTTNG_ASSERT(ctx);
1351
1352 /* Perf contexts are saved as event_perf_context_type */
1353 ret = config_writer_open_element(writer, config_element_context_perf);
1354 if (ret) {
1355 ret = LTTNG_ERR_SAVE_IO_FAIL;
1356 goto end;
1357 }
1358
1359 ret = config_writer_write_element_unsigned_int(
1360 writer, config_element_type, ctx->ctx.u.perf_counter.type);
1361 if (ret) {
1362 ret = LTTNG_ERR_SAVE_IO_FAIL;
1363 goto end;
1364 }
1365
1366 ret = config_writer_write_element_unsigned_int(
1367 writer, config_element_config, ctx->ctx.u.perf_counter.config);
1368 if (ret) {
1369 ret = LTTNG_ERR_SAVE_IO_FAIL;
1370 goto end;
1371 }
1372
1373 ret = config_writer_write_element_string(
1374 writer, config_element_name, ctx->ctx.u.perf_counter.name);
1375 if (ret) {
1376 ret = LTTNG_ERR_SAVE_IO_FAIL;
1377 goto end;
1378 }
1379
1380 /* /perf */
1381 ret = config_writer_close_element(writer);
1382 if (ret) {
1383 ret = LTTNG_ERR_SAVE_IO_FAIL;
1384 goto end;
1385 }
1386
1387 ret = LTTNG_OK;
1388 end:
1389 return ret;
1390 }
1391
1392 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1393 static int save_ust_context_app_ctx(struct config_writer *writer, struct ltt_ust_context *ctx)
1394 {
1395 int ret;
1396
1397 LTTNG_ASSERT(writer);
1398 LTTNG_ASSERT(ctx);
1399
1400 /* Application contexts are saved as application_context_type */
1401 ret = config_writer_open_element(writer, config_element_context_app);
1402 if (ret) {
1403 ret = LTTNG_ERR_SAVE_IO_FAIL;
1404 goto end;
1405 }
1406
1407 ret = config_writer_write_element_string(
1408 writer, config_element_context_app_provider_name, ctx->ctx.u.app_ctx.provider_name);
1409 if (ret) {
1410 ret = LTTNG_ERR_SAVE_IO_FAIL;
1411 goto end;
1412 }
1413
1414 ret = config_writer_write_element_string(
1415 writer, config_element_context_app_ctx_name, ctx->ctx.u.app_ctx.ctx_name);
1416 if (ret) {
1417 ret = LTTNG_ERR_SAVE_IO_FAIL;
1418 goto end;
1419 }
1420
1421 /* /app */
1422 ret = config_writer_close_element(writer);
1423 if (ret) {
1424 ret = LTTNG_ERR_SAVE_IO_FAIL;
1425 goto end;
1426 }
1427
1428 ret = LTTNG_OK;
1429 end:
1430 return ret;
1431 }
1432
1433 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1434 static int save_ust_context_generic(struct config_writer *writer, struct ltt_ust_context *ctx)
1435 {
1436 int ret;
1437 const char *context_type_string;
1438
1439 LTTNG_ASSERT(writer);
1440 LTTNG_ASSERT(ctx);
1441
1442 /* Save context as event_context_type_type */
1443 context_type_string = get_ust_context_type_string(ctx->ctx.ctx);
1444 if (!context_type_string) {
1445 ERR("Unsupported UST context type.");
1446 ret = LTTNG_ERR_SAVE_IO_FAIL;
1447 goto end;
1448 }
1449
1450 ret = config_writer_write_element_string(writer, config_element_type, context_type_string);
1451 if (ret) {
1452 ret = LTTNG_ERR_SAVE_IO_FAIL;
1453 goto end;
1454 }
1455
1456 ret = LTTNG_OK;
1457 end:
1458 return ret;
1459 }
1460
1461 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1462 static int save_ust_context(struct config_writer *writer, struct cds_list_head *ctx_list)
1463 {
1464 int ret;
1465 struct ltt_ust_context *ctx;
1466
1467 LTTNG_ASSERT(writer);
1468 LTTNG_ASSERT(ctx_list);
1469
1470 ret = config_writer_open_element(writer, config_element_contexts);
1471 if (ret) {
1472 ret = LTTNG_ERR_SAVE_IO_FAIL;
1473 goto end;
1474 }
1475
1476 cds_list_for_each_entry (ctx, ctx_list, list) {
1477 ret = config_writer_open_element(writer, config_element_context);
1478 if (ret) {
1479 ret = LTTNG_ERR_SAVE_IO_FAIL;
1480 goto end;
1481 }
1482
1483 switch (ctx->ctx.ctx) {
1484 case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
1485 ret = save_ust_context_perf_thread_counter(writer, ctx);
1486 break;
1487 case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
1488 ret = save_ust_context_app_ctx(writer, ctx);
1489 break;
1490 default:
1491 /* Save generic context. */
1492 ret = save_ust_context_generic(writer, ctx);
1493 }
1494 if (ret != LTTNG_OK) {
1495 goto end;
1496 }
1497
1498 /* /context */
1499 ret = config_writer_close_element(writer);
1500 if (ret) {
1501 ret = LTTNG_ERR_SAVE_IO_FAIL;
1502 goto end;
1503 }
1504 }
1505
1506 /* /contexts */
1507 ret = config_writer_close_element(writer);
1508 if (ret) {
1509 ret = LTTNG_ERR_SAVE_IO_FAIL;
1510 goto end;
1511 }
1512
1513 ret = LTTNG_OK;
1514 end:
1515 return ret;
1516 }
1517
1518 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1519 static int save_kernel_channel(struct config_writer *writer, struct ltt_kernel_channel *kchan)
1520 {
1521 int ret;
1522
1523 LTTNG_ASSERT(writer);
1524 LTTNG_ASSERT(kchan);
1525
1526 ret = config_writer_open_element(writer, config_element_channel);
1527 if (ret) {
1528 ret = LTTNG_ERR_SAVE_IO_FAIL;
1529 goto end;
1530 }
1531
1532 ret = config_writer_write_element_string(writer, config_element_name, kchan->channel->name);
1533 if (ret) {
1534 ret = LTTNG_ERR_SAVE_IO_FAIL;
1535 goto end;
1536 }
1537
1538 ret = config_writer_write_element_bool(
1539 writer, config_element_enabled, kchan->channel->enabled);
1540 if (ret) {
1541 ret = LTTNG_ERR_SAVE_IO_FAIL;
1542 goto end;
1543 }
1544
1545 ret = save_kernel_channel_attributes(writer, &kchan->channel->attr);
1546 if (ret != LTTNG_OK) {
1547 goto end;
1548 }
1549
1550 ret = save_kernel_events(writer, kchan);
1551 if (ret != LTTNG_OK) {
1552 goto end;
1553 }
1554
1555 ret = save_kernel_contexts(writer, kchan);
1556 if (ret != LTTNG_OK) {
1557 goto end;
1558 }
1559
1560 /* /channel */
1561 ret = config_writer_close_element(writer);
1562 if (ret) {
1563 ret = LTTNG_ERR_SAVE_IO_FAIL;
1564 goto end;
1565 }
1566
1567 ret = LTTNG_OK;
1568 end:
1569 return ret;
1570 }
1571
1572 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1573 static int save_ust_channel(struct config_writer *writer,
1574 struct ltt_ust_channel *ust_chan,
1575 struct ltt_ust_session *session)
1576 {
1577 int ret;
1578
1579 LTTNG_ASSERT(writer);
1580 LTTNG_ASSERT(ust_chan);
1581 LTTNG_ASSERT(session);
1582
1583 ret = config_writer_open_element(writer, config_element_channel);
1584 if (ret) {
1585 ret = LTTNG_ERR_SAVE_IO_FAIL;
1586 goto end;
1587 }
1588
1589 ret = config_writer_write_element_string(writer, config_element_name, ust_chan->name);
1590 if (ret) {
1591 ret = LTTNG_ERR_SAVE_IO_FAIL;
1592 goto end;
1593 }
1594
1595 ret = config_writer_write_element_bool(writer, config_element_enabled, ust_chan->enabled);
1596 if (ret) {
1597 ret = LTTNG_ERR_SAVE_IO_FAIL;
1598 goto end;
1599 }
1600
1601 ret = save_ust_channel_attributes(writer, &ust_chan->attr);
1602 if (ret != LTTNG_OK) {
1603 goto end;
1604 }
1605
1606 ret = config_writer_write_element_unsigned_int(
1607 writer, config_element_tracefile_size, ust_chan->tracefile_size);
1608 if (ret) {
1609 ret = LTTNG_ERR_SAVE_IO_FAIL;
1610 goto end;
1611 }
1612
1613 ret = config_writer_write_element_unsigned_int(
1614 writer, config_element_tracefile_count, ust_chan->tracefile_count);
1615 if (ret) {
1616 ret = LTTNG_ERR_SAVE_IO_FAIL;
1617 goto end;
1618 }
1619
1620 ret = config_writer_write_element_unsigned_int(
1621 writer, config_element_live_timer_interval, session->live_timer_interval);
1622 if (ret) {
1623 ret = LTTNG_ERR_SAVE_IO_FAIL;
1624 goto end;
1625 }
1626
1627 if (ust_chan->domain == LTTNG_DOMAIN_UST) {
1628 ret = save_ust_events(writer, ust_chan->events);
1629 if (ret != LTTNG_OK) {
1630 goto end;
1631 }
1632 } else {
1633 struct agent *agent = nullptr;
1634
1635 agent = trace_ust_find_agent(session, ust_chan->domain);
1636 if (!agent) {
1637 ret = LTTNG_ERR_SAVE_IO_FAIL;
1638 ERR("Could not find agent associated to UST subdomain");
1639 goto end;
1640 }
1641
1642 /*
1643 * Channels associated with a UST sub-domain (such as JUL, Log4j
1644 * or Python) don't have any non-internal events. We retrieve
1645 * the "agent" events associated with this channel and serialize
1646 * them.
1647 */
1648 ret = save_agent_events(writer, agent);
1649 if (ret != LTTNG_OK) {
1650 goto end;
1651 }
1652 }
1653
1654 ret = save_ust_context(writer, &ust_chan->ctx_list);
1655 if (ret != LTTNG_OK) {
1656 goto end;
1657 }
1658
1659 /* /channel */
1660 ret = config_writer_close_element(writer);
1661 if (ret) {
1662 ret = LTTNG_ERR_SAVE_IO_FAIL;
1663 goto end;
1664 }
1665
1666 ret = LTTNG_OK;
1667 end:
1668 return ret;
1669 }
1670
1671 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1672 static int save_kernel_session(struct config_writer *writer, struct ltt_session *session)
1673 {
1674 int ret;
1675 struct ltt_kernel_channel *kchan;
1676
1677 LTTNG_ASSERT(writer);
1678 LTTNG_ASSERT(session);
1679
1680 ret = config_writer_write_element_string(
1681 writer, config_element_type, config_domain_type_kernel);
1682 if (ret) {
1683 ret = LTTNG_ERR_SAVE_IO_FAIL;
1684 goto end;
1685 }
1686
1687 ret = config_writer_write_element_string(
1688 writer, config_element_buffer_type, config_buffer_type_global);
1689 if (ret) {
1690 ret = LTTNG_ERR_SAVE_IO_FAIL;
1691 goto end;
1692 }
1693
1694 ret = config_writer_open_element(writer, config_element_channels);
1695 if (ret) {
1696 ret = LTTNG_ERR_SAVE_IO_FAIL;
1697 goto end;
1698 }
1699
1700 cds_list_for_each_entry (kchan, &session->kernel_session->channel_list.head, list) {
1701 ret = save_kernel_channel(writer, kchan);
1702 if (ret != LTTNG_OK) {
1703 goto end;
1704 }
1705 }
1706
1707 /* /channels */
1708 ret = config_writer_close_element(writer);
1709 if (ret) {
1710 ret = LTTNG_ERR_SAVE_IO_FAIL;
1711 goto end;
1712 }
1713
1714 ret = LTTNG_OK;
1715 end:
1716 return ret;
1717 }
1718
1719 static const char *get_config_domain_str(enum lttng_domain_type domain)
1720 {
1721 const char *str_dom;
1722
1723 switch (domain) {
1724 case LTTNG_DOMAIN_KERNEL:
1725 str_dom = config_domain_type_kernel;
1726 break;
1727 case LTTNG_DOMAIN_UST:
1728 str_dom = config_domain_type_ust;
1729 break;
1730 case LTTNG_DOMAIN_JUL:
1731 str_dom = config_domain_type_jul;
1732 break;
1733 case LTTNG_DOMAIN_LOG4J:
1734 str_dom = config_domain_type_log4j;
1735 break;
1736 case LTTNG_DOMAIN_PYTHON:
1737 str_dom = config_domain_type_python;
1738 break;
1739 default:
1740 abort();
1741 }
1742
1743 return str_dom;
1744 }
1745
1746 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1747 static int save_process_attr_tracker(struct config_writer *writer,
1748 struct ltt_session *sess,
1749 int domain,
1750 enum lttng_process_attr process_attr)
1751 {
1752 int ret = LTTNG_OK;
1753 const char *element_id_tracker, *element_target_id, *element_id;
1754 const struct process_attr_tracker *tracker;
1755 enum lttng_tracking_policy tracking_policy;
1756 struct lttng_process_attr_values *values = nullptr;
1757
1758 switch (process_attr) {
1759 case LTTNG_PROCESS_ATTR_PROCESS_ID:
1760 element_id_tracker = config_element_process_attr_tracker_pid;
1761 element_target_id = config_element_process_attr_pid_value;
1762 element_id = config_element_process_attr_id;
1763 break;
1764 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1765 element_id_tracker = config_element_process_attr_tracker_vpid;
1766 element_target_id = config_element_process_attr_vpid_value;
1767 element_id = config_element_process_attr_id;
1768 break;
1769 case LTTNG_PROCESS_ATTR_USER_ID:
1770 element_id_tracker = config_element_process_attr_tracker_uid;
1771 element_target_id = config_element_process_attr_uid_value;
1772 element_id = config_element_process_attr_id;
1773 break;
1774 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
1775 element_id_tracker = config_element_process_attr_tracker_vuid;
1776 element_target_id = config_element_process_attr_vuid_value;
1777 element_id = config_element_process_attr_id;
1778 break;
1779 case LTTNG_PROCESS_ATTR_GROUP_ID:
1780 element_id_tracker = config_element_process_attr_tracker_gid;
1781 element_target_id = config_element_process_attr_gid_value;
1782 element_id = config_element_process_attr_id;
1783 break;
1784 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
1785 element_id_tracker = config_element_process_attr_tracker_vgid;
1786 element_target_id = config_element_process_attr_vgid_value;
1787 element_id = config_element_process_attr_id;
1788 break;
1789 default:
1790 ret = LTTNG_ERR_SAVE_IO_FAIL;
1791 goto end;
1792 }
1793
1794 switch (domain) {
1795 case LTTNG_DOMAIN_KERNEL:
1796 {
1797 tracker = kernel_get_process_attr_tracker(sess->kernel_session, process_attr);
1798 LTTNG_ASSERT(tracker);
1799 break;
1800 }
1801 case LTTNG_DOMAIN_UST:
1802 {
1803 tracker = trace_ust_get_process_attr_tracker(sess->ust_session, process_attr);
1804 LTTNG_ASSERT(tracker);
1805 break;
1806 }
1807 case LTTNG_DOMAIN_JUL:
1808 case LTTNG_DOMAIN_LOG4J:
1809 case LTTNG_DOMAIN_PYTHON:
1810 default:
1811 ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
1812 goto end;
1813 }
1814
1815 tracking_policy = process_attr_tracker_get_tracking_policy(tracker);
1816 if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_ALL) {
1817 /* Tracking all, nothing to output. */
1818 ret = LTTNG_OK;
1819 goto end;
1820 }
1821
1822 ret = config_writer_open_element(writer, element_id_tracker);
1823 if (ret) {
1824 ret = LTTNG_ERR_SAVE_IO_FAIL;
1825 goto end;
1826 }
1827
1828 ret = config_writer_open_element(writer, config_element_process_attr_values);
1829 if (ret) {
1830 ret = LTTNG_ERR_SAVE_IO_FAIL;
1831 goto end;
1832 }
1833
1834 if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_SET) {
1835 unsigned int i, count;
1836 enum process_attr_tracker_status status =
1837 process_attr_tracker_get_inclusion_set(tracker, &values);
1838
1839 if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
1840 ret = LTTNG_ERR_NOMEM;
1841 goto end;
1842 }
1843
1844 count = _lttng_process_attr_values_get_count(values);
1845
1846 for (i = 0; i < count; i++) {
1847 unsigned int integral_value = UINT_MAX;
1848 const char *name = nullptr;
1849 const struct process_attr_value *value =
1850 lttng_process_attr_tracker_values_get_at_index(values, i);
1851
1852 LTTNG_ASSERT(value);
1853 ret = config_writer_open_element(writer, element_target_id);
1854 if (ret) {
1855 ret = LTTNG_ERR_SAVE_IO_FAIL;
1856 goto end;
1857 }
1858
1859 switch (value->type) {
1860 case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
1861 integral_value = (unsigned int) value->value.pid;
1862 break;
1863 case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
1864 integral_value = (unsigned int) value->value.uid;
1865 break;
1866 case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
1867 integral_value = (unsigned int) value->value.gid;
1868 break;
1869 case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
1870 name = value->value.user_name;
1871 LTTNG_ASSERT(name);
1872 break;
1873 case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
1874 name = value->value.group_name;
1875 LTTNG_ASSERT(name);
1876 break;
1877 default:
1878 abort();
1879 }
1880
1881 if (name) {
1882 ret = config_writer_write_element_string(
1883 writer, config_element_name, name);
1884 } else {
1885 ret = config_writer_write_element_unsigned_int(
1886 writer, element_id, integral_value);
1887 }
1888
1889 if (ret) {
1890 ret = LTTNG_ERR_SAVE_IO_FAIL;
1891 goto end;
1892 }
1893
1894 /* /$element_target_id */
1895 ret = config_writer_close_element(writer);
1896 if (ret) {
1897 ret = LTTNG_ERR_SAVE_IO_FAIL;
1898 goto end;
1899 }
1900 }
1901 }
1902
1903 /* /values */
1904 ret = config_writer_close_element(writer);
1905 if (ret) {
1906 ret = LTTNG_ERR_SAVE_IO_FAIL;
1907 goto end;
1908 }
1909
1910 /* /$element_id_tracker */
1911 ret = config_writer_close_element(writer);
1912 if (ret) {
1913 ret = LTTNG_ERR_SAVE_IO_FAIL;
1914 goto end;
1915 }
1916
1917 ret = LTTNG_OK;
1918 end:
1919 lttng_process_attr_values_destroy(values);
1920 return ret;
1921 }
1922
1923 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1924 static int
1925 save_process_attr_trackers(struct config_writer *writer, struct ltt_session *sess, int domain)
1926 {
1927 int ret;
1928
1929 switch (domain) {
1930 case LTTNG_DOMAIN_KERNEL:
1931 ret = save_process_attr_tracker(
1932 writer, sess, domain, LTTNG_PROCESS_ATTR_PROCESS_ID);
1933 if (ret != LTTNG_OK) {
1934 goto end;
1935 }
1936 ret = save_process_attr_tracker(
1937 writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
1938 if (ret != LTTNG_OK) {
1939 goto end;
1940 }
1941 ret = save_process_attr_tracker(writer, sess, domain, LTTNG_PROCESS_ATTR_USER_ID);
1942 if (ret != LTTNG_OK) {
1943 goto end;
1944 }
1945 ret = save_process_attr_tracker(
1946 writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
1947 if (ret != LTTNG_OK) {
1948 goto end;
1949 }
1950 ret = save_process_attr_tracker(writer, sess, domain, LTTNG_PROCESS_ATTR_GROUP_ID);
1951 if (ret != LTTNG_OK) {
1952 goto end;
1953 }
1954 ret = save_process_attr_tracker(
1955 writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
1956 if (ret != LTTNG_OK) {
1957 goto end;
1958 }
1959 break;
1960 case LTTNG_DOMAIN_UST:
1961 ret = save_process_attr_tracker(
1962 writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
1963 if (ret != LTTNG_OK) {
1964 goto end;
1965 }
1966 ret = save_process_attr_tracker(
1967 writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
1968 if (ret != LTTNG_OK) {
1969 goto end;
1970 }
1971 ret = save_process_attr_tracker(
1972 writer, sess, domain, LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
1973 if (ret != LTTNG_OK) {
1974 goto end;
1975 }
1976 break;
1977 default:
1978 ret = LTTNG_ERR_INVALID;
1979 goto end;
1980 }
1981 ret = LTTNG_OK;
1982 end:
1983 return ret;
1984 }
1985
1986 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
1987 static int save_ust_domain(struct config_writer *writer,
1988 struct ltt_session *session,
1989 enum lttng_domain_type domain)
1990 {
1991 int ret;
1992 struct ltt_ust_channel *ust_chan;
1993 const char *buffer_type_string;
1994 struct lttng_ht_node_str *node;
1995 struct lttng_ht_iter iter;
1996 const char *config_domain_name;
1997
1998 LTTNG_ASSERT(writer);
1999 LTTNG_ASSERT(session);
2000
2001 ret = config_writer_open_element(writer, config_element_domain);
2002 if (ret) {
2003 ret = LTTNG_ERR_SAVE_IO_FAIL;
2004 goto end;
2005 }
2006
2007 config_domain_name = get_config_domain_str(domain);
2008 if (!config_domain_name) {
2009 ret = LTTNG_ERR_INVALID;
2010 goto end;
2011 }
2012
2013 ret = config_writer_write_element_string(writer, config_element_type, config_domain_name);
2014 if (ret) {
2015 ret = LTTNG_ERR_SAVE_IO_FAIL;
2016 goto end;
2017 }
2018
2019 buffer_type_string = get_buffer_type_string(session->ust_session->buffer_type);
2020 if (!buffer_type_string) {
2021 ERR("Unsupported buffer type.");
2022 ret = LTTNG_ERR_INVALID;
2023 goto end;
2024 }
2025
2026 ret = config_writer_write_element_string(
2027 writer, config_element_buffer_type, buffer_type_string);
2028 if (ret) {
2029 ret = LTTNG_ERR_SAVE_IO_FAIL;
2030 goto end;
2031 }
2032
2033 ret = config_writer_open_element(writer, config_element_channels);
2034 if (ret) {
2035 ret = LTTNG_ERR_SAVE_IO_FAIL;
2036 goto end;
2037 }
2038
2039 {
2040 lttng::urcu::read_lock_guard read_lock;
2041
2042 cds_lfht_for_each_entry (
2043 session->ust_session->domain_global.channels->ht, &iter.iter, node, node) {
2044 ust_chan = lttng::utils::container_of(node, &ltt_ust_channel::node);
2045 if (domain == ust_chan->domain) {
2046 ret = save_ust_channel(writer, ust_chan, session->ust_session);
2047 if (ret != LTTNG_OK) {
2048 goto end;
2049 }
2050 }
2051 }
2052 }
2053
2054 /* /channels */
2055 ret = config_writer_close_element(writer);
2056 if (ret) {
2057 ret = LTTNG_ERR_SAVE_IO_FAIL;
2058 goto end;
2059 }
2060
2061 if (domain == LTTNG_DOMAIN_UST) {
2062 ret = config_writer_open_element(writer, config_element_process_attr_trackers);
2063 if (ret) {
2064 ret = LTTNG_ERR_SAVE_IO_FAIL;
2065 goto end;
2066 }
2067
2068 ret = save_process_attr_trackers(writer, session, LTTNG_DOMAIN_UST);
2069 if (ret != LTTNG_OK) {
2070 goto end;
2071 }
2072
2073 /* /trackers */
2074 ret = config_writer_close_element(writer);
2075 if (ret) {
2076 ret = LTTNG_ERR_SAVE_IO_FAIL;
2077 goto end;
2078 }
2079 }
2080
2081 /* /domain */
2082 ret = config_writer_close_element(writer);
2083 if (ret) {
2084 ret = LTTNG_ERR_SAVE_IO_FAIL;
2085 goto end;
2086 }
2087
2088 ret = LTTNG_OK;
2089 end:
2090 return ret;
2091 }
2092
2093 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2094 static int save_domains(struct config_writer *writer, struct ltt_session *session)
2095 {
2096 int ret = LTTNG_OK;
2097
2098 LTTNG_ASSERT(writer);
2099 LTTNG_ASSERT(session);
2100
2101 if (!session->kernel_session && !session->ust_session) {
2102 goto end;
2103 }
2104
2105 ret = config_writer_open_element(writer, config_element_domains);
2106 if (ret) {
2107 ret = LTTNG_ERR_SAVE_IO_FAIL;
2108 goto end;
2109 }
2110
2111 if (session->kernel_session) {
2112 ret = config_writer_open_element(writer, config_element_domain);
2113 if (ret) {
2114 ret = LTTNG_ERR_SAVE_IO_FAIL;
2115 goto end;
2116 }
2117
2118 ret = save_kernel_session(writer, session);
2119 if (ret != LTTNG_OK) {
2120 goto end;
2121 }
2122
2123 ret = config_writer_open_element(writer, config_element_process_attr_trackers);
2124 if (ret) {
2125 ret = LTTNG_ERR_SAVE_IO_FAIL;
2126 goto end;
2127 }
2128
2129 ret = save_process_attr_trackers(writer, session, LTTNG_DOMAIN_KERNEL);
2130 if (ret != LTTNG_OK) {
2131 goto end;
2132 }
2133
2134 /* /trackers */
2135 ret = config_writer_close_element(writer);
2136 if (ret) {
2137 ret = LTTNG_ERR_SAVE_IO_FAIL;
2138 goto end;
2139 }
2140 /* /domain */
2141 ret = config_writer_close_element(writer);
2142 if (ret) {
2143 ret = LTTNG_ERR_SAVE_IO_FAIL;
2144 goto end;
2145 }
2146 }
2147
2148 if (session->ust_session) {
2149 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST);
2150 if (ret != LTTNG_OK) {
2151 goto end;
2152 }
2153
2154 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL);
2155 if (ret != LTTNG_OK) {
2156 goto end;
2157 }
2158
2159 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J);
2160 if (ret != LTTNG_OK) {
2161 goto end;
2162 }
2163
2164 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
2165 if (ret != LTTNG_OK) {
2166 goto end;
2167 }
2168 }
2169
2170 /* /domains */
2171 ret = config_writer_close_element(writer);
2172 if (ret) {
2173 ret = LTTNG_ERR_SAVE_IO_FAIL;
2174 goto end;
2175 }
2176
2177 ret = LTTNG_OK;
2178 end:
2179 return ret;
2180 }
2181
2182 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2183 static int save_consumer_output(struct config_writer *writer, struct consumer_output *output)
2184 {
2185 int ret;
2186
2187 LTTNG_ASSERT(writer);
2188 LTTNG_ASSERT(output);
2189
2190 ret = config_writer_open_element(writer, config_element_consumer_output);
2191 if (ret) {
2192 ret = LTTNG_ERR_SAVE_IO_FAIL;
2193 goto end;
2194 }
2195
2196 ret = config_writer_write_element_bool(writer, config_element_enabled, output->enabled);
2197 if (ret) {
2198 ret = LTTNG_ERR_SAVE_IO_FAIL;
2199 goto end;
2200 }
2201
2202 ret = config_writer_open_element(writer, config_element_destination);
2203 if (ret) {
2204 ret = LTTNG_ERR_SAVE_IO_FAIL;
2205 goto end;
2206 }
2207
2208 switch (output->type) {
2209 case CONSUMER_DST_LOCAL:
2210 ret = config_writer_write_element_string(
2211 writer, config_element_path, output->dst.session_root_path);
2212 if (ret) {
2213 ret = LTTNG_ERR_SAVE_IO_FAIL;
2214 goto end;
2215 }
2216 break;
2217 case CONSUMER_DST_NET:
2218 {
2219 char *uri;
2220
2221 uri = calloc<char>(PATH_MAX);
2222 if (!uri) {
2223 ret = LTTNG_ERR_NOMEM;
2224 goto end;
2225 }
2226
2227 ret = config_writer_open_element(writer, config_element_net_output);
2228 if (ret) {
2229 ret = LTTNG_ERR_SAVE_IO_FAIL;
2230 goto end_net_output;
2231 }
2232
2233 if (output->dst.net.control_isset && output->dst.net.data_isset) {
2234 ret = uri_to_str_url(&output->dst.net.control, uri, PATH_MAX);
2235 if (ret < 0) {
2236 ret = LTTNG_ERR_INVALID;
2237 goto end_net_output;
2238 }
2239
2240 ret = config_writer_write_element_string(
2241 writer, config_element_control_uri, uri);
2242 if (ret) {
2243 ret = LTTNG_ERR_SAVE_IO_FAIL;
2244 goto end_net_output;
2245 }
2246
2247 ret = uri_to_str_url(&output->dst.net.data, uri, PATH_MAX);
2248 if (ret < 0) {
2249 ret = LTTNG_ERR_INVALID;
2250 goto end_net_output;
2251 }
2252
2253 ret = config_writer_write_element_string(
2254 writer, config_element_data_uri, uri);
2255 if (ret) {
2256 ret = LTTNG_ERR_SAVE_IO_FAIL;
2257 goto end_net_output;
2258 }
2259 ret = LTTNG_OK;
2260 end_net_output:
2261 free(uri);
2262 if (ret != LTTNG_OK) {
2263 goto end;
2264 }
2265 } else {
2266 ret = !output->dst.net.control_isset ? LTTNG_ERR_URL_CTRL_MISS :
2267 LTTNG_ERR_URL_DATA_MISS;
2268 free(uri);
2269 goto end;
2270 }
2271
2272 ret = config_writer_close_element(writer);
2273 if (ret) {
2274 ret = LTTNG_ERR_SAVE_IO_FAIL;
2275 goto end;
2276 }
2277 break;
2278 }
2279 default:
2280 ERR("Unsupported consumer output type.");
2281 ret = LTTNG_ERR_INVALID;
2282 goto end;
2283 }
2284
2285 /* /destination */
2286 ret = config_writer_close_element(writer);
2287 if (ret) {
2288 ret = LTTNG_ERR_SAVE_IO_FAIL;
2289 goto end;
2290 }
2291
2292 /* /consumer_output */
2293 ret = config_writer_close_element(writer);
2294 if (ret) {
2295 ret = LTTNG_ERR_SAVE_IO_FAIL;
2296 goto end;
2297 }
2298
2299 ret = LTTNG_OK;
2300 end:
2301 return ret;
2302 }
2303
2304 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2305 static int save_snapshot_outputs(struct config_writer *writer, struct snapshot *snapshot)
2306 {
2307 int ret;
2308 struct lttng_ht_iter iter;
2309 struct snapshot_output *output;
2310
2311 LTTNG_ASSERT(writer);
2312 LTTNG_ASSERT(snapshot);
2313
2314 ret = config_writer_open_element(writer, config_element_snapshot_outputs);
2315 if (ret) {
2316 ret = LTTNG_ERR_SAVE_IO_FAIL;
2317 goto end;
2318 }
2319
2320 {
2321 lttng::urcu::read_lock_guard read_lock;
2322
2323 cds_lfht_for_each_entry (snapshot->output_ht->ht, &iter.iter, output, node.node) {
2324 ret = config_writer_open_element(writer, config_element_output);
2325 if (ret) {
2326 ret = LTTNG_ERR_SAVE_IO_FAIL;
2327 goto end_unlock;
2328 }
2329
2330 ret = config_writer_write_element_string(
2331 writer, config_element_name, output->name);
2332 if (ret) {
2333 ret = LTTNG_ERR_SAVE_IO_FAIL;
2334 goto end_unlock;
2335 }
2336
2337 ret = config_writer_write_element_unsigned_int(
2338 writer, config_element_max_size, output->max_size);
2339 if (ret) {
2340 ret = LTTNG_ERR_SAVE_IO_FAIL;
2341 goto end_unlock;
2342 }
2343
2344 ret = save_consumer_output(writer, output->consumer);
2345 if (ret != LTTNG_OK) {
2346 goto end_unlock;
2347 }
2348
2349 /* /output */
2350 ret = config_writer_close_element(writer);
2351 if (ret) {
2352 ret = LTTNG_ERR_SAVE_IO_FAIL;
2353 goto end_unlock;
2354 }
2355 }
2356 }
2357
2358 /* /snapshot_outputs */
2359 ret = config_writer_close_element(writer);
2360 if (ret) {
2361 ret = LTTNG_ERR_SAVE_IO_FAIL;
2362 goto end;
2363 }
2364
2365 ret = LTTNG_OK;
2366 end:
2367 return ret;
2368 end_unlock:
2369 return ret;
2370 }
2371
2372 /* Return LTTNG_OK on success else a LTTNG_ERR* code. */
2373 static int save_session_output(struct config_writer *writer, struct ltt_session *session)
2374 {
2375 int ret;
2376
2377 LTTNG_ASSERT(writer);
2378 LTTNG_ASSERT(session);
2379
2380 if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
2381 (!session->snapshot_mode && !session->consumer)) {
2382 /* Session is in no output mode */
2383 ret = LTTNG_OK;
2384 goto end;
2385 }
2386
2387 ret = config_writer_open_element(writer, config_element_output);
2388 if (ret) {
2389 ret = LTTNG_ERR_SAVE_IO_FAIL;
2390 goto end;
2391 }
2392
2393 if (session->snapshot_mode) {
2394 ret = save_snapshot_outputs(writer, &session->snapshot);
2395 if (ret != LTTNG_OK) {
2396 goto end;
2397 }
2398 } else {
2399 if (session->consumer) {
2400 ret = save_consumer_output(writer, session->consumer);
2401 if (ret != LTTNG_OK) {
2402 goto end;
2403 }
2404 }
2405 }
2406
2407 /* /output */
2408 ret = config_writer_close_element(writer);
2409 if (ret) {
2410 ret = LTTNG_ERR_SAVE_IO_FAIL;
2411 goto end;
2412 }
2413 ret = LTTNG_OK;
2414 end:
2415 return ret;
2416 }
2417
2418 static int save_session_rotation_schedule(struct config_writer *writer,
2419 enum lttng_rotation_schedule_type type,
2420 uint64_t value)
2421 {
2422 int ret = 0;
2423 const char *element_name;
2424 const char *value_name;
2425
2426 switch (type) {
2427 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
2428 element_name = config_element_rotation_schedule_periodic;
2429 value_name = config_element_rotation_schedule_periodic_time_us;
2430 break;
2431 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
2432 element_name = config_element_rotation_schedule_size_threshold;
2433 value_name = config_element_rotation_schedule_size_threshold_bytes;
2434 break;
2435 default:
2436 ret = -1;
2437 goto end;
2438 }
2439
2440 ret = config_writer_open_element(writer, element_name);
2441 if (ret) {
2442 goto end;
2443 }
2444
2445 ret = config_writer_write_element_unsigned_int(writer, value_name, value);
2446 if (ret) {
2447 goto end;
2448 }
2449
2450 /* Close schedule descriptor element. */
2451 ret = config_writer_close_element(writer);
2452 if (ret) {
2453 goto end;
2454 }
2455 end:
2456 return ret;
2457 }
2458
2459 static int save_session_rotation_schedules(struct config_writer *writer,
2460 struct ltt_session *session)
2461 {
2462 int ret;
2463
2464 ret = config_writer_open_element(writer, config_element_rotation_schedules);
2465 if (ret) {
2466 goto end;
2467 }
2468 if (session->rotate_timer_period) {
2469 ret = save_session_rotation_schedule(writer,
2470 LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC,
2471 session->rotate_timer_period);
2472 if (ret) {
2473 goto close_schedules;
2474 }
2475 }
2476 if (session->rotate_size) {
2477 ret = save_session_rotation_schedule(
2478 writer, LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD, session->rotate_size);
2479 if (ret) {
2480 goto close_schedules;
2481 }
2482 }
2483
2484 close_schedules:
2485 /* Close rotation schedules element. */
2486 ret = config_writer_close_element(writer);
2487 if (ret) {
2488 goto end;
2489 }
2490 end:
2491 return ret;
2492 }
2493
2494 /*
2495 * Save the given session.
2496 *
2497 * Return LTTNG_OK on success else a LTTNG_ERR* code.
2498 */
2499 static int save_session(struct ltt_session *session,
2500 struct lttng_save_session_attr *attr,
2501 lttng_sock_cred *creds)
2502 {
2503 int ret, fd = -1;
2504 char config_file_path[LTTNG_PATH_MAX];
2505 size_t len;
2506 struct config_writer *writer = nullptr;
2507 size_t session_name_len;
2508 const char *provided_path;
2509 int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC;
2510
2511 LTTNG_ASSERT(session);
2512 LTTNG_ASSERT(attr);
2513 LTTNG_ASSERT(creds);
2514
2515 session_name_len = strlen(session->name);
2516 memset(config_file_path, 0, sizeof(config_file_path));
2517
2518 if (!session_access_ok(session, LTTNG_SOCK_GET_UID_CRED(creds)) || session->destroyed) {
2519 ret = LTTNG_ERR_EPERM;
2520 goto end;
2521 }
2522
2523 provided_path = lttng_save_session_attr_get_output_url(attr);
2524 if (provided_path) {
2525 DBG3("Save session in provided path %s", provided_path);
2526 len = strlen(provided_path);
2527 if (len >= sizeof(config_file_path)) {
2528 ret = LTTNG_ERR_SET_URL;
2529 goto end;
2530 }
2531 strncpy(config_file_path, provided_path, sizeof(config_file_path));
2532 } else {
2533 ssize_t ret_len;
2534 char *home_dir = utils_get_user_home_dir(LTTNG_SOCK_GET_UID_CRED(creds));
2535 if (!home_dir) {
2536 ret = LTTNG_ERR_SET_URL;
2537 goto end;
2538 }
2539
2540 ret_len = snprintf(config_file_path,
2541 sizeof(config_file_path),
2542 DEFAULT_SESSION_HOME_CONFIGPATH,
2543 home_dir);
2544 free(home_dir);
2545 if (ret_len < 0) {
2546 PERROR("snprintf save session");
2547 ret = LTTNG_ERR_SET_URL;
2548 goto end;
2549 }
2550 len = ret_len;
2551 }
2552
2553 /*
2554 * Check the path fits in the config file path dst including the '/'
2555 * followed by trailing .lttng extension and the NULL terminated string.
2556 */
2557 if ((len + session_name_len + 2 + sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION)) >
2558 sizeof(config_file_path)) {
2559 ret = LTTNG_ERR_SET_URL;
2560 goto end;
2561 }
2562
2563 ret = run_as_mkdir_recursive(config_file_path,
2564 S_IRWXU | S_IRWXG,
2565 LTTNG_SOCK_GET_UID_CRED(creds),
2566 LTTNG_SOCK_GET_GID_CRED(creds));
2567 if (ret) {
2568 ret = LTTNG_ERR_SET_URL;
2569 goto end;
2570 }
2571
2572 /*
2573 * At this point, we know that everything fits in the buffer. Validation
2574 * was done just above.
2575 */
2576 config_file_path[len++] = '/';
2577 strncpy(config_file_path + len, session->name, sizeof(config_file_path) - len);
2578 len += session_name_len;
2579 strcpy(config_file_path + len, DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
2580 len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
2581 config_file_path[len] = '\0';
2582
2583 if (!attr->overwrite) {
2584 file_open_flags |= O_EXCL;
2585 }
2586
2587 fd = run_as_open(config_file_path,
2588 file_open_flags,
2589 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
2590 LTTNG_SOCK_GET_UID_CRED(creds),
2591 LTTNG_SOCK_GET_GID_CRED(creds));
2592 if (fd < 0) {
2593 PERROR("Could not create configuration file");
2594 switch (errno) {
2595 case EEXIST:
2596 ret = LTTNG_ERR_SAVE_FILE_EXIST;
2597 break;
2598 case EACCES:
2599 ret = LTTNG_ERR_EPERM;
2600 break;
2601 default:
2602 ret = LTTNG_ERR_SAVE_IO_FAIL;
2603 break;
2604 }
2605 goto end;
2606 }
2607
2608 writer = config_writer_create(fd, 1);
2609 if (!writer) {
2610 ret = LTTNG_ERR_NOMEM;
2611 goto end;
2612 }
2613
2614 ret = config_writer_open_element(writer, config_element_sessions);
2615 if (ret) {
2616 ret = LTTNG_ERR_SAVE_IO_FAIL;
2617 goto end;
2618 }
2619
2620 ret = config_writer_open_element(writer, config_element_session);
2621 if (ret) {
2622 ret = LTTNG_ERR_SAVE_IO_FAIL;
2623 goto end;
2624 }
2625
2626 ret = config_writer_write_element_string(writer, config_element_name, session->name);
2627 if (ret) {
2628 ret = LTTNG_ERR_SAVE_IO_FAIL;
2629 goto end;
2630 }
2631
2632 if (session->shm_path[0] != '\0') {
2633 ret = config_writer_write_element_string(
2634 writer, config_element_shared_memory_path, session->shm_path);
2635 if (ret) {
2636 ret = LTTNG_ERR_SAVE_IO_FAIL;
2637 goto end;
2638 }
2639 }
2640
2641 ret = save_domains(writer, session);
2642 if (ret != LTTNG_OK) {
2643 goto end;
2644 }
2645
2646 ret = config_writer_write_element_bool(writer, config_element_started, session->active);
2647 if (ret) {
2648 ret = LTTNG_ERR_SAVE_IO_FAIL;
2649 goto end;
2650 }
2651
2652 if (session->snapshot_mode || session->live_timer || session->rotate_timer_period ||
2653 session->rotate_size) {
2654 ret = config_writer_open_element(writer, config_element_attributes);
2655 if (ret) {
2656 ret = LTTNG_ERR_SAVE_IO_FAIL;
2657 goto end;
2658 }
2659
2660 if (session->snapshot_mode) {
2661 ret = config_writer_write_element_bool(
2662 writer, config_element_snapshot_mode, 1);
2663 if (ret) {
2664 ret = LTTNG_ERR_SAVE_IO_FAIL;
2665 goto end;
2666 }
2667 } else if (session->live_timer) {
2668 ret = config_writer_write_element_unsigned_int(
2669 writer, config_element_live_timer_interval, session->live_timer);
2670 if (ret) {
2671 ret = LTTNG_ERR_SAVE_IO_FAIL;
2672 goto end;
2673 }
2674 }
2675 if (session->rotate_timer_period || session->rotate_size) {
2676 ret = save_session_rotation_schedules(writer, session);
2677 if (ret) {
2678 ret = LTTNG_ERR_SAVE_IO_FAIL;
2679 goto end;
2680 }
2681 }
2682
2683 /* /attributes */
2684 ret = config_writer_close_element(writer);
2685 if (ret) {
2686 ret = LTTNG_ERR_SAVE_IO_FAIL;
2687 goto end;
2688 }
2689 }
2690
2691 ret = save_session_output(writer, session);
2692 if (ret != LTTNG_OK) {
2693 goto end;
2694 }
2695
2696 /* /session */
2697 ret = config_writer_close_element(writer);
2698 if (ret) {
2699 ret = LTTNG_ERR_SAVE_IO_FAIL;
2700 goto end;
2701 }
2702
2703 /* /sessions */
2704 ret = config_writer_close_element(writer);
2705 if (ret) {
2706 ret = LTTNG_ERR_SAVE_IO_FAIL;
2707 goto end;
2708 }
2709
2710 ret = LTTNG_OK;
2711 end:
2712 if (writer && config_writer_destroy(writer)) {
2713 /* Preserve the original error code */
2714 ret = ret != LTTNG_OK ? ret : LTTNG_ERR_SAVE_IO_FAIL;
2715 }
2716 if (ret != LTTNG_OK) {
2717 /* Delete file in case of error */
2718 if ((fd >= 0) && unlink(config_file_path)) {
2719 PERROR("Unlinking XML session configuration.");
2720 }
2721 }
2722
2723 if (fd >= 0) {
2724 int closeret;
2725
2726 closeret = close(fd);
2727 if (closeret) {
2728 PERROR("Closing XML session configuration");
2729 }
2730 }
2731
2732 return ret;
2733 }
2734
2735 int cmd_save_sessions(struct lttng_save_session_attr *attr, lttng_sock_cred *creds)
2736 {
2737 int ret;
2738 const char *session_name;
2739 struct ltt_session *session;
2740
2741 session_lock_list();
2742
2743 session_name = lttng_save_session_attr_get_session_name(attr);
2744 if (session_name) {
2745 session = session_find_by_name(session_name);
2746 if (!session) {
2747 ret = LTTNG_ERR_SESS_NOT_FOUND;
2748 goto end;
2749 }
2750
2751 session_lock(session);
2752 ret = save_session(session, attr, creds);
2753 session_unlock(session);
2754 session_put(session);
2755 if (ret != LTTNG_OK) {
2756 goto end;
2757 }
2758 } else {
2759 struct ltt_session_list *list = session_get_list();
2760
2761 cds_list_for_each_entry (session, &list->head, list) {
2762 if (!session_get(session)) {
2763 continue;
2764 }
2765 session_lock(session);
2766 ret = save_session(session, attr, creds);
2767 session_unlock(session);
2768 session_put(session);
2769 /* Don't abort if we don't have the required permissions. */
2770 if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) {
2771 goto end;
2772 }
2773 }
2774 }
2775 ret = LTTNG_OK;
2776
2777 end:
2778 session_unlock_list();
2779 return ret;
2780 }
This page took 0.082115 seconds and 5 git commands to generate.