2 * Copyright (C) 2014 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License, version 2 only, as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 51
15 * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <urcu/uatomic.h>
25 #include <common/defaults.h>
26 #include <common/error.h>
27 #include <common/config/session-config.h>
28 #include <common/utils.h>
29 #include <common/runas.h>
30 #include <lttng/save-internal.h>
36 #include "trace-ust.h"
40 int save_kernel_channel_attributes(struct config_writer
*writer
,
41 struct lttng_channel_attr
*attr
)
45 ret
= config_writer_write_element_string(writer
,
46 config_element_overwrite_mode
,
47 attr
->overwrite
? config_overwrite_mode_overwrite
:
48 config_overwrite_mode_discard
);
53 ret
= config_writer_write_element_unsigned_int(writer
,
54 config_element_subbuf_size
, attr
->subbuf_size
);
59 ret
= config_writer_write_element_unsigned_int(writer
,
60 config_element_num_subbuf
,
66 ret
= config_writer_write_element_unsigned_int(writer
,
67 config_element_switch_timer_interval
,
68 attr
->switch_timer_interval
);
73 ret
= config_writer_write_element_unsigned_int(writer
,
74 config_element_read_timer_interval
,
75 attr
->read_timer_interval
);
80 ret
= config_writer_write_element_string(writer
,
81 config_element_output_type
,
82 attr
->output
== LTTNG_EVENT_SPLICE
?
83 config_output_type_splice
: config_output_type_mmap
);
88 ret
= config_writer_write_element_unsigned_int(writer
,
89 config_element_tracefile_size
, attr
->tracefile_size
);
94 ret
= config_writer_write_element_unsigned_int(writer
,
95 config_element_tracefile_count
,
96 attr
->tracefile_count
);
101 ret
= config_writer_write_element_unsigned_int(writer
,
102 config_element_live_timer_interval
,
103 attr
->live_timer_interval
);
108 return ret
? LTTNG_ERR_SAVE_IO_FAIL
: 0;
112 int save_ust_channel_attributes(struct config_writer
*writer
,
113 struct lttng_ust_channel_attr
*attr
)
117 ret
= config_writer_write_element_string(writer
,
118 config_element_overwrite_mode
,
119 attr
->overwrite
? config_overwrite_mode_overwrite
:
120 config_overwrite_mode_discard
);
125 ret
= config_writer_write_element_unsigned_int(writer
,
126 config_element_subbuf_size
, attr
->subbuf_size
);
131 ret
= config_writer_write_element_unsigned_int(writer
,
132 config_element_num_subbuf
,
138 ret
= config_writer_write_element_unsigned_int(writer
,
139 config_element_switch_timer_interval
,
140 attr
->switch_timer_interval
);
145 ret
= config_writer_write_element_unsigned_int(writer
,
146 config_element_read_timer_interval
,
147 attr
->read_timer_interval
);
152 ret
= config_writer_write_element_string(writer
,
153 config_element_output_type
,
154 attr
->output
== LTTNG_UST_MMAP
?
155 config_output_type_mmap
: config_output_type_splice
);
160 return ret
? LTTNG_ERR_SAVE_IO_FAIL
: 0;
164 const char *get_kernel_instrumentation_string(
165 enum lttng_kernel_instrumentation instrumentation
)
167 const char *instrumentation_string
;
169 switch (instrumentation
) {
170 case LTTNG_KERNEL_ALL
:
171 instrumentation_string
= config_event_type_all
;
173 case LTTNG_KERNEL_TRACEPOINT
:
174 instrumentation_string
= config_event_type_tracepoint
;
176 case LTTNG_KERNEL_KPROBE
:
177 instrumentation_string
= config_event_type_kprobe
;
179 case LTTNG_KERNEL_FUNCTION
:
180 instrumentation_string
= config_event_type_function
;
182 case LTTNG_KERNEL_KRETPROBE
:
183 instrumentation_string
= config_event_type_kretprobe
;
185 case LTTNG_KERNEL_NOOP
:
186 instrumentation_string
= config_event_type_noop
;
188 case LTTNG_KERNEL_SYSCALL
:
189 instrumentation_string
= config_event_type_syscall
;
192 instrumentation_string
= NULL
;
195 return instrumentation_string
;
199 const char *get_kernel_context_type_string(
200 enum lttng_kernel_context_type context_type
)
202 const char *context_type_string
;
204 switch (context_type
) {
205 case LTTNG_KERNEL_CONTEXT_PID
:
206 context_type_string
= config_event_context_pid
;
208 case LTTNG_KERNEL_CONTEXT_PROCNAME
:
209 context_type_string
= config_event_context_procname
;
211 case LTTNG_KERNEL_CONTEXT_PRIO
:
212 context_type_string
= config_event_context_prio
;
214 case LTTNG_KERNEL_CONTEXT_NICE
:
215 context_type_string
= config_event_context_nice
;
217 case LTTNG_KERNEL_CONTEXT_VPID
:
218 context_type_string
= config_event_context_vpid
;
220 case LTTNG_KERNEL_CONTEXT_TID
:
221 context_type_string
= config_event_context_tid
;
223 case LTTNG_KERNEL_CONTEXT_VTID
:
224 context_type_string
= config_event_context_vtid
;
226 case LTTNG_KERNEL_CONTEXT_PPID
:
227 context_type_string
= config_event_context_ppid
;
229 case LTTNG_KERNEL_CONTEXT_VPPID
:
230 context_type_string
= config_event_context_vppid
;
232 case LTTNG_KERNEL_CONTEXT_HOSTNAME
:
233 context_type_string
= config_event_context_hostname
;
236 context_type_string
= NULL
;
239 return context_type_string
;
243 const char *get_ust_context_type_string(
244 enum lttng_ust_context_type context_type
)
246 const char *context_type_string
;
248 switch (context_type
) {
249 case LTTNG_UST_CONTEXT_PROCNAME
:
250 context_type_string
= config_event_context_procname
;
252 case LTTNG_UST_CONTEXT_VPID
:
253 context_type_string
= config_event_context_vpid
;
255 case LTTNG_UST_CONTEXT_VTID
:
256 context_type_string
= config_event_context_vtid
;
258 case LTTNG_UST_CONTEXT_IP
:
259 context_type_string
= config_event_context_ip
;
261 case LTTNG_UST_CONTEXT_PTHREAD_ID
:
262 context_type_string
= config_event_context_pthread_id
;
264 case LTTNG_UST_CONTEXT_APP_CONTEXT
:
265 context_type_string
= config_event_context_app
;
267 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
:
269 * Error, should not be stored in the XML, perf contexts
270 * are stored as a node of type event_perf_context_type.
273 context_type_string
= NULL
;
277 return context_type_string
;
281 const char *get_buffer_type_string(
282 enum lttng_buffer_type buffer_type
)
284 const char *buffer_type_string
;
286 switch (buffer_type
) {
287 case LTTNG_BUFFER_PER_PID
:
288 buffer_type_string
= config_buffer_type_per_pid
;
290 case LTTNG_BUFFER_PER_UID
:
291 buffer_type_string
= config_buffer_type_per_uid
;
293 case LTTNG_BUFFER_GLOBAL
:
294 buffer_type_string
= config_buffer_type_global
;
297 buffer_type_string
= NULL
;
300 return buffer_type_string
;
304 const char *get_loglevel_type_string(
305 enum lttng_ust_loglevel_type loglevel_type
)
307 const char *loglevel_type_string
;
309 switch (loglevel_type
) {
310 case LTTNG_UST_LOGLEVEL_ALL
:
311 loglevel_type_string
= config_loglevel_type_all
;
313 case LTTNG_UST_LOGLEVEL_RANGE
:
314 loglevel_type_string
= config_loglevel_type_range
;
316 case LTTNG_UST_LOGLEVEL_SINGLE
:
317 loglevel_type_string
= config_loglevel_type_single
;
320 loglevel_type_string
= NULL
;
323 return loglevel_type_string
;
327 int save_kernel_event(struct config_writer
*writer
,
328 struct ltt_kernel_event
*event
)
331 const char *instrumentation_type
;
333 ret
= config_writer_open_element(writer
, config_element_event
);
335 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
339 if (event
->event
->name
[0]) {
340 ret
= config_writer_write_element_string(writer
,
341 config_element_name
, event
->event
->name
);
343 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
348 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
351 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
355 instrumentation_type
= get_kernel_instrumentation_string(
356 event
->event
->instrumentation
);
357 if (!instrumentation_type
) {
358 ret
= LTTNG_ERR_INVALID
;
362 ret
= config_writer_write_element_string(writer
, config_element_type
,
363 instrumentation_type
);
365 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
369 if (event
->filter_expression
) {
370 ret
= config_writer_write_element_string(writer
,
371 config_element_filter
,
372 event
->filter_expression
);
374 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
379 if (event
->event
->instrumentation
== LTTNG_KERNEL_FUNCTION
||
380 event
->event
->instrumentation
== LTTNG_KERNEL_KPROBE
||
381 event
->event
->instrumentation
== LTTNG_KERNEL_KRETPROBE
) {
383 ret
= config_writer_open_element(writer
,
384 config_element_attributes
);
386 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
390 switch (event
->event
->instrumentation
) {
391 case LTTNG_KERNEL_SYSCALL
:
392 case LTTNG_KERNEL_FUNCTION
:
393 ret
= config_writer_open_element(writer
,
394 config_element_function_attributes
);
396 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
400 ret
= config_writer_write_element_string(writer
,
402 event
->event
->u
.ftrace
.symbol_name
);
404 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
408 /* /function attributes */
409 ret
= config_writer_close_element(writer
);
411 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
415 case LTTNG_KERNEL_KPROBE
:
416 case LTTNG_KERNEL_KRETPROBE
:
418 const char *symbol_name
;
422 if (event
->event
->instrumentation
==
423 LTTNG_KERNEL_KPROBE
) {
425 * Comments in lttng-kernel.h mention that
426 * either addr or symbol_name are set, not both.
428 addr
= event
->event
->u
.kprobe
.addr
;
429 offset
= event
->event
->u
.kprobe
.offset
;
430 symbol_name
= addr
? NULL
:
431 event
->event
->u
.kprobe
.symbol_name
;
434 event
->event
->u
.kretprobe
.symbol_name
;
435 addr
= event
->event
->u
.kretprobe
.addr
;
436 offset
= event
->event
->u
.kretprobe
.offset
;
439 ret
= config_writer_open_element(writer
,
440 config_element_probe_attributes
);
442 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
447 ret
= config_writer_write_element_string(writer
,
448 config_element_symbol_name
,
451 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
457 ret
= config_writer_write_element_unsigned_int(
458 writer
, config_element_address
, addr
);
460 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
466 ret
= config_writer_write_element_unsigned_int(
467 writer
, config_element_offset
, offset
);
469 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
474 ret
= config_writer_close_element(writer
);
476 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
482 ERR("Unsupported kernel instrumentation type.");
483 ret
= LTTNG_ERR_INVALID
;
488 ret
= config_writer_close_element(writer
);
490 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
496 ret
= config_writer_close_element(writer
);
498 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
506 int save_kernel_syscall(struct config_writer
*writer
,
507 struct ltt_kernel_channel
*kchan
)
511 struct lttng_event
*events
= NULL
;
516 count
= syscall_list_channel(kchan
, &events
, 0);
518 /* No syscalls, just gracefully return. */
523 for (i
= 0; i
< count
; i
++) {
524 struct ltt_kernel_event
*kevent
;
526 /* Create a temporary kevent in order to save it. */
528 * TODO: struct lttng_event does not really work for a filter,
529 * but unfortunately, it is exposed as external API (and used as
530 * internal representation. Using NULL meanwhile.
532 kevent
= trace_kernel_create_event(&events
[i
],
538 /* Init list in order so the destroy call can del the node. */
539 CDS_INIT_LIST_HEAD(&kevent
->list
);
541 ret
= save_kernel_event(writer
, kevent
);
542 trace_kernel_destroy_event(kevent
);
548 /* Everything went well */
557 int save_kernel_events(struct config_writer
*writer
,
558 struct ltt_kernel_channel
*kchan
)
561 struct ltt_kernel_event
*event
;
563 ret
= config_writer_open_element(writer
, config_element_events
);
565 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
569 cds_list_for_each_entry(event
, &kchan
->events_list
.head
, list
) {
570 ret
= save_kernel_event(writer
, event
);
576 /* Save syscalls if any. */
577 ret
= save_kernel_syscall(writer
, kchan
);
583 ret
= config_writer_close_element(writer
);
585 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
593 int save_ust_event(struct config_writer
*writer
,
594 struct ltt_ust_event
*event
)
597 const char *loglevel_type_string
;
599 ret
= config_writer_open_element(writer
, config_element_event
);
601 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
605 if (event
->attr
.name
[0]) {
606 ret
= config_writer_write_element_string(writer
,
607 config_element_name
, event
->attr
.name
);
609 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
614 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
617 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
621 if (event
->attr
.instrumentation
!= LTTNG_UST_TRACEPOINT
) {
622 ERR("Unsupported UST instrumentation type.");
623 ret
= LTTNG_ERR_INVALID
;
626 ret
= config_writer_write_element_string(writer
, config_element_type
,
627 config_event_type_tracepoint
);
629 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
633 loglevel_type_string
= get_loglevel_type_string(
634 event
->attr
.loglevel_type
);
635 if (!loglevel_type_string
) {
636 ERR("Unsupported UST loglevel type.");
637 ret
= LTTNG_ERR_INVALID
;
641 ret
= config_writer_write_element_string(writer
,
642 config_element_loglevel_type
, loglevel_type_string
);
644 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
648 /* The log level is irrelevant if no "filtering" is enabled */
649 if (event
->attr
.loglevel_type
!= LTTNG_UST_LOGLEVEL_ALL
) {
650 ret
= config_writer_write_element_signed_int(writer
,
651 config_element_loglevel
, event
->attr
.loglevel
);
653 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
658 if (event
->filter_expression
) {
659 ret
= config_writer_write_element_string(writer
,
660 config_element_filter
, event
->filter_expression
);
662 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
667 if (event
->exclusion
&& event
->exclusion
->count
) {
670 ret
= config_writer_open_element(writer
,
671 config_element_exclusions
);
673 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
677 for (i
= 0; i
< event
->exclusion
->count
; i
++) {
678 ret
= config_writer_write_element_string(writer
,
679 config_element_exclusion
,
680 LTTNG_EVENT_EXCLUSION_NAME_AT(
681 event
->exclusion
, i
));
683 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
689 ret
= config_writer_close_element(writer
);
691 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
697 ret
= config_writer_close_element(writer
);
699 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
707 int save_ust_events(struct config_writer
*writer
,
708 struct lttng_ht
*events
)
711 struct ltt_ust_event
*event
;
712 struct lttng_ht_node_str
*node
;
713 struct lttng_ht_iter iter
;
715 ret
= config_writer_open_element(writer
, config_element_events
);
717 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
722 cds_lfht_for_each_entry(events
->ht
, &iter
.iter
, node
, node
) {
723 event
= caa_container_of(node
, struct ltt_ust_event
, node
);
725 if (event
->internal
) {
726 /* Internal events must not be exposed to clients */
729 ret
= save_ust_event(writer
, event
);
738 ret
= config_writer_close_element(writer
);
740 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
748 int init_ust_event_from_agent_event(struct ltt_ust_event
*ust_event
,
749 struct agent_event
*agent_event
)
752 enum lttng_ust_loglevel_type ust_loglevel_type
;
754 ust_event
->enabled
= agent_event
->enabled
;
755 ust_event
->attr
.instrumentation
= LTTNG_UST_TRACEPOINT
;
756 strncpy(ust_event
->attr
.name
, agent_event
->name
, LTTNG_SYMBOL_NAME_LEN
);
757 switch (agent_event
->loglevel_type
) {
758 case LTTNG_EVENT_LOGLEVEL_ALL
:
759 ust_loglevel_type
= LTTNG_UST_LOGLEVEL_ALL
;
761 case LTTNG_EVENT_LOGLEVEL_SINGLE
:
762 ust_loglevel_type
= LTTNG_UST_LOGLEVEL_SINGLE
;
764 case LTTNG_EVENT_LOGLEVEL_RANGE
:
765 ust_loglevel_type
= LTTNG_UST_LOGLEVEL_RANGE
;
768 ERR("Invalid agent_event loglevel_type.");
773 ust_event
->attr
.loglevel_type
= ust_loglevel_type
;
774 ust_event
->attr
.loglevel
= agent_event
->loglevel_value
;
775 ust_event
->filter_expression
= agent_event
->filter_expression
;
776 ust_event
->exclusion
= agent_event
->exclusion
;
782 int save_agent_events(struct config_writer
*writer
,
783 struct ltt_ust_channel
*chan
,
787 struct lttng_ht_iter iter
;
788 struct lttng_ht_node_str
*node
;
790 ret
= config_writer_open_element(writer
, config_element_events
);
792 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
797 cds_lfht_for_each_entry(agent
->events
->ht
, &iter
.iter
, node
, node
) {
799 struct agent_event
*agent_event
;
800 struct ltt_ust_event fake_event
;
802 memset(&fake_event
, 0, sizeof(fake_event
));
803 agent_event
= caa_container_of(node
, struct agent_event
, node
);
806 * Initialize a fake ust event to reuse the same serialization
807 * function since UST and agent events contain the same info
808 * (and one could wonder why they don't reuse the same
811 ret
= init_ust_event_from_agent_event(&fake_event
, agent_event
);
816 ret
= save_ust_event(writer
, &fake_event
);
825 ret
= config_writer_close_element(writer
);
827 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
835 int save_kernel_context(struct config_writer
*writer
,
836 struct lttng_kernel_context
*ctx
)
844 ret
= config_writer_open_element(writer
, config_element_context
);
846 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
850 if (ctx
->ctx
== LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER
) {
851 ret
= config_writer_open_element(writer
,
852 config_element_context_perf
);
854 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
858 ret
= config_writer_write_element_unsigned_int(writer
,
859 config_element_type
, ctx
->u
.perf_counter
.type
);
861 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
865 ret
= config_writer_write_element_unsigned_int(writer
,
866 config_element_config
, ctx
->u
.perf_counter
.config
);
868 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
872 ret
= config_writer_write_element_string(writer
,
873 config_element_name
, ctx
->u
.perf_counter
.name
);
875 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
880 ret
= config_writer_close_element(writer
);
882 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
886 const char *context_type_string
=
887 get_kernel_context_type_string(ctx
->ctx
);
889 if (!context_type_string
) {
890 ERR("Unsupported kernel context type.");
891 ret
= LTTNG_ERR_INVALID
;
895 ret
= config_writer_write_element_string(writer
,
896 config_element_type
, context_type_string
);
898 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
904 ret
= config_writer_close_element(writer
);
906 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
915 int save_kernel_contexts(struct config_writer
*writer
,
916 struct ltt_kernel_channel
*kchan
)
919 struct ltt_kernel_context
*ctx
;
921 if (cds_list_empty(&kchan
->ctx_list
)) {
926 ret
= config_writer_open_element(writer
, config_element_contexts
);
928 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
932 cds_list_for_each_entry(ctx
, &kchan
->ctx_list
, list
) {
933 ret
= save_kernel_context(writer
, &ctx
->ctx
);
940 ret
= config_writer_close_element(writer
);
942 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
950 int save_ust_context_perf_thread_counter(struct config_writer
*writer
,
951 struct ltt_ust_context
*ctx
)
958 /* Perf contexts are saved as event_perf_context_type */
959 ret
= config_writer_open_element(writer
, config_element_context_perf
);
961 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
965 ret
= config_writer_write_element_unsigned_int(writer
,
966 config_element_type
, ctx
->ctx
.u
.perf_counter
.type
);
968 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
972 ret
= config_writer_write_element_unsigned_int(writer
,
973 config_element_config
, ctx
->ctx
.u
.perf_counter
.config
);
975 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
979 ret
= config_writer_write_element_string(writer
, config_element_name
,
980 ctx
->ctx
.u
.perf_counter
.name
);
982 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
987 ret
= config_writer_close_element(writer
);
989 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
997 int save_ust_context_app_ctx(struct config_writer
*writer
,
998 struct ltt_ust_context
*ctx
)
1005 /* Application contexts are saved as application_context_type */
1006 ret
= config_writer_open_element(writer
, config_element_context_app
);
1008 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1012 ret
= config_writer_write_element_string(writer
,
1013 config_element_context_app_provider_name
,
1014 ctx
->ctx
.u
.app_ctx
.provider_name
);
1016 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1020 ret
= config_writer_write_element_string(writer
,
1021 config_element_context_app_ctx_name
,
1022 ctx
->ctx
.u
.app_ctx
.ctx_name
);
1024 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1029 ret
= config_writer_close_element(writer
);
1031 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1039 int save_ust_context_generic(struct config_writer
*writer
,
1040 struct ltt_ust_context
*ctx
)
1043 const char *context_type_string
;
1048 /* Save context as event_context_type_type */
1049 context_type_string
= get_ust_context_type_string(
1051 if (!context_type_string
) {
1052 ERR("Unsupported UST context type.");
1053 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1057 ret
= config_writer_write_element_string(writer
,
1058 config_element_type
, context_type_string
);
1060 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1068 int save_ust_context(struct config_writer
*writer
,
1069 struct cds_list_head
*ctx_list
)
1072 struct ltt_ust_context
*ctx
;
1077 ret
= config_writer_open_element(writer
, config_element_contexts
);
1079 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1083 cds_list_for_each_entry(ctx
, ctx_list
, list
) {
1084 ret
= config_writer_open_element(writer
,
1085 config_element_context
);
1087 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1091 switch (ctx
->ctx
.ctx
) {
1092 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
:
1093 ret
= save_ust_context_perf_thread_counter(writer
, ctx
);
1095 case LTTNG_UST_CONTEXT_APP_CONTEXT
:
1096 ret
= save_ust_context_app_ctx(writer
, ctx
);
1099 /* Save generic context. */
1100 ret
= save_ust_context_generic(writer
, ctx
);
1107 ret
= config_writer_close_element(writer
);
1109 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1115 ret
= config_writer_close_element(writer
);
1117 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1125 int save_kernel_channel(struct config_writer
*writer
,
1126 struct ltt_kernel_channel
*kchan
)
1133 ret
= config_writer_open_element(writer
, config_element_channel
);
1135 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1139 ret
= config_writer_write_element_string(writer
, config_element_name
,
1140 kchan
->channel
->name
);
1142 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1146 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1147 kchan
->channel
->enabled
);
1149 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1153 ret
= save_kernel_channel_attributes(writer
, &kchan
->channel
->attr
);
1158 ret
= save_kernel_events(writer
, kchan
);
1163 ret
= save_kernel_contexts(writer
, kchan
);
1169 ret
= config_writer_close_element(writer
);
1171 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1179 int save_ust_channel(struct config_writer
*writer
,
1180 struct ltt_ust_channel
*ust_chan
,
1181 struct ltt_ust_session
*session
)
1189 ret
= config_writer_open_element(writer
, config_element_channel
);
1191 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1195 ret
= config_writer_write_element_string(writer
, config_element_name
,
1198 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1202 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1205 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1209 ret
= save_ust_channel_attributes(writer
, &ust_chan
->attr
);
1214 ret
= config_writer_write_element_unsigned_int(writer
,
1215 config_element_tracefile_size
, ust_chan
->tracefile_size
);
1217 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1221 ret
= config_writer_write_element_unsigned_int(writer
,
1222 config_element_tracefile_count
, ust_chan
->tracefile_count
);
1224 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1228 ret
= config_writer_write_element_unsigned_int(writer
,
1229 config_element_live_timer_interval
,
1230 session
->live_timer_interval
);
1232 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1236 if (ust_chan
->domain
== LTTNG_DOMAIN_UST
) {
1237 ret
= save_ust_events(writer
, ust_chan
->events
);
1242 struct agent
*agent
= NULL
;
1244 agent
= trace_ust_find_agent(session
, ust_chan
->domain
);
1246 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1247 ERR("Could not find agent associated to UST subdomain");
1252 * Channels associated with a UST sub-domain (such as JUL, Log4j
1253 * or Python) don't have any non-internal events. We retrieve
1254 * the "agent" events associated with this channel and serialize
1257 ret
= save_agent_events(writer
, ust_chan
, agent
);
1263 ret
= save_ust_context(writer
, &ust_chan
->ctx_list
);
1269 ret
= config_writer_close_element(writer
);
1271 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1279 int save_kernel_session(struct config_writer
*writer
,
1280 struct ltt_session
*session
)
1283 struct ltt_kernel_channel
*kchan
;
1288 ret
= config_writer_write_element_string(writer
, config_element_type
,
1289 config_domain_type_kernel
);
1291 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1295 ret
= config_writer_write_element_string(writer
,
1296 config_element_buffer_type
, config_buffer_type_global
);
1298 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1302 ret
= config_writer_open_element(writer
,
1303 config_element_channels
);
1305 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1309 cds_list_for_each_entry(kchan
, &session
->kernel_session
->channel_list
.head
,
1311 ret
= save_kernel_channel(writer
, kchan
);
1318 ret
= config_writer_close_element(writer
);
1320 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1328 const char *get_config_domain_str(enum lttng_domain_type domain
)
1330 const char *str_dom
;
1333 case LTTNG_DOMAIN_KERNEL
:
1334 str_dom
= config_domain_type_kernel
;
1336 case LTTNG_DOMAIN_UST
:
1337 str_dom
= config_domain_type_ust
;
1339 case LTTNG_DOMAIN_JUL
:
1340 str_dom
= config_domain_type_jul
;
1342 case LTTNG_DOMAIN_LOG4J
:
1343 str_dom
= config_domain_type_log4j
;
1345 case LTTNG_DOMAIN_PYTHON
:
1346 str_dom
= config_domain_type_python
;
1356 int save_pid_tracker(struct config_writer
*writer
,
1357 struct ltt_session
*sess
, int domain
)
1360 ssize_t nr_pids
= 0, i
;
1361 int32_t *pids
= NULL
;
1364 case LTTNG_DOMAIN_KERNEL
:
1366 nr_pids
= kernel_list_tracker_pids(sess
->kernel_session
, &pids
);
1368 ret
= LTTNG_ERR_KERN_LIST_FAIL
;
1373 case LTTNG_DOMAIN_UST
:
1375 nr_pids
= trace_ust_list_tracker_pids(sess
->ust_session
, &pids
);
1377 ret
= LTTNG_ERR_UST_LIST_FAIL
;
1382 case LTTNG_DOMAIN_JUL
:
1383 case LTTNG_DOMAIN_LOG4J
:
1384 case LTTNG_DOMAIN_PYTHON
:
1386 ret
= LTTNG_ERR_UNKNOWN_DOMAIN
;
1390 /* Only create a pid_tracker if enabled or untrack all */
1391 if (nr_pids
!= 1 || (nr_pids
== 1 && pids
[0] != -1)) {
1392 ret
= config_writer_open_element(writer
,
1393 config_element_pid_tracker
);
1395 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1399 ret
= config_writer_open_element(writer
,
1400 config_element_targets
);
1402 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1406 for (i
= 0; i
< nr_pids
; i
++) {
1407 ret
= config_writer_open_element(writer
,
1408 config_element_target_pid
);
1410 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1414 ret
= config_writer_write_element_unsigned_int(writer
,
1415 config_element_pid
, pids
[i
]);
1417 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1422 ret
= config_writer_close_element(writer
);
1424 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1430 ret
= config_writer_close_element(writer
);
1432 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1437 ret
= config_writer_close_element(writer
);
1439 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1449 int save_ust_domain(struct config_writer
*writer
,
1450 struct ltt_session
*session
, enum lttng_domain_type domain
)
1453 struct ltt_ust_channel
*ust_chan
;
1454 const char *buffer_type_string
;
1455 struct lttng_ht_node_str
*node
;
1456 struct lttng_ht_iter iter
;
1457 const char *config_domain_name
;
1462 ret
= config_writer_open_element(writer
,
1463 config_element_domain
);
1465 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1469 config_domain_name
= get_config_domain_str(domain
);
1470 if (!config_domain_name
) {
1471 ret
= LTTNG_ERR_INVALID
;
1475 ret
= config_writer_write_element_string(writer
,
1476 config_element_type
, config_domain_name
);
1478 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1482 buffer_type_string
= get_buffer_type_string(
1483 session
->ust_session
->buffer_type
);
1484 if (!buffer_type_string
) {
1485 ERR("Unsupported buffer type.");
1486 ret
= LTTNG_ERR_INVALID
;
1490 ret
= config_writer_write_element_string(writer
,
1491 config_element_buffer_type
, buffer_type_string
);
1493 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1497 ret
= config_writer_open_element(writer
, config_element_channels
);
1499 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1504 cds_lfht_for_each_entry(session
->ust_session
->domain_global
.channels
->ht
,
1505 &iter
.iter
, node
, node
) {
1506 ust_chan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
1507 if (domain
== ust_chan
->domain
) {
1508 ret
= save_ust_channel(writer
, ust_chan
, session
->ust_session
);
1518 ret
= config_writer_close_element(writer
);
1520 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1524 if (domain
== LTTNG_DOMAIN_UST
) {
1525 ret
= config_writer_open_element(writer
,
1526 config_element_trackers
);
1528 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1532 ret
= save_pid_tracker(writer
, session
, LTTNG_DOMAIN_UST
);
1538 ret
= config_writer_close_element(writer
);
1545 ret
= config_writer_close_element(writer
);
1547 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1556 int save_domains(struct config_writer
*writer
, struct ltt_session
*session
)
1563 if (!session
->kernel_session
&& !session
->ust_session
) {
1567 ret
= config_writer_open_element(writer
, config_element_domains
);
1569 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1574 if (session
->kernel_session
) {
1575 ret
= config_writer_open_element(writer
,
1576 config_element_domain
);
1578 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1582 ret
= save_kernel_session(writer
, session
);
1587 ret
= config_writer_open_element(writer
,
1588 config_element_trackers
);
1590 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1594 ret
= save_pid_tracker(writer
, session
, LTTNG_DOMAIN_KERNEL
);
1600 ret
= config_writer_close_element(writer
);
1602 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1606 ret
= config_writer_close_element(writer
);
1608 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1613 if (session
->ust_session
) {
1614 ret
= save_ust_domain(writer
, session
, LTTNG_DOMAIN_UST
);
1619 ret
= save_ust_domain(writer
, session
, LTTNG_DOMAIN_JUL
);
1624 ret
= save_ust_domain(writer
, session
, LTTNG_DOMAIN_LOG4J
);
1629 ret
= save_ust_domain(writer
, session
, LTTNG_DOMAIN_PYTHON
);
1636 ret
= config_writer_close_element(writer
);
1638 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1646 int save_consumer_output(struct config_writer
*writer
,
1647 struct consumer_output
*output
)
1654 ret
= config_writer_open_element(writer
, config_element_consumer_output
);
1656 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1660 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1663 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1667 ret
= config_writer_open_element(writer
, config_element_destination
);
1669 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1673 switch (output
->type
) {
1674 case CONSUMER_DST_LOCAL
:
1675 ret
= config_writer_write_element_string(writer
,
1676 config_element_path
, output
->dst
.trace_path
);
1678 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1682 case CONSUMER_DST_NET
:
1686 uri
= zmalloc(PATH_MAX
);
1688 ret
= LTTNG_ERR_NOMEM
;
1692 ret
= config_writer_open_element(writer
, config_element_net_output
);
1694 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1695 goto end_net_output
;
1698 if (output
->dst
.net
.control_isset
&&
1699 output
->dst
.net
.data_isset
) {
1700 ret
= uri_to_str_url(&output
->dst
.net
.control
, uri
, PATH_MAX
);
1702 ret
= LTTNG_ERR_INVALID
;
1703 goto end_net_output
;
1706 ret
= config_writer_write_element_string(writer
,
1707 config_element_control_uri
, uri
);
1709 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1710 goto end_net_output
;
1713 ret
= uri_to_str_url(&output
->dst
.net
.data
, uri
, PATH_MAX
);
1715 ret
= LTTNG_ERR_INVALID
;
1716 goto end_net_output
;
1719 ret
= config_writer_write_element_string(writer
,
1720 config_element_data_uri
, uri
);
1722 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1723 goto end_net_output
;
1732 ret
= !output
->dst
.net
.control_isset
?
1733 LTTNG_ERR_URL_CTRL_MISS
:
1734 LTTNG_ERR_URL_DATA_MISS
;
1739 ret
= config_writer_close_element(writer
);
1741 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1747 ERR("Unsupported consumer output type.");
1748 ret
= LTTNG_ERR_INVALID
;
1753 ret
= config_writer_close_element(writer
);
1755 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1759 /* /consumer_output */
1760 ret
= config_writer_close_element(writer
);
1762 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1770 int save_snapshot_outputs(struct config_writer
*writer
,
1771 struct snapshot
*snapshot
)
1774 struct lttng_ht_iter iter
;
1775 struct snapshot_output
*output
;
1780 ret
= config_writer_open_element(writer
, config_element_snapshot_outputs
);
1782 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1787 cds_lfht_for_each_entry(snapshot
->output_ht
->ht
, &iter
.iter
, output
,
1789 ret
= config_writer_open_element(writer
,
1790 config_element_output
);
1792 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1796 ret
= config_writer_write_element_string(writer
,
1797 config_element_name
, output
->name
);
1799 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1803 ret
= config_writer_write_element_unsigned_int(writer
,
1804 config_element_max_size
, output
->max_size
);
1806 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1810 ret
= save_consumer_output(writer
, output
->consumer
);
1816 ret
= config_writer_close_element(writer
);
1818 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1824 /* /snapshot_outputs */
1825 ret
= config_writer_close_element(writer
);
1827 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1839 int save_session_output(struct config_writer
*writer
,
1840 struct ltt_session
*session
)
1847 if ((session
->snapshot_mode
&& session
->snapshot
.nb_output
== 0) ||
1848 (!session
->snapshot_mode
&& !session
->consumer
)) {
1849 /* Session is in no output mode */
1854 ret
= config_writer_open_element(writer
, config_element_output
);
1856 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1860 if (session
->snapshot_mode
) {
1861 ret
= save_snapshot_outputs(writer
, &session
->snapshot
);
1866 if (session
->consumer
) {
1867 ret
= save_consumer_output(writer
, session
->consumer
);
1875 ret
= config_writer_close_element(writer
);
1877 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1885 * Save the given session.
1887 * Return 0 on success else a LTTNG_ERR* code.
1890 int save_session(struct ltt_session
*session
,
1891 struct lttng_save_session_attr
*attr
, lttng_sock_cred
*creds
)
1894 unsigned int file_opened
= 0; /* Indicate if the file has been opened */
1895 char config_file_path
[PATH_MAX
];
1897 struct config_writer
*writer
= NULL
;
1898 size_t session_name_len
;
1899 const char *provided_path
;
1905 session_name_len
= strlen(session
->name
);
1906 memset(config_file_path
, 0, sizeof(config_file_path
));
1908 if (!session_access_ok(session
,
1909 LTTNG_SOCK_GET_UID_CRED(creds
),
1910 LTTNG_SOCK_GET_GID_CRED(creds
))) {
1911 ret
= LTTNG_ERR_EPERM
;
1915 provided_path
= lttng_save_session_attr_get_output_url(attr
);
1916 if (provided_path
) {
1917 DBG3("Save session in provided path %s", provided_path
);
1918 len
= strlen(provided_path
);
1919 if (len
>= sizeof(config_file_path
)) {
1920 ret
= LTTNG_ERR_SET_URL
;
1923 strncpy(config_file_path
, provided_path
, len
);
1926 char *home_dir
= utils_get_user_home_dir(
1927 LTTNG_SOCK_GET_UID_CRED(creds
));
1929 ret
= LTTNG_ERR_SET_URL
;
1933 ret_len
= snprintf(config_file_path
, sizeof(config_file_path
),
1934 DEFAULT_SESSION_HOME_CONFIGPATH
, home_dir
);
1937 PERROR("snprintf save session");
1938 ret
= LTTNG_ERR_SET_URL
;
1945 * Check the path fits in the config file path dst including the '/'
1946 * followed by trailing .lttng extension and the NULL terminated string.
1948 if ((len
+ session_name_len
+ 2 +
1949 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
))
1950 > sizeof(config_file_path
)) {
1951 ret
= LTTNG_ERR_SET_URL
;
1955 ret
= run_as_mkdir_recursive(config_file_path
, S_IRWXU
| S_IRWXG
,
1956 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1958 ret
= LTTNG_ERR_SET_URL
;
1963 * At this point, we know that everything fits in the buffer. Validation
1964 * was done just above.
1966 config_file_path
[len
++] = '/';
1967 strncpy(config_file_path
+ len
, session
->name
, session_name_len
);
1968 len
+= session_name_len
;
1969 strcpy(config_file_path
+ len
, DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1970 len
+= sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1971 config_file_path
[len
] = '\0';
1973 if (!access(config_file_path
, F_OK
) && !attr
->overwrite
) {
1974 /* File exists, notify the user since the overwrite flag is off. */
1975 ret
= LTTNG_ERR_SAVE_FILE_EXIST
;
1979 fd
= run_as_open(config_file_path
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1980 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1981 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1983 PERROR("Could not create configuration file");
1984 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1989 writer
= config_writer_create(fd
, 1);
1991 ret
= LTTNG_ERR_NOMEM
;
1995 ret
= config_writer_open_element(writer
, config_element_sessions
);
1997 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2001 ret
= config_writer_open_element(writer
, config_element_session
);
2003 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2007 ret
= config_writer_write_element_string(writer
, config_element_name
,
2010 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2014 if(session
->shm_path
[0] != '\0') {
2015 ret
= config_writer_write_element_string(writer
,
2016 config_element_shared_memory_path
,
2019 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2024 ret
= save_domains(writer
, session
);
2029 ret
= config_writer_write_element_bool(writer
, config_element_started
,
2032 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2036 if (session
->snapshot_mode
|| session
->live_timer
) {
2037 ret
= config_writer_open_element(writer
, config_element_attributes
);
2039 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2043 if (session
->snapshot_mode
) {
2044 ret
= config_writer_write_element_bool(writer
,
2045 config_element_snapshot_mode
, 1);
2047 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2051 ret
= config_writer_write_element_unsigned_int(writer
,
2052 config_element_live_timer_interval
, session
->live_timer
);
2054 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2060 ret
= config_writer_close_element(writer
);
2062 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2067 ret
= save_session_output(writer
, session
);
2073 ret
= config_writer_close_element(writer
);
2075 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2080 ret
= config_writer_close_element(writer
);
2082 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
2086 if (writer
&& config_writer_destroy(writer
)) {
2087 /* Preserve the original error code */
2088 ret
= ret
? ret
: LTTNG_ERR_SAVE_IO_FAIL
;
2091 /* Delete file in case of error */
2092 if (file_opened
&& unlink(config_file_path
)) {
2093 PERROR("Unlinking XML session configuration.");
2100 int cmd_save_sessions(struct lttng_save_session_attr
*attr
,
2101 lttng_sock_cred
*creds
)
2104 const char *session_name
;
2105 struct ltt_session
*session
;
2107 session_lock_list();
2109 session_name
= lttng_save_session_attr_get_session_name(attr
);
2111 session
= session_find_by_name(session_name
);
2113 ret
= LTTNG_ERR_SESS_NOT_FOUND
;
2117 session_lock(session
);
2118 ret
= save_session(session
, attr
, creds
);
2119 session_unlock(session
);
2124 struct ltt_session_list
*list
= session_get_list();
2126 cds_list_for_each_entry(session
, &list
->head
, list
) {
2127 session_lock(session
);
2128 ret
= save_session(session
, attr
, creds
);
2129 session_unlock(session
);
2131 /* Don't abort if we don't have the required permissions. */
2132 if (ret
&& ret
!= LTTNG_ERR_EPERM
) {
2140 session_unlock_list();