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