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