Test: kernel testing for notification
[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"
0de3eda1 35#include "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:
218 instrumentation_string = config_event_type_kprobe;
219 break;
220 case LTTNG_KERNEL_FUNCTION:
221 instrumentation_string = config_event_type_function;
222 break;
223 case LTTNG_KERNEL_KRETPROBE:
224 instrumentation_string = config_event_type_kretprobe;
225 break;
226 case LTTNG_KERNEL_NOOP:
227 instrumentation_string = config_event_type_noop;
228 break;
229 case LTTNG_KERNEL_SYSCALL:
230 instrumentation_string = config_event_type_syscall;
231 break;
232 default:
233 instrumentation_string = NULL;
234 }
235
236 return instrumentation_string;
237}
238
239static
240const char *get_kernel_context_type_string(
241 enum lttng_kernel_context_type context_type)
242{
243 const char *context_type_string;
244
245 switch (context_type) {
246 case LTTNG_KERNEL_CONTEXT_PID:
247 context_type_string = config_event_context_pid;
248 break;
249 case LTTNG_KERNEL_CONTEXT_PROCNAME:
250 context_type_string = config_event_context_procname;
251 break;
252 case LTTNG_KERNEL_CONTEXT_PRIO:
253 context_type_string = config_event_context_prio;
254 break;
255 case LTTNG_KERNEL_CONTEXT_NICE:
256 context_type_string = config_event_context_nice;
257 break;
258 case LTTNG_KERNEL_CONTEXT_VPID:
259 context_type_string = config_event_context_vpid;
260 break;
261 case LTTNG_KERNEL_CONTEXT_TID:
262 context_type_string = config_event_context_tid;
263 break;
264 case LTTNG_KERNEL_CONTEXT_VTID:
265 context_type_string = config_event_context_vtid;
266 break;
267 case LTTNG_KERNEL_CONTEXT_PPID:
268 context_type_string = config_event_context_ppid;
269 break;
270 case LTTNG_KERNEL_CONTEXT_VPPID:
271 context_type_string = config_event_context_vppid;
272 break;
273 case LTTNG_KERNEL_CONTEXT_HOSTNAME:
274 context_type_string = config_event_context_hostname;
275 break;
1ae5e83e
JD
276 case LTTNG_KERNEL_CONTEXT_INTERRUPTIBLE:
277 context_type_string = config_event_context_interruptible;
278 break;
279 case LTTNG_KERNEL_CONTEXT_PREEMPTIBLE:
280 context_type_string = config_event_context_preemptible;
281 break;
282 case LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE:
283 context_type_string = config_event_context_need_reschedule;
284 break;
285 case LTTNG_KERNEL_CONTEXT_MIGRATABLE:
286 context_type_string = config_event_context_migratable;
287 break;
fb198a11
JG
288 default:
289 context_type_string = NULL;
290 }
291
292 return context_type_string;
293}
294
295static
296const char *get_ust_context_type_string(
297 enum lttng_ust_context_type context_type)
298{
299 const char *context_type_string;
300
301 switch (context_type) {
302 case LTTNG_UST_CONTEXT_PROCNAME:
303 context_type_string = config_event_context_procname;
304 break;
305 case LTTNG_UST_CONTEXT_VPID:
306 context_type_string = config_event_context_vpid;
307 break;
308 case LTTNG_UST_CONTEXT_VTID:
309 context_type_string = config_event_context_vtid;
310 break;
311 case LTTNG_UST_CONTEXT_IP:
312 context_type_string = config_event_context_ip;
313 break;
314 case LTTNG_UST_CONTEXT_PTHREAD_ID:
315 context_type_string = config_event_context_pthread_id;
316 break;
045fc617
JG
317 case LTTNG_UST_CONTEXT_APP_CONTEXT:
318 context_type_string = config_event_context_app;
319 break;
e885a367 320 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
14ce5bd8
JG
321 /*
322 * Error, should not be stored in the XML, perf contexts
323 * are stored as a node of type event_perf_context_type.
324 */
fb198a11
JG
325 default:
326 context_type_string = NULL;
e885a367 327 break;
fb198a11
JG
328 }
329
330 return context_type_string;
331}
332
333static
334const char *get_buffer_type_string(
335 enum lttng_buffer_type buffer_type)
336{
337 const char *buffer_type_string;
338
339 switch (buffer_type) {
340 case LTTNG_BUFFER_PER_PID:
341 buffer_type_string = config_buffer_type_per_pid;
342 break;
343 case LTTNG_BUFFER_PER_UID:
344 buffer_type_string = config_buffer_type_per_uid;
345 break;
346 case LTTNG_BUFFER_GLOBAL:
347 buffer_type_string = config_buffer_type_global;
348 break;
349 default:
350 buffer_type_string = NULL;
351 }
352
353 return buffer_type_string;
354}
355
356static
357const char *get_loglevel_type_string(
358 enum lttng_ust_loglevel_type loglevel_type)
359{
360 const char *loglevel_type_string;
361
362 switch (loglevel_type) {
363 case LTTNG_UST_LOGLEVEL_ALL:
364 loglevel_type_string = config_loglevel_type_all;
365 break;
366 case LTTNG_UST_LOGLEVEL_RANGE:
367 loglevel_type_string = config_loglevel_type_range;
368 break;
369 case LTTNG_UST_LOGLEVEL_SINGLE:
370 loglevel_type_string = config_loglevel_type_single;
371 break;
372 default:
373 loglevel_type_string = NULL;
374 }
375
376 return loglevel_type_string;
377}
378
379static
380int save_kernel_event(struct config_writer *writer,
381 struct ltt_kernel_event *event)
382{
383 int ret;
384 const char *instrumentation_type;
385
386 ret = config_writer_open_element(writer, config_element_event);
387 if (ret) {
388 ret = LTTNG_ERR_SAVE_IO_FAIL;
389 goto end;
390 }
391
392 if (event->event->name[0]) {
393 ret = config_writer_write_element_string(writer,
394 config_element_name, event->event->name);
395 if (ret) {
396 ret = LTTNG_ERR_SAVE_IO_FAIL;
397 goto end;
398 }
399 }
400
401 ret = config_writer_write_element_bool(writer, config_element_enabled,
402 event->enabled);
403 if (ret) {
404 ret = LTTNG_ERR_SAVE_IO_FAIL;
405 goto end;
406 }
407
408 instrumentation_type = get_kernel_instrumentation_string(
409 event->event->instrumentation);
410 if (!instrumentation_type) {
411 ret = LTTNG_ERR_INVALID;
412 goto end;
413 }
414
415 ret = config_writer_write_element_string(writer, config_element_type,
416 instrumentation_type);
417 if (ret) {
418 ret = LTTNG_ERR_SAVE_IO_FAIL;
419 goto end;
420 }
421
911d1560
JG
422 if (event->filter_expression) {
423 ret = config_writer_write_element_string(writer,
424 config_element_filter,
425 event->filter_expression);
426 if (ret) {
427 ret = LTTNG_ERR_SAVE_IO_FAIL;
428 goto end;
429 }
430 }
431
fb198a11
JG
432 if (event->event->instrumentation == LTTNG_KERNEL_FUNCTION ||
433 event->event->instrumentation == LTTNG_KERNEL_KPROBE ||
434 event->event->instrumentation == LTTNG_KERNEL_KRETPROBE) {
435
436 ret = config_writer_open_element(writer,
437 config_element_attributes);
438 if (ret) {
439 ret = LTTNG_ERR_SAVE_IO_FAIL;
440 goto end;
441 }
442
443 switch (event->event->instrumentation) {
0de3eda1 444 case LTTNG_KERNEL_SYSCALL:
fb198a11
JG
445 case LTTNG_KERNEL_FUNCTION:
446 ret = config_writer_open_element(writer,
447 config_element_function_attributes);
448 if (ret) {
449 ret = LTTNG_ERR_SAVE_IO_FAIL;
450 goto end;
451 }
452
453 ret = config_writer_write_element_string(writer,
454 config_element_name,
455 event->event->u.ftrace.symbol_name);
456 if (ret) {
457 ret = LTTNG_ERR_SAVE_IO_FAIL;
458 goto end;
459 }
460
461 /* /function attributes */
462 ret = config_writer_close_element(writer);
463 if (ret) {
464 ret = LTTNG_ERR_SAVE_IO_FAIL;
465 goto end;
466 }
467 break;
468 case LTTNG_KERNEL_KPROBE:
469 case LTTNG_KERNEL_KRETPROBE:
470 {
471 const char *symbol_name;
472 uint64_t addr;
473 uint64_t offset;
474
475 if (event->event->instrumentation ==
476 LTTNG_KERNEL_KPROBE) {
477 /*
478 * Comments in lttng-kernel.h mention that
479 * either addr or symbol_name are set, not both.
480 */
481 addr = event->event->u.kprobe.addr;
482 offset = event->event->u.kprobe.offset;
483 symbol_name = addr ? NULL :
484 event->event->u.kprobe.symbol_name;
485 } else {
486 symbol_name =
487 event->event->u.kretprobe.symbol_name;
488 addr = event->event->u.kretprobe.addr;
489 offset = event->event->u.kretprobe.offset;
490 }
491
492 ret = config_writer_open_element(writer,
493 config_element_probe_attributes);
494 if (ret) {
495 ret = LTTNG_ERR_SAVE_IO_FAIL;
496 goto end;
497 }
498
499 if (symbol_name) {
500 ret = config_writer_write_element_string(writer,
501 config_element_symbol_name,
502 symbol_name);
503 if (ret) {
504 ret = LTTNG_ERR_SAVE_IO_FAIL;
505 goto end;
506 }
507 }
508
509 if (addr) {
510 ret = config_writer_write_element_unsigned_int(
511 writer, config_element_address, addr);
512 if (ret) {
513 ret = LTTNG_ERR_SAVE_IO_FAIL;
514 goto end;
515 }
516 }
517
518 if (offset) {
519 ret = config_writer_write_element_unsigned_int(
520 writer, config_element_offset, offset);
521 if (ret) {
522 ret = LTTNG_ERR_SAVE_IO_FAIL;
523 goto end;
524 }
525 }
526
527 ret = config_writer_close_element(writer);
528 if (ret) {
529 ret = LTTNG_ERR_SAVE_IO_FAIL;
530 goto end;
531 }
532 break;
533 }
534 default:
535 ERR("Unsupported kernel instrumentation type.");
536 ret = LTTNG_ERR_INVALID;
537 goto end;
538 }
539
540 /* /attributes */
541 ret = config_writer_close_element(writer);
542 if (ret) {
543 ret = LTTNG_ERR_SAVE_IO_FAIL;
544 goto end;
545 }
546 }
547
548 /* /event */
549 ret = config_writer_close_element(writer);
550 if (ret) {
551 ret = LTTNG_ERR_SAVE_IO_FAIL;
552 goto end;
553 }
554end:
555 return ret;
556}
557
558static
559int save_kernel_events(struct config_writer *writer,
0de3eda1 560 struct ltt_kernel_channel *kchan)
fb198a11
JG
561{
562 int ret;
563 struct ltt_kernel_event *event;
564
565 ret = config_writer_open_element(writer, config_element_events);
566 if (ret) {
567 ret = LTTNG_ERR_SAVE_IO_FAIL;
568 goto end;
569 }
570
0de3eda1 571 cds_list_for_each_entry(event, &kchan->events_list.head, list) {
fb198a11
JG
572 ret = save_kernel_event(writer, event);
573 if (ret) {
574 goto end;
575 }
576 }
577
578 /* /events */
579 ret = config_writer_close_element(writer);
580 if (ret) {
581 ret = LTTNG_ERR_SAVE_IO_FAIL;
582 goto end;
583 }
584end:
585 return ret;
586}
587
588static
589int save_ust_event(struct config_writer *writer,
590 struct ltt_ust_event *event)
591{
592 int ret;
593 const char *loglevel_type_string;
594
595 ret = config_writer_open_element(writer, config_element_event);
596 if (ret) {
597 ret = LTTNG_ERR_SAVE_IO_FAIL;
598 goto end;
599 }
600
601 if (event->attr.name[0]) {
602 ret = config_writer_write_element_string(writer,
603 config_element_name, event->attr.name);
604 if (ret) {
605 ret = LTTNG_ERR_SAVE_IO_FAIL;
606 goto end;
607 }
608 }
609
610 ret = config_writer_write_element_bool(writer, config_element_enabled,
611 event->enabled);
612 if (ret) {
613 ret = LTTNG_ERR_SAVE_IO_FAIL;
614 goto end;
615 }
616
617 if (event->attr.instrumentation != LTTNG_UST_TRACEPOINT) {
618 ERR("Unsupported UST instrumentation type.");
619 ret = LTTNG_ERR_INVALID;
620 goto end;
621 }
622 ret = config_writer_write_element_string(writer, config_element_type,
623 config_event_type_tracepoint);
624 if (ret) {
625 ret = LTTNG_ERR_SAVE_IO_FAIL;
626 goto end;
627 }
628
629 loglevel_type_string = get_loglevel_type_string(
630 event->attr.loglevel_type);
631 if (!loglevel_type_string) {
632 ERR("Unsupported UST loglevel type.");
633 ret = LTTNG_ERR_INVALID;
634 goto end;
635 }
636
637 ret = config_writer_write_element_string(writer,
638 config_element_loglevel_type, loglevel_type_string);
639 if (ret) {
640 ret = LTTNG_ERR_SAVE_IO_FAIL;
641 goto end;
642 }
643
1adbdb10
JG
644 /* The log level is irrelevant if no "filtering" is enabled */
645 if (event->attr.loglevel_type != LTTNG_UST_LOGLEVEL_ALL) {
646 ret = config_writer_write_element_signed_int(writer,
647 config_element_loglevel, event->attr.loglevel);
648 if (ret) {
649 ret = LTTNG_ERR_SAVE_IO_FAIL;
650 goto end;
651 }
fb198a11
JG
652 }
653
654 if (event->filter_expression) {
655 ret = config_writer_write_element_string(writer,
656 config_element_filter, event->filter_expression);
657 if (ret) {
658 ret = LTTNG_ERR_SAVE_IO_FAIL;
659 goto end;
660 }
661 }
662
663 if (event->exclusion && event->exclusion->count) {
664 uint32_t i;
665
666 ret = config_writer_open_element(writer,
667 config_element_exclusions);
668 if (ret) {
669 ret = LTTNG_ERR_SAVE_IO_FAIL;
670 goto end;
671 }
672
673 for (i = 0; i < event->exclusion->count; i++) {
674 ret = config_writer_write_element_string(writer,
675 config_element_exclusion,
d7af3565
PP
676 LTTNG_EVENT_EXCLUSION_NAME_AT(
677 event->exclusion, i));
fb198a11
JG
678 if (ret) {
679 ret = LTTNG_ERR_SAVE_IO_FAIL;
680 goto end;
681 }
682 }
683
684 /* /exclusions */
685 ret = config_writer_close_element(writer);
686 if (ret) {
687 ret = LTTNG_ERR_SAVE_IO_FAIL;
688 goto end;
689 }
690 }
691
692 /* /event */
693 ret = config_writer_close_element(writer);
694 if (ret) {
695 ret = LTTNG_ERR_SAVE_IO_FAIL;
696 goto end;
697 }
698end:
699 return ret;
700}
701
702static
703int save_ust_events(struct config_writer *writer,
704 struct lttng_ht *events)
705{
706 int ret;
707 struct ltt_ust_event *event;
708 struct lttng_ht_node_str *node;
709 struct lttng_ht_iter iter;
710
711 ret = config_writer_open_element(writer, config_element_events);
712 if (ret) {
713 ret = LTTNG_ERR_SAVE_IO_FAIL;
714 goto end;
715 }
716
717 rcu_read_lock();
718 cds_lfht_for_each_entry(events->ht, &iter.iter, node, node) {
719 event = caa_container_of(node, struct ltt_ust_event, node);
720
af325ba1
JG
721 if (event->internal) {
722 /* Internal events must not be exposed to clients */
723 continue;
724 }
fb198a11
JG
725 ret = save_ust_event(writer, event);
726 if (ret) {
727 rcu_read_unlock();
728 goto end;
729 }
730 }
731 rcu_read_unlock();
732
733 /* /events */
734 ret = config_writer_close_element(writer);
735 if (ret) {
736 ret = LTTNG_ERR_SAVE_IO_FAIL;
737 goto end;
738 }
739end:
740 return ret;
741}
742
51755dc8 743static
0b35b846 744int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event,
51755dc8
JG
745 struct agent_event *agent_event)
746{
0b35b846
JG
747 int ret = 0;
748 enum lttng_ust_loglevel_type ust_loglevel_type;
749
51755dc8
JG
750 ust_event->enabled = agent_event->enabled;
751 ust_event->attr.instrumentation = LTTNG_UST_TRACEPOINT;
d333bdaa
MD
752 if (lttng_strncpy(ust_event->attr.name, agent_event->name,
753 LTTNG_SYMBOL_NAME_LEN)) {
754 ret = -1;
755 goto end;
756 }
0b35b846
JG
757 switch (agent_event->loglevel_type) {
758 case LTTNG_EVENT_LOGLEVEL_ALL:
759 ust_loglevel_type = LTTNG_UST_LOGLEVEL_ALL;
760 break;
761 case LTTNG_EVENT_LOGLEVEL_SINGLE:
762 ust_loglevel_type = LTTNG_UST_LOGLEVEL_SINGLE;
763 break;
764 case LTTNG_EVENT_LOGLEVEL_RANGE:
765 ust_loglevel_type = LTTNG_UST_LOGLEVEL_RANGE;
766 break;
767 default:
768 ERR("Invalid agent_event loglevel_type.");
769 ret = -1;
770 goto end;
771 }
772
773 ust_event->attr.loglevel_type = ust_loglevel_type;
2106efa0 774 ust_event->attr.loglevel = agent_event->loglevel_value;
51755dc8
JG
775 ust_event->filter_expression = agent_event->filter_expression;
776 ust_event->exclusion = agent_event->exclusion;
0b35b846
JG
777end:
778 return ret;
51755dc8
JG
779}
780
781static
782int save_agent_events(struct config_writer *writer,
783 struct ltt_ust_channel *chan,
784 struct agent *agent)
785{
786 int ret;
787 struct lttng_ht_iter iter;
788 struct lttng_ht_node_str *node;
789
790 ret = config_writer_open_element(writer, config_element_events);
791 if (ret) {
792 ret = LTTNG_ERR_SAVE_IO_FAIL;
793 goto end;
794 }
795
796 rcu_read_lock();
797 cds_lfht_for_each_entry(agent->events->ht, &iter.iter, node, node) {
798 int ret;
799 struct agent_event *agent_event;
800 struct ltt_ust_event fake_event;
801
802 memset(&fake_event, 0, sizeof(fake_event));
803 agent_event = caa_container_of(node, struct agent_event, node);
804
805 /*
806 * Initialize a fake ust event to reuse the same serialization
807 * function since UST and agent events contain the same info
808 * (and one could wonder why they don't reuse the same
809 * structures...).
810 */
0b35b846
JG
811 ret = init_ust_event_from_agent_event(&fake_event, agent_event);
812 if (ret) {
813 rcu_read_unlock();
814 goto end;
815 }
51755dc8
JG
816 ret = save_ust_event(writer, &fake_event);
817 if (ret) {
818 rcu_read_unlock();
819 goto end;
820 }
821 }
822 rcu_read_unlock();
823
824 /* /events */
825 ret = config_writer_close_element(writer);
826 if (ret) {
827 ret = LTTNG_ERR_SAVE_IO_FAIL;
828 goto end;
829 }
830end:
831 return ret;
832}
833
fb198a11
JG
834static
835int save_kernel_context(struct config_writer *writer,
836 struct lttng_kernel_context *ctx)
837{
838 int ret = 0;
839
840 if (!ctx) {
841 goto end;
842 }
843
fb198a11
JG
844 ret = config_writer_open_element(writer, config_element_context);
845 if (ret) {
846 ret = LTTNG_ERR_SAVE_IO_FAIL;
847 goto end;
848 }
849
cba45eda 850 if (ctx->ctx == LTTNG_KERNEL_CONTEXT_PERF_CPU_COUNTER) {
045fc617
JG
851 ret = config_writer_open_element(writer,
852 config_element_context_perf);
fb198a11
JG
853 if (ret) {
854 ret = LTTNG_ERR_SAVE_IO_FAIL;
855 goto end;
856 }
857
858 ret = config_writer_write_element_unsigned_int(writer,
859 config_element_type, ctx->u.perf_counter.type);
860 if (ret) {
861 ret = LTTNG_ERR_SAVE_IO_FAIL;
862 goto end;
863 }
864
865 ret = config_writer_write_element_unsigned_int(writer,
866 config_element_config, ctx->u.perf_counter.config);
867 if (ret) {
868 ret = LTTNG_ERR_SAVE_IO_FAIL;
869 goto end;
870 }
871
872 ret = config_writer_write_element_string(writer,
873 config_element_name, ctx->u.perf_counter.name);
874 if (ret) {
875 ret = LTTNG_ERR_SAVE_IO_FAIL;
876 goto end;
877 }
878
879 /* /perf */
880 ret = config_writer_close_element(writer);
881 if (ret) {
882 ret = LTTNG_ERR_SAVE_IO_FAIL;
883 goto end;
884 }
885 } else {
886 const char *context_type_string =
887 get_kernel_context_type_string(ctx->ctx);
888
889 if (!context_type_string) {
890 ERR("Unsupported kernel context type.");
891 ret = LTTNG_ERR_INVALID;
892 goto end;
893 }
894
895 ret = config_writer_write_element_string(writer,
896 config_element_type, context_type_string);
897 if (ret) {
898 ret = LTTNG_ERR_SAVE_IO_FAIL;
899 goto end;
900 }
901 }
902
903 /* /context */
904 ret = config_writer_close_element(writer);
905 if (ret) {
906 ret = LTTNG_ERR_SAVE_IO_FAIL;
907 goto end;
908 }
909
645328ae
DG
910end:
911 return ret;
912}
913
914static
915int save_kernel_contexts(struct config_writer *writer,
916 struct ltt_kernel_channel *kchan)
917{
918 int ret;
919 struct ltt_kernel_context *ctx;
920
2aa64052
JG
921 if (cds_list_empty(&kchan->ctx_list)) {
922 ret = 0;
923 goto end;
924 }
925
645328ae
DG
926 ret = config_writer_open_element(writer, config_element_contexts);
927 if (ret) {
928 ret = LTTNG_ERR_SAVE_IO_FAIL;
929 goto end;
930 }
931
932 cds_list_for_each_entry(ctx, &kchan->ctx_list, list) {
933 ret = save_kernel_context(writer, &ctx->ctx);
934 if (ret) {
935 goto end;
936 }
937 }
938
fb198a11
JG
939 /* /contexts */
940 ret = config_writer_close_element(writer);
941 if (ret) {
942 ret = LTTNG_ERR_SAVE_IO_FAIL;
943 goto end;
944 }
945end:
946 return ret;
947}
948
045fc617
JG
949static
950int save_ust_context_perf_thread_counter(struct config_writer *writer,
951 struct ltt_ust_context *ctx)
952{
953 int ret;
954
955 assert(writer);
956 assert(ctx);
957
958 /* Perf contexts are saved as event_perf_context_type */
959 ret = config_writer_open_element(writer, config_element_context_perf);
960 if (ret) {
961 ret = LTTNG_ERR_SAVE_IO_FAIL;
962 goto end;
963 }
964
965 ret = config_writer_write_element_unsigned_int(writer,
966 config_element_type, ctx->ctx.u.perf_counter.type);
967 if (ret) {
968 ret = LTTNG_ERR_SAVE_IO_FAIL;
969 goto end;
970 }
971
972 ret = config_writer_write_element_unsigned_int(writer,
973 config_element_config, ctx->ctx.u.perf_counter.config);
974 if (ret) {
975 ret = LTTNG_ERR_SAVE_IO_FAIL;
976 goto end;
977 }
978
979 ret = config_writer_write_element_string(writer, config_element_name,
980 ctx->ctx.u.perf_counter.name);
981 if (ret) {
982 ret = LTTNG_ERR_SAVE_IO_FAIL;
983 goto end;
984 }
985
986 /* /perf */
987 ret = config_writer_close_element(writer);
988 if (ret) {
989 ret = LTTNG_ERR_SAVE_IO_FAIL;
990 goto end;
991 }
992end:
993 return ret;
994}
995
996static
997int save_ust_context_app_ctx(struct config_writer *writer,
998 struct ltt_ust_context *ctx)
999{
1000 int ret;
1001
1002 assert(writer);
1003 assert(ctx);
1004
1005 /* Application contexts are saved as application_context_type */
1006 ret = config_writer_open_element(writer, config_element_context_app);
1007 if (ret) {
1008 ret = LTTNG_ERR_SAVE_IO_FAIL;
1009 goto end;
1010 }
1011
1012 ret = config_writer_write_element_string(writer,
1013 config_element_context_app_provider_name,
1014 ctx->ctx.u.app_ctx.provider_name);
1015 if (ret) {
1016 ret = LTTNG_ERR_SAVE_IO_FAIL;
1017 goto end;
1018 }
1019
1020 ret = config_writer_write_element_string(writer,
1021 config_element_context_app_ctx_name,
1022 ctx->ctx.u.app_ctx.ctx_name);
1023 if (ret) {
1024 ret = LTTNG_ERR_SAVE_IO_FAIL;
1025 goto end;
1026 }
1027
1028 /* /app */
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_context_generic(struct config_writer *writer,
1040 struct ltt_ust_context *ctx)
1041{
1042 int ret;
1043 const char *context_type_string;
1044
1045 assert(writer);
1046 assert(ctx);
1047
1048 /* Save context as event_context_type_type */
1049 context_type_string = get_ust_context_type_string(
1050 ctx->ctx.ctx);
1051 if (!context_type_string) {
1052 ERR("Unsupported UST context type.");
1053 ret = LTTNG_ERR_SAVE_IO_FAIL;
1054 goto end;
1055 }
1056
1057 ret = config_writer_write_element_string(writer,
1058 config_element_type, context_type_string);
1059 if (ret) {
1060 ret = LTTNG_ERR_SAVE_IO_FAIL;
1061 goto end;
1062 }
1063end:
1064 return ret;
1065}
1066
fb198a11
JG
1067static
1068int save_ust_context(struct config_writer *writer,
1069 struct cds_list_head *ctx_list)
1070{
1071 int ret;
1072 struct ltt_ust_context *ctx;
1073
1074 assert(writer);
1075 assert(ctx_list);
1076
1077 ret = config_writer_open_element(writer, config_element_contexts);
1078 if (ret) {
1079 ret = LTTNG_ERR_SAVE_IO_FAIL;
1080 goto end;
1081 }
1082
1083 cds_list_for_each_entry(ctx, ctx_list, list) {
fb198a11
JG
1084 ret = config_writer_open_element(writer,
1085 config_element_context);
1086 if (ret) {
1087 ret = LTTNG_ERR_SAVE_IO_FAIL;
1088 goto end;
1089 }
1090
045fc617
JG
1091 switch (ctx->ctx.ctx) {
1092 case LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER:
1093 ret = save_ust_context_perf_thread_counter(writer, ctx);
1094 break;
1095 case LTTNG_UST_CONTEXT_APP_CONTEXT:
1096 ret = save_ust_context_app_ctx(writer, ctx);
1097 break;
1098 default:
1099 /* Save generic context. */
1100 ret = save_ust_context_generic(writer, ctx);
1101 }
1102 if (ret) {
1103 goto end;
fb198a11
JG
1104 }
1105
1106 /* /context */
1107 ret = config_writer_close_element(writer);
1108 if (ret) {
1109 ret = LTTNG_ERR_SAVE_IO_FAIL;
1110 goto end;
1111 }
1112 }
1113
1114 /* /contexts */
1115 ret = config_writer_close_element(writer);
1116 if (ret) {
1117 ret = LTTNG_ERR_SAVE_IO_FAIL;
1118 goto end;
1119 }
1120end:
1121 return ret;
1122}
1123
1124static
1125int save_kernel_channel(struct config_writer *writer,
1126 struct ltt_kernel_channel *kchan)
1127{
1128 int ret;
1129
1130 assert(writer);
1131 assert(kchan);
1132
1133 ret = config_writer_open_element(writer, config_element_channel);
1134 if (ret) {
1135 ret = LTTNG_ERR_SAVE_IO_FAIL;
1136 goto end;
1137 }
1138
1139 ret = config_writer_write_element_string(writer, config_element_name,
1140 kchan->channel->name);
1141 if (ret) {
1142 ret = LTTNG_ERR_SAVE_IO_FAIL;
1143 goto end;
1144 }
1145
1146 ret = config_writer_write_element_bool(writer, config_element_enabled,
1147 kchan->channel->enabled);
1148 if (ret) {
1149 ret = LTTNG_ERR_SAVE_IO_FAIL;
1150 goto end;
1151 }
1152
1153 ret = save_kernel_channel_attributes(writer, &kchan->channel->attr);
1154 if (ret) {
1155 goto end;
1156 }
1157
0de3eda1 1158 ret = save_kernel_events(writer, kchan);
fb198a11
JG
1159 if (ret) {
1160 goto end;
1161 }
1162
645328ae 1163 ret = save_kernel_contexts(writer, kchan);
fb198a11
JG
1164 if (ret) {
1165 goto end;
1166 }
1167
1168 /* /channel */
1169 ret = config_writer_close_element(writer);
1170 if (ret) {
1171 ret = LTTNG_ERR_SAVE_IO_FAIL;
1172 goto end;
1173 }
1174end:
1175 return ret;
1176}
1177
1178static
1179int save_ust_channel(struct config_writer *writer,
1180 struct ltt_ust_channel *ust_chan,
1181 struct ltt_ust_session *session)
1182{
1183 int ret;
1184
1185 assert(writer);
1186 assert(ust_chan);
1187 assert(session);
1188
1189 ret = config_writer_open_element(writer, config_element_channel);
1190 if (ret) {
1191 ret = LTTNG_ERR_SAVE_IO_FAIL;
1192 goto end;
1193 }
1194
1195 ret = config_writer_write_element_string(writer, config_element_name,
1196 ust_chan->name);
1197 if (ret) {
1198 ret = LTTNG_ERR_SAVE_IO_FAIL;
1199 goto end;
1200 }
1201
1202 ret = config_writer_write_element_bool(writer, config_element_enabled,
1203 ust_chan->enabled);
1204 if (ret) {
1205 ret = LTTNG_ERR_SAVE_IO_FAIL;
1206 goto end;
1207 }
1208
1209 ret = save_ust_channel_attributes(writer, &ust_chan->attr);
1210 if (ret) {
1211 goto end;
1212 }
1213
1214 ret = config_writer_write_element_unsigned_int(writer,
1215 config_element_tracefile_size, ust_chan->tracefile_size);
1216 if (ret) {
1217 ret = LTTNG_ERR_SAVE_IO_FAIL;
1218 goto end;
1219 }
1220
1221 ret = config_writer_write_element_unsigned_int(writer,
1222 config_element_tracefile_count, ust_chan->tracefile_count);
1223 if (ret) {
1224 ret = LTTNG_ERR_SAVE_IO_FAIL;
1225 goto end;
1226 }
1227
1228 ret = config_writer_write_element_unsigned_int(writer,
1229 config_element_live_timer_interval,
1230 session->live_timer_interval);
1231 if (ret) {
1232 ret = LTTNG_ERR_SAVE_IO_FAIL;
1233 goto end;
1234 }
1235
51755dc8
JG
1236 if (ust_chan->domain == LTTNG_DOMAIN_UST) {
1237 ret = save_ust_events(writer, ust_chan->events);
1238 if (ret) {
1239 goto end;
1240 }
1241 } else {
1242 struct agent *agent = NULL;
1243
1244 agent = trace_ust_find_agent(session, ust_chan->domain);
1245 if (!agent) {
1246 ret = LTTNG_ERR_SAVE_IO_FAIL;
1247 ERR("Could not find agent associated to UST subdomain");
1248 goto end;
1249 }
1250
1251 /*
1252 * Channels associated with a UST sub-domain (such as JUL, Log4j
1253 * or Python) don't have any non-internal events. We retrieve
1254 * the "agent" events associated with this channel and serialize
1255 * them.
1256 */
1257 ret = save_agent_events(writer, ust_chan, agent);
1258 if (ret) {
1259 goto end;
1260 }
fb198a11
JG
1261 }
1262
1263 ret = save_ust_context(writer, &ust_chan->ctx_list);
1264 if (ret) {
1265 goto end;
1266 }
1267
1268 /* /channel */
1269 ret = config_writer_close_element(writer);
1270 if (ret) {
1271 ret = LTTNG_ERR_SAVE_IO_FAIL;
1272 goto end;
1273 }
1274end:
1275 return ret;
1276}
1277
1278static
1279int save_kernel_session(struct config_writer *writer,
1280 struct ltt_session *session)
1281{
1282 int ret;
1283 struct ltt_kernel_channel *kchan;
1284
1285 assert(writer);
1286 assert(session);
1287
1288 ret = config_writer_write_element_string(writer, config_element_type,
1289 config_domain_type_kernel);
1290 if (ret) {
1291 ret = LTTNG_ERR_SAVE_IO_FAIL;
1292 goto end;
1293 }
1294
1295 ret = config_writer_write_element_string(writer,
1296 config_element_buffer_type, config_buffer_type_global);
1297 if (ret) {
1298 ret = LTTNG_ERR_SAVE_IO_FAIL;
1299 goto end;
1300 }
1301
1302 ret = config_writer_open_element(writer,
1303 config_element_channels);
1304 if (ret) {
1305 ret = LTTNG_ERR_SAVE_IO_FAIL;
1306 goto end;
1307 }
1308
1309 cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head,
1310 list) {
1311 ret = save_kernel_channel(writer, kchan);
1312 if (ret) {
1313 goto end;
1314 }
1315 }
1316
1317 /* /channels */
1318 ret = config_writer_close_element(writer);
1319 if (ret) {
1320 ret = LTTNG_ERR_SAVE_IO_FAIL;
1321 goto end;
1322 }
1323end:
1324 return ret;
1325}
1326
1327static
51755dc8
JG
1328const char *get_config_domain_str(enum lttng_domain_type domain)
1329{
1330 const char *str_dom;
1331
1332 switch (domain) {
1333 case LTTNG_DOMAIN_KERNEL:
1334 str_dom = config_domain_type_kernel;
1335 break;
1336 case LTTNG_DOMAIN_UST:
1337 str_dom = config_domain_type_ust;
1338 break;
1339 case LTTNG_DOMAIN_JUL:
1340 str_dom = config_domain_type_jul;
1341 break;
1342 case LTTNG_DOMAIN_LOG4J:
1343 str_dom = config_domain_type_log4j;
1344 break;
1345 case LTTNG_DOMAIN_PYTHON:
1346 str_dom = config_domain_type_python;
1347 break;
1348 default:
1349 assert(0);
1350 }
1351
1352 return str_dom;
1353}
1354
e8fcabef
JG
1355static
1356int save_pid_tracker(struct config_writer *writer,
1357 struct ltt_session *sess, int domain)
1358{
1359 int ret = 0;
1360 ssize_t nr_pids = 0, i;
1361 int32_t *pids = NULL;
1362
1363 switch (domain) {
1364 case LTTNG_DOMAIN_KERNEL:
1365 {
1366 nr_pids = kernel_list_tracker_pids(sess->kernel_session, &pids);
1367 if (nr_pids < 0) {
1368 ret = LTTNG_ERR_KERN_LIST_FAIL;
1369 goto end;
1370 }
1371 break;
1372 }
1373 case LTTNG_DOMAIN_UST:
1374 {
1375 nr_pids = trace_ust_list_tracker_pids(sess->ust_session, &pids);
1376 if (nr_pids < 0) {
1377 ret = LTTNG_ERR_UST_LIST_FAIL;
1378 goto end;
1379 }
1380 break;
1381 }
1382 case LTTNG_DOMAIN_JUL:
1383 case LTTNG_DOMAIN_LOG4J:
1384 case LTTNG_DOMAIN_PYTHON:
1385 default:
1386 ret = LTTNG_ERR_UNKNOWN_DOMAIN;
1387 goto end;
1388 }
1389
1390 /* Only create a pid_tracker if enabled or untrack all */
1391 if (nr_pids != 1 || (nr_pids == 1 && pids[0] != -1)) {
1392 ret = config_writer_open_element(writer,
1393 config_element_pid_tracker);
1394 if (ret) {
1395 ret = LTTNG_ERR_SAVE_IO_FAIL;
1396 goto end;
1397 }
1398
1399 ret = config_writer_open_element(writer,
1400 config_element_targets);
1401 if (ret) {
1402 ret = LTTNG_ERR_SAVE_IO_FAIL;
1403 goto end;
1404 }
1405
1406 for (i = 0; i < nr_pids; i++) {
1407 ret = config_writer_open_element(writer,
1408 config_element_target_pid);
1409 if (ret) {
1410 ret = LTTNG_ERR_SAVE_IO_FAIL;
1411 goto end;
1412 }
1413
1414 ret = config_writer_write_element_unsigned_int(writer,
1415 config_element_pid, pids[i]);
1416 if (ret) {
1417 ret = LTTNG_ERR_SAVE_IO_FAIL;
1418 goto end;
1419 }
1420
1421 /* /pid_target */
1422 ret = config_writer_close_element(writer);
1423 if (ret) {
1424 ret = LTTNG_ERR_SAVE_IO_FAIL;
1425 goto end;
1426 }
1427 }
1428
1429 /* /targets */
1430 ret = config_writer_close_element(writer);
1431 if (ret) {
1432 ret = LTTNG_ERR_SAVE_IO_FAIL;
1433 goto end;
1434 }
1435
1436 /* /pid_tracker */
1437 ret = config_writer_close_element(writer);
1438 if (ret) {
1439 ret = LTTNG_ERR_SAVE_IO_FAIL;
1440 goto end;
1441 }
1442 }
1443end:
1444 free(pids);
1445 return ret;
1446}
1447
51755dc8
JG
1448static
1449int save_ust_domain(struct config_writer *writer,
1450 struct ltt_session *session, enum lttng_domain_type domain)
fb198a11
JG
1451{
1452 int ret;
1453 struct ltt_ust_channel *ust_chan;
1454 const char *buffer_type_string;
1455 struct lttng_ht_node_str *node;
1456 struct lttng_ht_iter iter;
51755dc8 1457 const char *config_domain_name;
fb198a11
JG
1458
1459 assert(writer);
1460 assert(session);
1461
51755dc8
JG
1462 ret = config_writer_open_element(writer,
1463 config_element_domain);
1464 if (ret) {
1465 ret = LTTNG_ERR_SAVE_IO_FAIL;
1466 goto end;
1467 }
1468
1469 config_domain_name = get_config_domain_str(domain);
1470 if (!config_domain_name) {
1471 ret = LTTNG_ERR_INVALID;
1472 goto end;
1473 }
1474
1475 ret = config_writer_write_element_string(writer,
1476 config_element_type, config_domain_name);
fb198a11
JG
1477 if (ret) {
1478 ret = LTTNG_ERR_SAVE_IO_FAIL;
1479 goto end;
1480 }
1481
1482 buffer_type_string = get_buffer_type_string(
1483 session->ust_session->buffer_type);
1484 if (!buffer_type_string) {
1485 ERR("Unsupported buffer type.");
1486 ret = LTTNG_ERR_INVALID;
1487 goto end;
1488 }
1489
1490 ret = config_writer_write_element_string(writer,
1491 config_element_buffer_type, buffer_type_string);
1492 if (ret) {
1493 ret = LTTNG_ERR_SAVE_IO_FAIL;
1494 goto end;
1495 }
1496
1497 ret = config_writer_open_element(writer, config_element_channels);
1498 if (ret) {
1499 ret = LTTNG_ERR_SAVE_IO_FAIL;
1500 goto end;
1501 }
1502
1503 rcu_read_lock();
1504 cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht,
1505 &iter.iter, node, node) {
fb198a11 1506 ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
51755dc8 1507 if (domain == ust_chan->domain) {
fb198a11
JG
1508 ret = save_ust_channel(writer, ust_chan, session->ust_session);
1509 if (ret) {
1510 rcu_read_unlock();
1511 goto end;
1512 }
1513 }
1514 }
1515 rcu_read_unlock();
1516
1517 /* /channels */
1518 ret = config_writer_close_element(writer);
1519 if (ret) {
1520 ret = LTTNG_ERR_SAVE_IO_FAIL;
1521 goto end;
1522 }
51755dc8 1523
e8fcabef 1524 if (domain == LTTNG_DOMAIN_UST) {
847a5916 1525 ret = config_writer_open_element(writer,
e8fcabef 1526 config_element_trackers);
847a5916
JR
1527 if (ret) {
1528 ret = LTTNG_ERR_SAVE_IO_FAIL;
1529 goto end;
1530 }
1531
e8fcabef 1532 ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_UST);
847a5916 1533 if (ret) {
847a5916
JR
1534 goto end;
1535 }
1536
e8fcabef 1537 /* /trackers */
847a5916
JR
1538 ret = config_writer_close_element(writer);
1539 if (ret) {
847a5916
JR
1540 goto end;
1541 }
e8fcabef 1542 }
847a5916 1543
e8fcabef
JG
1544 /* /domain */
1545 ret = config_writer_close_element(writer);
1546 if (ret) {
1547 ret = LTTNG_ERR_SAVE_IO_FAIL;
1548 goto end;
847a5916 1549 }
e8fcabef 1550
847a5916 1551end:
847a5916
JR
1552 return ret;
1553}
1554
fb198a11
JG
1555static
1556int save_domains(struct config_writer *writer, struct ltt_session *session)
1557{
1558 int ret = 0;
1559
1560 assert(writer);
1561 assert(session);
1562
1563 if (!session->kernel_session && !session->ust_session) {
1564 goto end;
1565 }
1566
1567 ret = config_writer_open_element(writer, config_element_domains);
1568 if (ret) {
1569 ret = LTTNG_ERR_SAVE_IO_FAIL;
1570 goto end;
1571 }
1572
1573
1574 if (session->kernel_session) {
1575 ret = config_writer_open_element(writer,
1576 config_element_domain);
1577 if (ret) {
1578 ret = LTTNG_ERR_SAVE_IO_FAIL;
1579 goto end;
1580 }
1581
1582 ret = save_kernel_session(writer, session);
1583 if (ret) {
1584 goto end;
1585 }
1586
847a5916
JR
1587 ret = config_writer_open_element(writer,
1588 config_element_trackers);
1589 if (ret) {
1590 ret = LTTNG_ERR_SAVE_IO_FAIL;
1591 goto end;
1592 }
1593
1594 ret = save_pid_tracker(writer, session, LTTNG_DOMAIN_KERNEL);
1595 if (ret) {
1596 goto end;
1597 }
1598
1599 /* /trackers */
1600 ret = config_writer_close_element(writer);
1601 if (ret) {
1602 ret = LTTNG_ERR_SAVE_IO_FAIL;
1603 goto end;
1604 }
fb198a11
JG
1605 /* /domain */
1606 ret = config_writer_close_element(writer);
1607 if (ret) {
1608 ret = LTTNG_ERR_SAVE_IO_FAIL;
1609 goto end;
1610 }
1611 }
1612
1613 if (session->ust_session) {
51755dc8 1614 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST);
fb198a11
JG
1615 if (ret) {
1616 goto end;
1617 }
1618
51755dc8 1619 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL);
fb198a11 1620 if (ret) {
fb198a11
JG
1621 goto end;
1622 }
fb198a11 1623
51755dc8
JG
1624 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J);
1625 if (ret) {
1626 goto end;
1627 }
65d72c41 1628
51755dc8
JG
1629 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
1630 if (ret) {
1631 goto end;
fb198a11
JG
1632 }
1633 }
1634
1635 /* /domains */
1636 ret = config_writer_close_element(writer);
1637 if (ret) {
1638 ret = LTTNG_ERR_SAVE_IO_FAIL;
1639 goto end;
1640 }
1641end:
1642 return ret;
1643}
1644
1645static
1646int save_consumer_output(struct config_writer *writer,
1647 struct consumer_output *output)
1648{
1649 int ret;
1650
1651 assert(writer);
1652 assert(output);
1653
1654 ret = config_writer_open_element(writer, config_element_consumer_output);
1655 if (ret) {
1656 ret = LTTNG_ERR_SAVE_IO_FAIL;
1657 goto end;
1658 }
1659
1660 ret = config_writer_write_element_bool(writer, config_element_enabled,
1661 output->enabled);
1662 if (ret) {
1663 ret = LTTNG_ERR_SAVE_IO_FAIL;
1664 goto end;
1665 }
1666
1667 ret = config_writer_open_element(writer, config_element_destination);
1668 if (ret) {
1669 ret = LTTNG_ERR_SAVE_IO_FAIL;
1670 goto end;
1671 }
1672
1673 switch (output->type) {
1674 case CONSUMER_DST_LOCAL:
1675 ret = config_writer_write_element_string(writer,
1676 config_element_path, output->dst.trace_path);
1677 if (ret) {
1678 ret = LTTNG_ERR_SAVE_IO_FAIL;
1679 goto end;
1680 }
1681 break;
1682 case CONSUMER_DST_NET:
1683 {
1684 char *uri;
1685
1686 uri = zmalloc(PATH_MAX);
1687 if (!uri) {
1688 ret = LTTNG_ERR_NOMEM;
1689 goto end;
1690 }
1691
1692 ret = config_writer_open_element(writer, config_element_net_output);
1693 if (ret) {
1694 ret = LTTNG_ERR_SAVE_IO_FAIL;
1695 goto end_net_output;
1696 }
1697
1698 if (output->dst.net.control_isset &&
1699 output->dst.net.data_isset) {
1700 ret = uri_to_str_url(&output->dst.net.control, uri, PATH_MAX);
1701 if (ret < 0) {
1702 ret = LTTNG_ERR_INVALID;
1703 goto end_net_output;
1704 }
1705
1706 ret = config_writer_write_element_string(writer,
1707 config_element_control_uri, uri);
1708 if (ret) {
1709 ret = LTTNG_ERR_SAVE_IO_FAIL;
1710 goto end_net_output;
1711 }
1712
1713 ret = uri_to_str_url(&output->dst.net.data, uri, PATH_MAX);
1714 if (ret < 0) {
1715 ret = LTTNG_ERR_INVALID;
1716 goto end_net_output;
1717 }
1718
1719 ret = config_writer_write_element_string(writer,
1720 config_element_data_uri, uri);
1721 if (ret) {
1722 ret = LTTNG_ERR_SAVE_IO_FAIL;
1723 goto end_net_output;
1724 }
1725
1726end_net_output:
1727 free(uri);
1728 if (ret) {
1729 goto end;
1730 }
1731 } else {
1732 ret = !output->dst.net.control_isset ?
1733 LTTNG_ERR_URL_CTRL_MISS :
1734 LTTNG_ERR_URL_DATA_MISS;
c39270e5 1735 free(uri);
fb198a11
JG
1736 goto end;
1737 }
1738
1739 ret = config_writer_close_element(writer);
1740 if (ret) {
1741 ret = LTTNG_ERR_SAVE_IO_FAIL;
1742 goto end;
1743 }
1744 break;
1745 }
1746 default:
1747 ERR("Unsupported consumer output type.");
1748 ret = LTTNG_ERR_INVALID;
1749 goto end;
1750 }
1751
1752 /* /destination */
1753 ret = config_writer_close_element(writer);
1754 if (ret) {
1755 ret = LTTNG_ERR_SAVE_IO_FAIL;
1756 goto end;
1757 }
1758
1759 /* /consumer_output */
1760 ret = config_writer_close_element(writer);
1761 if (ret) {
1762 ret = LTTNG_ERR_SAVE_IO_FAIL;
1763 goto end;
1764 }
1765end:
1766 return ret;
1767}
1768
1769static
1770int save_snapshot_outputs(struct config_writer *writer,
1771 struct snapshot *snapshot)
1772{
1773 int ret;
1774 struct lttng_ht_iter iter;
1775 struct snapshot_output *output;
1776
1777 assert(writer);
1778 assert(snapshot);
1779
1780 ret = config_writer_open_element(writer, config_element_snapshot_outputs);
1781 if (ret) {
1782 ret = LTTNG_ERR_SAVE_IO_FAIL;
1783 goto end;
1784 }
1785
1786 rcu_read_lock();
1787 cds_lfht_for_each_entry(snapshot->output_ht->ht, &iter.iter, output,
1788 node.node) {
1789 ret = config_writer_open_element(writer,
1790 config_element_output);
1791 if (ret) {
1792 ret = LTTNG_ERR_SAVE_IO_FAIL;
1793 goto end_unlock;
1794 }
1795
1796 ret = config_writer_write_element_string(writer,
1797 config_element_name, output->name);
1798 if (ret) {
1799 ret = LTTNG_ERR_SAVE_IO_FAIL;
1800 goto end_unlock;
1801 }
1802
1803 ret = config_writer_write_element_unsigned_int(writer,
1804 config_element_max_size, output->max_size);
1805 if (ret) {
1806 ret = LTTNG_ERR_SAVE_IO_FAIL;
1807 goto end_unlock;
1808 }
1809
1810 ret = save_consumer_output(writer, output->consumer);
1811 if (ret) {
1812 goto end_unlock;
1813 }
1814
1815 /* /output */
1816 ret = config_writer_close_element(writer);
1817 if (ret) {
1818 ret = LTTNG_ERR_SAVE_IO_FAIL;
1819 goto end_unlock;
1820 }
1821 }
1822 rcu_read_unlock();
1823
1824 /* /snapshot_outputs */
1825 ret = config_writer_close_element(writer);
1826 if (ret) {
1827 ret = LTTNG_ERR_SAVE_IO_FAIL;
1828 goto end;
1829 }
1830
1831end:
1832 return ret;
1833end_unlock:
1834 rcu_read_unlock();
1835 return ret;
1836}
1837
1838static
1839int save_session_output(struct config_writer *writer,
1840 struct ltt_session *session)
1841{
1842 int ret;
1843
1844 assert(writer);
1845 assert(session);
1846
1847 if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
1848 (!session->snapshot_mode && !session->consumer)) {
1849 /* Session is in no output mode */
1850 ret = 0;
1851 goto end;
1852 }
1853
1854 ret = config_writer_open_element(writer, config_element_output);
1855 if (ret) {
1856 ret = LTTNG_ERR_SAVE_IO_FAIL;
1857 goto end;
1858 }
1859
1860 if (session->snapshot_mode) {
1861 ret = save_snapshot_outputs(writer, &session->snapshot);
1862 if (ret) {
1863 goto end;
1864 }
1865 } else {
1866 if (session->consumer) {
1867 ret = save_consumer_output(writer, session->consumer);
1868 if (ret) {
1869 goto end;
1870 }
1871 }
1872 }
1873
1874 /* /output */
1875 ret = config_writer_close_element(writer);
1876 if (ret) {
1877 ret = LTTNG_ERR_SAVE_IO_FAIL;
1878 goto end;
1879 }
1880end:
1881 return ret;
1882}
1883
1884/*
1885 * Save the given session.
1886 *
1887 * Return 0 on success else a LTTNG_ERR* code.
1888 */
1889static
1890int save_session(struct ltt_session *session,
1891 struct lttng_save_session_attr *attr, lttng_sock_cred *creds)
1892{
1893 int ret, fd;
db471218 1894 unsigned int file_opened = 0; /* Indicate if the file has been opened */
fb198a11
JG
1895 char config_file_path[PATH_MAX];
1896 size_t len;
1897 struct config_writer *writer = NULL;
1898 size_t session_name_len;
1899 const char *provided_path;
1900
1901 assert(session);
1902 assert(attr);
1903 assert(creds);
1904
1905 session_name_len = strlen(session->name);
95a29ab8 1906 memset(config_file_path, 0, sizeof(config_file_path));
fb198a11
JG
1907
1908 if (!session_access_ok(session,
1909 LTTNG_SOCK_GET_UID_CRED(creds),
1910 LTTNG_SOCK_GET_GID_CRED(creds))) {
1911 ret = LTTNG_ERR_EPERM;
1912 goto end;
1913 }
1914
1915 provided_path = lttng_save_session_attr_get_output_url(attr);
1916 if (provided_path) {
95a29ab8 1917 DBG3("Save session in provided path %s", provided_path);
fb198a11 1918 len = strlen(provided_path);
d2992717 1919 if (len >= sizeof(config_file_path)) {
fb198a11
JG
1920 ret = LTTNG_ERR_SET_URL;
1921 goto end;
1922 }
1923 strncpy(config_file_path, provided_path, len);
1924 } else {
7e078ad1 1925 ssize_t ret_len;
fb198a11
JG
1926 char *home_dir = utils_get_user_home_dir(
1927 LTTNG_SOCK_GET_UID_CRED(creds));
1928 if (!home_dir) {
1929 ret = LTTNG_ERR_SET_URL;
1930 goto end;
1931 }
1932
d2992717 1933 ret_len = snprintf(config_file_path, sizeof(config_file_path),
fb198a11
JG
1934 DEFAULT_SESSION_HOME_CONFIGPATH, home_dir);
1935 free(home_dir);
7e078ad1 1936 if (ret_len < 0) {
fb198a11
JG
1937 PERROR("snprintf save session");
1938 ret = LTTNG_ERR_SET_URL;
1939 goto end;
1940 }
7e078ad1 1941 len = ret_len;
fb198a11
JG
1942 }
1943
1944 /*
d2992717
DG
1945 * Check the path fits in the config file path dst including the '/'
1946 * followed by trailing .lttng extension and the NULL terminated string.
fb198a11 1947 */
d2992717
DG
1948 if ((len + session_name_len + 2 +
1949 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION))
1950 > sizeof(config_file_path)) {
fb198a11
JG
1951 ret = LTTNG_ERR_SET_URL;
1952 goto end;
1953 }
1954
1955 ret = run_as_mkdir_recursive(config_file_path, S_IRWXU | S_IRWXG,
1956 LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds));
1957 if (ret) {
1958 ret = LTTNG_ERR_SET_URL;
1959 goto end;
1960 }
1961
d2992717
DG
1962 /*
1963 * At this point, we know that everything fits in the buffer. Validation
1964 * was done just above.
1965 */
fb198a11
JG
1966 config_file_path[len++] = '/';
1967 strncpy(config_file_path + len, session->name, session_name_len);
1968 len += session_name_len;
1969 strcpy(config_file_path + len, DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
95a29ab8
DG
1970 len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
1971 config_file_path[len] = '\0';
fb198a11
JG
1972
1973 if (!access(config_file_path, F_OK) && !attr->overwrite) {
f9b57ab2
DG
1974 /* File exists, notify the user since the overwrite flag is off. */
1975 ret = LTTNG_ERR_SAVE_FILE_EXIST;
fb198a11
JG
1976 goto end;
1977 }
1978
1979 fd = run_as_open(config_file_path, O_CREAT | O_WRONLY | O_TRUNC,
1980 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
1981 LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds));
1982 if (fd < 0) {
1983 PERROR("Could not create configuration file");
1984 ret = LTTNG_ERR_SAVE_IO_FAIL;
1985 goto end;
1986 }
db471218 1987 file_opened = 1;
fb198a11 1988
705bb62f 1989 writer = config_writer_create(fd, 1);
fb198a11
JG
1990 if (!writer) {
1991 ret = LTTNG_ERR_NOMEM;
1992 goto end;
1993 }
1994
1995 ret = config_writer_open_element(writer, config_element_sessions);
1996 if (ret) {
1997 ret = LTTNG_ERR_SAVE_IO_FAIL;
1998 goto end;
1999 }
2000
2001 ret = config_writer_open_element(writer, config_element_session);
2002 if (ret) {
2003 ret = LTTNG_ERR_SAVE_IO_FAIL;
2004 goto end;
2005 }
2006
2007 ret = config_writer_write_element_string(writer, config_element_name,
2008 session->name);
2009 if (ret) {
2010 ret = LTTNG_ERR_SAVE_IO_FAIL;
2011 goto end;
2012 }
2013
9e7c9f56
JR
2014 if(session->shm_path[0] != '\0') {
2015 ret = config_writer_write_element_string(writer,
2016 config_element_shared_memory_path,
2017 session->shm_path);
2018 if (ret) {
2019 ret = LTTNG_ERR_SAVE_IO_FAIL;
2020 goto end;
2021 }
2022 }
2023
fb198a11
JG
2024 ret = save_domains(writer, session);
2025 if (ret) {
2026 goto end;
2027 }
2028
2029 ret = config_writer_write_element_bool(writer, config_element_started,
8382cf6f 2030 session->active);
fb198a11
JG
2031 if (ret) {
2032 ret = LTTNG_ERR_SAVE_IO_FAIL;
2033 goto end;
2034 }
2035
2036 if (session->snapshot_mode || session->live_timer) {
2037 ret = config_writer_open_element(writer, config_element_attributes);
2038 if (ret) {
2039 ret = LTTNG_ERR_SAVE_IO_FAIL;
2040 goto end;
2041 }
2042
2043 if (session->snapshot_mode) {
2044 ret = config_writer_write_element_bool(writer,
2045 config_element_snapshot_mode, 1);
2046 if (ret) {
2047 ret = LTTNG_ERR_SAVE_IO_FAIL;
2048 goto end;
2049 }
2050 } else {
d98ad589 2051 ret = config_writer_write_element_unsigned_int(writer,
fb198a11
JG
2052 config_element_live_timer_interval, session->live_timer);
2053 if (ret) {
2054 ret = LTTNG_ERR_SAVE_IO_FAIL;
2055 goto end;
2056 }
2057 }
2058
2059 /* /attributes */
2060 ret = config_writer_close_element(writer);
2061 if (ret) {
2062 ret = LTTNG_ERR_SAVE_IO_FAIL;
2063 goto end;
2064 }
2065 }
2066
2067 ret = save_session_output(writer, session);
2068 if (ret) {
2069 goto end;
2070 }
2071
2072 /* /session */
2073 ret = config_writer_close_element(writer);
2074 if (ret) {
2075 ret = LTTNG_ERR_SAVE_IO_FAIL;
2076 goto end;
2077 }
2078
2079 /* /sessions */
2080 ret = config_writer_close_element(writer);
2081 if (ret) {
2082 ret = LTTNG_ERR_SAVE_IO_FAIL;
2083 goto end;
2084 }
2085end:
2086 if (writer && config_writer_destroy(writer)) {
2087 /* Preserve the original error code */
2088 ret = ret ? ret : LTTNG_ERR_SAVE_IO_FAIL;
2089 }
2090 if (ret) {
2091 /* Delete file in case of error */
db471218 2092 if (file_opened && unlink(config_file_path)) {
fb198a11
JG
2093 PERROR("Unlinking XML session configuration.");
2094 }
2095 }
2096
1d12100d
JR
2097 if (file_opened) {
2098 ret = close(fd);
2099 if (ret) {
2100 PERROR("Closing XML session configuration");
2101 }
2102 }
2103
fb198a11
JG
2104 return ret;
2105}
2106
2107int cmd_save_sessions(struct lttng_save_session_attr *attr,
2108 lttng_sock_cred *creds)
2109{
2110 int ret;
2111 const char *session_name;
2112 struct ltt_session *session;
2113
2114 session_lock_list();
2115
2116 session_name = lttng_save_session_attr_get_session_name(attr);
2117 if (session_name) {
2118 session = session_find_by_name(session_name);
2119 if (!session) {
2120 ret = LTTNG_ERR_SESS_NOT_FOUND;
2121 goto end;
2122 }
2123
2124 session_lock(session);
2125 ret = save_session(session, attr, creds);
2126 session_unlock(session);
2127 if (ret) {
2128 goto end;
2129 }
2130 } else {
2131 struct ltt_session_list *list = session_get_list();
2132
2133 cds_list_for_each_entry(session, &list->head, list) {
2134 session_lock(session);
2135 ret = save_session(session, attr, creds);
2136 session_unlock(session);
2137
2138 /* Don't abort if we don't have the required permissions. */
2139 if (ret && ret != LTTNG_ERR_EPERM) {
2140 goto end;
2141 }
2142 }
2143 }
2144 ret = LTTNG_OK;
2145
2146end:
2147 session_unlock_list();
2148 return ret;
2149}
This page took 0.133041 seconds and 5 git commands to generate.