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