Fix: sessiond: incorrect use of exclusions array leads to crash
[lttng-tools.git] / src / lib / lttng-ctl / tracker.cpp
CommitLineData
159b042f
JG
1/*
2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
c9e313bc 8#include "lttng-ctl-helper.hpp"
28ab034a 9
c9e313bc
SM
10#include <common/sessiond-comm/sessiond-comm.hpp>
11#include <common/tracker.hpp>
28ab034a
JG
12
13#include <lttng/domain.h>
14#include <lttng/lttng-error.h>
159b042f 15#include <lttng/tracker.h>
28ab034a 16
c9e313bc 17#include <type_traits>
159b042f
JG
18
19struct lttng_process_attr_tracker_handle {
20 char *session_name;
21 enum lttng_domain_type domain;
22 enum lttng_process_attr process_attr;
23 struct lttng_process_attr_values *inclusion_set;
24};
25
28ab034a 26void lttng_process_attr_tracker_handle_destroy(struct lttng_process_attr_tracker_handle *tracker)
159b042f
JG
27{
28 if (!tracker) {
29 return;
30 }
31
32 lttng_process_attr_values_destroy(tracker->inclusion_set);
33 free(tracker->session_name);
34 free(tracker);
35}
36
28ab034a
JG
37enum lttng_error_code
38lttng_session_get_tracker_handle(const char *session_name,
39 enum lttng_domain_type domain,
40 enum lttng_process_attr process_attr,
41 struct lttng_process_attr_tracker_handle **out_tracker_handle)
159b042f
JG
42{
43 enum lttng_error_code ret_code = LTTNG_OK;
cd9adb8b 44 struct lttng_process_attr_tracker_handle *handle = nullptr;
159b042f
JG
45 enum lttng_process_attr_tracker_handle_status status;
46 enum lttng_tracking_policy policy;
47
48 if (!session_name || !out_tracker_handle) {
49 ret_code = LTTNG_ERR_INVALID;
50 goto error;
51 }
52
53 if (domain != LTTNG_DOMAIN_KERNEL && domain != LTTNG_DOMAIN_UST) {
54 ret_code = LTTNG_ERR_UNSUPPORTED_DOMAIN;
55 goto error;
56 }
57
64803277 58 handle = zmalloc<lttng_process_attr_tracker_handle>();
159b042f
JG
59 if (!handle) {
60 ret_code = LTTNG_ERR_NOMEM;
61 goto error;
62 }
63
64 handle->session_name = strdup(session_name);
65 if (!handle->session_name) {
66 ret_code = LTTNG_ERR_NOMEM;
67 goto error;
68 }
69
70 handle->domain = domain;
71 handle->process_attr = process_attr;
72
73 /*
74 * Use the `get_tracking_policy` command to validate the tracker's
0f1b1d25 75 * existence.
159b042f 76 */
28ab034a 77 status = lttng_process_attr_tracker_handle_get_tracking_policy(handle, &policy);
159b042f
JG
78 switch (status) {
79 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
80 break;
81 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
82 ret_code = LTTNG_ERR_SESSION_NOT_EXIST;
83 goto error;
84 default:
85 ret_code = LTTNG_ERR_UNK;
86 goto error;
87 }
88
89 *out_tracker_handle = handle;
90 return ret_code;
91error:
92 lttng_process_attr_tracker_handle_destroy(handle);
93 return ret_code;
94}
95
28ab034a
JG
96enum lttng_process_attr_tracker_handle_status lttng_process_attr_tracker_handle_get_tracking_policy(
97 const struct lttng_process_attr_tracker_handle *tracker, enum lttng_tracking_policy *policy)
159b042f 98{
cd9adb8b 99 void *reply = nullptr;
e1b624d0 100 int reply_ret, copy_ret;
159b042f 101 enum lttng_process_attr_tracker_handle_status status =
28ab034a 102 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK;
159b042f 103 struct lttcomm_session_msg lsm = {
37a5ef39 104 .cmd_type = LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_GET_POLICY,
1c9a0b0e
MJ
105 .session = {},
106 .domain = {},
107 .u = {},
108 .fd_count = 0,
159b042f
JG
109 };
110
111 if (!tracker || !policy) {
112 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
113 goto end;
114 }
115
28ab034a 116 copy_ret = lttng_strncpy(lsm.session.name, tracker->session_name, sizeof(lsm.session.name));
e1b624d0
JG
117 if (copy_ret) {
118 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
119 goto end;
120 }
121
159b042f
JG
122 lsm.domain.type = tracker->domain;
123 lsm.u.process_attr_tracker_get_tracking_policy.process_attr =
28ab034a 124 (int32_t) tracker->process_attr;
159b042f
JG
125
126 /* Command returns a session descriptor on success. */
cd9adb8b 127 reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, nullptr, 0, &reply);
159b042f
JG
128 if (reply_ret != sizeof(uint32_t)) {
129 if (reply_ret == -LTTNG_ERR_SESSION_NOT_EXIST ||
28ab034a 130 reply_ret == -LTTNG_ERR_SESS_NOT_FOUND) {
159b042f
JG
131 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST;
132 } else {
133 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR;
134 }
135 goto end;
136 }
137
138 *policy = (enum lttng_tracking_policy)(*((const uint32_t *) reply));
139end:
140 free(reply);
141 return status;
142}
143
28ab034a
JG
144enum lttng_process_attr_tracker_handle_status lttng_process_attr_tracker_handle_set_tracking_policy(
145 const struct lttng_process_attr_tracker_handle *tracker, enum lttng_tracking_policy policy)
159b042f 146{
e1b624d0 147 int reply_ret, copy_ret;
159b042f 148 enum lttng_process_attr_tracker_handle_status status =
28ab034a 149 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK;
159b042f 150 struct lttcomm_session_msg lsm = {
37a5ef39 151 .cmd_type = LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_SET_POLICY,
1c9a0b0e
MJ
152 .session = {},
153 .domain = {},
154 .u = {},
155 .fd_count = 0,
159b042f
JG
156 };
157
158 if (!tracker) {
159 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
160 goto end;
161 }
162
28ab034a 163 copy_ret = lttng_strncpy(lsm.session.name, tracker->session_name, sizeof(lsm.session.name));
e1b624d0
JG
164 if (copy_ret) {
165 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
166 goto end;
167 }
168
159b042f
JG
169 lsm.domain.type = tracker->domain;
170 lsm.u.process_attr_tracker_set_tracking_policy.process_attr =
28ab034a
JG
171 (int32_t) tracker->process_attr;
172 lsm.u.process_attr_tracker_set_tracking_policy.tracking_policy = (int32_t) policy;
159b042f
JG
173
174 /* Command returns a session descriptor on success. */
cd9adb8b 175 reply_ret = lttng_ctl_ask_sessiond(&lsm, nullptr);
159b042f
JG
176 if (reply_ret < 0) {
177 if (reply_ret == -LTTNG_ERR_SESSION_NOT_EXIST) {
178 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST;
179 } else {
180 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR;
181 }
182 goto end;
183 }
184end:
185 return status;
186}
187
28ab034a
JG
188#define DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(command_upper, \
189 command_lower, \
190 process_attr_name, \
191 value_type_name, \
192 value_type_c, \
193 value_type_enum) \
194 enum lttng_process_attr_tracker_handle_status \
195 lttng_process_attr_##process_attr_name##_tracker_handle_##command_lower##_##value_type_name( \
196 const struct lttng_process_attr_tracker_handle *tracker, \
197 value_type_c value) \
198 { \
199 int ret; \
200 enum lttng_process_attr_tracker_handle_status status = \
201 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
202 struct lttcomm_session_msg lsm = { \
203 .cmd_type = \
204 LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE, \
205 .session = {}, \
206 .domain = {}, \
207 .u = {}, \
208 .fd_count = 0, \
209 }; \
210 \
211 if (!tracker) { \
212 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
213 goto end; \
214 } \
215 \
216 ret = lttng_strncpy( \
217 lsm.session.name, tracker->session_name, sizeof(lsm.session.name)); \
218 if (ret) { \
219 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
220 goto end; \
221 } \
222 \
223 lsm.domain.type = tracker->domain; \
224 lsm.u.process_attr_tracker_add_remove_include_value.process_attr = \
225 (int32_t) tracker->process_attr; \
226 lsm.u.process_attr_tracker_add_remove_include_value.value_type = \
227 (uint32_t) LTTNG_PROCESS_ATTR_VALUE_TYPE_##value_type_enum; \
228 \
229 if (std::is_signed<value_type_c>::value) { \
230 lsm.u.process_attr_tracker_add_remove_include_value.integral_value.u \
231 ._signed = value; \
232 } else { \
233 lsm.u.process_attr_tracker_add_remove_include_value.integral_value.u \
234 ._unsigned = value; \
235 } \
236 \
237 ret = lttng_ctl_ask_sessiond(&lsm, NULL); \
238 if (ret < 0) { \
239 switch (-ret) { \
240 case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
241 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
242 break; \
243 case LTTNG_ERR_PROCESS_ATTR_MISSING: \
244 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
245 break; \
246 case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
247 status = \
248 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
249 break; \
250 default: \
251 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
252 } \
253 } \
254 end: \
255 return status; \
256 }
257
258#define DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC( \
259 command_upper, command_lower, process_attr_name, value_type_name, value_type_enum) \
260 enum lttng_process_attr_tracker_handle_status \
261 lttng_process_attr_##process_attr_name##_tracker_handle_##command_lower##_##value_type_name( \
262 const struct lttng_process_attr_tracker_handle *tracker, \
263 const char *value) \
264 { \
265 int ret; \
266 enum lttng_process_attr_tracker_handle_status status = \
267 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
268 struct lttcomm_session_msg lsm = { \
269 .cmd_type = \
270 LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE, \
271 .session = {}, \
272 .domain = {}, \
273 .u = {}, \
274 .fd_count = 0, \
275 }; \
276 const size_t len = value ? strlen(value) + 1 : 0; \
277 \
278 if (!tracker || !value) { \
279 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
280 goto end; \
281 } \
282 \
283 ret = lttng_strncpy( \
284 lsm.session.name, tracker->session_name, sizeof(lsm.session.name)); \
285 if (ret) { \
286 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
287 goto end; \
288 } \
289 \
290 lsm.domain.type = tracker->domain; \
291 lsm.u.process_attr_tracker_add_remove_include_value.process_attr = \
292 (int32_t) tracker->process_attr; \
293 lsm.u.process_attr_tracker_add_remove_include_value.name_len = (uint32_t) len; \
294 lsm.u.process_attr_tracker_add_remove_include_value.value_type = \
295 (uint32_t) LTTNG_PROCESS_ATTR_VALUE_TYPE_##value_type_enum; \
296 \
297 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, value, len, NULL); \
298 if (ret < 0) { \
299 switch (-ret) { \
300 case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
301 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
302 break; \
303 case LTTNG_ERR_PROCESS_ATTR_MISSING: \
304 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
305 break; \
306 case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
307 status = \
308 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
309 break; \
310 case LTTNG_ERR_USER_NOT_FOUND: \
311 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND; \
312 break; \
313 case LTTNG_ERR_GROUP_NOT_FOUND: \
314 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND; \
315 break; \
316 default: \
317 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
318 } \
319 } \
320 end: \
321 return status; \
159b042f
JG
322 }
323
324/* PID */
28ab034a
JG
325DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD, add, process_id, pid, pid_t, PID);
326DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE, remove, process_id, pid, pid_t, PID);
159b042f
JG
327
328/* VPID */
28ab034a
JG
329DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD, add, virtual_process_id, pid, pid_t, PID);
330DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE, remove, virtual_process_id, pid, pid_t, PID);
159b042f
JG
331
332/* UID */
28ab034a
JG
333DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD, add, user_id, uid, uid_t, UID);
334DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE, remove, user_id, uid, uid_t, UID);
335DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD, add, user_id, user_name, USER_NAME);
336DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(REMOVE, remove, user_id, user_name, USER_NAME);
159b042f
JG
337
338/* VUID */
28ab034a
JG
339DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD, add, virtual_user_id, uid, uid_t, UID);
340DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE, remove, virtual_user_id, uid, uid_t, UID);
341DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD, add, virtual_user_id, user_name, USER_NAME);
342DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(REMOVE, remove, virtual_user_id, user_name, USER_NAME);
159b042f
JG
343
344/* GID */
28ab034a
JG
345DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD, add, group_id, gid, gid_t, GID);
346DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE, remove, group_id, gid, gid_t, GID);
347DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD, add, group_id, group_name, GROUP_NAME);
348DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(REMOVE, remove, group_id, group_name, GROUP_NAME);
159b042f
JG
349
350/* VGID */
28ab034a
JG
351DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD, add, virtual_group_id, gid, gid_t, GID);
352DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE, remove, virtual_group_id, gid, gid_t, GID);
353DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD, add, virtual_group_id, group_name, GROUP_NAME);
159b042f 354DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
28ab034a 355 REMOVE, remove, virtual_group_id, group_name, GROUP_NAME);
159b042f 356
28ab034a
JG
357enum lttng_process_attr_tracker_handle_status lttng_process_attr_tracker_handle_get_inclusion_set(
358 struct lttng_process_attr_tracker_handle *tracker,
359 const struct lttng_process_attr_values **values)
159b042f 360{
cd9adb8b 361 char *reply = nullptr;
e1b624d0 362 int reply_ret, copy_ret;
159b042f 363 enum lttng_process_attr_tracker_handle_status status =
28ab034a 364 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK;
159b042f 365 struct lttcomm_session_msg lsm = {
37a5ef39 366 .cmd_type = LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET,
1c9a0b0e
MJ
367 .session = {},
368 .domain = {},
369 .u = {},
370 .fd_count = 0,
159b042f
JG
371 };
372 struct lttng_buffer_view inclusion_set_view;
373 ssize_t inclusion_set_ret;
374
375 if (!tracker || !values) {
376 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
377 goto end;
378 }
379
380 lttng_process_attr_values_destroy(tracker->inclusion_set);
cd9adb8b 381 tracker->inclusion_set = nullptr;
159b042f 382
28ab034a 383 copy_ret = lttng_strncpy(lsm.session.name, tracker->session_name, sizeof(lsm.session.name));
e1b624d0
JG
384 if (copy_ret) {
385 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID;
386 goto end;
387 }
388
159b042f
JG
389 lsm.domain.type = tracker->domain;
390 lsm.u.process_attr_tracker_get_tracking_policy.process_attr =
28ab034a 391 (int32_t) tracker->process_attr;
159b042f
JG
392
393 /* Command returns a session descriptor on success. */
cd9adb8b 394 reply_ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, nullptr, 0, (void **) &reply);
159b042f
JG
395 if (reply_ret < 0) {
396 if (reply_ret == -LTTNG_ERR_SESSION_NOT_EXIST) {
397 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST;
28ab034a 398 } else if (reply_ret == -LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY) {
159b042f
JG
399 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY;
400 } else {
401 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR;
402 }
403 goto end;
404 } else if (reply_ret == 0) {
405 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR;
406 goto end;
407 }
408
409 inclusion_set_view = lttng_buffer_view_init(reply, 0, reply_ret);
410 if (!inclusion_set_view.data) {
411 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR;
412 goto end;
413 }
414
28ab034a
JG
415 inclusion_set_ret = lttng_process_attr_values_create_from_buffer(tracker->domain,
416 tracker->process_attr,
417 &inclusion_set_view,
418 &tracker->inclusion_set);
159b042f
JG
419 if (inclusion_set_ret < 0) {
420 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR;
421 goto end;
422 }
423 *values = tracker->inclusion_set;
424end:
425 free(reply);
426 return status;
427}
428
28ab034a
JG
429enum lttng_process_attr_values_status
430lttng_process_attr_values_get_count(const struct lttng_process_attr_values *values,
431 unsigned int *count)
159b042f 432{
28ab034a 433 enum lttng_process_attr_values_status status = LTTNG_PROCESS_ATTR_VALUES_STATUS_OK;
159b042f
JG
434
435 if (!values || !count) {
436 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID;
437 goto end;
438 }
439
440 *count = _lttng_process_attr_values_get_count(values);
441end:
442 return status;
443}
444
28ab034a
JG
445enum lttng_process_attr_value_type
446lttng_process_attr_values_get_type_at_index(const struct lttng_process_attr_values *values,
447 unsigned int index)
159b042f
JG
448{
449 enum lttng_process_attr_value_type type;
450 const struct process_attr_value *value;
451
452 if (!values) {
453 type = LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID;
454 goto end;
455 }
456
457 if (_lttng_process_attr_values_get_count(values) <= index) {
458 type = LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID;
459 goto end;
460 }
461
462 value = lttng_process_attr_tracker_values_get_at_index(values, index);
463 type = value->type;
464end:
465 return type;
466}
467
5c7248cd
JG
468#define DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(value_type_name, value_type, expected_value_type) \
469 enum lttng_process_attr_values_status \
470 lttng_process_attr_values_get_##value_type_name##_at_index( \
471 const struct lttng_process_attr_values *values, \
472 unsigned int index, \
473 value_type *out_value) /* NOLINT clang-tidy sees value_type as a value and \
474 adds parentheses */ \
475 { \
476 enum lttng_process_attr_values_status status = \
477 LTTNG_PROCESS_ATTR_VALUES_STATUS_OK; \
478 const struct process_attr_value *value; \
479 \
480 if (!values) { \
481 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
482 goto end; \
483 } \
484 \
485 if (_lttng_process_attr_values_get_count(values) <= index) { \
486 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
487 goto end; \
488 } \
489 \
490 value = lttng_process_attr_tracker_values_get_at_index(values, index); \
491 if (value->type != LTTNG_PROCESS_ATTR_VALUE_TYPE_##expected_value_type) { \
492 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE; \
493 goto end; \
494 } \
495 *out_value = value->value.value_type_name; \
496 end: \
497 return status; \
159b042f
JG
498 }
499
500DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(pid, pid_t, PID);
501DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(uid, uid_t, UID);
502DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(gid, gid_t, GID);
503DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(user_name, const char *, USER_NAME);
504DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(group_name, const char *, GROUP_NAME);
505
28ab034a
JG
506static enum lttng_error_code
507handle_status_to_error_code(enum lttng_process_attr_tracker_handle_status handle_status)
159b042f
JG
508{
509 switch (handle_status) {
510 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY:
511 return LTTNG_ERR_INVALID;
512 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST:
513 return LTTNG_ERR_SESSION_NOT_EXIST;
514 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR:
515 return LTTNG_ERR_INVALID_PROTOCOL;
516 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS:
517 return LTTNG_ERR_PID_TRACKED;
518 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING:
519 return LTTNG_ERR_PID_NOT_TRACKED;
520 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK:
521 return LTTNG_OK;
522 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR:
523 default:
524 /* fall-through. */
525 return LTTNG_ERR_UNK;
526 }
527}
528
529/*
530 * Add PID to session tracker.
531 * Return 0 on success else a negative LTTng error code.
532 */
533int lttng_track_pid(struct lttng_handle *handle, int pid)
534{
535 enum lttng_error_code ret_code;
cd9adb8b 536 struct lttng_process_attr_tracker_handle *tracker_handle = nullptr;
159b042f
JG
537 enum lttng_process_attr_tracker_handle_status handle_status;
538 enum lttng_tracking_policy policy;
539 enum lttng_process_attr process_attr;
540
541 if (!handle) {
542 ret_code = LTTNG_ERR_INVALID;
543 goto end;
544 }
545
546 process_attr = handle->domain.type == LTTNG_DOMAIN_KERNEL ?
28ab034a
JG
547 LTTNG_PROCESS_ATTR_PROCESS_ID :
548 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID;
159b042f 549
28ab034a
JG
550 ret_code = lttng_session_get_tracker_handle(
551 handle->session_name, handle->domain.type, process_attr, &tracker_handle);
159b042f
JG
552 if (ret_code != LTTNG_OK) {
553 goto end;
554 }
555
556 if (pid == -1) {
557 handle_status = lttng_process_attr_tracker_handle_set_tracking_policy(
28ab034a 558 tracker_handle, LTTNG_TRACKING_POLICY_INCLUDE_ALL);
159b042f
JG
559 ret_code = handle_status_to_error_code(handle_status);
560 goto end;
561 }
562
28ab034a
JG
563 handle_status =
564 lttng_process_attr_tracker_handle_get_tracking_policy(tracker_handle, &policy);
159b042f
JG
565 if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
566 ret_code = handle_status_to_error_code(handle_status);
567 goto end;
568 }
569
570 if (policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
571 handle_status = lttng_process_attr_tracker_handle_set_tracking_policy(
28ab034a 572 tracker_handle, LTTNG_TRACKING_POLICY_INCLUDE_SET);
159b042f
JG
573 if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
574 ret_code = handle_status_to_error_code(handle_status);
575 goto end;
576 }
577 }
578
579 handle_status = process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID ?
28ab034a
JG
580 lttng_process_attr_process_id_tracker_handle_add_pid(tracker_handle, (pid_t) pid) :
581 lttng_process_attr_virtual_process_id_tracker_handle_add_pid(tracker_handle,
582 (pid_t) pid);
159b042f
JG
583 ret_code = handle_status_to_error_code(handle_status);
584end:
403e01ee 585 lttng_process_attr_tracker_handle_destroy(tracker_handle);
159b042f
JG
586 return ret_code == LTTNG_OK ? 0 : -ret_code;
587}
588
589/*
590 * Remove PID from session tracker.
591 * Return 0 on success else a negative LTTng error code.
592 */
593int lttng_untrack_pid(struct lttng_handle *handle, int pid)
594{
595 enum lttng_error_code ret_code;
cd9adb8b 596 struct lttng_process_attr_tracker_handle *tracker_handle = nullptr;
159b042f
JG
597 enum lttng_process_attr_tracker_handle_status handle_status;
598 enum lttng_tracking_policy policy;
599 enum lttng_process_attr process_attr;
600
601 if (!handle) {
602 ret_code = LTTNG_ERR_INVALID;
603 goto end;
604 }
605
606 process_attr = handle->domain.type == LTTNG_DOMAIN_KERNEL ?
28ab034a
JG
607 LTTNG_PROCESS_ATTR_PROCESS_ID :
608 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID;
609 ret_code = lttng_session_get_tracker_handle(
610 handle->session_name, handle->domain.type, process_attr, &tracker_handle);
159b042f
JG
611 if (ret_code != LTTNG_OK) {
612 goto end;
613 }
614
615 if (pid == -1) {
616 handle_status = lttng_process_attr_tracker_handle_set_tracking_policy(
28ab034a 617 tracker_handle, LTTNG_TRACKING_POLICY_EXCLUDE_ALL);
159b042f
JG
618 ret_code = handle_status_to_error_code(handle_status);
619 goto end;
620 }
621
28ab034a
JG
622 handle_status =
623 lttng_process_attr_tracker_handle_get_tracking_policy(tracker_handle, &policy);
159b042f
JG
624 if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
625 ret_code = handle_status_to_error_code(handle_status);
626 goto end;
627 }
628
629 if (policy == LTTNG_TRACKING_POLICY_EXCLUDE_ALL) {
630 ret_code = LTTNG_ERR_PID_NOT_TRACKED;
631 goto end;
632 } else if (policy == LTTNG_TRACKING_POLICY_INCLUDE_ALL) {
633 ret_code = LTTNG_ERR_INVALID;
634 goto end;
635 }
636
637 handle_status = process_attr == LTTNG_PROCESS_ATTR_PROCESS_ID ?
28ab034a
JG
638 lttng_process_attr_process_id_tracker_handle_remove_pid(tracker_handle,
639 (pid_t) pid) :
640 lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(tracker_handle,
641 (pid_t) pid);
159b042f
JG
642 if (handle_status == LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY) {
643 ret_code = LTTNG_ERR_PID_NOT_TRACKED;
644 }
645end:
403e01ee 646 lttng_process_attr_tracker_handle_destroy(tracker_handle);
159b042f
JG
647 return ret_code == LTTNG_OK ? 0 : -ret_code;
648}
649
650/*
651 * List PIDs in the tracker.
652 *
653 * enabled is set to whether the PID tracker is enabled.
654 * pids is set to an allocated array of PIDs currently tracked. On
655 * success, pids must be freed by the caller.
656 * nr_pids is set to the number of entries contained by the pids array.
657 *
658 * Returns 0 on success, else a negative LTTng error code.
659 */
660int lttng_list_tracker_pids(struct lttng_handle *handle,
28ab034a
JG
661 int *_enabled,
662 int32_t **_pids,
663 size_t *_nr_pids)
159b042f
JG
664{
665 enum lttng_error_code ret_code;
cd9adb8b 666 struct lttng_process_attr_tracker_handle *tracker_handle = nullptr;
159b042f
JG
667 enum lttng_process_attr_tracker_handle_status handle_status;
668 const struct lttng_process_attr_values *values;
669 enum lttng_tracking_policy policy;
670 unsigned int pid_count, i;
cd9adb8b 671 int32_t *pid_array = nullptr;
159b042f
JG
672
673 if (!handle || !_enabled || !_pids || !_nr_pids) {
674 ret_code = LTTNG_ERR_INVALID;
675 goto end;
676 }
677
678 ret_code = lttng_session_get_tracker_handle(handle->session_name,
28ab034a
JG
679 handle->domain.type,
680 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID,
681 &tracker_handle);
159b042f
JG
682 if (ret_code != LTTNG_OK) {
683 goto end;
684 }
685
686 while (true) {
28ab034a
JG
687 handle_status = lttng_process_attr_tracker_handle_get_inclusion_set(tracker_handle,
688 &values);
689 if (handle_status == LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
159b042f
JG
690 policy = LTTNG_TRACKING_POLICY_INCLUDE_SET;
691 break;
692 } else if (handle_status !=
28ab034a 693 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY) {
159b042f
JG
694 ret_code = handle_status_to_error_code(handle_status);
695 goto end;
696 }
697
698 handle_status = lttng_process_attr_tracker_handle_get_tracking_policy(
28ab034a
JG
699 tracker_handle, &policy);
700 if (handle_status != LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK) {
159b042f
JG
701 ret_code = handle_status_to_error_code(handle_status);
702 goto end;
703 }
704
705 /* Tracking policy changed in the meantime, retry. */
706 if (policy == LTTNG_TRACKING_POLICY_INCLUDE_SET) {
707 continue;
708 }
709 break;
710 }
711
712 switch (policy) {
713 case LTTNG_TRACKING_POLICY_INCLUDE_ALL:
714 *_enabled = 0;
715 goto end;
716 case LTTNG_TRACKING_POLICY_EXCLUDE_ALL:
717 *_enabled = 1;
718 pid_count = 0;
719 break;
720 case LTTNG_TRACKING_POLICY_INCLUDE_SET:
721 {
722 const enum lttng_process_attr_values_status values_status =
28ab034a 723 lttng_process_attr_values_get_count(values, &pid_count);
159b042f
JG
724
725 if (values_status != LTTNG_PROCESS_ATTR_VALUES_STATUS_OK) {
726 ret_code = LTTNG_ERR_UNK;
727 goto end;
728 }
729 break;
730 }
731 default:
732 ret_code = LTTNG_ERR_INVALID_PROTOCOL;
733 goto end;
734 }
735
64803277 736 pid_array = calloc<int32_t>(pid_count);
159b042f
JG
737 if (!pid_array) {
738 ret_code = LTTNG_ERR_NOMEM;
739 goto end;
740 }
741
742 /* Extract values to a raw array. */
743 for (i = 0; i < pid_count; i++) {
744 pid_t pid;
745 const enum lttng_process_attr_values_status values_status =
28ab034a 746 lttng_process_attr_values_get_pid_at_index(values, i, &pid);
159b042f
JG
747
748 if (values_status != LTTNG_PROCESS_ATTR_VALUES_STATUS_OK) {
749 ret_code = LTTNG_ERR_UNK;
750 goto end;
751 }
752 pid_array[i] = (int32_t) pid;
753 }
754 *_nr_pids = (size_t) pid_count;
755 *_pids = pid_array;
cd9adb8b 756 pid_array = nullptr;
159b042f
JG
757end:
758 lttng_process_attr_tracker_handle_destroy(tracker_handle);
759 free(pid_array);
760 return ret_code == LTTNG_OK ? 0 : -ret_code;
761}
This page took 0.075877 seconds and 4 git commands to generate.