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