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