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