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