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/config/config-session-internal.h>
29 #include <common/utils.h>
30 #include <common/runas.h>
31 #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
;
263 context_type_string
= NULL
;
266 return context_type_string
;
270 const char *get_buffer_type_string(
271 enum lttng_buffer_type buffer_type
)
273 const char *buffer_type_string
;
275 switch (buffer_type
) {
276 case LTTNG_BUFFER_PER_PID
:
277 buffer_type_string
= config_buffer_type_per_pid
;
279 case LTTNG_BUFFER_PER_UID
:
280 buffer_type_string
= config_buffer_type_per_uid
;
282 case LTTNG_BUFFER_GLOBAL
:
283 buffer_type_string
= config_buffer_type_global
;
286 buffer_type_string
= NULL
;
289 return buffer_type_string
;
293 const char *get_loglevel_type_string(
294 enum lttng_ust_loglevel_type loglevel_type
)
296 const char *loglevel_type_string
;
298 switch (loglevel_type
) {
299 case LTTNG_UST_LOGLEVEL_ALL
:
300 loglevel_type_string
= config_loglevel_type_all
;
302 case LTTNG_UST_LOGLEVEL_RANGE
:
303 loglevel_type_string
= config_loglevel_type_range
;
305 case LTTNG_UST_LOGLEVEL_SINGLE
:
306 loglevel_type_string
= config_loglevel_type_single
;
309 loglevel_type_string
= NULL
;
312 return loglevel_type_string
;
316 int save_kernel_event(struct config_writer
*writer
,
317 struct ltt_kernel_event
*event
)
320 const char *instrumentation_type
;
322 ret
= config_writer_open_element(writer
, config_element_event
);
324 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
328 if (event
->event
->name
[0]) {
329 ret
= config_writer_write_element_string(writer
,
330 config_element_name
, event
->event
->name
);
332 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
337 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
340 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
344 instrumentation_type
= get_kernel_instrumentation_string(
345 event
->event
->instrumentation
);
346 if (!instrumentation_type
) {
347 ret
= LTTNG_ERR_INVALID
;
351 ret
= config_writer_write_element_string(writer
, config_element_type
,
352 instrumentation_type
);
354 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
358 if (event
->event
->instrumentation
== LTTNG_KERNEL_FUNCTION
||
359 event
->event
->instrumentation
== LTTNG_KERNEL_KPROBE
||
360 event
->event
->instrumentation
== LTTNG_KERNEL_KRETPROBE
) {
362 ret
= config_writer_open_element(writer
,
363 config_element_attributes
);
365 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
369 switch (event
->event
->instrumentation
) {
370 case LTTNG_KERNEL_FUNCTION
:
371 ret
= config_writer_open_element(writer
,
372 config_element_function_attributes
);
374 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
378 ret
= config_writer_write_element_string(writer
,
380 event
->event
->u
.ftrace
.symbol_name
);
382 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
386 /* /function attributes */
387 ret
= config_writer_close_element(writer
);
389 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
393 case LTTNG_KERNEL_KPROBE
:
394 case LTTNG_KERNEL_KRETPROBE
:
396 const char *symbol_name
;
400 if (event
->event
->instrumentation
==
401 LTTNG_KERNEL_KPROBE
) {
403 * Comments in lttng-kernel.h mention that
404 * either addr or symbol_name are set, not both.
406 addr
= event
->event
->u
.kprobe
.addr
;
407 offset
= event
->event
->u
.kprobe
.offset
;
408 symbol_name
= addr
? NULL
:
409 event
->event
->u
.kprobe
.symbol_name
;
412 event
->event
->u
.kretprobe
.symbol_name
;
413 addr
= event
->event
->u
.kretprobe
.addr
;
414 offset
= event
->event
->u
.kretprobe
.offset
;
417 ret
= config_writer_open_element(writer
,
418 config_element_probe_attributes
);
420 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
425 ret
= config_writer_write_element_string(writer
,
426 config_element_symbol_name
,
429 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
435 ret
= config_writer_write_element_unsigned_int(
436 writer
, config_element_address
, addr
);
438 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
444 ret
= config_writer_write_element_unsigned_int(
445 writer
, config_element_offset
, offset
);
447 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
452 ret
= config_writer_close_element(writer
);
454 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
460 ERR("Unsupported kernel instrumentation type.");
461 ret
= LTTNG_ERR_INVALID
;
466 ret
= config_writer_close_element(writer
);
468 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
474 ret
= config_writer_close_element(writer
);
476 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
484 int save_kernel_events(struct config_writer
*writer
,
485 struct ltt_kernel_event_list
*event_list
)
488 struct ltt_kernel_event
*event
;
490 ret
= config_writer_open_element(writer
, config_element_events
);
492 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
496 cds_list_for_each_entry(event
, &event_list
->head
, list
) {
497 ret
= save_kernel_event(writer
, event
);
504 ret
= config_writer_close_element(writer
);
506 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
514 int save_ust_event(struct config_writer
*writer
,
515 struct ltt_ust_event
*event
)
518 const char *loglevel_type_string
;
520 ret
= config_writer_open_element(writer
, config_element_event
);
522 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
526 if (event
->attr
.name
[0]) {
527 ret
= config_writer_write_element_string(writer
,
528 config_element_name
, event
->attr
.name
);
530 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
535 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
538 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
542 if (event
->attr
.instrumentation
!= LTTNG_UST_TRACEPOINT
) {
543 ERR("Unsupported UST instrumentation type.");
544 ret
= LTTNG_ERR_INVALID
;
547 ret
= config_writer_write_element_string(writer
, config_element_type
,
548 config_event_type_tracepoint
);
550 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
554 loglevel_type_string
= get_loglevel_type_string(
555 event
->attr
.loglevel_type
);
556 if (!loglevel_type_string
) {
557 ERR("Unsupported UST loglevel type.");
558 ret
= LTTNG_ERR_INVALID
;
562 ret
= config_writer_write_element_string(writer
,
563 config_element_loglevel_type
, loglevel_type_string
);
565 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
569 ret
= config_writer_write_element_signed_int(writer
,
570 config_element_loglevel
, event
->attr
.loglevel
);
572 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
576 if (event
->filter_expression
) {
577 ret
= config_writer_write_element_string(writer
,
578 config_element_filter
, event
->filter_expression
);
580 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
585 if (event
->exclusion
&& event
->exclusion
->count
) {
588 ret
= config_writer_open_element(writer
,
589 config_element_exclusions
);
591 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
595 for (i
= 0; i
< event
->exclusion
->count
; i
++) {
596 ret
= config_writer_write_element_string(writer
,
597 config_element_exclusion
,
598 &event
->exclusion
->names
[0][i
]);
600 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
606 ret
= config_writer_close_element(writer
);
608 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
614 ret
= config_writer_close_element(writer
);
616 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
624 int save_ust_events(struct config_writer
*writer
,
625 struct lttng_ht
*events
)
628 struct ltt_ust_event
*event
;
629 struct lttng_ht_node_str
*node
;
630 struct lttng_ht_iter iter
;
632 ret
= config_writer_open_element(writer
, config_element_events
);
634 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
639 cds_lfht_for_each_entry(events
->ht
, &iter
.iter
, node
, node
) {
640 event
= caa_container_of(node
, struct ltt_ust_event
, node
);
642 ret
= save_ust_event(writer
, event
);
651 ret
= config_writer_close_element(writer
);
653 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
661 int save_kernel_context(struct config_writer
*writer
,
662 struct lttng_kernel_context
*ctx
)
670 ret
= config_writer_open_element(writer
, config_element_contexts
);
672 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
676 ret
= config_writer_open_element(writer
, config_element_context
);
678 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
682 if (ctx
->ctx
== LTTNG_KERNEL_CONTEXT_PERF_COUNTER
) {
683 ret
= config_writer_open_element(writer
, config_element_perf
);
685 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
689 ret
= config_writer_write_element_unsigned_int(writer
,
690 config_element_type
, ctx
->u
.perf_counter
.type
);
692 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
696 ret
= config_writer_write_element_unsigned_int(writer
,
697 config_element_config
, ctx
->u
.perf_counter
.config
);
699 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
703 ret
= config_writer_write_element_string(writer
,
704 config_element_name
, ctx
->u
.perf_counter
.name
);
706 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
711 ret
= config_writer_close_element(writer
);
713 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
717 const char *context_type_string
=
718 get_kernel_context_type_string(ctx
->ctx
);
720 if (!context_type_string
) {
721 ERR("Unsupported kernel context type.");
722 ret
= LTTNG_ERR_INVALID
;
726 ret
= config_writer_write_element_string(writer
,
727 config_element_type
, context_type_string
);
729 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
735 ret
= config_writer_close_element(writer
);
737 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
742 ret
= config_writer_close_element(writer
);
744 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
752 int save_ust_context(struct config_writer
*writer
,
753 struct cds_list_head
*ctx_list
)
756 struct ltt_ust_context
*ctx
;
761 ret
= config_writer_open_element(writer
, config_element_contexts
);
763 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
767 cds_list_for_each_entry(ctx
, ctx_list
, list
) {
768 const char *context_type_string
;
770 context_type_string
= get_ust_context_type_string(ctx
->ctx
.ctx
);
771 if (!context_type_string
) {
772 ERR("Unsupported UST context type.")
773 ret
= LTTNG_ERR_INVALID
;
777 ret
= config_writer_open_element(writer
,
778 config_element_context
);
780 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
784 ret
= config_writer_write_element_string(writer
,
785 config_element_type
, context_type_string
);
787 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
792 ret
= config_writer_close_element(writer
);
794 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
800 ret
= config_writer_close_element(writer
);
802 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
810 int save_kernel_channel(struct config_writer
*writer
,
811 struct ltt_kernel_channel
*kchan
)
818 ret
= config_writer_open_element(writer
, config_element_channel
);
820 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
824 ret
= config_writer_write_element_string(writer
, config_element_name
,
825 kchan
->channel
->name
);
827 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
831 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
832 kchan
->channel
->enabled
);
834 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
838 ret
= save_kernel_channel_attributes(writer
, &kchan
->channel
->attr
);
843 ret
= save_kernel_events(writer
, &kchan
->events_list
);
848 ret
= save_kernel_context(writer
, kchan
->ctx
);
854 ret
= config_writer_close_element(writer
);
856 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
864 int save_ust_channel(struct config_writer
*writer
,
865 struct ltt_ust_channel
*ust_chan
,
866 struct ltt_ust_session
*session
)
874 ret
= config_writer_open_element(writer
, config_element_channel
);
876 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
880 ret
= config_writer_write_element_string(writer
, config_element_name
,
883 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
887 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
890 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
894 ret
= save_ust_channel_attributes(writer
, &ust_chan
->attr
);
899 ret
= config_writer_write_element_unsigned_int(writer
,
900 config_element_tracefile_size
, ust_chan
->tracefile_size
);
902 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
906 ret
= config_writer_write_element_unsigned_int(writer
,
907 config_element_tracefile_count
, ust_chan
->tracefile_count
);
909 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
913 ret
= config_writer_write_element_unsigned_int(writer
,
914 config_element_live_timer_interval
,
915 session
->live_timer_interval
);
917 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
921 ret
= save_ust_events(writer
, ust_chan
->events
);
923 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
927 ret
= save_ust_context(writer
, &ust_chan
->ctx_list
);
933 ret
= config_writer_close_element(writer
);
935 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
943 int save_kernel_session(struct config_writer
*writer
,
944 struct ltt_session
*session
)
947 struct ltt_kernel_channel
*kchan
;
952 ret
= config_writer_write_element_string(writer
, config_element_type
,
953 config_domain_type_kernel
);
955 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
959 ret
= config_writer_write_element_string(writer
,
960 config_element_buffer_type
, config_buffer_type_global
);
962 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
966 ret
= config_writer_open_element(writer
,
967 config_element_channels
);
969 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
973 cds_list_for_each_entry(kchan
, &session
->kernel_session
->channel_list
.head
,
975 ret
= save_kernel_channel(writer
, kchan
);
982 ret
= config_writer_close_element(writer
);
984 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
992 int save_ust_session(struct config_writer
*writer
,
993 struct ltt_session
*session
, int save_jul
)
996 struct ltt_ust_channel
*ust_chan
;
997 const char *buffer_type_string
;
998 struct lttng_ht_node_str
*node
;
999 struct lttng_ht_iter iter
;
1004 ret
= config_writer_write_element_string(writer
, config_element_type
,
1005 save_jul
? config_domain_type_jul
: config_domain_type_ust
);
1007 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1011 buffer_type_string
= get_buffer_type_string(
1012 session
->ust_session
->buffer_type
);
1013 if (!buffer_type_string
) {
1014 ERR("Unsupported buffer type.");
1015 ret
= LTTNG_ERR_INVALID
;
1019 ret
= config_writer_write_element_string(writer
,
1020 config_element_buffer_type
, buffer_type_string
);
1022 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1026 ret
= config_writer_open_element(writer
, config_element_channels
);
1028 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1033 cds_lfht_for_each_entry(session
->ust_session
->domain_global
.channels
->ht
,
1034 &iter
.iter
, node
, node
) {
1037 ust_chan
= caa_container_of(node
, struct ltt_ust_channel
, node
);
1038 jul_channel
= !strcmp(DEFAULT_JUL_CHANNEL_NAME
, ust_chan
->name
);
1039 if (!(save_jul
^ jul_channel
)) {
1040 ret
= save_ust_channel(writer
, ust_chan
, session
->ust_session
);
1050 ret
= config_writer_close_element(writer
);
1052 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1060 int save_domains(struct config_writer
*writer
, struct ltt_session
*session
)
1067 if (!session
->kernel_session
&& !session
->ust_session
) {
1071 ret
= config_writer_open_element(writer
, config_element_domains
);
1073 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1078 if (session
->kernel_session
) {
1079 ret
= config_writer_open_element(writer
,
1080 config_element_domain
);
1082 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1086 ret
= save_kernel_session(writer
, session
);
1092 ret
= config_writer_close_element(writer
);
1094 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1099 if (session
->ust_session
) {
1100 ret
= config_writer_open_element(writer
,
1101 config_element_domain
);
1103 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1107 ret
= save_ust_session(writer
, session
, 0);
1113 ret
= config_writer_close_element(writer
);
1115 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1120 if (session
->ust_session
&&
1121 session
->ust_session
->domain_jul
.being_used
) {
1122 ret
= config_writer_open_element(writer
,
1123 config_element_domain
);
1125 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1129 ret
= save_ust_session(writer
, session
, 1);
1135 ret
= config_writer_close_element(writer
);
1137 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1143 ret
= config_writer_close_element(writer
);
1145 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1153 int save_consumer_output(struct config_writer
*writer
,
1154 struct consumer_output
*output
)
1161 ret
= config_writer_open_element(writer
, config_element_consumer_output
);
1163 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1167 ret
= config_writer_write_element_bool(writer
, config_element_enabled
,
1170 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1174 ret
= config_writer_open_element(writer
, config_element_destination
);
1176 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1180 switch (output
->type
) {
1181 case CONSUMER_DST_LOCAL
:
1182 ret
= config_writer_write_element_string(writer
,
1183 config_element_path
, output
->dst
.trace_path
);
1185 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1189 case CONSUMER_DST_NET
:
1193 uri
= zmalloc(PATH_MAX
);
1195 ret
= LTTNG_ERR_NOMEM
;
1199 ret
= config_writer_open_element(writer
, config_element_net_output
);
1201 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1202 goto end_net_output
;
1205 if (output
->dst
.net
.control_isset
&&
1206 output
->dst
.net
.data_isset
) {
1207 ret
= uri_to_str_url(&output
->dst
.net
.control
, uri
, PATH_MAX
);
1209 ret
= LTTNG_ERR_INVALID
;
1210 goto end_net_output
;
1213 ret
= config_writer_write_element_string(writer
,
1214 config_element_control_uri
, uri
);
1216 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1217 goto end_net_output
;
1220 ret
= uri_to_str_url(&output
->dst
.net
.data
, uri
, PATH_MAX
);
1222 ret
= LTTNG_ERR_INVALID
;
1223 goto end_net_output
;
1226 ret
= config_writer_write_element_string(writer
,
1227 config_element_data_uri
, uri
);
1229 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1230 goto end_net_output
;
1239 ret
= !output
->dst
.net
.control_isset
?
1240 LTTNG_ERR_URL_CTRL_MISS
:
1241 LTTNG_ERR_URL_DATA_MISS
;
1246 ret
= config_writer_close_element(writer
);
1248 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1254 ERR("Unsupported consumer output type.");
1255 ret
= LTTNG_ERR_INVALID
;
1260 ret
= config_writer_close_element(writer
);
1262 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1266 /* /consumer_output */
1267 ret
= config_writer_close_element(writer
);
1269 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1277 int save_snapshot_outputs(struct config_writer
*writer
,
1278 struct snapshot
*snapshot
)
1281 struct lttng_ht_iter iter
;
1282 struct snapshot_output
*output
;
1287 ret
= config_writer_open_element(writer
, config_element_snapshot_outputs
);
1289 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1294 cds_lfht_for_each_entry(snapshot
->output_ht
->ht
, &iter
.iter
, output
,
1296 ret
= config_writer_open_element(writer
,
1297 config_element_output
);
1299 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1303 ret
= config_writer_write_element_string(writer
,
1304 config_element_name
, output
->name
);
1306 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1310 ret
= config_writer_write_element_unsigned_int(writer
,
1311 config_element_max_size
, output
->max_size
);
1313 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1317 ret
= save_consumer_output(writer
, output
->consumer
);
1323 ret
= config_writer_close_element(writer
);
1325 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1331 /* /snapshot_outputs */
1332 ret
= config_writer_close_element(writer
);
1334 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1346 int save_session_output(struct config_writer
*writer
,
1347 struct ltt_session
*session
)
1354 if ((session
->snapshot_mode
&& session
->snapshot
.nb_output
== 0) ||
1355 (!session
->snapshot_mode
&& !session
->consumer
)) {
1356 /* Session is in no output mode */
1361 ret
= config_writer_open_element(writer
, config_element_output
);
1363 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1367 if (session
->snapshot_mode
) {
1368 ret
= save_snapshot_outputs(writer
, &session
->snapshot
);
1373 if (session
->consumer
) {
1374 ret
= save_consumer_output(writer
, session
->consumer
);
1382 ret
= config_writer_close_element(writer
);
1384 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1392 * Save the given session.
1394 * Return 0 on success else a LTTNG_ERR* code.
1397 int save_session(struct ltt_session
*session
,
1398 struct lttng_save_session_attr
*attr
, lttng_sock_cred
*creds
)
1401 unsigned int file_opened
= 0; /* Indicate if the file has been opened */
1402 char config_file_path
[PATH_MAX
];
1404 struct config_writer
*writer
= NULL
;
1405 size_t session_name_len
;
1406 const char *provided_path
;
1412 session_name_len
= strlen(session
->name
);
1414 if (!session_access_ok(session
,
1415 LTTNG_SOCK_GET_UID_CRED(creds
),
1416 LTTNG_SOCK_GET_GID_CRED(creds
))) {
1417 ret
= LTTNG_ERR_EPERM
;
1421 provided_path
= lttng_save_session_attr_get_output_url(attr
);
1422 if (provided_path
) {
1423 len
= strlen(provided_path
);
1424 if (len
>= sizeof(config_file_path
)) {
1425 ret
= LTTNG_ERR_SET_URL
;
1428 strncpy(config_file_path
, provided_path
, len
);
1431 char *home_dir
= utils_get_user_home_dir(
1432 LTTNG_SOCK_GET_UID_CRED(creds
));
1434 ret
= LTTNG_ERR_SET_URL
;
1438 ret_len
= snprintf(config_file_path
, sizeof(config_file_path
),
1439 DEFAULT_SESSION_HOME_CONFIGPATH
, home_dir
);
1442 PERROR("snprintf save session");
1443 ret
= LTTNG_ERR_SET_URL
;
1450 * Check the path fits in the config file path dst including the '/'
1451 * followed by trailing .lttng extension and the NULL terminated string.
1453 if ((len
+ session_name_len
+ 2 +
1454 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION
))
1455 > sizeof(config_file_path
)) {
1456 ret
= LTTNG_ERR_SET_URL
;
1460 ret
= run_as_mkdir_recursive(config_file_path
, S_IRWXU
| S_IRWXG
,
1461 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1463 ret
= LTTNG_ERR_SET_URL
;
1468 * At this point, we know that everything fits in the buffer. Validation
1469 * was done just above.
1471 config_file_path
[len
++] = '/';
1472 strncpy(config_file_path
+ len
, session
->name
, session_name_len
);
1473 len
+= session_name_len
;
1474 strcpy(config_file_path
+ len
, DEFAULT_SESSION_CONFIG_FILE_EXTENSION
);
1476 if (!access(config_file_path
, F_OK
) && !attr
->overwrite
) {
1477 /* A file with the same name already exists, skip */
1481 fd
= run_as_open(config_file_path
, O_CREAT
| O_WRONLY
| O_TRUNC
,
1482 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
,
1483 LTTNG_SOCK_GET_UID_CRED(creds
), LTTNG_SOCK_GET_GID_CRED(creds
));
1485 PERROR("Could not create configuration file");
1486 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1491 writer
= config_writer_create(fd
);
1493 ret
= LTTNG_ERR_NOMEM
;
1497 ret
= config_writer_open_element(writer
, config_element_sessions
);
1499 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1503 ret
= config_writer_open_element(writer
, config_element_session
);
1505 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1509 ret
= config_writer_write_element_string(writer
, config_element_name
,
1512 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1516 ret
= save_domains(writer
, session
);
1521 ret
= config_writer_write_element_bool(writer
, config_element_started
,
1524 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1528 if (session
->snapshot_mode
|| session
->live_timer
) {
1529 ret
= config_writer_open_element(writer
, config_element_attributes
);
1531 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1535 if (session
->snapshot_mode
) {
1536 ret
= config_writer_write_element_bool(writer
,
1537 config_element_snapshot_mode
, 1);
1539 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1543 ret
= config_writer_write_element_signed_int(writer
,
1544 config_element_live_timer_interval
, session
->live_timer
);
1546 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1552 ret
= config_writer_close_element(writer
);
1554 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1559 ret
= save_session_output(writer
, session
);
1565 ret
= config_writer_close_element(writer
);
1567 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1572 ret
= config_writer_close_element(writer
);
1574 ret
= LTTNG_ERR_SAVE_IO_FAIL
;
1578 if (writer
&& config_writer_destroy(writer
)) {
1579 /* Preserve the original error code */
1580 ret
= ret
? ret
: LTTNG_ERR_SAVE_IO_FAIL
;
1583 /* Delete file in case of error */
1584 if (file_opened
&& unlink(config_file_path
)) {
1585 PERROR("Unlinking XML session configuration.");
1592 int cmd_save_sessions(struct lttng_save_session_attr
*attr
,
1593 lttng_sock_cred
*creds
)
1596 const char *session_name
;
1597 struct ltt_session
*session
;
1599 session_lock_list();
1601 session_name
= lttng_save_session_attr_get_session_name(attr
);
1603 session
= session_find_by_name(session_name
);
1605 ret
= LTTNG_ERR_SESS_NOT_FOUND
;
1609 session_lock(session
);
1610 ret
= save_session(session
, attr
, creds
);
1611 session_unlock(session
);
1616 struct ltt_session_list
*list
= session_get_list();
1618 cds_list_for_each_entry(session
, &list
->head
, list
) {
1619 session_lock(session
);
1620 ret
= save_session(session
, attr
, creds
);
1621 session_unlock(session
);
1623 /* Don't abort if we don't have the required permissions. */
1624 if (ret
&& ret
!= LTTNG_ERR_EPERM
) {
1632 session_unlock_list();