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