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/config.h>
28 #include <common/utils.h>
29 #include <common/runas.h>
30 #include <lttng/save-internal.h>
35 #include "trace-ust.h"
38 int save_kernel_channel_attributes(struct config_writer
*writer
,
39 struct lttng_channel_attr
*attr
)
43 ret
= config_writer_write_element_string(writer
,
44 config_element_overwrite_mode
,
45 attr
->overwrite
? config_overwrite_mode_overwrite
:
46 config_overwrite_mode_discard
);
51 ret
= config_writer_write_element_unsigned_int(writer
,
52 config_element_subbuf_size
, attr
->subbuf_size
);
57 ret
= config_writer_write_element_unsigned_int(writer
,
58 config_element_num_subbuf
,
64 ret
= config_writer_write_element_unsigned_int(writer
,
65 config_element_switch_timer_interval
,
66 attr
->switch_timer_interval
);
71 ret
= config_writer_write_element_unsigned_int(writer
,
72 config_element_read_timer_interval
,
73 attr
->read_timer_interval
);
78 ret
= config_writer_write_element_string(writer
,
79 config_element_output_type
,
80 attr
->output
== LTTNG_EVENT_SPLICE
?
81 config_output_type_splice
: config_output_type_mmap
);
86 ret
= config_writer_write_element_unsigned_int(writer
,
87 config_element_tracefile_size
, attr
->tracefile_size
);
92 ret
= config_writer_write_element_unsigned_int(writer
,
93 config_element_tracefile_count
,
94 attr
->tracefile_count
);
99 ret
= config_writer_write_element_unsigned_int(writer
,
100 config_element_live_timer_interval
,
101 attr
->live_timer_interval
);
106 return ret
? LTTNG_ERR_SAVE_IO_FAIL
: 0;
110 int save_ust_channel_attributes(struct config_writer
*writer
,
111 struct lttng_ust_channel_attr
*attr
)
115 ret
= config_writer_write_element_string(writer
,
116 config_element_overwrite_mode
,
117 attr
->overwrite
? config_overwrite_mode_overwrite
:
118 config_overwrite_mode_discard
);
123 ret
= config_writer_write_element_unsigned_int(writer
,
124 config_element_subbuf_size
, attr
->subbuf_size
);
129 ret
= config_writer_write_element_unsigned_int(writer
,
130 config_element_num_subbuf
,
136 ret
= config_writer_write_element_unsigned_int(writer
,
137 config_element_switch_timer_interval
,
138 attr
->switch_timer_interval
);
143 ret
= config_writer_write_element_unsigned_int(writer
,
144 config_element_read_timer_interval
,
145 attr
->read_timer_interval
);
150 ret
= config_writer_write_element_string(writer
,
151 config_element_output_type
,
152 attr
->output
== LTTNG_UST_MMAP
?
153 config_output_type_mmap
: config_output_type_splice
);
158 return ret
? LTTNG_ERR_SAVE_IO_FAIL
: 0;
162 const char *get_kernel_instrumentation_string(
163 enum lttng_kernel_instrumentation instrumentation
)
165 const char *instrumentation_string
;
167 switch (instrumentation
) {
168 case LTTNG_KERNEL_ALL
:
169 instrumentation_string
= config_event_type_all
;
171 case LTTNG_KERNEL_TRACEPOINT
:
172 instrumentation_string
= config_event_type_tracepoint
;
174 case LTTNG_KERNEL_KPROBE
:
175 instrumentation_string
= config_event_type_kprobe
;
177 case LTTNG_KERNEL_FUNCTION
:
178 instrumentation_string
= config_event_type_function
;
180 case LTTNG_KERNEL_KRETPROBE
:
181 instrumentation_string
= config_event_type_kretprobe
;
183 case LTTNG_KERNEL_NOOP
:
184 instrumentation_string
= config_event_type_noop
;
186 case LTTNG_KERNEL_SYSCALL
:
187 instrumentation_string
= config_event_type_syscall
;
190 instrumentation_string
= NULL
;
193 return instrumentation_string
;
197 const char *get_kernel_context_type_string(
198 enum lttng_kernel_context_type context_type
)
200 const char *context_type_string
;
202 switch (context_type
) {
203 case LTTNG_KERNEL_CONTEXT_PID
:
204 context_type_string
= config_event_context_pid
;
206 case LTTNG_KERNEL_CONTEXT_PROCNAME
:
207 context_type_string
= config_event_context_procname
;
209 case LTTNG_KERNEL_CONTEXT_PRIO
:
210 context_type_string
= config_event_context_prio
;
212 case LTTNG_KERNEL_CONTEXT_NICE
:
213 context_type_string
= config_event_context_nice
;
215 case LTTNG_KERNEL_CONTEXT_VPID
:
216 context_type_string
= config_event_context_vpid
;
218 case LTTNG_KERNEL_CONTEXT_TID
:
219 context_type_string
= config_event_context_tid
;
221 case LTTNG_KERNEL_CONTEXT_VTID
:
222 context_type_string
= config_event_context_vtid
;
224 case LTTNG_KERNEL_CONTEXT_PPID
:
225 context_type_string
= config_event_context_ppid
;
227 case LTTNG_KERNEL_CONTEXT_VPPID
:
228 context_type_string
= config_event_context_vppid
;
230 case LTTNG_KERNEL_CONTEXT_HOSTNAME
:
231 context_type_string
= config_event_context_hostname
;
234 context_type_string
= NULL
;
237 return context_type_string
;
241 const char *get_ust_context_type_string(
242 enum lttng_ust_context_type context_type
)
244 const char *context_type_string
;
246 switch (context_type
) {
247 case LTTNG_UST_CONTEXT_PROCNAME
:
248 context_type_string
= config_event_context_procname
;
250 case LTTNG_UST_CONTEXT_VPID
:
251 context_type_string
= config_event_context_vpid
;
253 case LTTNG_UST_CONTEXT_VTID
:
254 context_type_string
= config_event_context_vtid
;
256 case LTTNG_UST_CONTEXT_IP
:
257 context_type_string
= config_event_context_ip
;
259 case LTTNG_UST_CONTEXT_PTHREAD_ID
:
260 context_type_string
= config_event_context_pthread_id
;
262 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
:
264 * Error, should not be stored in the XML, perf contexts
265 * are stored as a node of type event_perf_context_type.
268 context_type_string
= NULL
;
272 return context_type_string
;
276 const char *get_buffer_type_string(
277 enum lttng_buffer_type buffer_type
)
279 const char *buffer_type_string
;
281 switch (buffer_type
) {
282 case LTTNG_BUFFER_PER_PID
:
283 buffer_type_string
= config_buffer_type_per_pid
;
285 case LTTNG_BUFFER_PER_UID
:
286 buffer_type_string
= config_buffer_type_per_uid
;
288 case LTTNG_BUFFER_GLOBAL
:
289 buffer_type_string
= config_buffer_type_global
;
292 buffer_type_string
= NULL
;
295 return buffer_type_string
;
299 const char *get_loglevel_type_string(
300 enum lttng_ust_loglevel_type loglevel_type
)
302 const char *loglevel_type_string
;
304 switch (loglevel_type
) {
305 case LTTNG_UST_LOGLEVEL_ALL
:
306 loglevel_type_string
= config_loglevel_type_all
;
308 case LTTNG_UST_LOGLEVEL_RANGE
:
309 loglevel_type_string
= config_loglevel_type_range
;
311 case LTTNG_UST_LOGLEVEL_SINGLE
:
312 loglevel_type_string
= config_loglevel_type_single
;
315 loglevel_type_string
= NULL
;
318 return loglevel_type_string
;
322 int save_kernel_event(struct config_writer
*writer
,
323 struct ltt_kernel_event
*event
)
326 const char *instrumentation_type
;
328 ret
= config_writer_open_element(writer
, config_element_event
);
330 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
334 if (event
->event
->name
[0]) {
335 ret
= config_writer_write_element_string(writer
,
336 config_element_name
, event
->event
->name
);
338 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
343 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
346 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
350 instrumentation_type
= get_kernel_instrumentation_string(
351 event
->event
->instrumentation
);
352 if (!instrumentation_type
) {
353 ret
= LTTNG_ERR_INVALID
;
357 ret
= config_writer_write_element_string(writer
, config_element_type
,
358 instrumentation_type
);
360 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
364 if (event
->event
->instrumentation
== LTTNG_KERNEL_FUNCTION
||
365 event
->event
->instrumentation
== LTTNG_KERNEL_KPROBE
||
366 event
->event
->instrumentation
== LTTNG_KERNEL_KRETPROBE
) {
368 ret
= config_writer_open_element(writer
,
369 config_element_attributes
);
371 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
375 switch (event
->event
->instrumentation
) {
376 case LTTNG_KERNEL_SYSCALL
:
377 case LTTNG_KERNEL_FUNCTION
:
378 ret
= config_writer_open_element(writer
,
379 config_element_function_attributes
);
381 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
385 ret
= config_writer_write_element_string(writer
,
387 event
->event
->u
.ftrace
.symbol_name
);
389 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
393 /* /function attributes */
394 ret
= config_writer_close_element(writer
);
396 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
400 case LTTNG_KERNEL_KPROBE
:
401 case LTTNG_KERNEL_KRETPROBE
:
403 const char *symbol_name
;
407 if (event
->event
->instrumentation
==
408 LTTNG_KERNEL_KPROBE
) {
410 * Comments in lttng-kernel.h mention that
411 * either addr or symbol_name are set, not both.
413 addr
= event
->event
->u
.kprobe
.addr
;
414 offset
= event
->event
->u
.kprobe
.offset
;
415 symbol_name
= addr
? NULL
:
416 event
->event
->u
.kprobe
.symbol_name
;
419 event
->event
->u
.kretprobe
.symbol_name
;
420 addr
= event
->event
->u
.kretprobe
.addr
;
421 offset
= event
->event
->u
.kretprobe
.offset
;
424 ret
= config_writer_open_element(writer
,
425 config_element_probe_attributes
);
427 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
432 ret
= config_writer_write_element_string(writer
,
433 config_element_symbol_name
,
436 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
442 ret
= config_writer_write_element_unsigned_int(
443 writer
, config_element_address
, addr
);
445 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
451 ret
= config_writer_write_element_unsigned_int(
452 writer
, config_element_offset
, offset
);
454 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
459 ret
= config_writer_close_element(writer
);
461 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
467 ERR("Unsupported kernel instrumentation type.");
468 ret
= LTTNG_ERR_INVALID
;
473 ret
= config_writer_close_element(writer
);
475 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
481 ret
= config_writer_close_element(writer
);
483 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
491 int save_kernel_syscall(struct config_writer
*writer
,
492 struct ltt_kernel_channel
*kchan
)
496 struct lttng_event
*events
= NULL
;
501 count
= syscall_list_channel(kchan
, &events
, 0);
503 /* No syscalls, just gracefully return. */
508 for (i
= 0; i
< count
; i
++) {
509 struct ltt_kernel_event
*kevent
;
511 /* Create a temporary kevent in order to save it. */
512 kevent
= trace_kernel_create_event(&events
[i
]);
517 /* Init list in order so the destroy call can del the node. */
518 CDS_INIT_LIST_HEAD(&kevent
->list
);
520 ret
= save_kernel_event(writer
, kevent
);
521 trace_kernel_destroy_event(kevent
);
527 /* Everything went well */
536 int save_kernel_events(struct config_writer
*writer
,
537 struct ltt_kernel_channel
*kchan
)
540 struct ltt_kernel_event
*event
;
542 ret
= config_writer_open_element(writer
, config_element_events
);
544 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
548 cds_list_for_each_entry(event
, &kchan
->events_list
.head
, list
) {
549 ret
= save_kernel_event(writer
, event
);
555 /* Save syscalls if any. */
556 ret
= save_kernel_syscall(writer
, kchan
);
562 ret
= config_writer_close_element(writer
);
564 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
572 int save_ust_event(struct config_writer
*writer
,
573 struct ltt_ust_event
*event
)
576 const char *loglevel_type_string
;
578 ret
= config_writer_open_element(writer
, config_element_event
);
580 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
584 if (event
->attr
.name
[0]) {
585 ret
= config_writer_write_element_string(writer
,
586 config_element_name
, event
->attr
.name
);
588 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
593 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
596 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
600 if (event
->attr
.instrumentation
!= LTTNG_UST_TRACEPOINT
) {
601 ERR("Unsupported UST instrumentation type.");
602 ret
= LTTNG_ERR_INVALID
;
605 ret
= config_writer_write_element_string(writer
, config_element_type
,
606 config_event_type_tracepoint
);
608 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
612 loglevel_type_string
= get_loglevel_type_string(
613 event
->attr
.loglevel_type
);
614 if (!loglevel_type_string
) {
615 ERR("Unsupported UST loglevel type.");
616 ret
= LTTNG_ERR_INVALID
;
620 ret
= config_writer_write_element_string(writer
,
621 config_element_loglevel_type
, loglevel_type_string
);
623 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
627 ret
= config_writer_write_element_signed_int(writer
,
628 config_element_loglevel
, event
->attr
.loglevel
);
630 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
634 if (event
->filter_expression
) {
635 ret
= config_writer_write_element_string(writer
,
636 config_element_filter
, event
->filter_expression
);
638 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
643 if (event
->exclusion
&& event
->exclusion
->count
) {
646 ret
= config_writer_open_element(writer
,
647 config_element_exclusions
);
649 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
653 for (i
= 0; i
< event
->exclusion
->count
; i
++) {
654 ret
= config_writer_write_element_string(writer
,
655 config_element_exclusion
,
656 &event
->exclusion
->names
[0][i
]);
658 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
664 ret
= config_writer_close_element(writer
);
666 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
672 ret
= config_writer_close_element(writer
);
674 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
682 int save_ust_events(struct config_writer
*writer
,
683 struct lttng_ht
*events
)
686 struct ltt_ust_event
*event
;
687 struct lttng_ht_node_str
*node
;
688 struct lttng_ht_iter iter
;
690 ret
= config_writer_open_element(writer
, config_element_events
);
692 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
697 cds_lfht_for_each_entry(events
->ht
, &iter
.iter
, node
, node
) {
698 event
= caa_container_of(node
, struct ltt_ust_event
, node
);
700 ret
= save_ust_event(writer
, event
);
709 ret
= config_writer_close_element(writer
);
711 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
719 int save_kernel_context(struct config_writer
*writer
,
720 struct lttng_kernel_context
*ctx
)
728 ret
= config_writer_open_element(writer
, config_element_context
);
730 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
734 if (ctx
->ctx
== LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER
) {
735 ret
= config_writer_open_element(writer
, config_element_perf
);
737 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
741 ret
= config_writer_write_element_unsigned_int(writer
,
742 config_element_type
, ctx
->u
.perf_counter
.type
);
744 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
748 ret
= config_writer_write_element_unsigned_int(writer
,
749 config_element_config
, ctx
->u
.perf_counter
.config
);
751 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
755 ret
= config_writer_write_element_string(writer
,
756 config_element_name
, ctx
->u
.perf_counter
.name
);
758 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
763 ret
= config_writer_close_element(writer
);
765 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
769 const char *context_type_string
=
770 get_kernel_context_type_string(ctx
->ctx
);
772 if (!context_type_string
) {
773 ERR("Unsupported kernel context type.");
774 ret
= LTTNG_ERR_INVALID
;
778 ret
= config_writer_write_element_string(writer
,
779 config_element_type
, context_type_string
);
781 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
787 ret
= config_writer_close_element(writer
);
789 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
798 int save_kernel_contexts(struct config_writer
*writer
,
799 struct ltt_kernel_channel
*kchan
)
802 struct ltt_kernel_context
*ctx
;
804 if (cds_list_empty(&kchan
->ctx_list
)) {
809 ret
= config_writer_open_element(writer
, config_element_contexts
);
811 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
815 cds_list_for_each_entry(ctx
, &kchan
->ctx_list
, list
) {
816 ret
= save_kernel_context(writer
, &ctx
->ctx
);
823 ret
= config_writer_close_element(writer
);
825 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
833 int save_ust_context(struct config_writer
*writer
,
834 struct cds_list_head
*ctx_list
)
837 struct ltt_ust_context
*ctx
;
842 ret
= config_writer_open_element(writer
, config_element_contexts
);
844 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
848 cds_list_for_each_entry(ctx
, ctx_list
, list
) {
849 const char *context_type_string
;
852 ret
= config_writer_open_element(writer
,
853 config_element_context
);
855 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
859 if (ctx
->ctx
.ctx
== LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
) {
860 /* Perf contexts are saved as event_perf_context_type */
861 ret
= config_writer_open_element(writer
,
862 config_element_perf
);
864 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
868 ret
= config_writer_write_element_unsigned_int(writer
,
870 ctx
->ctx
.u
.perf_counter
.type
);
872 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
876 ret
= config_writer_write_element_unsigned_int(writer
,
877 config_element_config
,
878 ctx
->ctx
.u
.perf_counter
.config
);
880 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
884 ret
= config_writer_write_element_string(writer
,
886 ctx
->ctx
.u
.perf_counter
.name
);
888 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
893 ret
= config_writer_close_element(writer
);
895 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
899 /* Save context as event_context_type_type */
900 context_type_string
= get_ust_context_type_string(
902 if (!context_type_string
) {
903 ERR("Unsupported UST context type.")
904 ret
= LTTNG_ERR_INVALID
;
908 ret
= config_writer_write_element_string(writer
,
909 config_element_type
, context_type_string
);
911 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
917 ret
= config_writer_close_element(writer
);
919 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
925 ret
= config_writer_close_element(writer
);
927 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
935 int save_kernel_channel(struct config_writer
*writer
,
936 struct ltt_kernel_channel
*kchan
)
943 ret
= config_writer_open_element(writer
, config_element_channel
);
945 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
949 ret
= config_writer_write_element_string(writer
, config_element_name
,
950 kchan
->channel
->name
);
952 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
956 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
957 kchan
->channel
->enabled
);
959 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
963 ret
= save_kernel_channel_attributes(writer
, &kchan
->channel
->attr
);
968 ret
= save_kernel_events(writer
, kchan
);
973 ret
= save_kernel_contexts(writer
, kchan
);
979 ret
= config_writer_close_element(writer
);
981 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
989 int save_ust_channel(struct config_writer
*writer
,
990 struct ltt_ust_channel
*ust_chan
,
991 struct ltt_ust_session
*session
)
999 ret
= config_writer_open_element(writer
, config_element_channel
);
1001 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1005 ret
= config_writer_write_element_string(writer
, config_element_name
,
1008 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1012 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1015 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1019 ret
= save_ust_channel_attributes(writer
, &ust_chan
->attr
);
1024 ret
= config_writer_write_element_unsigned_int(writer
,
1025 config_element_tracefile_size
, ust_chan
->tracefile_size
);
1027 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1031 ret
= config_writer_write_element_unsigned_int(writer
,
1032 config_element_tracefile_count
, ust_chan
->tracefile_count
);
1034 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1038 ret
= config_writer_write_element_unsigned_int(writer
,
1039 config_element_live_timer_interval
,
1040 session
->live_timer_interval
);
1042 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1046 ret
= save_ust_events(writer
, ust_chan
->events
);
1048 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1052 ret
= save_ust_context(writer
, &ust_chan
->ctx_list
);
1058 ret
= config_writer_close_element(writer
);
1060 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1068 int save_kernel_session(struct config_writer
*writer
,
1069 struct ltt_session
*session
)
1072 struct ltt_kernel_channel
*kchan
;
1077 ret
= config_writer_write_element_string(writer
, config_element_type
,
1078 config_domain_type_kernel
);
1080 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1084 ret
= config_writer_write_element_string(writer
,
1085 config_element_buffer_type
, config_buffer_type_global
);
1087 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1091 ret
= config_writer_open_element(writer
,
1092 config_element_channels
);
1094 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1098 cds_list_for_each_entry(kchan
, &session
->kernel_session
->channel_list
.head
,
1100 ret
= save_kernel_channel(writer
, kchan
);
1107 ret
= config_writer_close_element(writer
);
1109 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1117 int save_ust_session(struct config_writer
*writer
,
1118 struct ltt_session
*session
, int save_agent
)
1121 struct ltt_ust_channel
*ust_chan
;
1122 const char *buffer_type_string
;
1123 struct lttng_ht_node_str
*node
;
1124 struct lttng_ht_iter iter
;
1129 ret
= config_writer_write_element_string(writer
, config_element_type
,
1130 save_agent
? config_domain_type_jul
: config_domain_type_ust
);
1132 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1136 buffer_type_string
= get_buffer_type_string(
1137 session
->ust_session
->buffer_type
);
1138 if (!buffer_type_string
) {
1139 ERR("Unsupported buffer type.");
1140 ret
= LTTNG_ERR_INVALID
;
1144 ret
= config_writer_write_element_string(writer
,
1145 config_element_buffer_type
, buffer_type_string
);
1147 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1151 ret
= config_writer_open_element(writer
, config_element_channels
);
1153 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1158 cds_lfht_for_each_entry(session
->ust_session
->domain_global
.channels
->ht
,
1159 &iter
.iter
, node
, node
) {
1162 ust_chan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
1163 agent_channel
= !strcmp(DEFAULT_JUL_CHANNEL_NAME
, ust_chan
->name
) ||
1164 !strcmp(DEFAULT_LOG4J_CHANNEL_NAME
, ust_chan
->name
);
1165 if (!(save_agent
^ agent_channel
)) {
1166 ret
= save_ust_channel(writer
, ust_chan
, session
->ust_session
);
1176 ret
= config_writer_close_element(writer
);
1178 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1186 int save_domains(struct config_writer
*writer
, struct ltt_session
*session
)
1193 if (!session
->kernel_session
&& !session
->ust_session
) {
1197 ret
= config_writer_open_element(writer
, config_element_domains
);
1199 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1204 if (session
->kernel_session
) {
1205 ret
= config_writer_open_element(writer
,
1206 config_element_domain
);
1208 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1212 ret
= save_kernel_session(writer
, session
);
1218 ret
= config_writer_close_element(writer
);
1220 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1225 if (session
->ust_session
) {
1226 unsigned long agent_count
;
1228 ret
= config_writer_open_element(writer
,
1229 config_element_domain
);
1231 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1235 ret
= save_ust_session(writer
, session
, 0);
1241 ret
= config_writer_close_element(writer
);
1243 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1249 lttng_ht_get_count(session
->ust_session
->agents
);
1252 if (agent_count
> 0) {
1253 ret
= config_writer_open_element(writer
,
1254 config_element_domain
);
1256 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1260 ret
= save_ust_session(writer
, session
, 1);
1266 ret
= config_writer_close_element(writer
);
1268 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1274 if (session
->ust_session
) {
1278 ret
= config_writer_close_element(writer
);
1280 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1288 int save_consumer_output(struct config_writer
*writer
,
1289 struct consumer_output
*output
)
1296 ret
= config_writer_open_element(writer
, config_element_consumer_output
);
1298 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1302 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1305 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1309 ret
= config_writer_open_element(writer
, config_element_destination
);
1311 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1315 switch (output
->type
) {
1316 case CONSUMER_DST_LOCAL
:
1317 ret
= config_writer_write_element_string(writer
,
1318 config_element_path
, output
->dst
.trace_path
);
1320 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1324 case CONSUMER_DST_NET
:
1328 uri
= zmalloc(PATH_MAX
);
1330 ret
= LTTNG_ERR_NOMEM
;
1334 ret
= config_writer_open_element(writer
, config_element_net_output
);
1336 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1337 goto end_net_output
;
1340 if (output
->dst
.net
.control_isset
&&
1341 output
->dst
.net
.data_isset
) {
1342 ret
= uri_to_str_url(&output
->dst
.net
.control
, uri
, PATH_MAX
);
1344 ret
= LTTNG_ERR_INVALID
;
1345 goto end_net_output
;
1348 ret
= config_writer_write_element_string(writer
,
1349 config_element_control_uri
, uri
);
1351 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1352 goto end_net_output
;
1355 ret
= uri_to_str_url(&output
->dst
.net
.data
, uri
, PATH_MAX
);
1357 ret
= LTTNG_ERR_INVALID
;
1358 goto end_net_output
;
1361 ret
= config_writer_write_element_string(writer
,
1362 config_element_data_uri
, uri
);
1364 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1365 goto end_net_output
;
1374 ret
= !output
->dst
.net
.control_isset
?
1375 LTTNG_ERR_URL_CTRL_MISS
:
1376 LTTNG_ERR_URL_DATA_MISS
;
1381 ret
= config_writer_close_element(writer
);
1383 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1389 ERR("Unsupported consumer output type.");
1390 ret
= LTTNG_ERR_INVALID
;
1395 ret
= config_writer_close_element(writer
);
1397 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1401 /* /consumer_output */
1402 ret
= config_writer_close_element(writer
);
1404 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1412 int save_snapshot_outputs(struct config_writer
*writer
,
1413 struct snapshot
*snapshot
)
1416 struct lttng_ht_iter iter
;
1417 struct snapshot_output
*output
;
1422 ret
= config_writer_open_element(writer
, config_element_snapshot_outputs
);
1424 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1429 cds_lfht_for_each_entry(snapshot
->output_ht
->ht
, &iter
.iter
, output
,
1431 ret
= config_writer_open_element(writer
,
1432 config_element_output
);
1434 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1438 ret
= config_writer_write_element_string(writer
,
1439 config_element_name
, output
->name
);
1441 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1445 ret
= config_writer_write_element_unsigned_int(writer
,
1446 config_element_max_size
, output
->max_size
);
1448 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1452 ret
= save_consumer_output(writer
, output
->consumer
);
1458 ret
= config_writer_close_element(writer
);
1460 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1466 /* /snapshot_outputs */
1467 ret
= config_writer_close_element(writer
);
1469 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1481 int save_session_output(struct config_writer
*writer
,
1482 struct ltt_session
*session
)
1489 if ((session
->snapshot_mode
&& session
->snapshot
.nb_output
== 0) ||
1490 (!session
->snapshot_mode
&& !session
->consumer
)) {
1491 /* Session is in no output mode */
1496 ret
= config_writer_open_element(writer
, config_element_output
);
1498 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1502 if (session
->snapshot_mode
) {
1503 ret
= save_snapshot_outputs(writer
, &session
->snapshot
);
1508 if (session
->consumer
) {
1509 ret
= save_consumer_output(writer
, session
->consumer
);
1517 ret
= config_writer_close_element(writer
);
1519 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1527 * Save the given session.
1529 * Return 0 on success else a LTTNG_ERR* code.
1532 int save_session(struct ltt_session
*session
,
1533 struct lttng_save_session_attr
*attr
, lttng_sock_cred
*creds
)
1536 unsigned int file_opened
= 0; /* Indicate if the file has been opened */
1537 char config_file_path
[PATH_MAX
];
1539 struct config_writer
*writer
= NULL
;
1540 size_t session_name_len
;
1541 const char *provided_path
;
1547 session_name_len
= strlen(session
->name
);
1548 memset(config_file_path
, 0, sizeof(config_file_path
));
1550 if (!session_access_ok(session
,
1551 LTTNG_SOCK_GET_UID_CRED(creds
),
1552 LTTNG_SOCK_GET_GID_CRED(creds
))) {
1553 ret
= LTTNG_ERR_EPERM
;
1557 provided_path
= lttng_save_session_attr_get_output_url(attr
);
1558 if (provided_path
) {
1559 DBG3("Save session in provided path %s", provided_path
);
1560 len
= strlen(provided_path
);
1561 if (len
>= sizeof(config_file_path
)) {
1562 ret
= LTTNG_ERR_SET_URL
;
1565 strncpy(config_file_path
, provided_path
, len
);
1568 char *home_dir
= utils_get_user_home_dir(
1569 LTTNG_SOCK_GET_UID_CRED(creds
));
1571 ret
= LTTNG_ERR_SET_URL
;
1575 ret_len
= snprintf(config_file_path
, sizeof(config_file_path
),
1576 DEFAULT_SESSION_HOME_CONFIGPATH
, home_dir
);
1579 PERROR("snprintf save session");
1580 ret
= LTTNG_ERR_SET_URL
;
1587 * Check the path fits in the config file path dst including the '/'
1588 * followed by trailing .lttng extension and the NULL terminated string.
1590 if ((len
+ session_name_len
+ 2 +
1591 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
))
1592 > sizeof(config_file_path
)) {
1593 ret
= LTTNG_ERR_SET_URL
;
1597 ret
= run_as_mkdir_recursive(config_file_path
, S_IRWXU
| S_IRWXG
,
1598 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1600 ret
= LTTNG_ERR_SET_URL
;
1605 * At this point, we know that everything fits in the buffer. Validation
1606 * was done just above.
1608 config_file_path
[len
++] = '/';
1609 strncpy(config_file_path
+ len
, session
->name
, session_name_len
);
1610 len
+= session_name_len
;
1611 strcpy(config_file_path
+ len
, DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1612 len
+= sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1613 config_file_path
[len
] = '\0';
1615 if (!access(config_file_path
, F_OK
) && !attr
->overwrite
) {
1616 /* File exists, notify the user since the overwrite flag is off. */
1617 ret
= LTTNG_ERR_SAVE_FILE_EXIST
;
1621 fd
= run_as_open(config_file_path
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1622 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1623 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1625 PERROR("Could not create configuration file");
1626 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1631 writer
= config_writer_create(fd
, 1);
1633 ret
= LTTNG_ERR_NOMEM
;
1637 ret
= config_writer_open_element(writer
, config_element_sessions
);
1639 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1643 ret
= config_writer_open_element(writer
, config_element_session
);
1645 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1649 ret
= config_writer_write_element_string(writer
, config_element_name
,
1652 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1656 ret
= save_domains(writer
, session
);
1661 ret
= config_writer_write_element_bool(writer
, config_element_started
,
1664 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1668 if (session
->snapshot_mode
|| session
->live_timer
) {
1669 ret
= config_writer_open_element(writer
, config_element_attributes
);
1671 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1675 if (session
->snapshot_mode
) {
1676 ret
= config_writer_write_element_bool(writer
,
1677 config_element_snapshot_mode
, 1);
1679 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1683 ret
= config_writer_write_element_unsigned_int(writer
,
1684 config_element_live_timer_interval
, session
->live_timer
);
1686 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1692 ret
= config_writer_close_element(writer
);
1694 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1699 ret
= save_session_output(writer
, session
);
1705 ret
= config_writer_close_element(writer
);
1707 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1712 ret
= config_writer_close_element(writer
);
1714 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1718 if (writer
&& config_writer_destroy(writer
)) {
1719 /* Preserve the original error code */
1720 ret
= ret
? ret
: LTTNG_ERR_SAVE_IO_FAIL
;
1723 /* Delete file in case of error */
1724 if (file_opened
&& unlink(config_file_path
)) {
1725 PERROR("Unlinking XML session configuration.");
1732 int cmd_save_sessions(struct lttng_save_session_attr
*attr
,
1733 lttng_sock_cred
*creds
)
1736 const char *session_name
;
1737 struct ltt_session
*session
;
1739 session_lock_list();
1741 session_name
= lttng_save_session_attr_get_session_name(attr
);
1743 session
= session_find_by_name(session_name
);
1745 ret
= LTTNG_ERR_SESS_NOT_FOUND
;
1749 session_lock(session
);
1750 ret
= save_session(session
, attr
, creds
);
1751 session_unlock(session
);
1756 struct ltt_session_list
*list
= session_get_list();
1758 cds_list_for_each_entry(session
, &list
->head
, list
) {
1759 session_lock(session
);
1760 ret
= save_session(session
, attr
, creds
);
1761 session_unlock(session
);
1763 /* Don't abort if we don't have the required permissions. */
1764 if (ret
&& ret
!= LTTNG_ERR_EPERM
) {
1772 session_unlock_list();