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