configure: add '-Wundef' to warning flags
[lttng-tools.git] / src / bin / lttng-sessiond / save.cpp
CommitLineData
fb198a11 1/*
ab5be9fa 2 * Copyright (C) 2014 Jérémie Galarneau <jeremie.galarneau@efficios.com>
fb198a11 3 *
ab5be9fa 4 * SPDX-License-Identifier: GPL-2.0-only
fb198a11 5 *
fb198a11
JG
6 */
7
6c1c0768 8#define _LGPL_SOURCE
fb198a11
JG
9#include <inttypes.h>
10#include <string.h>
11#include <urcu/uatomic.h>
12#include <unistd.h>
13
14#include <common/defaults.h>
15#include <common/error.h>
f40ef1d5 16#include <common/config/session-config.h>
fb198a11
JG
17#include <common/utils.h>
18#include <common/runas.h>
19#include <lttng/save-internal.h>
20
847a5916 21#include "kernel.h"
fb198a11
JG
22#include "save.h"
23#include "session.h"
0dbc2034 24#include "lttng-syscall.h"
fb198a11 25#include "trace-ust.h"
51755dc8 26#include "agent.h"
fb198a11 27
55c9e7ca 28/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
29static
30int save_kernel_channel_attributes(struct config_writer *writer,
31 struct lttng_channel_attr *attr)
32{
33 int ret;
34
35 ret = config_writer_write_element_string(writer,
36 config_element_overwrite_mode,
37 attr->overwrite ? config_overwrite_mode_overwrite :
38 config_overwrite_mode_discard);
39 if (ret) {
55c9e7ca 40 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
41 goto end;
42 }
43
44 ret = config_writer_write_element_unsigned_int(writer,
45 config_element_subbuf_size, attr->subbuf_size);
46 if (ret) {
55c9e7ca 47 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
48 goto end;
49 }
50
51 ret = config_writer_write_element_unsigned_int(writer,
52 config_element_num_subbuf,
53 attr->num_subbuf);
54 if (ret) {
55c9e7ca 55 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
56 goto end;
57 }
58
59 ret = config_writer_write_element_unsigned_int(writer,
60 config_element_switch_timer_interval,
61 attr->switch_timer_interval);
62 if (ret) {
55c9e7ca 63 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
64 goto end;
65 }
66
67 ret = config_writer_write_element_unsigned_int(writer,
68 config_element_read_timer_interval,
69 attr->read_timer_interval);
70 if (ret) {
55c9e7ca 71 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
72 goto end;
73 }
74
75 ret = config_writer_write_element_string(writer,
76 config_element_output_type,
77 attr->output == LTTNG_EVENT_SPLICE ?
78 config_output_type_splice : config_output_type_mmap);
79 if (ret) {
55c9e7ca 80 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
81 goto end;
82 }
83
84 ret = config_writer_write_element_unsigned_int(writer,
85 config_element_tracefile_size, attr->tracefile_size);
86 if (ret) {
55c9e7ca 87 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
88 goto end;
89 }
90
91 ret = config_writer_write_element_unsigned_int(writer,
92 config_element_tracefile_count,
93 attr->tracefile_count);
94 if (ret) {
55c9e7ca 95 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
96 goto end;
97 }
98
99 ret = config_writer_write_element_unsigned_int(writer,
100 config_element_live_timer_interval,
101 attr->live_timer_interval);
102 if (ret) {
55c9e7ca 103 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
104 goto end;
105 }
4fc2b126
JR
106
107 if (attr->extended.ptr) {
108 struct lttng_channel_extended *ext = NULL;
109
110 ext = (struct lttng_channel_extended *) attr->extended.ptr;
111 ret = config_writer_write_element_unsigned_int(writer,
112 config_element_monitor_timer_interval,
113 ext->monitor_timer_interval);
114 if (ret) {
55c9e7ca 115 ret = LTTNG_ERR_SAVE_IO_FAIL;
4fc2b126
JR
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) {
55c9e7ca 123 ret = LTTNG_ERR_SAVE_IO_FAIL;
275472aa
JR
124 goto end;
125 }
4fc2b126
JR
126 }
127
55c9e7ca 128 ret = LTTNG_OK;
fb198a11 129end:
55c9e7ca 130 return ret;
fb198a11
JG
131}
132
55c9e7ca 133/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
134static
135int save_ust_channel_attributes(struct config_writer *writer,
fc4b93fa 136 struct lttng_ust_abi_channel_attr *attr)
fb198a11
JG
137{
138 int ret;
4fc2b126 139 struct ltt_ust_channel *channel = NULL;
fb198a11
JG
140
141 ret = config_writer_write_element_string(writer,
142 config_element_overwrite_mode,
143 attr->overwrite ? config_overwrite_mode_overwrite :
144 config_overwrite_mode_discard);
145 if (ret) {
55c9e7ca 146 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
147 goto end;
148 }
149
150 ret = config_writer_write_element_unsigned_int(writer,
151 config_element_subbuf_size, attr->subbuf_size);
152 if (ret) {
55c9e7ca 153 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
154 goto end;
155 }
156
157 ret = config_writer_write_element_unsigned_int(writer,
158 config_element_num_subbuf,
159 attr->num_subbuf);
160 if (ret) {
55c9e7ca 161 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
162 goto end;
163 }
164
165 ret = config_writer_write_element_unsigned_int(writer,
166 config_element_switch_timer_interval,
167 attr->switch_timer_interval);
168 if (ret) {
55c9e7ca 169 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
170 goto end;
171 }
172
173 ret = config_writer_write_element_unsigned_int(writer,
174 config_element_read_timer_interval,
175 attr->read_timer_interval);
176 if (ret) {
55c9e7ca 177 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
178 goto end;
179 }
180
181 ret = config_writer_write_element_string(writer,
182 config_element_output_type,
fc4b93fa 183 attr->output == LTTNG_UST_ABI_MMAP ?
fb198a11
JG
184 config_output_type_mmap : config_output_type_splice);
185 if (ret) {
55c9e7ca 186 ret = LTTNG_ERR_SAVE_IO_FAIL;
fb198a11
JG
187 goto end;
188 }
4fc2b126 189
275472aa
JR
190 ret = config_writer_write_element_signed_int(writer,
191 config_element_blocking_timeout,
192 attr->u.s.blocking_timeout);
193 if (ret) {
55c9e7ca 194 ret = LTTNG_ERR_SAVE_IO_FAIL;
275472aa
JR
195 goto end;
196 }
197
4fc2b126
JR
198 /*
199 * Fetch the monitor timer which is located in the parent of
200 * lttng_ust_channel_attr
201 */
202 channel = caa_container_of(attr, struct ltt_ust_channel, attr);
203 ret = config_writer_write_element_unsigned_int(writer,
204 config_element_monitor_timer_interval,
205 channel->monitor_timer_interval);
206 if (ret) {
55c9e7ca 207 ret = LTTNG_ERR_SAVE_IO_FAIL;
4fc2b126
JR
208 goto end;
209 }
210
55c9e7ca 211 ret = LTTNG_OK;
fb198a11 212end:
55c9e7ca 213 return ret;
fb198a11
JG
214}
215
216static
217const char *get_kernel_instrumentation_string(
b8e2fb80 218 enum lttng_kernel_abi_instrumentation instrumentation)
fb198a11
JG
219{
220 const char *instrumentation_string;
221
222 switch (instrumentation) {
b8e2fb80 223 case LTTNG_KERNEL_ABI_ALL:
fb198a11
JG
224 instrumentation_string = config_event_type_all;
225 break;
b8e2fb80 226 case LTTNG_KERNEL_ABI_TRACEPOINT:
fb198a11
JG
227 instrumentation_string = config_event_type_tracepoint;
228 break;
b8e2fb80 229 case LTTNG_KERNEL_ABI_KPROBE:
9d82c4c2 230 instrumentation_string = config_event_type_probe;
fb198a11 231 break;
b8e2fb80 232 case LTTNG_KERNEL_ABI_UPROBE:
c1e83fb4
FD
233 instrumentation_string = config_event_type_userspace_probe;
234 break;
b8e2fb80 235 case LTTNG_KERNEL_ABI_FUNCTION:
9d82c4c2 236 instrumentation_string = config_event_type_function_entry;
fb198a11 237 break;
b8e2fb80 238 case LTTNG_KERNEL_ABI_KRETPROBE:
9d82c4c2 239 instrumentation_string = config_event_type_function;
fb198a11 240 break;
b8e2fb80 241 case LTTNG_KERNEL_ABI_NOOP:
fb198a11
JG
242 instrumentation_string = config_event_type_noop;
243 break;
b8e2fb80 244 case LTTNG_KERNEL_ABI_SYSCALL:
fb198a11
JG
245 instrumentation_string = config_event_type_syscall;
246 break;
247 default:
248 instrumentation_string = NULL;
249 }
250
251 return instrumentation_string;
252}
253
254static
255const char *get_kernel_context_type_string(
b8e2fb80 256 enum lttng_kernel_abi_context_type context_type)
fb198a11
JG
257{
258 const char *context_type_string;
259
260 switch (context_type) {
b8e2fb80 261 case LTTNG_KERNEL_ABI_CONTEXT_PID:
fb198a11
JG
262 context_type_string = config_event_context_pid;
263 break;
b8e2fb80 264 case LTTNG_KERNEL_ABI_CONTEXT_PROCNAME:
fb198a11
JG
265 context_type_string = config_event_context_procname;
266 break;
b8e2fb80 267 case LTTNG_KERNEL_ABI_CONTEXT_PRIO:
fb198a11
JG
268 context_type_string = config_event_context_prio;
269 break;
b8e2fb80 270 case LTTNG_KERNEL_ABI_CONTEXT_NICE:
fb198a11
JG
271 context_type_string = config_event_context_nice;
272 break;
b8e2fb80 273 case LTTNG_KERNEL_ABI_CONTEXT_VPID:
fb198a11
JG
274 context_type_string = config_event_context_vpid;
275 break;
b8e2fb80 276 case LTTNG_KERNEL_ABI_CONTEXT_TID:
fb198a11
JG
277 context_type_string = config_event_context_tid;
278 break;
b8e2fb80 279 case LTTNG_KERNEL_ABI_CONTEXT_VTID:
fb198a11
JG
280 context_type_string = config_event_context_vtid;
281 break;
b8e2fb80 282 case LTTNG_KERNEL_ABI_CONTEXT_PPID:
fb198a11
JG
283 context_type_string = config_event_context_ppid;
284 break;
b8e2fb80 285 case LTTNG_KERNEL_ABI_CONTEXT_VPPID:
fb198a11
JG
286 context_type_string = config_event_context_vppid;
287 break;
b8e2fb80 288 case LTTNG_KERNEL_ABI_CONTEXT_HOSTNAME:
fb198a11
JG
289 context_type_string = config_event_context_hostname;
290 break;
b8e2fb80 291 case LTTNG_KERNEL_ABI_CONTEXT_INTERRUPTIBLE:
1ae5e83e
JD
292 context_type_string = config_event_context_interruptible;
293 break;
b8e2fb80 294 case LTTNG_KERNEL_ABI_CONTEXT_PREEMPTIBLE:
1ae5e83e
JD
295 context_type_string = config_event_context_preemptible;
296 break;
b8e2fb80 297 case LTTNG_KERNEL_ABI_CONTEXT_NEED_RESCHEDULE:
1ae5e83e
JD
298 context_type_string = config_event_context_need_reschedule;
299 break;
b8e2fb80 300 case LTTNG_KERNEL_ABI_CONTEXT_MIGRATABLE:
1ae5e83e
JD
301 context_type_string = config_event_context_migratable;
302 break;
b8e2fb80 303 case LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_USER:
16c4c991
FD
304 context_type_string = config_event_context_callstack_user;
305 break;
b8e2fb80 306 case LTTNG_KERNEL_ABI_CONTEXT_CALLSTACK_KERNEL:
16c4c991
FD
307 context_type_string = config_event_context_callstack_kernel;
308 break;
b8e2fb80 309 case LTTNG_KERNEL_ABI_CONTEXT_CGROUP_NS:
40e14884
MJ
310 context_type_string = config_event_context_cgroup_ns;
311 break;
b8e2fb80 312 case LTTNG_KERNEL_ABI_CONTEXT_IPC_NS:
40e14884
MJ
313 context_type_string = config_event_context_ipc_ns;
314 break;
b8e2fb80 315 case LTTNG_KERNEL_ABI_CONTEXT_MNT_NS:
40e14884
MJ
316 context_type_string = config_event_context_mnt_ns;
317 break;
b8e2fb80 318 case LTTNG_KERNEL_ABI_CONTEXT_NET_NS:
40e14884
MJ
319 context_type_string = config_event_context_net_ns;
320 break;
b8e2fb80 321 case LTTNG_KERNEL_ABI_CONTEXT_PID_NS:
40e14884
MJ
322 context_type_string = config_event_context_pid_ns;
323 break;
b8e2fb80 324 case LTTNG_KERNEL_ABI_CONTEXT_TIME_NS:
d37ac3cd
MJ
325 context_type_string = config_event_context_time_ns;
326 break;
b8e2fb80 327 case LTTNG_KERNEL_ABI_CONTEXT_USER_NS:
40e14884
MJ
328 context_type_string = config_event_context_user_ns;
329 break;
b8e2fb80 330 case LTTNG_KERNEL_ABI_CONTEXT_UTS_NS:
40e14884
MJ
331 context_type_string = config_event_context_uts_ns;
332 break;
b8e2fb80 333 case LTTNG_KERNEL_ABI_CONTEXT_UID:
499cbfa1
MJ
334 context_type_string = config_event_context_uid;
335 break;
b8e2fb80 336 case LTTNG_KERNEL_ABI_CONTEXT_EUID:
499cbfa1
MJ
337 context_type_string = config_event_context_euid;
338 break;
b8e2fb80 339 case LTTNG_KERNEL_ABI_CONTEXT_SUID:
499cbfa1
MJ
340 context_type_string = config_event_context_suid;
341 break;
b8e2fb80 342 case LTTNG_KERNEL_ABI_CONTEXT_GID:
499cbfa1
MJ
343 context_type_string = config_event_context_gid;
344 break;
b8e2fb80 345 case LTTNG_KERNEL_ABI_CONTEXT_EGID:
499cbfa1
MJ
346 context_type_string = config_event_context_egid;
347 break;
b8e2fb80 348 case LTTNG_KERNEL_ABI_CONTEXT_SGID:
499cbfa1
MJ
349 context_type_string = config_event_context_sgid;
350 break;
b8e2fb80 351 case LTTNG_KERNEL_ABI_CONTEXT_VUID:
499cbfa1
MJ
352 context_type_string = config_event_context_vuid;
353 break;
b8e2fb80 354 case LTTNG_KERNEL_ABI_CONTEXT_VEUID:
499cbfa1
MJ
355 context_type_string = config_event_context_veuid;
356 break;
b8e2fb80 357 case LTTNG_KERNEL_ABI_CONTEXT_VSUID:
499cbfa1
MJ
358 context_type_string = config_event_context_vsuid;
359 break;
b8e2fb80 360 case LTTNG_KERNEL_ABI_CONTEXT_VGID:
499cbfa1
MJ
361 context_type_string = config_event_context_vgid;
362 break;
b8e2fb80 363 case LTTNG_KERNEL_ABI_CONTEXT_VEGID:
499cbfa1
MJ
364 context_type_string = config_event_context_vegid;
365 break;
b8e2fb80 366 case LTTNG_KERNEL_ABI_CONTEXT_VSGID:
499cbfa1
MJ
367 context_type_string = config_event_context_vsgid;
368 break;
fb198a11
JG
369 default:
370 context_type_string = NULL;
371 }
372
373 return context_type_string;
374}
375
376static
377const char *get_ust_context_type_string(
fc4b93fa 378 enum lttng_ust_abi_context_type context_type)
fb198a11
JG
379{
380 const char *context_type_string;
381
382 switch (context_type) {
fc4b93fa 383 case LTTNG_UST_ABI_CONTEXT_PROCNAME:
fb198a11
JG
384 context_type_string = config_event_context_procname;
385 break;
fc4b93fa 386 case LTTNG_UST_ABI_CONTEXT_VPID:
fb198a11
JG
387 context_type_string = config_event_context_vpid;
388 break;
fc4b93fa 389 case LTTNG_UST_ABI_CONTEXT_VTID:
fb198a11
JG
390 context_type_string = config_event_context_vtid;
391 break;
fc4b93fa 392 case LTTNG_UST_ABI_CONTEXT_IP:
fb198a11
JG
393 context_type_string = config_event_context_ip;
394 break;
fc4b93fa 395 case LTTNG_UST_ABI_CONTEXT_PTHREAD_ID:
fb198a11
JG
396 context_type_string = config_event_context_pthread_id;
397 break;
fc4b93fa 398 case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
045fc617
JG
399 context_type_string = config_event_context_app;
400 break;
fc4b93fa 401 case LTTNG_UST_ABI_CONTEXT_CGROUP_NS:
f17b8732
MJ
402 context_type_string = config_event_context_cgroup_ns;
403 break;
fc4b93fa 404 case LTTNG_UST_ABI_CONTEXT_IPC_NS:
f17b8732
MJ
405 context_type_string = config_event_context_ipc_ns;
406 break;
fc4b93fa 407 case LTTNG_UST_ABI_CONTEXT_MNT_NS:
f17b8732
MJ
408 context_type_string = config_event_context_mnt_ns;
409 break;
fc4b93fa 410 case LTTNG_UST_ABI_CONTEXT_NET_NS:
f17b8732
MJ
411 context_type_string = config_event_context_net_ns;
412 break;
fc4b93fa 413 case LTTNG_UST_ABI_CONTEXT_TIME_NS:
d37ac3cd
MJ
414 context_type_string = config_event_context_time_ns;
415 break;
fc4b93fa 416 case LTTNG_UST_ABI_CONTEXT_PID_NS:
f17b8732
MJ
417 context_type_string = config_event_context_pid_ns;
418 break;
fc4b93fa 419 case LTTNG_UST_ABI_CONTEXT_USER_NS:
f17b8732
MJ
420 context_type_string = config_event_context_user_ns;
421 break;
fc4b93fa 422 case LTTNG_UST_ABI_CONTEXT_UTS_NS:
f17b8732
MJ
423 context_type_string = config_event_context_uts_ns;
424 break;
fc4b93fa 425 case LTTNG_UST_ABI_CONTEXT_VUID:
4fc59cb8
MJ
426 context_type_string = config_event_context_vuid;
427 break;
fc4b93fa 428 case LTTNG_UST_ABI_CONTEXT_VEUID:
4fc59cb8
MJ
429 context_type_string = config_event_context_veuid;
430 break;
fc4b93fa 431 case LTTNG_UST_ABI_CONTEXT_VSUID:
4fc59cb8
MJ
432 context_type_string = config_event_context_vsuid;
433 break;
fc4b93fa 434 case LTTNG_UST_ABI_CONTEXT_VGID:
4fc59cb8
MJ
435 context_type_string = config_event_context_vgid;
436 break;
fc4b93fa 437 case LTTNG_UST_ABI_CONTEXT_VEGID:
4fc59cb8
MJ
438 context_type_string = config_event_context_vegid;
439 break;
fc4b93fa 440 case LTTNG_UST_ABI_CONTEXT_VSGID:
4fc59cb8
MJ
441 context_type_string = config_event_context_vsgid;
442 break;
fc4b93fa 443 case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
14ce5bd8
JG
444 /*
445 * Error, should not be stored in the XML, perf contexts
446 * are stored as a node of type event_perf_context_type.
447 */
fb198a11
JG
448 default:
449 context_type_string = NULL;
e885a367 450 break;
fb198a11
JG
451 }
452
453 return context_type_string;
454}
455
456static
457const char *get_buffer_type_string(
458 enum lttng_buffer_type buffer_type)
459{
460 const char *buffer_type_string;
461
462 switch (buffer_type) {
463 case LTTNG_BUFFER_PER_PID:
464 buffer_type_string = config_buffer_type_per_pid;
465 break;
466 case LTTNG_BUFFER_PER_UID:
467 buffer_type_string = config_buffer_type_per_uid;
468 break;
469 case LTTNG_BUFFER_GLOBAL:
470 buffer_type_string = config_buffer_type_global;
471 break;
472 default:
473 buffer_type_string = NULL;
474 }
475
476 return buffer_type_string;
477}
478
479static
480const char *get_loglevel_type_string(
fc4b93fa 481 enum lttng_ust_abi_loglevel_type loglevel_type)
fb198a11
JG
482{
483 const char *loglevel_type_string;
484
485 switch (loglevel_type) {
fc4b93fa 486 case LTTNG_UST_ABI_LOGLEVEL_ALL:
fb198a11
JG
487 loglevel_type_string = config_loglevel_type_all;
488 break;
fc4b93fa 489 case LTTNG_UST_ABI_LOGLEVEL_RANGE:
fb198a11
JG
490 loglevel_type_string = config_loglevel_type_range;
491 break;
fc4b93fa 492 case LTTNG_UST_ABI_LOGLEVEL_SINGLE:
fb198a11
JG
493 loglevel_type_string = config_loglevel_type_single;
494 break;
495 default:
496 loglevel_type_string = NULL;
497 }
498
499 return loglevel_type_string;
500}
501
55c9e7ca 502/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11 503static
83712c39
FD
504int save_kernel_function_event(struct config_writer *writer,
505 struct ltt_kernel_event *event)
506{
507 int ret;
508
509 ret = config_writer_open_element(writer, config_element_function_attributes);
510 if (ret) {
511 ret = LTTNG_ERR_SAVE_IO_FAIL;
512 goto end;
513 }
514
515 ret = config_writer_write_element_string(writer, config_element_name,
516 event->event->u.ftrace.symbol_name);
517 if (ret) {
518 ret = LTTNG_ERR_SAVE_IO_FAIL;
519 goto end;
520 }
521
522 /* /function attributes */
523 ret = config_writer_close_element(writer);
524 if (ret) {
525 ret = LTTNG_ERR_SAVE_IO_FAIL;
526 goto end;
527 }
528end:
529 return ret;
530}
531
532static
533int save_kernel_kprobe_event(struct config_writer *writer,
534 struct ltt_kernel_event *event)
535{
536 int ret;
537 const char *symbol_name;
538 uint64_t addr;
539 uint64_t offset;
540
541 switch (event->event->instrumentation) {
b8e2fb80 542 case LTTNG_KERNEL_ABI_KPROBE:
83712c39
FD
543 /*
544 * Comments in lttng-kernel.h mention that
545 * either addr or symbol_name are set, not both.
546 */
547 addr = event->event->u.kprobe.addr;
548 offset = event->event->u.kprobe.offset;
549 symbol_name = addr ? NULL : event->event->u.kprobe.symbol_name;
550 break;
b8e2fb80 551 case LTTNG_KERNEL_ABI_KRETPROBE:
83712c39
FD
552 addr = event->event->u.kretprobe.addr;
553 offset = event->event->u.kretprobe.offset;
c1e83fb4 554 symbol_name = addr ? NULL : event->event->u.kretprobe.symbol_name;
83712c39
FD
555 break;
556 default:
a0377dfe 557 LTTNG_ASSERT(1);
c1e83fb4
FD
558 ERR("Unsupported kernel instrumentation type.");
559 ret = LTTNG_ERR_INVALID;
560 goto end;
83712c39
FD
561 }
562
563 ret = config_writer_open_element(writer, config_element_probe_attributes);
564 if (ret) {
565 ret = LTTNG_ERR_SAVE_IO_FAIL;
566 goto end;
567 }
568
c1e83fb4
FD
569 if (addr) {
570 ret = config_writer_write_element_unsigned_int( writer,
571 config_element_address, addr);
572 if (ret) {
573 ret = LTTNG_ERR_SAVE_IO_FAIL;
574 goto end;
575 }
576 } else if (symbol_name) {
83712c39
FD
577 ret = config_writer_write_element_string(writer,
578 config_element_symbol_name, symbol_name);
579 if (ret) {
580 ret = LTTNG_ERR_SAVE_IO_FAIL;
581 goto end;
582 }
c1e83fb4
FD
583 /* If the offset is non-zero, write it.*/
584 if (offset) {
585 ret = config_writer_write_element_unsigned_int(writer,
586 config_element_offset, offset);
587 if (ret) {
588 ret = LTTNG_ERR_SAVE_IO_FAIL;
589 goto end;
590 }
591 }
592 } else {
593 /*
594 * This really should not happen as we are either setting the
595 * address or the symbol above.
596 */
597 ERR("Invalid probe/function description.");
598 ret = LTTNG_ERR_INVALID;
599 goto end;
83712c39
FD
600 }
601
c1e83fb4
FD
602
603 ret = config_writer_close_element(writer);
604 if (ret) {
605 ret = LTTNG_ERR_SAVE_IO_FAIL;
606 goto end;
607 }
608end:
609 return ret;
610}
611
612/*
613 * Save the userspace probe tracepoint event associated with the event to the
614 * config writer.
615 */
616static
617int save_kernel_userspace_probe_tracepoint_event(struct config_writer *writer,
618 struct ltt_kernel_event *event)
619{
620 int ret = 0;
621 const char *probe_name, *provider_name, *binary_path;
87597c2c
JG
622 const struct lttng_userspace_probe_location *userspace_probe_location;
623 const struct lttng_userspace_probe_location_lookup_method *lookup_method;
c1e83fb4
FD
624 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
625
626 /* Get userspace probe location from the event. */
627 userspace_probe_location = event->userspace_probe_location;
628 if (!userspace_probe_location) {
629 ret = LTTNG_ERR_SAVE_IO_FAIL;
630 goto end;
631 }
632
633 /* Get lookup method and lookup method type. */
634 lookup_method = lttng_userspace_probe_location_get_lookup_method(userspace_probe_location);
635 if (!lookup_method) {
636 ret = LTTNG_ERR_SAVE_IO_FAIL;
637 goto end;
638 }
639
640 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
641
642 /* Get the binary path, probe name and provider name. */
643 binary_path =
644 lttng_userspace_probe_location_tracepoint_get_binary_path(
645 userspace_probe_location);
646 if (!binary_path) {
647 ret = LTTNG_ERR_SAVE_IO_FAIL;
648 goto end;
649 }
650
651 probe_name =
652 lttng_userspace_probe_location_tracepoint_get_probe_name(
653 userspace_probe_location);
654 if (!probe_name) {
655 ret = LTTNG_ERR_SAVE_IO_FAIL;
656 goto end;
657 }
658
659 provider_name =
660 lttng_userspace_probe_location_tracepoint_get_provider_name(
661 userspace_probe_location);
662 if (!provider_name) {
663 ret = LTTNG_ERR_SAVE_IO_FAIL;
664 goto end;
665 }
666
667 /* Open a userspace probe tracepoint attribute. */
668 ret = config_writer_open_element(writer, config_element_userspace_probe_tracepoint_attributes);
669 if (ret) {
670 ret = LTTNG_ERR_SAVE_IO_FAIL;
671 goto end;
672 }
673
674 switch (lookup_type) {
675 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_TRACEPOINT_SDT:
676 ret = config_writer_write_element_string(writer,
677 config_element_userspace_probe_lookup,
678 config_element_userspace_probe_lookup_tracepoint_sdt);
83712c39
FD
679 if (ret) {
680 ret = LTTNG_ERR_SAVE_IO_FAIL;
681 goto end;
682 }
c1e83fb4
FD
683 break;
684 default:
685 ERR("Unsupported kernel userspace probe tracepoint lookup method.");
686 ret = LTTNG_ERR_INVALID;
687 goto end;
83712c39
FD
688 }
689
c1e83fb4
FD
690 /* Write the binary path, provider name and the probe name. */
691 ret = config_writer_write_element_string(writer,
692 config_element_userspace_probe_location_binary_path,
693 binary_path);
694 if (ret) {
695 ret = LTTNG_ERR_SAVE_IO_FAIL;
696 goto end;
697 }
698
699 ret = config_writer_write_element_string(writer,
700 config_element_userspace_probe_tracepoint_location_provider_name,
701 provider_name);
702 if (ret) {
703 ret = LTTNG_ERR_SAVE_IO_FAIL;
704 goto end;
705 }
706
707 ret = config_writer_write_element_string(writer,
708 config_element_userspace_probe_tracepoint_location_probe_name,
709 probe_name);
710 if (ret) {
711 ret = LTTNG_ERR_SAVE_IO_FAIL;
712 goto end;
713 }
714
715 /* Close the userspace probe tracepoint attribute. */
716 ret = config_writer_close_element(writer);
717 if (ret) {
718 ret = LTTNG_ERR_SAVE_IO_FAIL;
719 goto end;
720 }
721
722end:
723 return ret;
724}
725
726/*
727 * Save the userspace probe function event associated with the event to the
728 * config writer.
729 */
730static
731int save_kernel_userspace_probe_function_event(struct config_writer *writer,
732 struct ltt_kernel_event *event)
733{
734 int ret = 0;
735 const char *function_name, *binary_path;
87597c2c
JG
736 const struct lttng_userspace_probe_location *userspace_probe_location;
737 const struct lttng_userspace_probe_location_lookup_method *lookup_method;
c1e83fb4
FD
738 enum lttng_userspace_probe_location_lookup_method_type lookup_type;
739
740 /* Get userspace probe location from the event. */
741 userspace_probe_location = event->userspace_probe_location;
742 if (!userspace_probe_location) {
743 ret = LTTNG_ERR_SAVE_IO_FAIL;
744 goto end;
745 }
746
747 /* Get lookup method and lookup method type. */
748 lookup_method = lttng_userspace_probe_location_get_lookup_method(
749 userspace_probe_location);
750 if (!lookup_method) {
751 ret = LTTNG_ERR_SAVE_IO_FAIL;
752 goto end;
753 }
754
755 /* Get the binary path and the function name. */
756 binary_path =
757 lttng_userspace_probe_location_function_get_binary_path(
758 userspace_probe_location);
759 if (!binary_path) {
760 ret = LTTNG_ERR_SAVE_IO_FAIL;
761 goto end;
762 }
763
764 function_name =
765 lttng_userspace_probe_location_function_get_function_name(
766 userspace_probe_location);
767 if (!function_name) {
768 ret = LTTNG_ERR_SAVE_IO_FAIL;
769 goto end;
770 }
771
772 /* Open a userspace probe function attribute. */
773 ret = config_writer_open_element(writer,
774 config_element_userspace_probe_function_attributes);
775 if (ret) {
776 ret = LTTNG_ERR_SAVE_IO_FAIL;
777 goto end;
778 }
779
780 lookup_type = lttng_userspace_probe_location_lookup_method_get_type(lookup_method);
781 switch (lookup_type) {
782 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_ELF:
783 ret = config_writer_write_element_string(writer,
784 config_element_userspace_probe_lookup,
785 config_element_userspace_probe_lookup_function_elf);
83712c39
FD
786 if (ret) {
787 ret = LTTNG_ERR_SAVE_IO_FAIL;
788 goto end;
789 }
c1e83fb4
FD
790 break;
791 case LTTNG_USERSPACE_PROBE_LOCATION_LOOKUP_METHOD_TYPE_FUNCTION_DEFAULT:
792 ret = config_writer_write_element_string(writer,
793 config_element_userspace_probe_lookup,
794 config_element_userspace_probe_lookup_function_default);
795 if (ret) {
796 ret = LTTNG_ERR_SAVE_IO_FAIL;
797 goto end;
798 }
799 break;
800 default:
801 ERR("Unsupported kernel userspace probe function lookup method.");
802 ret = LTTNG_ERR_INVALID;
803 goto end;
83712c39
FD
804 }
805
c1e83fb4
FD
806 /* Write the binary path and the function name. */
807 ret = config_writer_write_element_string(writer,
808 config_element_userspace_probe_location_binary_path,
809 binary_path);
810 if (ret) {
811 ret = LTTNG_ERR_SAVE_IO_FAIL;
812 goto end;
813 }
814
815 ret = config_writer_write_element_string(writer,
816 config_element_userspace_probe_function_location_function_name,
817 function_name);
818 if (ret) {
819 ret = LTTNG_ERR_SAVE_IO_FAIL;
820 goto end;
821 }
822
823 /* Close the userspace probe function attribute. */
83712c39
FD
824 ret = config_writer_close_element(writer);
825 if (ret) {
826 ret = LTTNG_ERR_SAVE_IO_FAIL;
827 goto end;
828 }
c1e83fb4 829
83712c39
FD
830end:
831 return ret;
832}
c1e83fb4
FD
833
834static
835int save_kernel_userspace_probe_event(struct config_writer *writer,
836 struct ltt_kernel_event *event)
837{
838 int ret;
839 struct lttng_userspace_probe_location *userspace_probe_location;
840
841 /* Get userspace probe location from the event. */
842 userspace_probe_location = event->userspace_probe_location;
843 if (!userspace_probe_location) {
844 ret = LTTNG_ERR_SAVE_IO_FAIL;
845 goto end;
846 }
847
848 switch(lttng_userspace_probe_location_get_type(userspace_probe_location)) {
849 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_FUNCTION:
850 {
851 ret = save_kernel_userspace_probe_function_event(writer, event);
852 if (ret) {
853 ret = LTTNG_ERR_SAVE_IO_FAIL;
854 goto end;
855 }
856 break;
857 }
858 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_TRACEPOINT:
859 {
860 ret = save_kernel_userspace_probe_tracepoint_event(writer, event);
861 if (ret) {
862 ret = LTTNG_ERR_SAVE_IO_FAIL;
863 goto end;
864 }
865 break;
866 }
867 case LTTNG_USERSPACE_PROBE_LOCATION_TYPE_UNKNOWN:
868 default:
869 ERR("Unsupported kernel userspace probe location type.");
870 ret = LTTNG_ERR_INVALID;
871 goto end;
872 }
873
874end:
875 return ret;
876}
877
878static
fb198a11 879int save_kernel_event(struct config_writer *writer,
83712c39 880 struct ltt_kernel_event *event)
fb198a11
JG
881{
882 int ret;
883 const char *instrumentation_type;
884
885 ret = config_writer_open_element(writer, config_element_event);
886 if (ret) {
887 ret = LTTNG_ERR_SAVE_IO_FAIL;
888 goto end;
889 }
890
891 if (event->event->name[0]) {
892 ret = config_writer_write_element_string(writer,
893 config_element_name, event->event->name);
894 if (ret) {
895 ret = LTTNG_ERR_SAVE_IO_FAIL;
896 goto end;
897 }
898 }
899
900 ret = config_writer_write_element_bool(writer, config_element_enabled,
901 event->enabled);
902 if (ret) {
903 ret = LTTNG_ERR_SAVE_IO_FAIL;
904 goto end;
905 }
906
907 instrumentation_type = get_kernel_instrumentation_string(
908 event->event->instrumentation);
909 if (!instrumentation_type) {
910 ret = LTTNG_ERR_INVALID;
911 goto end;
912 }
913
914 ret = config_writer_write_element_string(writer, config_element_type,
915 instrumentation_type);
916 if (ret) {
917 ret = LTTNG_ERR_SAVE_IO_FAIL;
918 goto end;
919 }
920
911d1560
JG
921 if (event->filter_expression) {
922 ret = config_writer_write_element_string(writer,
923 config_element_filter,
924 event->filter_expression);
925 if (ret) {
926 ret = LTTNG_ERR_SAVE_IO_FAIL;
927 goto end;
928 }
929 }
930
b8e2fb80
FD
931 if (event->event->instrumentation == LTTNG_KERNEL_ABI_FUNCTION ||
932 event->event->instrumentation == LTTNG_KERNEL_ABI_KPROBE ||
933 event->event->instrumentation == LTTNG_KERNEL_ABI_UPROBE ||
934 event->event->instrumentation == LTTNG_KERNEL_ABI_KRETPROBE) {
fb198a11
JG
935
936 ret = config_writer_open_element(writer,
937 config_element_attributes);
938 if (ret) {
939 ret = LTTNG_ERR_SAVE_IO_FAIL;
940 goto end;
941 }
942
943 switch (event->event->instrumentation) {
b8e2fb80
FD
944 case LTTNG_KERNEL_ABI_SYSCALL:
945 case LTTNG_KERNEL_ABI_FUNCTION:
83712c39 946 ret = save_kernel_function_event(writer, event);
fb198a11 947 if (ret) {
fb198a11
JG
948 goto end;
949 }
950 break;
b8e2fb80
FD
951 case LTTNG_KERNEL_ABI_KPROBE:
952 case LTTNG_KERNEL_ABI_KRETPROBE:
83712c39 953 ret = save_kernel_kprobe_event(writer, event);
fb198a11 954 if (ret) {
fb198a11
JG
955 goto end;
956 }
957 break;
b8e2fb80 958 case LTTNG_KERNEL_ABI_UPROBE:
c1e83fb4
FD
959 ret = save_kernel_userspace_probe_event(writer, event);
960 if (ret) {
961 goto end;
962 }
963 break;
fb198a11
JG
964 default:
965 ERR("Unsupported kernel instrumentation type.");
966 ret = LTTNG_ERR_INVALID;
967 goto end;
968 }
969
970 /* /attributes */
971 ret = config_writer_close_element(writer);
972 if (ret) {
973 ret = LTTNG_ERR_SAVE_IO_FAIL;
974 goto end;
975 }
976 }
977
978 /* /event */
979 ret = config_writer_close_element(writer);
980 if (ret) {
981 ret = LTTNG_ERR_SAVE_IO_FAIL;
982 goto end;
983 }
55c9e7ca
JR
984
985 ret = LTTNG_OK;
fb198a11
JG
986end:
987 return ret;
988}
989
55c9e7ca 990/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
991static
992int save_kernel_events(struct config_writer *writer,
0de3eda1 993 struct ltt_kernel_channel *kchan)
fb198a11
JG
994{
995 int ret;
996 struct ltt_kernel_event *event;
997
998 ret = config_writer_open_element(writer, config_element_events);
999 if (ret) {
1000 ret = LTTNG_ERR_SAVE_IO_FAIL;
1001 goto end;
1002 }
1003
0de3eda1 1004 cds_list_for_each_entry(event, &kchan->events_list.head, list) {
fb198a11 1005 ret = save_kernel_event(writer, event);
55c9e7ca 1006 if (ret != LTTNG_OK) {
fb198a11
JG
1007 goto end;
1008 }
1009 }
1010
1011 /* /events */
1012 ret = config_writer_close_element(writer);
1013 if (ret) {
1014 ret = LTTNG_ERR_SAVE_IO_FAIL;
1015 goto end;
1016 }
55c9e7ca
JR
1017
1018 ret = LTTNG_OK;
fb198a11
JG
1019end:
1020 return ret;
1021}
1022
55c9e7ca 1023/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1024static
1025int save_ust_event(struct config_writer *writer,
1026 struct ltt_ust_event *event)
1027{
1028 int ret;
1029 const char *loglevel_type_string;
1030
1031 ret = config_writer_open_element(writer, config_element_event);
1032 if (ret) {
1033 ret = LTTNG_ERR_SAVE_IO_FAIL;
1034 goto end;
1035 }
1036
1037 if (event->attr.name[0]) {
1038 ret = config_writer_write_element_string(writer,
1039 config_element_name, event->attr.name);
1040 if (ret) {
1041 ret = LTTNG_ERR_SAVE_IO_FAIL;
1042 goto end;
1043 }
1044 }
1045
1046 ret = config_writer_write_element_bool(writer, config_element_enabled,
1047 event->enabled);
1048 if (ret) {
1049 ret = LTTNG_ERR_SAVE_IO_FAIL;
1050 goto end;
1051 }
1052
fc4b93fa 1053 if (event->attr.instrumentation != LTTNG_UST_ABI_TRACEPOINT) {
fb198a11
JG
1054 ERR("Unsupported UST instrumentation type.");
1055 ret = LTTNG_ERR_INVALID;
1056 goto end;
1057 }
1058 ret = config_writer_write_element_string(writer, config_element_type,
1059 config_event_type_tracepoint);
1060 if (ret) {
1061 ret = LTTNG_ERR_SAVE_IO_FAIL;
1062 goto end;
1063 }
1064
1065 loglevel_type_string = get_loglevel_type_string(
7966af57 1066 (lttng_ust_abi_loglevel_type) event->attr.loglevel_type);
fb198a11
JG
1067 if (!loglevel_type_string) {
1068 ERR("Unsupported UST loglevel type.");
1069 ret = LTTNG_ERR_INVALID;
1070 goto end;
1071 }
1072
1073 ret = config_writer_write_element_string(writer,
1074 config_element_loglevel_type, loglevel_type_string);
1075 if (ret) {
1076 ret = LTTNG_ERR_SAVE_IO_FAIL;
1077 goto end;
1078 }
1079
1adbdb10 1080 /* The log level is irrelevant if no "filtering" is enabled */
fc4b93fa 1081 if (event->attr.loglevel_type != LTTNG_UST_ABI_LOGLEVEL_ALL) {
1adbdb10
JG
1082 ret = config_writer_write_element_signed_int(writer,
1083 config_element_loglevel, event->attr.loglevel);
1084 if (ret) {
1085 ret = LTTNG_ERR_SAVE_IO_FAIL;
1086 goto end;
1087 }
fb198a11
JG
1088 }
1089
1090 if (event->filter_expression) {
1091 ret = config_writer_write_element_string(writer,
1092 config_element_filter, event->filter_expression);
1093 if (ret) {
1094 ret = LTTNG_ERR_SAVE_IO_FAIL;
1095 goto end;
1096 }
1097 }
1098
1099 if (event->exclusion && event->exclusion->count) {
1100 uint32_t i;
1101
1102 ret = config_writer_open_element(writer,
1103 config_element_exclusions);
1104 if (ret) {
1105 ret = LTTNG_ERR_SAVE_IO_FAIL;
1106 goto end;
1107 }
1108
1109 for (i = 0; i < event->exclusion->count; i++) {
1110 ret = config_writer_write_element_string(writer,
1111 config_element_exclusion,
d7af3565
PP
1112 LTTNG_EVENT_EXCLUSION_NAME_AT(
1113 event->exclusion, i));
fb198a11
JG
1114 if (ret) {
1115 ret = LTTNG_ERR_SAVE_IO_FAIL;
1116 goto end;
1117 }
1118 }
1119
1120 /* /exclusions */
1121 ret = config_writer_close_element(writer);
1122 if (ret) {
1123 ret = LTTNG_ERR_SAVE_IO_FAIL;
1124 goto end;
1125 }
1126 }
1127
1128 /* /event */
1129 ret = config_writer_close_element(writer);
1130 if (ret) {
1131 ret = LTTNG_ERR_SAVE_IO_FAIL;
1132 goto end;
1133 }
55c9e7ca
JR
1134
1135 ret = LTTNG_OK;
fb198a11
JG
1136end:
1137 return ret;
1138}
1139
55c9e7ca 1140/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1141static
1142int save_ust_events(struct config_writer *writer,
1143 struct lttng_ht *events)
1144{
1145 int ret;
1146 struct ltt_ust_event *event;
1147 struct lttng_ht_node_str *node;
1148 struct lttng_ht_iter iter;
1149
1150 ret = config_writer_open_element(writer, config_element_events);
1151 if (ret) {
1152 ret = LTTNG_ERR_SAVE_IO_FAIL;
1153 goto end;
1154 }
1155
1156 rcu_read_lock();
1157 cds_lfht_for_each_entry(events->ht, &iter.iter, node, node) {
1158 event = caa_container_of(node, struct ltt_ust_event, node);
1159
af325ba1
JG
1160 if (event->internal) {
1161 /* Internal events must not be exposed to clients */
1162 continue;
1163 }
fb198a11 1164 ret = save_ust_event(writer, event);
55c9e7ca 1165 if (ret != LTTNG_OK) {
fb198a11
JG
1166 rcu_read_unlock();
1167 goto end;
1168 }
1169 }
1170 rcu_read_unlock();
1171
1172 /* /events */
1173 ret = config_writer_close_element(writer);
1174 if (ret) {
1175 ret = LTTNG_ERR_SAVE_IO_FAIL;
1176 goto end;
1177 }
55c9e7ca
JR
1178
1179 ret = LTTNG_OK;
fb198a11
JG
1180end:
1181 return ret;
1182}
1183
55c9e7ca 1184/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
51755dc8 1185static
0b35b846 1186int init_ust_event_from_agent_event(struct ltt_ust_event *ust_event,
51755dc8
JG
1187 struct agent_event *agent_event)
1188{
55c9e7ca 1189 int ret;
fc4b93fa 1190 enum lttng_ust_abi_loglevel_type ust_loglevel_type;
0b35b846 1191
44760c20 1192 ust_event->enabled = AGENT_EVENT_IS_ENABLED(agent_event);
fc4b93fa 1193 ust_event->attr.instrumentation = LTTNG_UST_ABI_TRACEPOINT;
d333bdaa
MD
1194 if (lttng_strncpy(ust_event->attr.name, agent_event->name,
1195 LTTNG_SYMBOL_NAME_LEN)) {
55c9e7ca 1196 ret = LTTNG_ERR_INVALID;
d333bdaa
MD
1197 goto end;
1198 }
0b35b846
JG
1199 switch (agent_event->loglevel_type) {
1200 case LTTNG_EVENT_LOGLEVEL_ALL:
fc4b93fa 1201 ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_ALL;
0b35b846
JG
1202 break;
1203 case LTTNG_EVENT_LOGLEVEL_SINGLE:
fc4b93fa 1204 ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_SINGLE;
0b35b846
JG
1205 break;
1206 case LTTNG_EVENT_LOGLEVEL_RANGE:
fc4b93fa 1207 ust_loglevel_type = LTTNG_UST_ABI_LOGLEVEL_RANGE;
0b35b846
JG
1208 break;
1209 default:
1210 ERR("Invalid agent_event loglevel_type.");
55c9e7ca 1211 ret = LTTNG_ERR_INVALID;
0b35b846
JG
1212 goto end;
1213 }
1214
1215 ust_event->attr.loglevel_type = ust_loglevel_type;
2106efa0 1216 ust_event->attr.loglevel = agent_event->loglevel_value;
51755dc8
JG
1217 ust_event->filter_expression = agent_event->filter_expression;
1218 ust_event->exclusion = agent_event->exclusion;
55c9e7ca
JR
1219
1220 ret = LTTNG_OK;
0b35b846
JG
1221end:
1222 return ret;
51755dc8
JG
1223}
1224
55c9e7ca 1225/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
51755dc8
JG
1226static
1227int save_agent_events(struct config_writer *writer,
51755dc8
JG
1228 struct agent *agent)
1229{
1230 int ret;
1231 struct lttng_ht_iter iter;
1232 struct lttng_ht_node_str *node;
1233
1234 ret = config_writer_open_element(writer, config_element_events);
1235 if (ret) {
1236 ret = LTTNG_ERR_SAVE_IO_FAIL;
1237 goto end;
1238 }
1239
1240 rcu_read_lock();
1241 cds_lfht_for_each_entry(agent->events->ht, &iter.iter, node, node) {
51755dc8
JG
1242 struct agent_event *agent_event;
1243 struct ltt_ust_event fake_event;
1244
1245 memset(&fake_event, 0, sizeof(fake_event));
1246 agent_event = caa_container_of(node, struct agent_event, node);
1247
1248 /*
1249 * Initialize a fake ust event to reuse the same serialization
1250 * function since UST and agent events contain the same info
1251 * (and one could wonder why they don't reuse the same
1252 * structures...).
1253 */
0b35b846 1254 ret = init_ust_event_from_agent_event(&fake_event, agent_event);
55c9e7ca 1255 if (ret != LTTNG_OK) {
0b35b846
JG
1256 rcu_read_unlock();
1257 goto end;
1258 }
51755dc8 1259 ret = save_ust_event(writer, &fake_event);
55c9e7ca 1260 if (ret != LTTNG_OK) {
51755dc8
JG
1261 rcu_read_unlock();
1262 goto end;
1263 }
1264 }
1265 rcu_read_unlock();
1266
1267 /* /events */
1268 ret = config_writer_close_element(writer);
1269 if (ret) {
1270 ret = LTTNG_ERR_SAVE_IO_FAIL;
1271 goto end;
1272 }
55c9e7ca
JR
1273
1274 ret = LTTNG_OK;
51755dc8
JG
1275end:
1276 return ret;
1277}
1278
55c9e7ca 1279/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1280static
1281int save_kernel_context(struct config_writer *writer,
b8e2fb80 1282 struct lttng_kernel_abi_context *ctx)
fb198a11 1283{
55c9e7ca 1284 int ret = LTTNG_OK;
fb198a11
JG
1285
1286 if (!ctx) {
1287 goto end;
1288 }
1289
fb198a11
JG
1290 ret = config_writer_open_element(writer, config_element_context);
1291 if (ret) {
1292 ret = LTTNG_ERR_SAVE_IO_FAIL;
1293 goto end;
1294 }
1295
b8e2fb80 1296 if (ctx->ctx == LTTNG_KERNEL_ABI_CONTEXT_PERF_CPU_COUNTER) {
045fc617
JG
1297 ret = config_writer_open_element(writer,
1298 config_element_context_perf);
fb198a11
JG
1299 if (ret) {
1300 ret = LTTNG_ERR_SAVE_IO_FAIL;
1301 goto end;
1302 }
1303
1304 ret = config_writer_write_element_unsigned_int(writer,
1305 config_element_type, ctx->u.perf_counter.type);
1306 if (ret) {
1307 ret = LTTNG_ERR_SAVE_IO_FAIL;
1308 goto end;
1309 }
1310
1311 ret = config_writer_write_element_unsigned_int(writer,
1312 config_element_config, ctx->u.perf_counter.config);
1313 if (ret) {
1314 ret = LTTNG_ERR_SAVE_IO_FAIL;
1315 goto end;
1316 }
1317
1318 ret = config_writer_write_element_string(writer,
1319 config_element_name, ctx->u.perf_counter.name);
1320 if (ret) {
1321 ret = LTTNG_ERR_SAVE_IO_FAIL;
1322 goto end;
1323 }
1324
1325 /* /perf */
1326 ret = config_writer_close_element(writer);
1327 if (ret) {
1328 ret = LTTNG_ERR_SAVE_IO_FAIL;
1329 goto end;
1330 }
1331 } else {
1332 const char *context_type_string =
1333 get_kernel_context_type_string(ctx->ctx);
1334
1335 if (!context_type_string) {
1336 ERR("Unsupported kernel context type.");
1337 ret = LTTNG_ERR_INVALID;
1338 goto end;
1339 }
1340
1341 ret = config_writer_write_element_string(writer,
1342 config_element_type, context_type_string);
1343 if (ret) {
1344 ret = LTTNG_ERR_SAVE_IO_FAIL;
1345 goto end;
1346 }
1347 }
1348
1349 /* /context */
1350 ret = config_writer_close_element(writer);
1351 if (ret) {
1352 ret = LTTNG_ERR_SAVE_IO_FAIL;
1353 goto end;
1354 }
1355
55c9e7ca 1356 ret = LTTNG_OK;
645328ae
DG
1357end:
1358 return ret;
1359}
1360
55c9e7ca 1361/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
645328ae
DG
1362static
1363int save_kernel_contexts(struct config_writer *writer,
1364 struct ltt_kernel_channel *kchan)
1365{
1366 int ret;
1367 struct ltt_kernel_context *ctx;
1368
2aa64052 1369 if (cds_list_empty(&kchan->ctx_list)) {
55c9e7ca 1370 ret = LTTNG_OK;
2aa64052
JG
1371 goto end;
1372 }
1373
645328ae
DG
1374 ret = config_writer_open_element(writer, config_element_contexts);
1375 if (ret) {
1376 ret = LTTNG_ERR_SAVE_IO_FAIL;
1377 goto end;
1378 }
1379
1380 cds_list_for_each_entry(ctx, &kchan->ctx_list, list) {
1381 ret = save_kernel_context(writer, &ctx->ctx);
55c9e7ca 1382 if (ret != LTTNG_OK) {
645328ae
DG
1383 goto end;
1384 }
1385 }
1386
fb198a11
JG
1387 /* /contexts */
1388 ret = config_writer_close_element(writer);
1389 if (ret) {
1390 ret = LTTNG_ERR_SAVE_IO_FAIL;
1391 goto end;
1392 }
55c9e7ca
JR
1393
1394 ret = LTTNG_OK;
fb198a11
JG
1395end:
1396 return ret;
1397}
1398
55c9e7ca 1399/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
045fc617
JG
1400static
1401int save_ust_context_perf_thread_counter(struct config_writer *writer,
1402 struct ltt_ust_context *ctx)
1403{
1404 int ret;
1405
a0377dfe
FD
1406 LTTNG_ASSERT(writer);
1407 LTTNG_ASSERT(ctx);
045fc617
JG
1408
1409 /* Perf contexts are saved as event_perf_context_type */
1410 ret = config_writer_open_element(writer, config_element_context_perf);
1411 if (ret) {
1412 ret = LTTNG_ERR_SAVE_IO_FAIL;
1413 goto end;
1414 }
1415
1416 ret = config_writer_write_element_unsigned_int(writer,
1417 config_element_type, ctx->ctx.u.perf_counter.type);
1418 if (ret) {
1419 ret = LTTNG_ERR_SAVE_IO_FAIL;
1420 goto end;
1421 }
1422
1423 ret = config_writer_write_element_unsigned_int(writer,
1424 config_element_config, ctx->ctx.u.perf_counter.config);
1425 if (ret) {
1426 ret = LTTNG_ERR_SAVE_IO_FAIL;
1427 goto end;
1428 }
1429
1430 ret = config_writer_write_element_string(writer, config_element_name,
1431 ctx->ctx.u.perf_counter.name);
1432 if (ret) {
1433 ret = LTTNG_ERR_SAVE_IO_FAIL;
1434 goto end;
1435 }
1436
1437 /* /perf */
1438 ret = config_writer_close_element(writer);
1439 if (ret) {
1440 ret = LTTNG_ERR_SAVE_IO_FAIL;
1441 goto end;
1442 }
55c9e7ca
JR
1443
1444 ret = LTTNG_OK;
045fc617
JG
1445end:
1446 return ret;
1447}
1448
55c9e7ca 1449/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
045fc617
JG
1450static
1451int save_ust_context_app_ctx(struct config_writer *writer,
1452 struct ltt_ust_context *ctx)
1453{
1454 int ret;
1455
a0377dfe
FD
1456 LTTNG_ASSERT(writer);
1457 LTTNG_ASSERT(ctx);
045fc617
JG
1458
1459 /* Application contexts are saved as application_context_type */
1460 ret = config_writer_open_element(writer, config_element_context_app);
1461 if (ret) {
1462 ret = LTTNG_ERR_SAVE_IO_FAIL;
1463 goto end;
1464 }
1465
1466 ret = config_writer_write_element_string(writer,
1467 config_element_context_app_provider_name,
1468 ctx->ctx.u.app_ctx.provider_name);
1469 if (ret) {
1470 ret = LTTNG_ERR_SAVE_IO_FAIL;
1471 goto end;
1472 }
1473
1474 ret = config_writer_write_element_string(writer,
1475 config_element_context_app_ctx_name,
1476 ctx->ctx.u.app_ctx.ctx_name);
1477 if (ret) {
1478 ret = LTTNG_ERR_SAVE_IO_FAIL;
1479 goto end;
1480 }
1481
1482 /* /app */
1483 ret = config_writer_close_element(writer);
1484 if (ret) {
1485 ret = LTTNG_ERR_SAVE_IO_FAIL;
1486 goto end;
1487 }
55c9e7ca
JR
1488
1489 ret = LTTNG_OK;
045fc617
JG
1490end:
1491 return ret;
1492}
1493
55c9e7ca 1494/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
045fc617
JG
1495static
1496int save_ust_context_generic(struct config_writer *writer,
1497 struct ltt_ust_context *ctx)
1498{
1499 int ret;
1500 const char *context_type_string;
1501
a0377dfe
FD
1502 LTTNG_ASSERT(writer);
1503 LTTNG_ASSERT(ctx);
045fc617
JG
1504
1505 /* Save context as event_context_type_type */
1506 context_type_string = get_ust_context_type_string(
1507 ctx->ctx.ctx);
1508 if (!context_type_string) {
1509 ERR("Unsupported UST context type.");
1510 ret = LTTNG_ERR_SAVE_IO_FAIL;
1511 goto end;
1512 }
1513
1514 ret = config_writer_write_element_string(writer,
1515 config_element_type, context_type_string);
1516 if (ret) {
1517 ret = LTTNG_ERR_SAVE_IO_FAIL;
1518 goto end;
1519 }
55c9e7ca
JR
1520
1521 ret = LTTNG_OK;
045fc617
JG
1522end:
1523 return ret;
1524}
1525
55c9e7ca 1526/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1527static
1528int save_ust_context(struct config_writer *writer,
1529 struct cds_list_head *ctx_list)
1530{
1531 int ret;
1532 struct ltt_ust_context *ctx;
1533
a0377dfe
FD
1534 LTTNG_ASSERT(writer);
1535 LTTNG_ASSERT(ctx_list);
fb198a11
JG
1536
1537 ret = config_writer_open_element(writer, config_element_contexts);
1538 if (ret) {
1539 ret = LTTNG_ERR_SAVE_IO_FAIL;
1540 goto end;
1541 }
1542
1543 cds_list_for_each_entry(ctx, ctx_list, list) {
fb198a11
JG
1544 ret = config_writer_open_element(writer,
1545 config_element_context);
1546 if (ret) {
1547 ret = LTTNG_ERR_SAVE_IO_FAIL;
1548 goto end;
1549 }
1550
045fc617 1551 switch (ctx->ctx.ctx) {
fc4b93fa 1552 case LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER:
045fc617
JG
1553 ret = save_ust_context_perf_thread_counter(writer, ctx);
1554 break;
fc4b93fa 1555 case LTTNG_UST_ABI_CONTEXT_APP_CONTEXT:
045fc617
JG
1556 ret = save_ust_context_app_ctx(writer, ctx);
1557 break;
1558 default:
1559 /* Save generic context. */
1560 ret = save_ust_context_generic(writer, ctx);
1561 }
55c9e7ca 1562 if (ret != LTTNG_OK) {
045fc617 1563 goto end;
fb198a11
JG
1564 }
1565
1566 /* /context */
1567 ret = config_writer_close_element(writer);
1568 if (ret) {
1569 ret = LTTNG_ERR_SAVE_IO_FAIL;
1570 goto end;
1571 }
1572 }
1573
1574 /* /contexts */
1575 ret = config_writer_close_element(writer);
1576 if (ret) {
1577 ret = LTTNG_ERR_SAVE_IO_FAIL;
1578 goto end;
1579 }
55c9e7ca
JR
1580
1581 ret = LTTNG_OK;
fb198a11
JG
1582end:
1583 return ret;
1584}
1585
55c9e7ca 1586/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1587static
1588int save_kernel_channel(struct config_writer *writer,
1589 struct ltt_kernel_channel *kchan)
1590{
1591 int ret;
1592
a0377dfe
FD
1593 LTTNG_ASSERT(writer);
1594 LTTNG_ASSERT(kchan);
fb198a11
JG
1595
1596 ret = config_writer_open_element(writer, config_element_channel);
1597 if (ret) {
1598 ret = LTTNG_ERR_SAVE_IO_FAIL;
1599 goto end;
1600 }
1601
1602 ret = config_writer_write_element_string(writer, config_element_name,
1603 kchan->channel->name);
1604 if (ret) {
1605 ret = LTTNG_ERR_SAVE_IO_FAIL;
1606 goto end;
1607 }
1608
1609 ret = config_writer_write_element_bool(writer, config_element_enabled,
1610 kchan->channel->enabled);
1611 if (ret) {
1612 ret = LTTNG_ERR_SAVE_IO_FAIL;
1613 goto end;
1614 }
1615
1616 ret = save_kernel_channel_attributes(writer, &kchan->channel->attr);
55c9e7ca 1617 if (ret != LTTNG_OK) {
fb198a11
JG
1618 goto end;
1619 }
1620
0de3eda1 1621 ret = save_kernel_events(writer, kchan);
55c9e7ca 1622 if (ret != LTTNG_OK) {
fb198a11
JG
1623 goto end;
1624 }
1625
645328ae 1626 ret = save_kernel_contexts(writer, kchan);
55c9e7ca 1627 if (ret != LTTNG_OK) {
fb198a11
JG
1628 goto end;
1629 }
1630
1631 /* /channel */
1632 ret = config_writer_close_element(writer);
1633 if (ret) {
1634 ret = LTTNG_ERR_SAVE_IO_FAIL;
1635 goto end;
1636 }
55c9e7ca
JR
1637
1638 ret = LTTNG_OK;
fb198a11
JG
1639end:
1640 return ret;
1641}
1642
55c9e7ca 1643/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1644static
1645int save_ust_channel(struct config_writer *writer,
1646 struct ltt_ust_channel *ust_chan,
1647 struct ltt_ust_session *session)
1648{
1649 int ret;
1650
a0377dfe
FD
1651 LTTNG_ASSERT(writer);
1652 LTTNG_ASSERT(ust_chan);
1653 LTTNG_ASSERT(session);
fb198a11
JG
1654
1655 ret = config_writer_open_element(writer, config_element_channel);
1656 if (ret) {
1657 ret = LTTNG_ERR_SAVE_IO_FAIL;
1658 goto end;
1659 }
1660
1661 ret = config_writer_write_element_string(writer, config_element_name,
1662 ust_chan->name);
1663 if (ret) {
1664 ret = LTTNG_ERR_SAVE_IO_FAIL;
1665 goto end;
1666 }
1667
1668 ret = config_writer_write_element_bool(writer, config_element_enabled,
1669 ust_chan->enabled);
1670 if (ret) {
1671 ret = LTTNG_ERR_SAVE_IO_FAIL;
1672 goto end;
1673 }
1674
1675 ret = save_ust_channel_attributes(writer, &ust_chan->attr);
55c9e7ca 1676 if (ret != LTTNG_OK) {
fb198a11
JG
1677 goto end;
1678 }
1679
1680 ret = config_writer_write_element_unsigned_int(writer,
1681 config_element_tracefile_size, ust_chan->tracefile_size);
1682 if (ret) {
1683 ret = LTTNG_ERR_SAVE_IO_FAIL;
1684 goto end;
1685 }
1686
1687 ret = config_writer_write_element_unsigned_int(writer,
1688 config_element_tracefile_count, ust_chan->tracefile_count);
1689 if (ret) {
1690 ret = LTTNG_ERR_SAVE_IO_FAIL;
1691 goto end;
1692 }
1693
1694 ret = config_writer_write_element_unsigned_int(writer,
1695 config_element_live_timer_interval,
1696 session->live_timer_interval);
1697 if (ret) {
1698 ret = LTTNG_ERR_SAVE_IO_FAIL;
1699 goto end;
1700 }
1701
51755dc8
JG
1702 if (ust_chan->domain == LTTNG_DOMAIN_UST) {
1703 ret = save_ust_events(writer, ust_chan->events);
55c9e7ca 1704 if (ret != LTTNG_OK) {
51755dc8
JG
1705 goto end;
1706 }
1707 } else {
1708 struct agent *agent = NULL;
1709
1710 agent = trace_ust_find_agent(session, ust_chan->domain);
1711 if (!agent) {
1712 ret = LTTNG_ERR_SAVE_IO_FAIL;
1713 ERR("Could not find agent associated to UST subdomain");
1714 goto end;
1715 }
1716
1717 /*
1718 * Channels associated with a UST sub-domain (such as JUL, Log4j
1719 * or Python) don't have any non-internal events. We retrieve
1720 * the "agent" events associated with this channel and serialize
1721 * them.
1722 */
8cd0a98d 1723 ret = save_agent_events(writer, agent);
55c9e7ca 1724 if (ret != LTTNG_OK) {
51755dc8
JG
1725 goto end;
1726 }
fb198a11
JG
1727 }
1728
1729 ret = save_ust_context(writer, &ust_chan->ctx_list);
55c9e7ca 1730 if (ret != LTTNG_OK) {
fb198a11
JG
1731 goto end;
1732 }
1733
1734 /* /channel */
1735 ret = config_writer_close_element(writer);
1736 if (ret) {
1737 ret = LTTNG_ERR_SAVE_IO_FAIL;
1738 goto end;
1739 }
55c9e7ca
JR
1740
1741 ret = LTTNG_OK;
fb198a11
JG
1742end:
1743 return ret;
1744}
1745
55c9e7ca 1746/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
1747static
1748int save_kernel_session(struct config_writer *writer,
1749 struct ltt_session *session)
1750{
1751 int ret;
1752 struct ltt_kernel_channel *kchan;
1753
a0377dfe
FD
1754 LTTNG_ASSERT(writer);
1755 LTTNG_ASSERT(session);
fb198a11
JG
1756
1757 ret = config_writer_write_element_string(writer, config_element_type,
1758 config_domain_type_kernel);
1759 if (ret) {
1760 ret = LTTNG_ERR_SAVE_IO_FAIL;
1761 goto end;
1762 }
1763
1764 ret = config_writer_write_element_string(writer,
1765 config_element_buffer_type, config_buffer_type_global);
1766 if (ret) {
1767 ret = LTTNG_ERR_SAVE_IO_FAIL;
1768 goto end;
1769 }
1770
1771 ret = config_writer_open_element(writer,
1772 config_element_channels);
1773 if (ret) {
1774 ret = LTTNG_ERR_SAVE_IO_FAIL;
1775 goto end;
1776 }
1777
1778 cds_list_for_each_entry(kchan, &session->kernel_session->channel_list.head,
1779 list) {
1780 ret = save_kernel_channel(writer, kchan);
55c9e7ca 1781 if (ret != LTTNG_OK) {
fb198a11
JG
1782 goto end;
1783 }
1784 }
1785
1786 /* /channels */
1787 ret = config_writer_close_element(writer);
1788 if (ret) {
1789 ret = LTTNG_ERR_SAVE_IO_FAIL;
1790 goto end;
1791 }
55c9e7ca
JR
1792
1793 ret = LTTNG_OK;
fb198a11
JG
1794end:
1795 return ret;
1796}
1797
1798static
51755dc8
JG
1799const char *get_config_domain_str(enum lttng_domain_type domain)
1800{
1801 const char *str_dom;
1802
1803 switch (domain) {
1804 case LTTNG_DOMAIN_KERNEL:
1805 str_dom = config_domain_type_kernel;
1806 break;
1807 case LTTNG_DOMAIN_UST:
1808 str_dom = config_domain_type_ust;
1809 break;
1810 case LTTNG_DOMAIN_JUL:
1811 str_dom = config_domain_type_jul;
1812 break;
1813 case LTTNG_DOMAIN_LOG4J:
1814 str_dom = config_domain_type_log4j;
1815 break;
1816 case LTTNG_DOMAIN_PYTHON:
1817 str_dom = config_domain_type_python;
1818 break;
1819 default:
a0377dfe 1820 abort();
51755dc8
JG
1821 }
1822
1823 return str_dom;
1824}
1825
55c9e7ca 1826/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
159b042f 1827static int save_process_attr_tracker(struct config_writer *writer,
55c9e7ca
JR
1828 struct ltt_session *sess,
1829 int domain,
159b042f 1830 enum lttng_process_attr process_attr)
e8fcabef 1831{
55c9e7ca 1832 int ret = LTTNG_OK;
55c9e7ca 1833 const char *element_id_tracker, *element_target_id, *element_id;
159b042f
JG
1834 const struct process_attr_tracker *tracker;
1835 enum lttng_tracking_policy tracking_policy;
1836 struct lttng_process_attr_values *values = NULL;
1837
1838 switch (process_attr) {
1839 case LTTNG_PROCESS_ATTR_PROCESS_ID:
1840 element_id_tracker = config_element_process_attr_tracker_pid;
1841 element_target_id = config_element_process_attr_pid_value;
1842 element_id = config_element_process_attr_id;
1843 break;
1844 case LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID:
1845 element_id_tracker = config_element_process_attr_tracker_vpid;
1846 element_target_id = config_element_process_attr_vpid_value;
1847 element_id = config_element_process_attr_id;
1848 break;
1849 case LTTNG_PROCESS_ATTR_USER_ID:
1850 element_id_tracker = config_element_process_attr_tracker_uid;
1851 element_target_id = config_element_process_attr_uid_value;
1852 element_id = config_element_process_attr_id;
1853 break;
1854 case LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID:
1855 element_id_tracker = config_element_process_attr_tracker_vuid;
1856 element_target_id = config_element_process_attr_vuid_value;
1857 element_id = config_element_process_attr_id;
1858 break;
1859 case LTTNG_PROCESS_ATTR_GROUP_ID:
1860 element_id_tracker = config_element_process_attr_tracker_gid;
1861 element_target_id = config_element_process_attr_gid_value;
1862 element_id = config_element_process_attr_id;
1863 break;
1864 case LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID:
1865 element_id_tracker = config_element_process_attr_tracker_vgid;
1866 element_target_id = config_element_process_attr_vgid_value;
1867 element_id = config_element_process_attr_id;
55c9e7ca
JR
1868 break;
1869 default:
1870 ret = LTTNG_ERR_SAVE_IO_FAIL;
1871 goto end;
1872 }
e8fcabef
JG
1873
1874 switch (domain) {
1875 case LTTNG_DOMAIN_KERNEL:
1876 {
159b042f
JG
1877 tracker = kernel_get_process_attr_tracker(
1878 sess->kernel_session, process_attr);
a0377dfe 1879 LTTNG_ASSERT(tracker);
e8fcabef
JG
1880 break;
1881 }
1882 case LTTNG_DOMAIN_UST:
1883 {
159b042f
JG
1884 tracker = trace_ust_get_process_attr_tracker(
1885 sess->ust_session, process_attr);
a0377dfe 1886 LTTNG_ASSERT(tracker);
e8fcabef
JG
1887 break;
1888 }
1889 case LTTNG_DOMAIN_JUL:
1890 case LTTNG_DOMAIN_LOG4J:
1891 case LTTNG_DOMAIN_PYTHON:
1892 default:
159b042f 1893 ret = LTTNG_ERR_UNSUPPORTED_DOMAIN;
e8fcabef
JG
1894 goto end;
1895 }
1896
159b042f
JG
1897 tracking_policy = process_attr_tracker_get_tracking_policy(tracker);
1898 if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_ALL) {
1899 /* Tracking all, nothing to output. */
1900 ret = LTTNG_OK;
e283e4a0
JR
1901 goto end;
1902 }
a7a533cd 1903
55c9e7ca
JR
1904 ret = config_writer_open_element(writer, element_id_tracker);
1905 if (ret) {
1906 ret = LTTNG_ERR_SAVE_IO_FAIL;
1907 goto end;
1908 }
1909
159b042f
JG
1910 ret = config_writer_open_element(
1911 writer, config_element_process_attr_values);
55c9e7ca
JR
1912 if (ret) {
1913 ret = LTTNG_ERR_SAVE_IO_FAIL;
1914 goto end;
1915 }
1916
88ac6301 1917 if (tracking_policy == LTTNG_TRACKING_POLICY_INCLUDE_SET) {
159b042f
JG
1918 unsigned int i, count;
1919 enum process_attr_tracker_status status =
1920 process_attr_tracker_get_inclusion_set(
1921 tracker, &values);
1922
1923 if (status != PROCESS_ATTR_TRACKER_STATUS_OK) {
1924 ret = LTTNG_ERR_NOMEM;
1925 goto end;
1926 }
1927
1928 count = _lttng_process_attr_values_get_count(values);
1929
1930 for (i = 0; i < count; i++) {
1931 unsigned int integral_value = UINT_MAX;
1932 const char *name = NULL;
1933 const struct process_attr_value *value =
1934 lttng_process_attr_tracker_values_get_at_index(
1935 values, i);
1936
a0377dfe 1937 LTTNG_ASSERT(value);
159b042f
JG
1938 ret = config_writer_open_element(
1939 writer, element_target_id);
1940 if (ret) {
a7a533cd
JR
1941 ret = LTTNG_ERR_SAVE_IO_FAIL;
1942 goto end;
1943 }
159b042f
JG
1944
1945 switch (value->type) {
1946 case LTTNG_PROCESS_ATTR_VALUE_TYPE_PID:
1947 integral_value =
1948 (unsigned int) value->value.pid;
55c9e7ca 1949 break;
159b042f
JG
1950 case LTTNG_PROCESS_ATTR_VALUE_TYPE_UID:
1951 integral_value =
1952 (unsigned int) value->value.uid;
1953 break;
1954 case LTTNG_PROCESS_ATTR_VALUE_TYPE_GID:
1955 integral_value =
1956 (unsigned int) value->value.gid;
1957 break;
1958 case LTTNG_PROCESS_ATTR_VALUE_TYPE_USER_NAME:
1959 name = value->value.user_name;
a0377dfe 1960 LTTNG_ASSERT(name);
159b042f
JG
1961 break;
1962 case LTTNG_PROCESS_ATTR_VALUE_TYPE_GROUP_NAME:
1963 name = value->value.group_name;
a0377dfe 1964 LTTNG_ASSERT(name);
55c9e7ca
JR
1965 break;
1966 default:
159b042f 1967 abort();
e8fcabef 1968 }
159b042f
JG
1969
1970 if (name) {
1971 ret = config_writer_write_element_string(writer,
1972 config_element_name, name);
1973 } else {
1974 ret = config_writer_write_element_unsigned_int(
1975 writer, element_id,
1976 integral_value);
e8fcabef 1977 }
159b042f
JG
1978
1979 if (ret) {
2d97a006
JR
1980 ret = LTTNG_ERR_SAVE_IO_FAIL;
1981 goto end;
1982 }
e8fcabef 1983
55c9e7ca 1984 /* /$element_target_id */
e8fcabef
JG
1985 ret = config_writer_close_element(writer);
1986 if (ret) {
1987 ret = LTTNG_ERR_SAVE_IO_FAIL;
1988 goto end;
1989 }
1990 }
55c9e7ca 1991 }
e8fcabef 1992
88ac6301 1993 /* /values */
55c9e7ca
JR
1994 ret = config_writer_close_element(writer);
1995 if (ret) {
1996 ret = LTTNG_ERR_SAVE_IO_FAIL;
1997 goto end;
1998 }
e8fcabef 1999
55c9e7ca
JR
2000 /* /$element_id_tracker */
2001 ret = config_writer_close_element(writer);
2002 if (ret) {
2003 ret = LTTNG_ERR_SAVE_IO_FAIL;
2004 goto end;
e8fcabef 2005 }
55c9e7ca
JR
2006
2007 ret = LTTNG_OK;
e8fcabef 2008end:
159b042f 2009 lttng_process_attr_values_destroy(values);
e8fcabef
JG
2010 return ret;
2011}
2012
55c9e7ca 2013/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
159b042f 2014static int save_process_attr_trackers(struct config_writer *writer,
55c9e7ca
JR
2015 struct ltt_session *sess,
2016 int domain)
2017{
2018 int ret;
2019
2020 switch (domain) {
2021 case LTTNG_DOMAIN_KERNEL:
159b042f
JG
2022 ret = save_process_attr_tracker(writer, sess, domain,
2023 LTTNG_PROCESS_ATTR_PROCESS_ID);
2024 if (ret != LTTNG_OK) {
2025 goto end;
2026 }
2027 ret = save_process_attr_tracker(writer, sess, domain,
2028 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
2029 if (ret != LTTNG_OK) {
2030 goto end;
2031 }
2032 ret = save_process_attr_tracker(writer, sess, domain,
2033 LTTNG_PROCESS_ATTR_USER_ID);
2034 if (ret != LTTNG_OK) {
2035 goto end;
2036 }
2037 ret = save_process_attr_tracker(writer, sess, domain,
2038 LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
2039 if (ret != LTTNG_OK) {
2040 goto end;
2041 }
2042 ret = save_process_attr_tracker(writer, sess, domain,
2043 LTTNG_PROCESS_ATTR_GROUP_ID);
2044 if (ret != LTTNG_OK) {
2045 goto end;
2046 }
2047 ret = save_process_attr_tracker(writer, sess, domain,
2048 LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
2049 if (ret != LTTNG_OK) {
2050 goto end;
2051 }
55c9e7ca
JR
2052 break;
2053 case LTTNG_DOMAIN_UST:
159b042f
JG
2054 ret = save_process_attr_tracker(writer, sess, domain,
2055 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID);
2056 if (ret != LTTNG_OK) {
2057 goto end;
2058 }
2059 ret = save_process_attr_tracker(writer, sess, domain,
2060 LTTNG_PROCESS_ATTR_VIRTUAL_USER_ID);
2061 if (ret != LTTNG_OK) {
2062 goto end;
2063 }
2064 ret = save_process_attr_tracker(writer, sess, domain,
2065 LTTNG_PROCESS_ATTR_VIRTUAL_GROUP_ID);
2066 if (ret != LTTNG_OK) {
2067 goto end;
2068 }
55c9e7ca
JR
2069 break;
2070 default:
159b042f 2071 ret = LTTNG_ERR_INVALID;
74675e31 2072 goto end;
55c9e7ca 2073 }
159b042f
JG
2074 ret = LTTNG_OK;
2075end:
2076 return ret;
55c9e7ca
JR
2077}
2078
2079/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
51755dc8
JG
2080static
2081int save_ust_domain(struct config_writer *writer,
2082 struct ltt_session *session, enum lttng_domain_type domain)
fb198a11
JG
2083{
2084 int ret;
2085 struct ltt_ust_channel *ust_chan;
2086 const char *buffer_type_string;
2087 struct lttng_ht_node_str *node;
2088 struct lttng_ht_iter iter;
51755dc8 2089 const char *config_domain_name;
fb198a11 2090
a0377dfe
FD
2091 LTTNG_ASSERT(writer);
2092 LTTNG_ASSERT(session);
fb198a11 2093
51755dc8
JG
2094 ret = config_writer_open_element(writer,
2095 config_element_domain);
2096 if (ret) {
2097 ret = LTTNG_ERR_SAVE_IO_FAIL;
2098 goto end;
2099 }
2100
2101 config_domain_name = get_config_domain_str(domain);
2102 if (!config_domain_name) {
2103 ret = LTTNG_ERR_INVALID;
2104 goto end;
2105 }
2106
2107 ret = config_writer_write_element_string(writer,
2108 config_element_type, config_domain_name);
fb198a11
JG
2109 if (ret) {
2110 ret = LTTNG_ERR_SAVE_IO_FAIL;
2111 goto end;
2112 }
2113
2114 buffer_type_string = get_buffer_type_string(
2115 session->ust_session->buffer_type);
2116 if (!buffer_type_string) {
2117 ERR("Unsupported buffer type.");
2118 ret = LTTNG_ERR_INVALID;
2119 goto end;
2120 }
2121
2122 ret = config_writer_write_element_string(writer,
2123 config_element_buffer_type, buffer_type_string);
2124 if (ret) {
2125 ret = LTTNG_ERR_SAVE_IO_FAIL;
2126 goto end;
2127 }
2128
2129 ret = config_writer_open_element(writer, config_element_channels);
2130 if (ret) {
2131 ret = LTTNG_ERR_SAVE_IO_FAIL;
2132 goto end;
2133 }
2134
2135 rcu_read_lock();
2136 cds_lfht_for_each_entry(session->ust_session->domain_global.channels->ht,
2137 &iter.iter, node, node) {
fb198a11 2138 ust_chan = caa_container_of(node, struct ltt_ust_channel, node);
51755dc8 2139 if (domain == ust_chan->domain) {
fb198a11 2140 ret = save_ust_channel(writer, ust_chan, session->ust_session);
55c9e7ca 2141 if (ret != LTTNG_OK) {
fb198a11
JG
2142 rcu_read_unlock();
2143 goto end;
2144 }
2145 }
2146 }
2147 rcu_read_unlock();
2148
2149 /* /channels */
2150 ret = config_writer_close_element(writer);
2151 if (ret) {
2152 ret = LTTNG_ERR_SAVE_IO_FAIL;
2153 goto end;
2154 }
51755dc8 2155
e8fcabef 2156 if (domain == LTTNG_DOMAIN_UST) {
159b042f
JG
2157 ret = config_writer_open_element(
2158 writer, config_element_process_attr_trackers);
847a5916
JR
2159 if (ret) {
2160 ret = LTTNG_ERR_SAVE_IO_FAIL;
2161 goto end;
2162 }
2163
159b042f
JG
2164 ret = save_process_attr_trackers(
2165 writer, session, LTTNG_DOMAIN_UST);
55c9e7ca 2166 if (ret != LTTNG_OK) {
847a5916
JR
2167 goto end;
2168 }
2169
e8fcabef 2170 /* /trackers */
847a5916
JR
2171 ret = config_writer_close_element(writer);
2172 if (ret) {
55c9e7ca 2173 ret = LTTNG_ERR_SAVE_IO_FAIL;
847a5916
JR
2174 goto end;
2175 }
e8fcabef 2176 }
847a5916 2177
e8fcabef
JG
2178 /* /domain */
2179 ret = config_writer_close_element(writer);
2180 if (ret) {
2181 ret = LTTNG_ERR_SAVE_IO_FAIL;
2182 goto end;
847a5916 2183 }
e8fcabef 2184
55c9e7ca 2185 ret = LTTNG_OK;
847a5916 2186end:
847a5916
JR
2187 return ret;
2188}
2189
55c9e7ca 2190/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
2191static
2192int save_domains(struct config_writer *writer, struct ltt_session *session)
2193{
55c9e7ca 2194 int ret = LTTNG_OK;
fb198a11 2195
a0377dfe
FD
2196 LTTNG_ASSERT(writer);
2197 LTTNG_ASSERT(session);
fb198a11
JG
2198
2199 if (!session->kernel_session && !session->ust_session) {
2200 goto end;
2201 }
2202
2203 ret = config_writer_open_element(writer, config_element_domains);
2204 if (ret) {
2205 ret = LTTNG_ERR_SAVE_IO_FAIL;
2206 goto end;
2207 }
2208
fb198a11
JG
2209 if (session->kernel_session) {
2210 ret = config_writer_open_element(writer,
2211 config_element_domain);
2212 if (ret) {
2213 ret = LTTNG_ERR_SAVE_IO_FAIL;
2214 goto end;
2215 }
2216
2217 ret = save_kernel_session(writer, session);
55c9e7ca 2218 if (ret != LTTNG_OK) {
fb198a11
JG
2219 goto end;
2220 }
2221
159b042f
JG
2222 ret = config_writer_open_element(
2223 writer, config_element_process_attr_trackers);
847a5916
JR
2224 if (ret) {
2225 ret = LTTNG_ERR_SAVE_IO_FAIL;
2226 goto end;
2227 }
2228
159b042f
JG
2229 ret = save_process_attr_trackers(
2230 writer, session, LTTNG_DOMAIN_KERNEL);
55c9e7ca 2231 if (ret != LTTNG_OK) {
847a5916
JR
2232 goto end;
2233 }
2234
2235 /* /trackers */
2236 ret = config_writer_close_element(writer);
2237 if (ret) {
2238 ret = LTTNG_ERR_SAVE_IO_FAIL;
2239 goto end;
2240 }
fb198a11
JG
2241 /* /domain */
2242 ret = config_writer_close_element(writer);
2243 if (ret) {
2244 ret = LTTNG_ERR_SAVE_IO_FAIL;
2245 goto end;
2246 }
2247 }
2248
2249 if (session->ust_session) {
51755dc8 2250 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_UST);
55c9e7ca 2251 if (ret != LTTNG_OK) {
fb198a11
JG
2252 goto end;
2253 }
2254
51755dc8 2255 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_JUL);
55c9e7ca 2256 if (ret != LTTNG_OK) {
fb198a11
JG
2257 goto end;
2258 }
fb198a11 2259
51755dc8 2260 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_LOG4J);
55c9e7ca 2261 if (ret != LTTNG_OK) {
51755dc8
JG
2262 goto end;
2263 }
65d72c41 2264
51755dc8 2265 ret = save_ust_domain(writer, session, LTTNG_DOMAIN_PYTHON);
55c9e7ca 2266 if (ret != LTTNG_OK) {
51755dc8 2267 goto end;
fb198a11
JG
2268 }
2269 }
2270
2271 /* /domains */
2272 ret = config_writer_close_element(writer);
2273 if (ret) {
2274 ret = LTTNG_ERR_SAVE_IO_FAIL;
2275 goto end;
2276 }
55c9e7ca
JR
2277
2278 ret = LTTNG_OK;
fb198a11
JG
2279end:
2280 return ret;
2281}
2282
55c9e7ca 2283/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
2284static
2285int save_consumer_output(struct config_writer *writer,
2286 struct consumer_output *output)
2287{
2288 int ret;
2289
a0377dfe
FD
2290 LTTNG_ASSERT(writer);
2291 LTTNG_ASSERT(output);
fb198a11
JG
2292
2293 ret = config_writer_open_element(writer, config_element_consumer_output);
2294 if (ret) {
2295 ret = LTTNG_ERR_SAVE_IO_FAIL;
2296 goto end;
2297 }
2298
2299 ret = config_writer_write_element_bool(writer, config_element_enabled,
2300 output->enabled);
2301 if (ret) {
2302 ret = LTTNG_ERR_SAVE_IO_FAIL;
2303 goto end;
2304 }
2305
2306 ret = config_writer_open_element(writer, config_element_destination);
2307 if (ret) {
2308 ret = LTTNG_ERR_SAVE_IO_FAIL;
2309 goto end;
2310 }
2311
2312 switch (output->type) {
2313 case CONSUMER_DST_LOCAL:
2314 ret = config_writer_write_element_string(writer,
366a9222 2315 config_element_path, output->dst.session_root_path);
fb198a11
JG
2316 if (ret) {
2317 ret = LTTNG_ERR_SAVE_IO_FAIL;
2318 goto end;
2319 }
2320 break;
2321 case CONSUMER_DST_NET:
2322 {
2323 char *uri;
2324
7966af57 2325 uri = (char *) zmalloc(PATH_MAX);
fb198a11
JG
2326 if (!uri) {
2327 ret = LTTNG_ERR_NOMEM;
2328 goto end;
2329 }
2330
2331 ret = config_writer_open_element(writer, config_element_net_output);
2332 if (ret) {
2333 ret = LTTNG_ERR_SAVE_IO_FAIL;
2334 goto end_net_output;
2335 }
2336
2337 if (output->dst.net.control_isset &&
2338 output->dst.net.data_isset) {
2339 ret = uri_to_str_url(&output->dst.net.control, uri, PATH_MAX);
2340 if (ret < 0) {
2341 ret = LTTNG_ERR_INVALID;
2342 goto end_net_output;
2343 }
2344
2345 ret = config_writer_write_element_string(writer,
2346 config_element_control_uri, uri);
2347 if (ret) {
2348 ret = LTTNG_ERR_SAVE_IO_FAIL;
2349 goto end_net_output;
2350 }
2351
2352 ret = uri_to_str_url(&output->dst.net.data, uri, PATH_MAX);
2353 if (ret < 0) {
2354 ret = LTTNG_ERR_INVALID;
2355 goto end_net_output;
2356 }
2357
2358 ret = config_writer_write_element_string(writer,
2359 config_element_data_uri, uri);
2360 if (ret) {
2361 ret = LTTNG_ERR_SAVE_IO_FAIL;
2362 goto end_net_output;
2363 }
55c9e7ca 2364 ret = LTTNG_OK;
fb198a11
JG
2365end_net_output:
2366 free(uri);
55c9e7ca 2367 if (ret != LTTNG_OK) {
fb198a11
JG
2368 goto end;
2369 }
2370 } else {
2371 ret = !output->dst.net.control_isset ?
2372 LTTNG_ERR_URL_CTRL_MISS :
2373 LTTNG_ERR_URL_DATA_MISS;
c39270e5 2374 free(uri);
fb198a11
JG
2375 goto end;
2376 }
2377
2378 ret = config_writer_close_element(writer);
2379 if (ret) {
2380 ret = LTTNG_ERR_SAVE_IO_FAIL;
2381 goto end;
2382 }
2383 break;
2384 }
2385 default:
2386 ERR("Unsupported consumer output type.");
2387 ret = LTTNG_ERR_INVALID;
2388 goto end;
2389 }
2390
2391 /* /destination */
2392 ret = config_writer_close_element(writer);
2393 if (ret) {
2394 ret = LTTNG_ERR_SAVE_IO_FAIL;
2395 goto end;
2396 }
2397
2398 /* /consumer_output */
2399 ret = config_writer_close_element(writer);
2400 if (ret) {
2401 ret = LTTNG_ERR_SAVE_IO_FAIL;
2402 goto end;
2403 }
55c9e7ca
JR
2404
2405 ret = LTTNG_OK;
fb198a11
JG
2406end:
2407 return ret;
2408}
2409
55c9e7ca 2410/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
2411static
2412int save_snapshot_outputs(struct config_writer *writer,
2413 struct snapshot *snapshot)
2414{
2415 int ret;
2416 struct lttng_ht_iter iter;
2417 struct snapshot_output *output;
2418
a0377dfe
FD
2419 LTTNG_ASSERT(writer);
2420 LTTNG_ASSERT(snapshot);
fb198a11
JG
2421
2422 ret = config_writer_open_element(writer, config_element_snapshot_outputs);
2423 if (ret) {
2424 ret = LTTNG_ERR_SAVE_IO_FAIL;
2425 goto end;
2426 }
2427
2428 rcu_read_lock();
2429 cds_lfht_for_each_entry(snapshot->output_ht->ht, &iter.iter, output,
2430 node.node) {
2431 ret = config_writer_open_element(writer,
2432 config_element_output);
2433 if (ret) {
2434 ret = LTTNG_ERR_SAVE_IO_FAIL;
2435 goto end_unlock;
2436 }
2437
2438 ret = config_writer_write_element_string(writer,
2439 config_element_name, output->name);
2440 if (ret) {
2441 ret = LTTNG_ERR_SAVE_IO_FAIL;
2442 goto end_unlock;
2443 }
2444
2445 ret = config_writer_write_element_unsigned_int(writer,
2446 config_element_max_size, output->max_size);
2447 if (ret) {
2448 ret = LTTNG_ERR_SAVE_IO_FAIL;
2449 goto end_unlock;
2450 }
2451
2452 ret = save_consumer_output(writer, output->consumer);
55c9e7ca 2453 if (ret != LTTNG_OK) {
fb198a11
JG
2454 goto end_unlock;
2455 }
2456
2457 /* /output */
2458 ret = config_writer_close_element(writer);
2459 if (ret) {
2460 ret = LTTNG_ERR_SAVE_IO_FAIL;
2461 goto end_unlock;
2462 }
2463 }
2464 rcu_read_unlock();
2465
2466 /* /snapshot_outputs */
2467 ret = config_writer_close_element(writer);
2468 if (ret) {
2469 ret = LTTNG_ERR_SAVE_IO_FAIL;
2470 goto end;
2471 }
2472
55c9e7ca 2473 ret = LTTNG_OK;
fb198a11
JG
2474end:
2475 return ret;
2476end_unlock:
2477 rcu_read_unlock();
2478 return ret;
2479}
2480
55c9e7ca 2481/* Return LTTNG_OK on success else a LTTNG_ERR* code. */
fb198a11
JG
2482static
2483int save_session_output(struct config_writer *writer,
2484 struct ltt_session *session)
2485{
2486 int ret;
2487
a0377dfe
FD
2488 LTTNG_ASSERT(writer);
2489 LTTNG_ASSERT(session);
fb198a11
JG
2490
2491 if ((session->snapshot_mode && session->snapshot.nb_output == 0) ||
2492 (!session->snapshot_mode && !session->consumer)) {
2493 /* Session is in no output mode */
55c9e7ca 2494 ret = LTTNG_OK;
fb198a11
JG
2495 goto end;
2496 }
2497
2498 ret = config_writer_open_element(writer, config_element_output);
2499 if (ret) {
2500 ret = LTTNG_ERR_SAVE_IO_FAIL;
2501 goto end;
2502 }
2503
2504 if (session->snapshot_mode) {
2505 ret = save_snapshot_outputs(writer, &session->snapshot);
55c9e7ca 2506 if (ret != LTTNG_OK) {
fb198a11
JG
2507 goto end;
2508 }
2509 } else {
2510 if (session->consumer) {
2511 ret = save_consumer_output(writer, session->consumer);
55c9e7ca 2512 if (ret != LTTNG_OK) {
fb198a11
JG
2513 goto end;
2514 }
2515 }
2516 }
2517
2518 /* /output */
2519 ret = config_writer_close_element(writer);
2520 if (ret) {
2521 ret = LTTNG_ERR_SAVE_IO_FAIL;
2522 goto end;
2523 }
55c9e7ca 2524 ret = LTTNG_OK;
fb198a11
JG
2525end:
2526 return ret;
2527}
2528
ce6176f2
JG
2529static
2530int save_session_rotation_schedule(struct config_writer *writer,
2531 enum lttng_rotation_schedule_type type, uint64_t value)
2532{
2533 int ret = 0;
2534 const char *element_name;
2535 const char *value_name;
2536
2537 switch (type) {
2538 case LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC:
2539 element_name = config_element_rotation_schedule_periodic;
2540 value_name = config_element_rotation_schedule_periodic_time_us;
2541 break;
2542 case LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD:
2543 element_name = config_element_rotation_schedule_size_threshold;
2544 value_name = config_element_rotation_schedule_size_threshold_bytes;
2545 break;
2546 default:
2547 ret = -1;
2548 goto end;
2549 }
2550
2551 ret = config_writer_open_element(writer, element_name);
2552 if (ret) {
2553 goto end;
2554 }
2555
2556 ret = config_writer_write_element_unsigned_int(writer,
2557 value_name, value);
2558 if (ret) {
2559 goto end;
2560 }
2561
2562 /* Close schedule descriptor element. */
2563 ret = config_writer_close_element(writer);
2564 if (ret) {
2565 goto end;
2566 }
2567end:
2568 return ret;
2569}
2570
2571static
2572int save_session_rotation_schedules(struct config_writer *writer,
2573 struct ltt_session *session)
2574{
2575 int ret;
2576
2577 ret = config_writer_open_element(writer,
2578 config_element_rotation_schedules);
f829d17a
JG
2579 if (ret) {
2580 goto end;
2581 }
ce6176f2
JG
2582 if (session->rotate_timer_period) {
2583 ret = save_session_rotation_schedule(writer,
2584 LTTNG_ROTATION_SCHEDULE_TYPE_PERIODIC,
2585 session->rotate_timer_period);
2586 if (ret) {
2587 goto close_schedules;
2588 }
2589 }
2590 if (session->rotate_size) {
2591 ret = save_session_rotation_schedule(writer,
2592 LTTNG_ROTATION_SCHEDULE_TYPE_SIZE_THRESHOLD,
2593 session->rotate_size);
2594 if (ret) {
2595 goto close_schedules;
2596 }
2597 }
2598
2599close_schedules:
2600 /* Close rotation schedules element. */
2601 ret = config_writer_close_element(writer);
2602 if (ret) {
2603 goto end;
2604 }
2605end:
2606 return ret;
2607}
2608
fb198a11
JG
2609/*
2610 * Save the given session.
2611 *
55c9e7ca 2612 * Return LTTNG_OK on success else a LTTNG_ERR* code.
fb198a11
JG
2613 */
2614static
2615int save_session(struct ltt_session *session,
2616 struct lttng_save_session_attr *attr, lttng_sock_cred *creds)
2617{
b45f9ad2 2618 int ret, fd = -1;
511653c3 2619 char config_file_path[LTTNG_PATH_MAX];
fb198a11
JG
2620 size_t len;
2621 struct config_writer *writer = NULL;
2622 size_t session_name_len;
2623 const char *provided_path;
f376ad9c 2624 int file_open_flags = O_CREAT | O_WRONLY | O_TRUNC;
fb198a11 2625
a0377dfe
FD
2626 LTTNG_ASSERT(session);
2627 LTTNG_ASSERT(attr);
2628 LTTNG_ASSERT(creds);
fb198a11
JG
2629
2630 session_name_len = strlen(session->name);
95a29ab8 2631 memset(config_file_path, 0, sizeof(config_file_path));
fb198a11
JG
2632
2633 if (!session_access_ok(session,
d7b377ed 2634 LTTNG_SOCK_GET_UID_CRED(creds)) || session->destroyed) {
fb198a11
JG
2635 ret = LTTNG_ERR_EPERM;
2636 goto end;
2637 }
2638
2639 provided_path = lttng_save_session_attr_get_output_url(attr);
2640 if (provided_path) {
95a29ab8 2641 DBG3("Save session in provided path %s", provided_path);
fb198a11 2642 len = strlen(provided_path);
d2992717 2643 if (len >= sizeof(config_file_path)) {
fb198a11
JG
2644 ret = LTTNG_ERR_SET_URL;
2645 goto end;
2646 }
511653c3 2647 strncpy(config_file_path, provided_path, sizeof(config_file_path));
fb198a11 2648 } else {
7e078ad1 2649 ssize_t ret_len;
fb198a11
JG
2650 char *home_dir = utils_get_user_home_dir(
2651 LTTNG_SOCK_GET_UID_CRED(creds));
2652 if (!home_dir) {
2653 ret = LTTNG_ERR_SET_URL;
2654 goto end;
2655 }
2656
d2992717 2657 ret_len = snprintf(config_file_path, sizeof(config_file_path),
fb198a11
JG
2658 DEFAULT_SESSION_HOME_CONFIGPATH, home_dir);
2659 free(home_dir);
7e078ad1 2660 if (ret_len < 0) {
fb198a11
JG
2661 PERROR("snprintf save session");
2662 ret = LTTNG_ERR_SET_URL;
2663 goto end;
2664 }
7e078ad1 2665 len = ret_len;
fb198a11
JG
2666 }
2667
2668 /*
d2992717
DG
2669 * Check the path fits in the config file path dst including the '/'
2670 * followed by trailing .lttng extension and the NULL terminated string.
fb198a11 2671 */
d2992717
DG
2672 if ((len + session_name_len + 2 +
2673 sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION))
2674 > sizeof(config_file_path)) {
fb198a11
JG
2675 ret = LTTNG_ERR_SET_URL;
2676 goto end;
2677 }
2678
2679 ret = run_as_mkdir_recursive(config_file_path, S_IRWXU | S_IRWXG,
2680 LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds));
2681 if (ret) {
2682 ret = LTTNG_ERR_SET_URL;
2683 goto end;
2684 }
2685
d2992717
DG
2686 /*
2687 * At this point, we know that everything fits in the buffer. Validation
2688 * was done just above.
2689 */
fb198a11 2690 config_file_path[len++] = '/';
511653c3 2691 strncpy(config_file_path + len, session->name, sizeof(config_file_path) - len);
fb198a11
JG
2692 len += session_name_len;
2693 strcpy(config_file_path + len, DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
95a29ab8
DG
2694 len += sizeof(DEFAULT_SESSION_CONFIG_FILE_EXTENSION);
2695 config_file_path[len] = '\0';
fb198a11 2696
f376ad9c
JG
2697 if (!attr->overwrite) {
2698 file_open_flags |= O_EXCL;
fb198a11
JG
2699 }
2700
f376ad9c 2701 fd = run_as_open(config_file_path, file_open_flags,
fb198a11
JG
2702 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
2703 LTTNG_SOCK_GET_UID_CRED(creds), LTTNG_SOCK_GET_GID_CRED(creds));
2704 if (fd < 0) {
2705 PERROR("Could not create configuration file");
f376ad9c
JG
2706 switch (errno) {
2707 case EEXIST:
2708 ret = LTTNG_ERR_SAVE_FILE_EXIST;
2709 break;
2710 case EACCES:
2711 ret = LTTNG_ERR_EPERM;
2712 break;
2713 default:
2714 ret = LTTNG_ERR_SAVE_IO_FAIL;
2715 break;
2716 }
fb198a11
JG
2717 goto end;
2718 }
2719
705bb62f 2720 writer = config_writer_create(fd, 1);
fb198a11
JG
2721 if (!writer) {
2722 ret = LTTNG_ERR_NOMEM;
2723 goto end;
2724 }
2725
2726 ret = config_writer_open_element(writer, config_element_sessions);
2727 if (ret) {
2728 ret = LTTNG_ERR_SAVE_IO_FAIL;
2729 goto end;
2730 }
2731
2732 ret = config_writer_open_element(writer, config_element_session);
2733 if (ret) {
2734 ret = LTTNG_ERR_SAVE_IO_FAIL;
2735 goto end;
2736 }
2737
2738 ret = config_writer_write_element_string(writer, config_element_name,
2739 session->name);
2740 if (ret) {
2741 ret = LTTNG_ERR_SAVE_IO_FAIL;
2742 goto end;
2743 }
2744
55c9e7ca 2745 if (session->shm_path[0] != '\0') {
9e7c9f56
JR
2746 ret = config_writer_write_element_string(writer,
2747 config_element_shared_memory_path,
2748 session->shm_path);
2749 if (ret) {
2750 ret = LTTNG_ERR_SAVE_IO_FAIL;
2751 goto end;
2752 }
2753 }
2754
fb198a11 2755 ret = save_domains(writer, session);
55c9e7ca 2756 if (ret != LTTNG_OK) {
fb198a11
JG
2757 goto end;
2758 }
2759
2760 ret = config_writer_write_element_bool(writer, config_element_started,
8382cf6f 2761 session->active);
fb198a11
JG
2762 if (ret) {
2763 ret = LTTNG_ERR_SAVE_IO_FAIL;
2764 goto end;
2765 }
2766
329f3443
JD
2767 if (session->snapshot_mode || session->live_timer ||
2768 session->rotate_timer_period || session->rotate_size) {
fb198a11
JG
2769 ret = config_writer_open_element(writer, config_element_attributes);
2770 if (ret) {
2771 ret = LTTNG_ERR_SAVE_IO_FAIL;
2772 goto end;
2773 }
2774
2775 if (session->snapshot_mode) {
2776 ret = config_writer_write_element_bool(writer,
2777 config_element_snapshot_mode, 1);
2778 if (ret) {
2779 ret = LTTNG_ERR_SAVE_IO_FAIL;
2780 goto end;
2781 }
329f3443 2782 } else if (session->live_timer) {
d98ad589 2783 ret = config_writer_write_element_unsigned_int(writer,
fb198a11
JG
2784 config_element_live_timer_interval, session->live_timer);
2785 if (ret) {
2786 ret = LTTNG_ERR_SAVE_IO_FAIL;
2787 goto end;
2788 }
2789 }
ce6176f2
JG
2790 if (session->rotate_timer_period || session->rotate_size) {
2791 ret = save_session_rotation_schedules(writer,
2792 session);
329f3443
JD
2793 if (ret) {
2794 ret = LTTNG_ERR_SAVE_IO_FAIL;
2795 goto end;
2796 }
2797 }
fb198a11
JG
2798
2799 /* /attributes */
2800 ret = config_writer_close_element(writer);
2801 if (ret) {
2802 ret = LTTNG_ERR_SAVE_IO_FAIL;
2803 goto end;
2804 }
2805 }
2806
2807 ret = save_session_output(writer, session);
55c9e7ca 2808 if (ret != LTTNG_OK) {
fb198a11
JG
2809 goto end;
2810 }
2811
2812 /* /session */
2813 ret = config_writer_close_element(writer);
2814 if (ret) {
2815 ret = LTTNG_ERR_SAVE_IO_FAIL;
2816 goto end;
2817 }
2818
2819 /* /sessions */
2820 ret = config_writer_close_element(writer);
2821 if (ret) {
2822 ret = LTTNG_ERR_SAVE_IO_FAIL;
2823 goto end;
2824 }
55c9e7ca
JR
2825
2826 ret = LTTNG_OK;
fb198a11
JG
2827end:
2828 if (writer && config_writer_destroy(writer)) {
2829 /* Preserve the original error code */
55c9e7ca 2830 ret = ret != LTTNG_OK ? ret : LTTNG_ERR_SAVE_IO_FAIL;
fb198a11 2831 }
55c9e7ca 2832 if (ret != LTTNG_OK) {
fb198a11 2833 /* Delete file in case of error */
b45f9ad2 2834 if ((fd >= 0) && unlink(config_file_path)) {
fb198a11
JG
2835 PERROR("Unlinking XML session configuration.");
2836 }
2837 }
2838
b45f9ad2 2839 if (fd >= 0) {
55c9e7ca
JR
2840 int closeret;
2841
2842 closeret = close(fd);
2843 if (closeret) {
1d12100d
JR
2844 PERROR("Closing XML session configuration");
2845 }
2846 }
2847
fb198a11
JG
2848 return ret;
2849}
2850
2851int cmd_save_sessions(struct lttng_save_session_attr *attr,
2852 lttng_sock_cred *creds)
2853{
2854 int ret;
2855 const char *session_name;
2856 struct ltt_session *session;
2857
2858 session_lock_list();
2859
2860 session_name = lttng_save_session_attr_get_session_name(attr);
2861 if (session_name) {
2862 session = session_find_by_name(session_name);
2863 if (!session) {
2864 ret = LTTNG_ERR_SESS_NOT_FOUND;
2865 goto end;
2866 }
2867
2868 session_lock(session);
2869 ret = save_session(session, attr, creds);
2870 session_unlock(session);
e32d7f27 2871 session_put(session);
55c9e7ca 2872 if (ret != LTTNG_OK) {
fb198a11
JG
2873 goto end;
2874 }
2875 } else {
2876 struct ltt_session_list *list = session_get_list();
2877
2878 cds_list_for_each_entry(session, &list->head, list) {
e32d7f27
JG
2879 if (!session_get(session)) {
2880 continue;
2881 }
fb198a11
JG
2882 session_lock(session);
2883 ret = save_session(session, attr, creds);
2884 session_unlock(session);
e32d7f27 2885 session_put(session);
fb198a11 2886 /* Don't abort if we don't have the required permissions. */
55c9e7ca 2887 if (ret != LTTNG_OK && ret != LTTNG_ERR_EPERM) {
fb198a11
JG
2888 goto end;
2889 }
2890 }
2891 }
2892 ret = LTTNG_OK;
2893
2894end:
2895 session_unlock_list();
2896 return ret;
2897}
This page took 0.203164 seconds and 4 git commands to generate.