2 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include "lttng-ctl-helper.hpp"
10 #include <common/sessiond-comm/sessiond-comm.hpp>
11 #include <common/tracker.hpp>
13 #include <lttng/domain.h>
14 #include <lttng/lttng-error.h>
15 #include <lttng/tracker.h>
17 #include <type_traits>
19 struct lttng_process_attr_tracker_handle
{
21 enum lttng_domain_type domain
;
22 enum lttng_process_attr process_attr
;
23 struct lttng_process_attr_values
*inclusion_set
;
26 void lttng_process_attr_tracker_handle_destroy(struct lttng_process_attr_tracker_handle
*tracker
)
32 lttng_process_attr_values_destroy(tracker
->inclusion_set
);
33 free(tracker
->session_name
);
38 lttng_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
)
43 enum lttng_error_code ret_code
= LTTNG_OK
;
44 struct lttng_process_attr_tracker_handle
*handle
= nullptr;
45 enum lttng_process_attr_tracker_handle_status status
;
46 enum lttng_tracking_policy policy
;
48 if (!session_name
|| !out_tracker_handle
) {
49 ret_code
= LTTNG_ERR_INVALID
;
53 if (domain
!= LTTNG_DOMAIN_KERNEL
&& domain
!= LTTNG_DOMAIN_UST
) {
54 ret_code
= LTTNG_ERR_UNSUPPORTED_DOMAIN
;
58 handle
= zmalloc
<lttng_process_attr_tracker_handle
>();
60 ret_code
= LTTNG_ERR_NOMEM
;
64 handle
->session_name
= strdup(session_name
);
65 if (!handle
->session_name
) {
66 ret_code
= LTTNG_ERR_NOMEM
;
70 handle
->domain
= domain
;
71 handle
->process_attr
= process_attr
;
74 * Use the `get_tracking_policy` command to validate the tracker's
77 status
= lttng_process_attr_tracker_handle_get_tracking_policy(handle
, &policy
);
79 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
:
81 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
:
82 ret_code
= LTTNG_ERR_SESSION_NOT_EXIST
;
85 ret_code
= LTTNG_ERR_UNK
;
89 *out_tracker_handle
= handle
;
92 lttng_process_attr_tracker_handle_destroy(handle
);
96 enum 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
)
99 void *reply
= nullptr;
100 int reply_ret
, copy_ret
;
101 enum lttng_process_attr_tracker_handle_status status
=
102 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
;
103 struct lttcomm_session_msg lsm
= {
104 .cmd_type
= LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_GET_POLICY
,
111 if (!tracker
|| !policy
) {
112 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
116 copy_ret
= lttng_strncpy(lsm
.session
.name
, tracker
->session_name
, sizeof(lsm
.session
.name
));
118 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
122 lsm
.domain
.type
= tracker
->domain
;
123 lsm
.u
.process_attr_tracker_get_tracking_policy
.process_attr
=
124 (int32_t) tracker
->process_attr
;
126 /* Command returns a session descriptor on success. */
127 reply_ret
= lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm
, nullptr, 0, &reply
);
128 if (reply_ret
!= sizeof(uint32_t)) {
129 if (reply_ret
== -LTTNG_ERR_SESSION_NOT_EXIST
||
130 reply_ret
== -LTTNG_ERR_SESS_NOT_FOUND
) {
131 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
;
133 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
;
138 *policy
= (enum lttng_tracking_policy
)(*((const uint32_t *) reply
));
144 enum 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
)
147 int reply_ret
, copy_ret
;
148 enum lttng_process_attr_tracker_handle_status status
=
149 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
;
150 struct lttcomm_session_msg lsm
= {
151 .cmd_type
= LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_SET_POLICY
,
159 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
163 copy_ret
= lttng_strncpy(lsm
.session
.name
, tracker
->session_name
, sizeof(lsm
.session
.name
));
165 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
169 lsm
.domain
.type
= tracker
->domain
;
170 lsm
.u
.process_attr_tracker_set_tracking_policy
.process_attr
=
171 (int32_t) tracker
->process_attr
;
172 lsm
.u
.process_attr_tracker_set_tracking_policy
.tracking_policy
= (int32_t) policy
;
174 /* Command returns a session descriptor on success. */
175 reply_ret
= lttng_ctl_ask_sessiond(&lsm
, nullptr);
177 if (reply_ret
== -LTTNG_ERR_SESSION_NOT_EXIST
) {
178 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
;
180 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
;
188 #define DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(command_upper, \
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) \
200 enum lttng_process_attr_tracker_handle_status status = \
201 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
202 struct lttcomm_session_msg lsm = { \
204 LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE, \
212 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
216 ret = lttng_strncpy( \
217 lsm.session.name, tracker->session_name, sizeof(lsm.session.name)); \
219 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
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; \
229 if (std::is_signed<value_type_c>::value) { \
230 lsm.u.process_attr_tracker_add_remove_include_value.integral_value.u \
233 lsm.u.process_attr_tracker_add_remove_include_value.integral_value.u \
234 ._unsigned = value; \
237 ret = lttng_ctl_ask_sessiond(&lsm, NULL); \
240 case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
241 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
243 case LTTNG_ERR_PROCESS_ATTR_MISSING: \
244 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
246 case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
248 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
251 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
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, \
266 enum lttng_process_attr_tracker_handle_status status = \
267 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
268 struct lttcomm_session_msg lsm = { \
270 LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE, \
276 const size_t len = value ? strlen(value) + 1 : 0; \
278 if (!tracker || !value) { \
279 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
283 ret = lttng_strncpy( \
284 lsm.session.name, tracker->session_name, sizeof(lsm.session.name)); \
286 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
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; \
297 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm, value, len, NULL); \
300 case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
301 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
303 case LTTNG_ERR_PROCESS_ATTR_MISSING: \
304 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
306 case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
308 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
310 case LTTNG_ERR_USER_NOT_FOUND: \
311 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND; \
313 case LTTNG_ERR_GROUP_NOT_FOUND: \
314 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND; \
317 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
325 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD
, add
, process_id
, pid
, pid_t
, PID
);
326 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE
, remove
, process_id
, pid
, pid_t
, PID
);
329 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD
, add
, virtual_process_id
, pid
, pid_t
, PID
);
330 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE
, remove
, virtual_process_id
, pid
, pid_t
, PID
);
333 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD
, add
, user_id
, uid
, uid_t
, UID
);
334 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE
, remove
, user_id
, uid
, uid_t
, UID
);
335 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD
, add
, user_id
, user_name
, USER_NAME
);
336 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(REMOVE
, remove
, user_id
, user_name
, USER_NAME
);
339 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD
, add
, virtual_user_id
, uid
, uid_t
, UID
);
340 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE
, remove
, virtual_user_id
, uid
, uid_t
, UID
);
341 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD
, add
, virtual_user_id
, user_name
, USER_NAME
);
342 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(REMOVE
, remove
, virtual_user_id
, user_name
, USER_NAME
);
345 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD
, add
, group_id
, gid
, gid_t
, GID
);
346 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE
, remove
, group_id
, gid
, gid_t
, GID
);
347 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD
, add
, group_id
, group_name
, GROUP_NAME
);
348 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(REMOVE
, remove
, group_id
, group_name
, GROUP_NAME
);
351 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(ADD
, add
, virtual_group_id
, gid
, gid_t
, GID
);
352 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(REMOVE
, remove
, virtual_group_id
, gid
, gid_t
, GID
);
353 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(ADD
, add
, virtual_group_id
, group_name
, GROUP_NAME
);
354 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
355 REMOVE
, remove
, virtual_group_id
, group_name
, GROUP_NAME
);
357 enum 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
)
361 char *reply
= nullptr;
362 int reply_ret
, copy_ret
;
363 enum lttng_process_attr_tracker_handle_status status
=
364 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
;
365 struct lttcomm_session_msg lsm
= {
366 .cmd_type
= LTTCOMM_SESSIOND_COMMAND_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET
,
372 struct lttng_buffer_view inclusion_set_view
;
373 ssize_t inclusion_set_ret
;
375 if (!tracker
|| !values
) {
376 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
380 lttng_process_attr_values_destroy(tracker
->inclusion_set
);
381 tracker
->inclusion_set
= nullptr;
383 copy_ret
= lttng_strncpy(lsm
.session
.name
, tracker
->session_name
, sizeof(lsm
.session
.name
));
385 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
389 lsm
.domain
.type
= tracker
->domain
;
390 lsm
.u
.process_attr_tracker_get_tracking_policy
.process_attr
=
391 (int32_t) tracker
->process_attr
;
393 /* Command returns a session descriptor on success. */
394 reply_ret
= lttng_ctl_ask_sessiond_varlen_no_cmd_header(&lsm
, nullptr, 0, (void **) &reply
);
396 if (reply_ret
== -LTTNG_ERR_SESSION_NOT_EXIST
) {
397 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
;
398 } else if (reply_ret
== -LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY
) {
399 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
;
401 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
;
404 } else if (reply_ret
== 0) {
405 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
;
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
;
415 inclusion_set_ret
= lttng_process_attr_values_create_from_buffer(tracker
->domain
,
416 tracker
->process_attr
,
418 &tracker
->inclusion_set
);
419 if (inclusion_set_ret
< 0) {
420 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
;
423 *values
= tracker
->inclusion_set
;
429 enum lttng_process_attr_values_status
430 lttng_process_attr_values_get_count(const struct lttng_process_attr_values
*values
,
433 enum lttng_process_attr_values_status status
= LTTNG_PROCESS_ATTR_VALUES_STATUS_OK
;
435 if (!values
|| !count
) {
436 status
= LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID
;
440 *count
= _lttng_process_attr_values_get_count(values
);
445 enum lttng_process_attr_value_type
446 lttng_process_attr_values_get_type_at_index(const struct lttng_process_attr_values
*values
,
449 enum lttng_process_attr_value_type type
;
450 const struct process_attr_value
*value
;
453 type
= LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID
;
457 if (_lttng_process_attr_values_get_count(values
) <= index
) {
458 type
= LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID
;
462 value
= lttng_process_attr_tracker_values_get_at_index(values
, index
);
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) \
475 enum lttng_process_attr_values_status status = \
476 LTTNG_PROCESS_ATTR_VALUES_STATUS_OK; \
477 const struct process_attr_value *value; \
480 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
484 if (_lttng_process_attr_values_get_count(values) <= index) { \
485 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
489 value = lttng_process_attr_tracker_values_get_at_index(values, index); \
490 if (value->type != LTTNG_PROCESS_ATTR_VALUE_TYPE_##expected_value_type) { \
491 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE; \
494 *out_value = value->value.value_type_name; \
499 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(pid
, pid_t
, PID
);
500 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(uid
, uid_t
, UID
);
501 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(gid
, gid_t
, GID
);
502 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(user_name
, const char *, USER_NAME
);
503 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(group_name
, const char *, GROUP_NAME
);
505 static enum lttng_error_code
506 handle_status_to_error_code(enum lttng_process_attr_tracker_handle_status handle_status
)
508 switch (handle_status
) {
509 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
:
510 return LTTNG_ERR_INVALID
;
511 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
:
512 return LTTNG_ERR_SESSION_NOT_EXIST
;
513 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
:
514 return LTTNG_ERR_INVALID_PROTOCOL
;
515 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS
:
516 return LTTNG_ERR_PID_TRACKED
;
517 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING
:
518 return LTTNG_ERR_PID_NOT_TRACKED
;
519 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
:
521 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
:
524 return LTTNG_ERR_UNK
;
529 * Add PID to session tracker.
530 * Return 0 on success else a negative LTTng error code.
532 int lttng_track_pid(struct lttng_handle
*handle
, int pid
)
534 enum lttng_error_code ret_code
;
535 struct lttng_process_attr_tracker_handle
*tracker_handle
= nullptr;
536 enum lttng_process_attr_tracker_handle_status handle_status
;
537 enum lttng_tracking_policy policy
;
538 enum lttng_process_attr process_attr
;
541 ret_code
= LTTNG_ERR_INVALID
;
545 process_attr
= handle
->domain
.type
== LTTNG_DOMAIN_KERNEL
?
546 LTTNG_PROCESS_ATTR_PROCESS_ID
:
547 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID
;
549 ret_code
= lttng_session_get_tracker_handle(
550 handle
->session_name
, handle
->domain
.type
, process_attr
, &tracker_handle
);
551 if (ret_code
!= LTTNG_OK
) {
556 handle_status
= lttng_process_attr_tracker_handle_set_tracking_policy(
557 tracker_handle
, LTTNG_TRACKING_POLICY_INCLUDE_ALL
);
558 ret_code
= handle_status_to_error_code(handle_status
);
563 lttng_process_attr_tracker_handle_get_tracking_policy(tracker_handle
, &policy
);
564 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
565 ret_code
= handle_status_to_error_code(handle_status
);
569 if (policy
!= LTTNG_TRACKING_POLICY_INCLUDE_SET
) {
570 handle_status
= lttng_process_attr_tracker_handle_set_tracking_policy(
571 tracker_handle
, LTTNG_TRACKING_POLICY_INCLUDE_SET
);
572 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
573 ret_code
= handle_status_to_error_code(handle_status
);
578 handle_status
= process_attr
== LTTNG_PROCESS_ATTR_PROCESS_ID
?
579 lttng_process_attr_process_id_tracker_handle_add_pid(tracker_handle
, (pid_t
) pid
) :
580 lttng_process_attr_virtual_process_id_tracker_handle_add_pid(tracker_handle
,
582 ret_code
= handle_status_to_error_code(handle_status
);
584 lttng_process_attr_tracker_handle_destroy(tracker_handle
);
585 return ret_code
== LTTNG_OK
? 0 : -ret_code
;
589 * Remove PID from session tracker.
590 * Return 0 on success else a negative LTTng error code.
592 int lttng_untrack_pid(struct lttng_handle
*handle
, int pid
)
594 enum lttng_error_code ret_code
;
595 struct lttng_process_attr_tracker_handle
*tracker_handle
= nullptr;
596 enum lttng_process_attr_tracker_handle_status handle_status
;
597 enum lttng_tracking_policy policy
;
598 enum lttng_process_attr process_attr
;
601 ret_code
= LTTNG_ERR_INVALID
;
605 process_attr
= handle
->domain
.type
== LTTNG_DOMAIN_KERNEL
?
606 LTTNG_PROCESS_ATTR_PROCESS_ID
:
607 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID
;
608 ret_code
= lttng_session_get_tracker_handle(
609 handle
->session_name
, handle
->domain
.type
, process_attr
, &tracker_handle
);
610 if (ret_code
!= LTTNG_OK
) {
615 handle_status
= lttng_process_attr_tracker_handle_set_tracking_policy(
616 tracker_handle
, LTTNG_TRACKING_POLICY_EXCLUDE_ALL
);
617 ret_code
= handle_status_to_error_code(handle_status
);
622 lttng_process_attr_tracker_handle_get_tracking_policy(tracker_handle
, &policy
);
623 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
624 ret_code
= handle_status_to_error_code(handle_status
);
628 if (policy
== LTTNG_TRACKING_POLICY_EXCLUDE_ALL
) {
629 ret_code
= LTTNG_ERR_PID_NOT_TRACKED
;
631 } else if (policy
== LTTNG_TRACKING_POLICY_INCLUDE_ALL
) {
632 ret_code
= LTTNG_ERR_INVALID
;
636 handle_status
= process_attr
== LTTNG_PROCESS_ATTR_PROCESS_ID
?
637 lttng_process_attr_process_id_tracker_handle_remove_pid(tracker_handle
,
639 lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(tracker_handle
,
641 if (handle_status
== LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
) {
642 ret_code
= LTTNG_ERR_PID_NOT_TRACKED
;
645 lttng_process_attr_tracker_handle_destroy(tracker_handle
);
646 return ret_code
== LTTNG_OK
? 0 : -ret_code
;
650 * List PIDs in the tracker.
652 * enabled is set to whether the PID tracker is enabled.
653 * pids is set to an allocated array of PIDs currently tracked. On
654 * success, pids must be freed by the caller.
655 * nr_pids is set to the number of entries contained by the pids array.
657 * Returns 0 on success, else a negative LTTng error code.
659 int lttng_list_tracker_pids(struct lttng_handle
*handle
,
664 enum lttng_error_code ret_code
;
665 struct lttng_process_attr_tracker_handle
*tracker_handle
= nullptr;
666 enum lttng_process_attr_tracker_handle_status handle_status
;
667 const struct lttng_process_attr_values
*values
;
668 enum lttng_tracking_policy policy
;
669 unsigned int pid_count
, i
;
670 int32_t *pid_array
= nullptr;
672 if (!handle
|| !_enabled
|| !_pids
|| !_nr_pids
) {
673 ret_code
= LTTNG_ERR_INVALID
;
677 ret_code
= lttng_session_get_tracker_handle(handle
->session_name
,
679 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID
,
681 if (ret_code
!= LTTNG_OK
) {
686 handle_status
= lttng_process_attr_tracker_handle_get_inclusion_set(tracker_handle
,
688 if (handle_status
== LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
689 policy
= LTTNG_TRACKING_POLICY_INCLUDE_SET
;
691 } else if (handle_status
!=
692 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
) {
693 ret_code
= handle_status_to_error_code(handle_status
);
697 handle_status
= lttng_process_attr_tracker_handle_get_tracking_policy(
698 tracker_handle
, &policy
);
699 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
700 ret_code
= handle_status_to_error_code(handle_status
);
704 /* Tracking policy changed in the meantime, retry. */
705 if (policy
== LTTNG_TRACKING_POLICY_INCLUDE_SET
) {
712 case LTTNG_TRACKING_POLICY_INCLUDE_ALL
:
715 case LTTNG_TRACKING_POLICY_EXCLUDE_ALL
:
719 case LTTNG_TRACKING_POLICY_INCLUDE_SET
:
721 const enum lttng_process_attr_values_status values_status
=
722 lttng_process_attr_values_get_count(values
, &pid_count
);
724 if (values_status
!= LTTNG_PROCESS_ATTR_VALUES_STATUS_OK
) {
725 ret_code
= LTTNG_ERR_UNK
;
731 ret_code
= LTTNG_ERR_INVALID_PROTOCOL
;
735 pid_array
= calloc
<int32_t>(pid_count
);
737 ret_code
= LTTNG_ERR_NOMEM
;
741 /* Extract values to a raw array. */
742 for (i
= 0; i
< pid_count
; i
++) {
744 const enum lttng_process_attr_values_status values_status
=
745 lttng_process_attr_values_get_pid_at_index(values
, i
, &pid
);
747 if (values_status
!= LTTNG_PROCESS_ATTR_VALUES_STATUS_OK
) {
748 ret_code
= LTTNG_ERR_UNK
;
751 pid_array
[i
] = (int32_t) pid
;
753 *_nr_pids
= (size_t) pid_count
;
757 lttng_process_attr_tracker_handle_destroy(tracker_handle
);
759 return ret_code
== LTTNG_OK
? 0 : -ret_code
;