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