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