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.
23 #include <urcu/uatomic.h>
26 #include <common/defaults.h>
27 #include <common/error.h>
28 #include <common/config/config.h>
29 #include <common/utils.h>
30 #include <common/runas.h>
31 #include <lttng/save-internal.h>
36 #include "trace-ust.h"
39 int save_kernel_channel_attributes(struct config_writer
*writer
,
40 struct lttng_channel_attr
*attr
)
44 ret
= config_writer_write_element_string(writer
,
45 config_element_overwrite_mode
,
46 attr
->overwrite
? config_overwrite_mode_overwrite
:
47 config_overwrite_mode_discard
);
52 ret
= config_writer_write_element_unsigned_int(writer
,
53 config_element_subbuf_size
, attr
->subbuf_size
);
58 ret
= config_writer_write_element_unsigned_int(writer
,
59 config_element_num_subbuf
,
65 ret
= config_writer_write_element_unsigned_int(writer
,
66 config_element_switch_timer_interval
,
67 attr
->switch_timer_interval
);
72 ret
= config_writer_write_element_unsigned_int(writer
,
73 config_element_read_timer_interval
,
74 attr
->read_timer_interval
);
79 ret
= config_writer_write_element_string(writer
,
80 config_element_output_type
,
81 attr
->output
== LTTNG_EVENT_SPLICE
?
82 config_output_type_splice
: config_output_type_mmap
);
87 ret
= config_writer_write_element_unsigned_int(writer
,
88 config_element_tracefile_size
, attr
->tracefile_size
);
93 ret
= config_writer_write_element_unsigned_int(writer
,
94 config_element_tracefile_count
,
95 attr
->tracefile_count
);
100 ret
= config_writer_write_element_unsigned_int(writer
,
101 config_element_live_timer_interval
,
102 attr
->live_timer_interval
);
107 return ret
? LTTNG_ERR_SAVE_IO_FAIL
: 0;
111 int save_ust_channel_attributes(struct config_writer
*writer
,
112 struct lttng_ust_channel_attr
*attr
)
116 ret
= config_writer_write_element_string(writer
,
117 config_element_overwrite_mode
,
118 attr
->overwrite
? config_overwrite_mode_overwrite
:
119 config_overwrite_mode_discard
);
124 ret
= config_writer_write_element_unsigned_int(writer
,
125 config_element_subbuf_size
, attr
->subbuf_size
);
130 ret
= config_writer_write_element_unsigned_int(writer
,
131 config_element_num_subbuf
,
137 ret
= config_writer_write_element_unsigned_int(writer
,
138 config_element_switch_timer_interval
,
139 attr
->switch_timer_interval
);
144 ret
= config_writer_write_element_unsigned_int(writer
,
145 config_element_read_timer_interval
,
146 attr
->read_timer_interval
);
151 ret
= config_writer_write_element_string(writer
,
152 config_element_output_type
,
153 attr
->output
== LTTNG_UST_MMAP
?
154 config_output_type_mmap
: config_output_type_splice
);
159 return ret
? LTTNG_ERR_SAVE_IO_FAIL
: 0;
163 const char *get_kernel_instrumentation_string(
164 enum lttng_kernel_instrumentation instrumentation
)
166 const char *instrumentation_string
;
168 switch (instrumentation
) {
169 case LTTNG_KERNEL_ALL
:
170 instrumentation_string
= config_event_type_all
;
172 case LTTNG_KERNEL_TRACEPOINT
:
173 instrumentation_string
= config_event_type_tracepoint
;
175 case LTTNG_KERNEL_KPROBE
:
176 instrumentation_string
= config_event_type_kprobe
;
178 case LTTNG_KERNEL_FUNCTION
:
179 instrumentation_string
= config_event_type_function
;
181 case LTTNG_KERNEL_KRETPROBE
:
182 instrumentation_string
= config_event_type_kretprobe
;
184 case LTTNG_KERNEL_NOOP
:
185 instrumentation_string
= config_event_type_noop
;
187 case LTTNG_KERNEL_SYSCALL
:
188 instrumentation_string
= config_event_type_syscall
;
191 instrumentation_string
= NULL
;
194 return instrumentation_string
;
198 const char *get_kernel_context_type_string(
199 enum lttng_kernel_context_type context_type
)
201 const char *context_type_string
;
203 switch (context_type
) {
204 case LTTNG_KERNEL_CONTEXT_PID
:
205 context_type_string
= config_event_context_pid
;
207 case LTTNG_KERNEL_CONTEXT_PROCNAME
:
208 context_type_string
= config_event_context_procname
;
210 case LTTNG_KERNEL_CONTEXT_PRIO
:
211 context_type_string
= config_event_context_prio
;
213 case LTTNG_KERNEL_CONTEXT_NICE
:
214 context_type_string
= config_event_context_nice
;
216 case LTTNG_KERNEL_CONTEXT_VPID
:
217 context_type_string
= config_event_context_vpid
;
219 case LTTNG_KERNEL_CONTEXT_TID
:
220 context_type_string
= config_event_context_tid
;
222 case LTTNG_KERNEL_CONTEXT_VTID
:
223 context_type_string
= config_event_context_vtid
;
225 case LTTNG_KERNEL_CONTEXT_PPID
:
226 context_type_string
= config_event_context_ppid
;
228 case LTTNG_KERNEL_CONTEXT_VPPID
:
229 context_type_string
= config_event_context_vppid
;
231 case LTTNG_KERNEL_CONTEXT_HOSTNAME
:
232 context_type_string
= config_event_context_hostname
;
235 context_type_string
= NULL
;
238 return context_type_string
;
242 const char *get_ust_context_type_string(
243 enum lttng_ust_context_type context_type
)
245 const char *context_type_string
;
247 switch (context_type
) {
248 case LTTNG_UST_CONTEXT_PROCNAME
:
249 context_type_string
= config_event_context_procname
;
251 case LTTNG_UST_CONTEXT_VPID
:
252 context_type_string
= config_event_context_vpid
;
254 case LTTNG_UST_CONTEXT_VTID
:
255 context_type_string
= config_event_context_vtid
;
257 case LTTNG_UST_CONTEXT_IP
:
258 context_type_string
= config_event_context_ip
;
260 case LTTNG_UST_CONTEXT_PTHREAD_ID
:
261 context_type_string
= config_event_context_pthread_id
;
263 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
:
265 * Error, should not be stored in the XML, perf contexts
266 * are stored as a node of type event_perf_context_type.
269 context_type_string
= NULL
;
273 return context_type_string
;
277 const char *get_buffer_type_string(
278 enum lttng_buffer_type buffer_type
)
280 const char *buffer_type_string
;
282 switch (buffer_type
) {
283 case LTTNG_BUFFER_PER_PID
:
284 buffer_type_string
= config_buffer_type_per_pid
;
286 case LTTNG_BUFFER_PER_UID
:
287 buffer_type_string
= config_buffer_type_per_uid
;
289 case LTTNG_BUFFER_GLOBAL
:
290 buffer_type_string
= config_buffer_type_global
;
293 buffer_type_string
= NULL
;
296 return buffer_type_string
;
300 const char *get_loglevel_type_string(
301 enum lttng_ust_loglevel_type loglevel_type
)
303 const char *loglevel_type_string
;
305 switch (loglevel_type
) {
306 case LTTNG_UST_LOGLEVEL_ALL
:
307 loglevel_type_string
= config_loglevel_type_all
;
309 case LTTNG_UST_LOGLEVEL_RANGE
:
310 loglevel_type_string
= config_loglevel_type_range
;
312 case LTTNG_UST_LOGLEVEL_SINGLE
:
313 loglevel_type_string
= config_loglevel_type_single
;
316 loglevel_type_string
= NULL
;
319 return loglevel_type_string
;
323 int save_kernel_event(struct config_writer
*writer
,
324 struct ltt_kernel_event
*event
)
327 const char *instrumentation_type
;
329 ret
= config_writer_open_element(writer
, config_element_event
);
331 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
335 if (event
->event
->name
[0]) {
336 ret
= config_writer_write_element_string(writer
,
337 config_element_name
, event
->event
->name
);
339 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
344 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
347 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
351 instrumentation_type
= get_kernel_instrumentation_string(
352 event
->event
->instrumentation
);
353 if (!instrumentation_type
) {
354 ret
= LTTNG_ERR_INVALID
;
358 ret
= config_writer_write_element_string(writer
, config_element_type
,
359 instrumentation_type
);
361 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
365 if (event
->event
->instrumentation
== LTTNG_KERNEL_FUNCTION
||
366 event
->event
->instrumentation
== LTTNG_KERNEL_KPROBE
||
367 event
->event
->instrumentation
== LTTNG_KERNEL_KRETPROBE
) {
369 ret
= config_writer_open_element(writer
,
370 config_element_attributes
);
372 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
376 switch (event
->event
->instrumentation
) {
377 case LTTNG_KERNEL_SYSCALL
:
378 case LTTNG_KERNEL_FUNCTION
:
379 ret
= config_writer_open_element(writer
,
380 config_element_function_attributes
);
382 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
386 ret
= config_writer_write_element_string(writer
,
388 event
->event
->u
.ftrace
.symbol_name
);
390 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
394 /* /function attributes */
395 ret
= config_writer_close_element(writer
);
397 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
401 case LTTNG_KERNEL_KPROBE
:
402 case LTTNG_KERNEL_KRETPROBE
:
404 const char *symbol_name
;
408 if (event
->event
->instrumentation
==
409 LTTNG_KERNEL_KPROBE
) {
411 * Comments in lttng-kernel.h mention that
412 * either addr or symbol_name are set, not both.
414 addr
= event
->event
->u
.kprobe
.addr
;
415 offset
= event
->event
->u
.kprobe
.offset
;
416 symbol_name
= addr
? NULL
:
417 event
->event
->u
.kprobe
.symbol_name
;
420 event
->event
->u
.kretprobe
.symbol_name
;
421 addr
= event
->event
->u
.kretprobe
.addr
;
422 offset
= event
->event
->u
.kretprobe
.offset
;
425 ret
= config_writer_open_element(writer
,
426 config_element_probe_attributes
);
428 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
433 ret
= config_writer_write_element_string(writer
,
434 config_element_symbol_name
,
437 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
443 ret
= config_writer_write_element_unsigned_int(
444 writer
, config_element_address
, addr
);
446 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
452 ret
= config_writer_write_element_unsigned_int(
453 writer
, config_element_offset
, offset
);
455 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
460 ret
= config_writer_close_element(writer
);
462 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
468 ERR("Unsupported kernel instrumentation type.");
469 ret
= LTTNG_ERR_INVALID
;
474 ret
= config_writer_close_element(writer
);
476 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
482 ret
= config_writer_close_element(writer
);
484 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
492 int save_kernel_syscall(struct config_writer
*writer
,
493 struct ltt_kernel_channel
*kchan
)
497 struct lttng_event
*events
= NULL
;
502 count
= syscall_list_channel(kchan
, &events
, 0);
504 /* No syscalls, just gracefully return. */
509 for (i
= 0; i
< count
; i
++) {
510 struct ltt_kernel_event
*kevent
;
512 /* Create a temporary kevent in order to save it. */
514 * TODO: struct lttng_event does not really work for a filter,
515 * but unfortunately, it is exposed as external API (and used as
516 * internal representation. Using NULL meanwhile.
518 kevent
= trace_kernel_create_event(&events
[i
],
524 /* Init list in order so the destroy call can del the node. */
525 CDS_INIT_LIST_HEAD(&kevent
->list
);
527 ret
= save_kernel_event(writer
, kevent
);
528 trace_kernel_destroy_event(kevent
);
534 /* Everything went well */
543 int save_kernel_events(struct config_writer
*writer
,
544 struct ltt_kernel_channel
*kchan
)
547 struct ltt_kernel_event
*event
;
549 ret
= config_writer_open_element(writer
, config_element_events
);
551 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
555 cds_list_for_each_entry(event
, &kchan
->events_list
.head
, list
) {
556 ret
= save_kernel_event(writer
, event
);
562 /* Save syscalls if any. */
563 ret
= save_kernel_syscall(writer
, kchan
);
569 ret
= config_writer_close_element(writer
);
571 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
579 int save_ust_event(struct config_writer
*writer
,
580 struct ltt_ust_event
*event
)
583 const char *loglevel_type_string
;
585 ret
= config_writer_open_element(writer
, config_element_event
);
587 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
591 if (event
->attr
.name
[0]) {
592 ret
= config_writer_write_element_string(writer
,
593 config_element_name
, event
->attr
.name
);
595 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
600 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
603 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
607 if (event
->attr
.instrumentation
!= LTTNG_UST_TRACEPOINT
) {
608 ERR("Unsupported UST instrumentation type.");
609 ret
= LTTNG_ERR_INVALID
;
612 ret
= config_writer_write_element_string(writer
, config_element_type
,
613 config_event_type_tracepoint
);
615 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
619 loglevel_type_string
= get_loglevel_type_string(
620 event
->attr
.loglevel_type
);
621 if (!loglevel_type_string
) {
622 ERR("Unsupported UST loglevel type.");
623 ret
= LTTNG_ERR_INVALID
;
627 ret
= config_writer_write_element_string(writer
,
628 config_element_loglevel_type
, loglevel_type_string
);
630 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
634 ret
= config_writer_write_element_signed_int(writer
,
635 config_element_loglevel
, event
->attr
.loglevel
);
637 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
641 if (event
->filter_expression
) {
642 ret
= config_writer_write_element_string(writer
,
643 config_element_filter
, event
->filter_expression
);
645 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
650 if (event
->exclusion
&& event
->exclusion
->count
) {
653 ret
= config_writer_open_element(writer
,
654 config_element_exclusions
);
656 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
660 for (i
= 0; i
< event
->exclusion
->count
; i
++) {
661 ret
= config_writer_write_element_string(writer
,
662 config_element_exclusion
,
663 &event
->exclusion
->names
[0][i
]);
665 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
671 ret
= config_writer_close_element(writer
);
673 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
679 ret
= config_writer_close_element(writer
);
681 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
689 int save_ust_events(struct config_writer
*writer
,
690 struct lttng_ht
*events
)
693 struct ltt_ust_event
*event
;
694 struct lttng_ht_node_str
*node
;
695 struct lttng_ht_iter iter
;
697 ret
= config_writer_open_element(writer
, config_element_events
);
699 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
704 cds_lfht_for_each_entry(events
->ht
, &iter
.iter
, node
, node
) {
705 event
= caa_container_of(node
, struct ltt_ust_event
, node
);
707 ret
= save_ust_event(writer
, event
);
716 ret
= config_writer_close_element(writer
);
718 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
725 /* TODO: save/restore tracker pid */
728 int save_kernel_context(struct config_writer
*writer
,
729 struct lttng_kernel_context
*ctx
)
737 ret
= config_writer_open_element(writer
, config_element_context
);
739 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
743 if (ctx
->ctx
== LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER
) {
744 ret
= config_writer_open_element(writer
, config_element_perf
);
746 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
750 ret
= config_writer_write_element_unsigned_int(writer
,
751 config_element_type
, ctx
->u
.perf_counter
.type
);
753 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
757 ret
= config_writer_write_element_unsigned_int(writer
,
758 config_element_config
, ctx
->u
.perf_counter
.config
);
760 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
764 ret
= config_writer_write_element_string(writer
,
765 config_element_name
, ctx
->u
.perf_counter
.name
);
767 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
772 ret
= config_writer_close_element(writer
);
774 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
778 const char *context_type_string
=
779 get_kernel_context_type_string(ctx
->ctx
);
781 if (!context_type_string
) {
782 ERR("Unsupported kernel context type.");
783 ret
= LTTNG_ERR_INVALID
;
787 ret
= config_writer_write_element_string(writer
,
788 config_element_type
, context_type_string
);
790 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
796 ret
= config_writer_close_element(writer
);
798 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
807 int save_kernel_contexts(struct config_writer
*writer
,
808 struct ltt_kernel_channel
*kchan
)
811 struct ltt_kernel_context
*ctx
;
813 if (cds_list_empty(&kchan
->ctx_list
)) {
818 ret
= config_writer_open_element(writer
, config_element_contexts
);
820 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
824 cds_list_for_each_entry(ctx
, &kchan
->ctx_list
, list
) {
825 ret
= save_kernel_context(writer
, &ctx
->ctx
);
832 ret
= config_writer_close_element(writer
);
834 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
842 int save_ust_context(struct config_writer
*writer
,
843 struct cds_list_head
*ctx_list
)
846 struct ltt_ust_context
*ctx
;
851 ret
= config_writer_open_element(writer
, config_element_contexts
);
853 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
857 cds_list_for_each_entry(ctx
, ctx_list
, list
) {
858 const char *context_type_string
;
861 ret
= config_writer_open_element(writer
,
862 config_element_context
);
864 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
868 if (ctx
->ctx
.ctx
== LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER
) {
869 /* Perf contexts are saved as event_perf_context_type */
870 ret
= config_writer_open_element(writer
,
871 config_element_perf
);
873 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
877 ret
= config_writer_write_element_unsigned_int(writer
,
879 ctx
->ctx
.u
.perf_counter
.type
);
881 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
885 ret
= config_writer_write_element_unsigned_int(writer
,
886 config_element_config
,
887 ctx
->ctx
.u
.perf_counter
.config
);
889 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
893 ret
= config_writer_write_element_string(writer
,
895 ctx
->ctx
.u
.perf_counter
.name
);
897 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
902 ret
= config_writer_close_element(writer
);
904 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
908 /* Save context as event_context_type_type */
909 context_type_string
= get_ust_context_type_string(
911 if (!context_type_string
) {
912 ERR("Unsupported UST context type.")
913 ret
= LTTNG_ERR_INVALID
;
917 ret
= config_writer_write_element_string(writer
,
918 config_element_type
, context_type_string
);
920 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
926 ret
= config_writer_close_element(writer
);
928 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
934 ret
= config_writer_close_element(writer
);
936 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
944 int save_kernel_channel(struct config_writer
*writer
,
945 struct ltt_kernel_channel
*kchan
)
952 ret
= config_writer_open_element(writer
, config_element_channel
);
954 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
958 ret
= config_writer_write_element_string(writer
, config_element_name
,
959 kchan
->channel
->name
);
961 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
965 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
966 kchan
->channel
->enabled
);
968 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
972 ret
= save_kernel_channel_attributes(writer
, &kchan
->channel
->attr
);
977 ret
= save_kernel_events(writer
, kchan
);
982 ret
= save_kernel_contexts(writer
, kchan
);
988 ret
= config_writer_close_element(writer
);
990 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
998 int save_ust_channel(struct config_writer
*writer
,
999 struct ltt_ust_channel
*ust_chan
,
1000 struct ltt_ust_session
*session
)
1008 ret
= config_writer_open_element(writer
, config_element_channel
);
1010 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1014 ret
= config_writer_write_element_string(writer
, config_element_name
,
1017 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1021 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1024 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1028 ret
= save_ust_channel_attributes(writer
, &ust_chan
->attr
);
1033 ret
= config_writer_write_element_unsigned_int(writer
,
1034 config_element_tracefile_size
, ust_chan
->tracefile_size
);
1036 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1040 ret
= config_writer_write_element_unsigned_int(writer
,
1041 config_element_tracefile_count
, ust_chan
->tracefile_count
);
1043 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1047 ret
= config_writer_write_element_unsigned_int(writer
,
1048 config_element_live_timer_interval
,
1049 session
->live_timer_interval
);
1051 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1055 ret
= save_ust_events(writer
, ust_chan
->events
);
1057 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1061 ret
= save_ust_context(writer
, &ust_chan
->ctx_list
);
1067 ret
= config_writer_close_element(writer
);
1069 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1077 int save_kernel_session(struct config_writer
*writer
,
1078 struct ltt_session
*session
)
1081 struct ltt_kernel_channel
*kchan
;
1086 ret
= config_writer_write_element_string(writer
, config_element_type
,
1087 config_domain_type_kernel
);
1089 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1093 ret
= config_writer_write_element_string(writer
,
1094 config_element_buffer_type
, config_buffer_type_global
);
1096 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1100 ret
= config_writer_open_element(writer
,
1101 config_element_channels
);
1103 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1107 cds_list_for_each_entry(kchan
, &session
->kernel_session
->channel_list
.head
,
1109 ret
= save_kernel_channel(writer
, kchan
);
1116 ret
= config_writer_close_element(writer
);
1118 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1126 int save_ust_session(struct config_writer
*writer
,
1127 struct ltt_session
*session
, int save_agent
)
1130 struct ltt_ust_channel
*ust_chan
;
1131 const char *buffer_type_string
;
1132 struct lttng_ht_node_str
*node
;
1133 struct lttng_ht_iter iter
;
1138 ret
= config_writer_write_element_string(writer
, config_element_type
,
1139 save_agent
? config_domain_type_jul
: config_domain_type_ust
);
1141 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1145 buffer_type_string
= get_buffer_type_string(
1146 session
->ust_session
->buffer_type
);
1147 if (!buffer_type_string
) {
1148 ERR("Unsupported buffer type.");
1149 ret
= LTTNG_ERR_INVALID
;
1153 ret
= config_writer_write_element_string(writer
,
1154 config_element_buffer_type
, buffer_type_string
);
1156 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1160 ret
= config_writer_open_element(writer
, config_element_channels
);
1162 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1167 cds_lfht_for_each_entry(session
->ust_session
->domain_global
.channels
->ht
,
1168 &iter
.iter
, node
, node
) {
1171 ust_chan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
1172 agent_channel
= !strcmp(DEFAULT_JUL_CHANNEL_NAME
, ust_chan
->name
) ||
1173 !strcmp(DEFAULT_LOG4J_CHANNEL_NAME
, ust_chan
->name
) ||
1174 !strcmp(DEFAULT_PYTHON_CHANNEL_NAME
, ust_chan
->name
);
1175 if (!(save_agent
^ agent_channel
)) {
1176 ret
= save_ust_channel(writer
, ust_chan
, session
->ust_session
);
1186 ret
= config_writer_close_element(writer
);
1188 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1196 int save_domains(struct config_writer
*writer
, struct ltt_session
*session
)
1203 if (!session
->kernel_session
&& !session
->ust_session
) {
1207 ret
= config_writer_open_element(writer
, config_element_domains
);
1209 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1214 if (session
->kernel_session
) {
1215 ret
= config_writer_open_element(writer
,
1216 config_element_domain
);
1218 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1222 ret
= save_kernel_session(writer
, session
);
1228 ret
= config_writer_close_element(writer
);
1230 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1235 if (session
->ust_session
) {
1236 unsigned long agent_count
;
1238 ret
= config_writer_open_element(writer
,
1239 config_element_domain
);
1241 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1245 ret
= save_ust_session(writer
, session
, 0);
1251 ret
= config_writer_close_element(writer
);
1253 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1259 lttng_ht_get_count(session
->ust_session
->agents
);
1262 if (agent_count
> 0) {
1263 ret
= config_writer_open_element(writer
,
1264 config_element_domain
);
1266 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1270 ret
= save_ust_session(writer
, session
, 1);
1276 ret
= config_writer_close_element(writer
);
1278 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1284 if (session
->ust_session
) {
1288 ret
= config_writer_close_element(writer
);
1290 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1298 int save_consumer_output(struct config_writer
*writer
,
1299 struct consumer_output
*output
)
1306 ret
= config_writer_open_element(writer
, config_element_consumer_output
);
1308 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1312 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1315 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1319 ret
= config_writer_open_element(writer
, config_element_destination
);
1321 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1325 switch (output
->type
) {
1326 case CONSUMER_DST_LOCAL
:
1327 ret
= config_writer_write_element_string(writer
,
1328 config_element_path
, output
->dst
.trace_path
);
1330 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1334 case CONSUMER_DST_NET
:
1338 uri
= zmalloc(PATH_MAX
);
1340 ret
= LTTNG_ERR_NOMEM
;
1344 ret
= config_writer_open_element(writer
, config_element_net_output
);
1346 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1347 goto end_net_output
;
1350 if (output
->dst
.net
.control_isset
&&
1351 output
->dst
.net
.data_isset
) {
1352 ret
= uri_to_str_url(&output
->dst
.net
.control
, uri
, PATH_MAX
);
1354 ret
= LTTNG_ERR_INVALID
;
1355 goto end_net_output
;
1358 ret
= config_writer_write_element_string(writer
,
1359 config_element_control_uri
, uri
);
1361 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1362 goto end_net_output
;
1365 ret
= uri_to_str_url(&output
->dst
.net
.data
, uri
, PATH_MAX
);
1367 ret
= LTTNG_ERR_INVALID
;
1368 goto end_net_output
;
1371 ret
= config_writer_write_element_string(writer
,
1372 config_element_data_uri
, uri
);
1374 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1375 goto end_net_output
;
1384 ret
= !output
->dst
.net
.control_isset
?
1385 LTTNG_ERR_URL_CTRL_MISS
:
1386 LTTNG_ERR_URL_DATA_MISS
;
1391 ret
= config_writer_close_element(writer
);
1393 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1399 ERR("Unsupported consumer output type.");
1400 ret
= LTTNG_ERR_INVALID
;
1405 ret
= config_writer_close_element(writer
);
1407 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1411 /* /consumer_output */
1412 ret
= config_writer_close_element(writer
);
1414 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1422 int save_snapshot_outputs(struct config_writer
*writer
,
1423 struct snapshot
*snapshot
)
1426 struct lttng_ht_iter iter
;
1427 struct snapshot_output
*output
;
1432 ret
= config_writer_open_element(writer
, config_element_snapshot_outputs
);
1434 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1439 cds_lfht_for_each_entry(snapshot
->output_ht
->ht
, &iter
.iter
, output
,
1441 ret
= config_writer_open_element(writer
,
1442 config_element_output
);
1444 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1448 ret
= config_writer_write_element_string(writer
,
1449 config_element_name
, output
->name
);
1451 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1455 ret
= config_writer_write_element_unsigned_int(writer
,
1456 config_element_max_size
, output
->max_size
);
1458 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1462 ret
= save_consumer_output(writer
, output
->consumer
);
1468 ret
= config_writer_close_element(writer
);
1470 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1476 /* /snapshot_outputs */
1477 ret
= config_writer_close_element(writer
);
1479 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1491 int save_session_output(struct config_writer
*writer
,
1492 struct ltt_session
*session
)
1499 if ((session
->snapshot_mode
&& session
->snapshot
.nb_output
== 0) ||
1500 (!session
->snapshot_mode
&& !session
->consumer
)) {
1501 /* Session is in no output mode */
1506 ret
= config_writer_open_element(writer
, config_element_output
);
1508 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1512 if (session
->snapshot_mode
) {
1513 ret
= save_snapshot_outputs(writer
, &session
->snapshot
);
1518 if (session
->consumer
) {
1519 ret
= save_consumer_output(writer
, session
->consumer
);
1527 ret
= config_writer_close_element(writer
);
1529 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1537 * Save the given session.
1539 * Return 0 on success else a LTTNG_ERR* code.
1542 int save_session(struct ltt_session
*session
,
1543 struct lttng_save_session_attr
*attr
, lttng_sock_cred
*creds
)
1546 unsigned int file_opened
= 0; /* Indicate if the file has been opened */
1547 char config_file_path
[PATH_MAX
];
1549 struct config_writer
*writer
= NULL
;
1550 size_t session_name_len
;
1551 const char *provided_path
;
1557 session_name_len
= strlen(session
->name
);
1558 memset(config_file_path
, 0, sizeof(config_file_path
));
1560 if (!session_access_ok(session
,
1561 LTTNG_SOCK_GET_UID_CRED(creds
),
1562 LTTNG_SOCK_GET_GID_CRED(creds
))) {
1563 ret
= LTTNG_ERR_EPERM
;
1567 provided_path
= lttng_save_session_attr_get_output_url(attr
);
1568 if (provided_path
) {
1569 DBG3("Save session in provided path %s", provided_path
);
1570 len
= strlen(provided_path
);
1571 if (len
>= sizeof(config_file_path
)) {
1572 ret
= LTTNG_ERR_SET_URL
;
1575 strncpy(config_file_path
, provided_path
, len
);
1578 char *home_dir
= utils_get_user_home_dir(
1579 LTTNG_SOCK_GET_UID_CRED(creds
));
1581 ret
= LTTNG_ERR_SET_URL
;
1585 ret_len
= snprintf(config_file_path
, sizeof(config_file_path
),
1586 DEFAULT_SESSION_HOME_CONFIGPATH
, home_dir
);
1589 PERROR("snprintf save session");
1590 ret
= LTTNG_ERR_SET_URL
;
1597 * Check the path fits in the config file path dst including the '/'
1598 * followed by trailing .lttng extension and the NULL terminated string.
1600 if ((len
+ session_name_len
+ 2 +
1601 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
))
1602 > sizeof(config_file_path
)) {
1603 ret
= LTTNG_ERR_SET_URL
;
1607 ret
= run_as_mkdir_recursive(config_file_path
, S_IRWXU
| S_IRWXG
,
1608 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1610 ret
= LTTNG_ERR_SET_URL
;
1615 * At this point, we know that everything fits in the buffer. Validation
1616 * was done just above.
1618 config_file_path
[len
++] = '/';
1619 strncpy(config_file_path
+ len
, session
->name
, session_name_len
);
1620 len
+= session_name_len
;
1621 strcpy(config_file_path
+ len
, DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1622 len
+= sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1623 config_file_path
[len
] = '\0';
1625 if (!access(config_file_path
, F_OK
) && !attr
->overwrite
) {
1626 /* File exists, notify the user since the overwrite flag is off. */
1627 ret
= LTTNG_ERR_SAVE_FILE_EXIST
;
1631 fd
= run_as_open(config_file_path
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1632 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1633 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1635 PERROR("Could not create configuration file");
1636 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1641 writer
= config_writer_create(fd
, 1);
1643 ret
= LTTNG_ERR_NOMEM
;
1647 ret
= config_writer_open_element(writer
, config_element_sessions
);
1649 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1653 ret
= config_writer_open_element(writer
, config_element_session
);
1655 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1659 ret
= config_writer_write_element_string(writer
, config_element_name
,
1662 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1666 if(session
->shm_path
[0] != '\0') {
1667 ret
= config_writer_write_element_string(writer
,
1668 config_element_shared_memory_path
,
1671 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1676 ret
= save_domains(writer
, session
);
1681 ret
= config_writer_write_element_bool(writer
, config_element_started
,
1684 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1688 if (session
->snapshot_mode
|| session
->live_timer
) {
1689 ret
= config_writer_open_element(writer
, config_element_attributes
);
1691 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1695 if (session
->snapshot_mode
) {
1696 ret
= config_writer_write_element_bool(writer
,
1697 config_element_snapshot_mode
, 1);
1699 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1703 ret
= config_writer_write_element_unsigned_int(writer
,
1704 config_element_live_timer_interval
, session
->live_timer
);
1706 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1712 ret
= config_writer_close_element(writer
);
1714 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1719 ret
= save_session_output(writer
, session
);
1725 ret
= config_writer_close_element(writer
);
1727 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1732 ret
= config_writer_close_element(writer
);
1734 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1738 if (writer
&& config_writer_destroy(writer
)) {
1739 /* Preserve the original error code */
1740 ret
= ret
? ret
: LTTNG_ERR_SAVE_IO_FAIL
;
1743 /* Delete file in case of error */
1744 if (file_opened
&& unlink(config_file_path
)) {
1745 PERROR("Unlinking XML session configuration.");
1752 int cmd_save_sessions(struct lttng_save_session_attr
*attr
,
1753 lttng_sock_cred
*creds
)
1756 const char *session_name
;
1757 struct ltt_session
*session
;
1759 session_lock_list();
1761 session_name
= lttng_save_session_attr_get_session_name(attr
);
1763 session
= session_find_by_name(session_name
);
1765 ret
= LTTNG_ERR_SESS_NOT_FOUND
;
1769 session_lock(session
);
1770 ret
= save_session(session
, attr
, creds
);
1771 session_unlock(session
);
1776 struct ltt_session_list
*list
= session_get_list();
1778 cds_list_for_each_entry(session
, &list
->head
, list
) {
1779 session_lock(session
);
1780 ret
= save_session(session
, attr
, creds
);
1781 session_unlock(session
);
1783 /* Don't abort if we don't have the required permissions. */
1784 if (ret
&& ret
!= LTTNG_ERR_EPERM
) {
1792 session_unlock_list();