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