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.h"
9 #include "lttng/domain.h"
10 #include "lttng/lttng-error.h"
11 #include <common/sessiond-comm/sessiond-comm.h>
12 #include <common/tracker.h>
13 #include <lttng/tracker.h>
15 struct lttng_process_attr_tracker_handle
{
17 enum lttng_domain_type domain
;
18 enum lttng_process_attr process_attr
;
19 struct lttng_process_attr_values
*inclusion_set
;
22 void lttng_process_attr_tracker_handle_destroy(
23 struct lttng_process_attr_tracker_handle
*tracker
)
29 lttng_process_attr_values_destroy(tracker
->inclusion_set
);
30 free(tracker
->session_name
);
34 enum lttng_error_code
lttng_session_get_tracker_handle(const char *session_name
,
35 enum lttng_domain_type domain
,
36 enum lttng_process_attr process_attr
,
37 struct lttng_process_attr_tracker_handle
**out_tracker_handle
)
39 enum lttng_error_code ret_code
= LTTNG_OK
;
40 struct lttng_process_attr_tracker_handle
*handle
= NULL
;
41 enum lttng_process_attr_tracker_handle_status status
;
42 enum lttng_tracking_policy policy
;
44 if (!session_name
|| !out_tracker_handle
) {
45 ret_code
= LTTNG_ERR_INVALID
;
49 if (domain
!= LTTNG_DOMAIN_KERNEL
&& domain
!= LTTNG_DOMAIN_UST
) {
50 ret_code
= LTTNG_ERR_UNSUPPORTED_DOMAIN
;
54 handle
= zmalloc(sizeof(*handle
));
56 ret_code
= LTTNG_ERR_NOMEM
;
60 handle
->session_name
= strdup(session_name
);
61 if (!handle
->session_name
) {
62 ret_code
= LTTNG_ERR_NOMEM
;
66 handle
->domain
= domain
;
67 handle
->process_attr
= process_attr
;
70 * Use the `get_tracking_policy` command to validate the tracker's
73 status
= lttng_process_attr_tracker_handle_get_tracking_policy(
76 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
:
78 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
:
79 ret_code
= LTTNG_ERR_SESSION_NOT_EXIST
;
82 ret_code
= LTTNG_ERR_UNK
;
86 *out_tracker_handle
= handle
;
89 lttng_process_attr_tracker_handle_destroy(handle
);
93 enum lttng_process_attr_tracker_handle_status
94 lttng_process_attr_tracker_handle_get_tracking_policy(
95 const struct lttng_process_attr_tracker_handle
*tracker
,
96 enum lttng_tracking_policy
*policy
)
100 enum lttng_process_attr_tracker_handle_status status
=
101 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
;
102 struct lttcomm_session_msg lsm
= {
103 .cmd_type
= LTTNG_PROCESS_ATTR_TRACKER_GET_POLICY
,
106 if (!tracker
|| !policy
) {
107 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
111 lttng_ctl_copy_string(lsm
.session
.name
, tracker
->session_name
,
112 sizeof(lsm
.session
.name
));
113 lsm
.domain
.type
= tracker
->domain
;
114 lsm
.u
.process_attr_tracker_get_tracking_policy
.process_attr
=
115 (int32_t) tracker
->process_attr
;
117 /* Command returns a session descriptor on success. */
118 reply_ret
= lttng_ctl_ask_sessiond_varlen_no_cmd_header(
119 &lsm
, NULL
, 0, &reply
);
120 if (reply_ret
!= sizeof(uint32_t)) {
121 if (reply_ret
== -LTTNG_ERR_SESSION_NOT_EXIST
||
122 reply_ret
== -LTTNG_ERR_SESS_NOT_FOUND
) {
123 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
;
125 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
;
130 *policy
= (enum lttng_tracking_policy
)(*((const uint32_t *) reply
));
136 enum lttng_process_attr_tracker_handle_status
137 lttng_process_attr_tracker_handle_set_tracking_policy(
138 const struct lttng_process_attr_tracker_handle
*tracker
,
139 enum lttng_tracking_policy policy
)
142 enum lttng_process_attr_tracker_handle_status status
=
143 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
;
144 struct lttcomm_session_msg lsm
= {
145 .cmd_type
= LTTNG_PROCESS_ATTR_TRACKER_SET_POLICY
,
149 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
153 lttng_ctl_copy_string(lsm
.session
.name
, tracker
->session_name
,
154 sizeof(lsm
.session
.name
));
155 lsm
.domain
.type
= tracker
->domain
;
156 lsm
.u
.process_attr_tracker_set_tracking_policy
.process_attr
=
157 (int32_t) tracker
->process_attr
;
158 lsm
.u
.process_attr_tracker_set_tracking_policy
.tracking_policy
=
161 /* Command returns a session descriptor on success. */
162 reply_ret
= lttng_ctl_ask_sessiond(&lsm
, NULL
);
164 if (reply_ret
== -LTTNG_ERR_SESSION_NOT_EXIST
) {
165 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
;
167 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
;
175 #define DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(command_upper, \
176 command_lower, process_attr_name, value_type_name, \
177 value_type_c, value_type_enum) \
178 enum lttng_process_attr_tracker_handle_status \
179 lttng_process_attr_##process_attr_name##_tracker_handle_##command_lower##_##value_type_name( \
180 const struct lttng_process_attr_tracker_handle \
182 value_type_c value) \
185 enum lttng_process_attr_tracker_handle_status status = \
186 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
187 struct lttcomm_session_msg lsm = { \
188 .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE}; \
191 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
195 lttng_ctl_copy_string(lsm.session.name, tracker->session_name, \
196 sizeof(lsm.session.name)); \
197 lsm.domain.type = tracker->domain; \
198 lsm.u.process_attr_tracker_add_remove_include_value \
200 (int32_t) tracker->process_attr; \
201 lsm.u.process_attr_tracker_add_remove_include_value \
202 .value_type = (uint32_t) \
203 LTTNG_PROCESS_ATTR_VALUE_TYPE_##value_type_enum; \
205 if (is_signed(value_type_c)) { \
206 lsm.u.process_attr_tracker_add_remove_include_value \
207 .integral_value.u._signed = value; \
209 lsm.u.process_attr_tracker_add_remove_include_value \
210 .integral_value.u._unsigned = value; \
213 ret = lttng_ctl_ask_sessiond(&lsm, NULL); \
216 case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
217 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
219 case LTTNG_ERR_PROCESS_ATTR_MISSING: \
220 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
222 case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
223 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
226 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
233 #define DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(command_upper, \
234 command_lower, process_attr_name, value_type_name, \
236 enum lttng_process_attr_tracker_handle_status \
237 lttng_process_attr_##process_attr_name##_tracker_handle_##command_lower##_##value_type_name( \
238 const struct lttng_process_attr_tracker_handle \
243 enum lttng_process_attr_tracker_handle_status status = \
244 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK; \
245 struct lttcomm_session_msg lsm = { \
246 .cmd_type = LTTNG_PROCESS_ATTR_TRACKER_##command_upper##_INCLUDE_VALUE}; \
247 const size_t len = value ? strlen(value) + 1 : 0; \
249 if (!tracker || !value) { \
250 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID; \
254 lttng_ctl_copy_string(lsm.session.name, tracker->session_name, \
255 sizeof(lsm.session.name)); \
256 lsm.domain.type = tracker->domain; \
257 lsm.u.process_attr_tracker_add_remove_include_value \
259 (int32_t) tracker->process_attr; \
260 lsm.u.process_attr_tracker_add_remove_include_value.name_len = \
262 lsm.u.process_attr_tracker_add_remove_include_value \
263 .value_type = (uint32_t) \
264 LTTNG_PROCESS_ATTR_VALUE_TYPE_##value_type_enum; \
266 ret = lttng_ctl_ask_sessiond_varlen_no_cmd_header( \
267 &lsm, value, len, NULL); \
270 case LTTNG_ERR_PROCESS_ATTR_EXISTS: \
271 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS; \
273 case LTTNG_ERR_PROCESS_ATTR_MISSING: \
274 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING; \
276 case LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY: \
277 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY; \
279 case LTTNG_ERR_USER_NOT_FOUND: \
280 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_USER_NOT_FOUND; \
282 case LTTNG_ERR_GROUP_NOT_FOUND: \
283 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_GROUP_NOT_FOUND; \
286 status = LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR; \
294 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
295 ADD
, add
, process_id
, pid
, pid_t
, PID
);
296 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
297 REMOVE
, remove
, process_id
, pid
, pid_t
, PID
);
300 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
301 ADD
, add
, virtual_process_id
, pid
, pid_t
, PID
);
302 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
303 REMOVE
, remove
, virtual_process_id
, pid
, pid_t
, PID
);
306 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
307 ADD
, add
, user_id
, uid
, uid_t
, UID
);
308 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
309 REMOVE
, remove
, user_id
, uid
, uid_t
, UID
);
310 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
311 ADD
, add
, user_id
, user_name
, USER_NAME
);
312 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
313 REMOVE
, remove
, user_id
, user_name
, USER_NAME
);
316 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
317 ADD
, add
, virtual_user_id
, uid
, uid_t
, UID
);
318 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
319 REMOVE
, remove
, virtual_user_id
, uid
, uid_t
, UID
);
320 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
321 ADD
, add
, virtual_user_id
, user_name
, USER_NAME
);
322 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
323 REMOVE
, remove
, virtual_user_id
, user_name
, USER_NAME
);
326 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
327 ADD
, add
, group_id
, gid
, gid_t
, GID
);
328 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
329 REMOVE
, remove
, group_id
, gid
, gid_t
, GID
);
330 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
331 ADD
, add
, group_id
, group_name
, GROUP_NAME
);
332 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
333 REMOVE
, remove
, group_id
, group_name
, GROUP_NAME
);
336 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
337 ADD
, add
, virtual_group_id
, gid
, gid_t
, GID
);
338 DEFINE_TRACKER_ADD_REMOVE_INTEGRAL_VALUE_FUNC(
339 REMOVE
, remove
, virtual_group_id
, gid
, gid_t
, GID
);
340 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
341 ADD
, add
, virtual_group_id
, group_name
, GROUP_NAME
);
342 DEFINE_TRACKER_ADD_REMOVE_STRING_VALUE_FUNC(
343 REMOVE
, remove
, virtual_group_id
, group_name
, GROUP_NAME
);
345 enum lttng_process_attr_tracker_handle_status
346 lttng_process_attr_tracker_handle_get_inclusion_set(
347 struct lttng_process_attr_tracker_handle
*tracker
,
348 const struct lttng_process_attr_values
**values
)
352 enum lttng_process_attr_tracker_handle_status status
=
353 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
;
354 struct lttcomm_session_msg lsm
= {
355 .cmd_type
= LTTNG_PROCESS_ATTR_TRACKER_GET_INCLUSION_SET
,
357 struct lttng_buffer_view inclusion_set_view
;
358 ssize_t inclusion_set_ret
;
360 if (!tracker
|| !values
) {
361 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID
;
365 lttng_process_attr_values_destroy(tracker
->inclusion_set
);
366 tracker
->inclusion_set
= NULL
;
368 lttng_ctl_copy_string(lsm
.session
.name
, tracker
->session_name
,
369 sizeof(lsm
.session
.name
));
370 lsm
.domain
.type
= tracker
->domain
;
371 lsm
.u
.process_attr_tracker_get_tracking_policy
.process_attr
=
372 (int32_t) tracker
->process_attr
;
374 /* Command returns a session descriptor on success. */
375 reply_ret
= lttng_ctl_ask_sessiond_varlen_no_cmd_header(
376 &lsm
, NULL
, 0, &reply
);
378 if (reply_ret
== -LTTNG_ERR_SESSION_NOT_EXIST
) {
379 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
;
380 } else if (reply_ret
==
381 -LTTNG_ERR_PROCESS_ATTR_TRACKER_INVALID_TRACKING_POLICY
) {
382 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
;
384 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
;
387 } else if (reply_ret
== 0) {
388 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
;
392 inclusion_set_view
= lttng_buffer_view_init(reply
, 0, reply_ret
);
393 if (!inclusion_set_view
.data
) {
394 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
;
398 inclusion_set_ret
= lttng_process_attr_values_create_from_buffer(
399 tracker
->domain
, tracker
->process_attr
,
400 &inclusion_set_view
, &tracker
->inclusion_set
);
401 if (inclusion_set_ret
< 0) {
402 status
= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
;
405 *values
= tracker
->inclusion_set
;
411 enum lttng_process_attr_values_status
lttng_process_attr_values_get_count(
412 const struct lttng_process_attr_values
*values
,
415 enum lttng_process_attr_values_status status
=
416 LTTNG_PROCESS_ATTR_VALUES_STATUS_OK
;
418 if (!values
|| !count
) {
419 status
= LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID
;
423 *count
= _lttng_process_attr_values_get_count(values
);
428 enum lttng_process_attr_value_type
lttng_process_attr_values_get_type_at_index(
429 const struct lttng_process_attr_values
*values
,
432 enum lttng_process_attr_value_type type
;
433 const struct process_attr_value
*value
;
436 type
= LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID
;
440 if (_lttng_process_attr_values_get_count(values
) <= index
) {
441 type
= LTTNG_PROCESS_ATTR_VALUE_TYPE_INVALID
;
445 value
= lttng_process_attr_tracker_values_get_at_index(values
, index
);
451 #define DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER( \
452 value_type_name, value_type, expected_value_type) \
453 enum lttng_process_attr_values_status \
454 lttng_process_attr_values_get_##value_type_name##_at_index( \
455 const struct lttng_process_attr_values \
457 unsigned int index, \
458 value_type *out_value) \
460 enum lttng_process_attr_values_status status = \
461 LTTNG_PROCESS_ATTR_VALUES_STATUS_OK; \
462 const struct process_attr_value *value; \
465 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
469 if (_lttng_process_attr_values_get_count(values) <= index) { \
470 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID; \
474 value = lttng_process_attr_tracker_values_get_at_index( \
477 LTTNG_PROCESS_ATTR_VALUE_TYPE_##expected_value_type) { \
478 status = LTTNG_PROCESS_ATTR_VALUES_STATUS_INVALID_TYPE; \
481 *out_value = value->value.value_type_name; \
486 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(pid
, pid_t
, PID
);
487 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(uid
, uid_t
, UID
);
488 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(gid
, gid_t
, GID
);
489 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(user_name
, const char *, USER_NAME
);
490 DEFINE_LTTNG_PROCESS_ATTR_VALUES_GETTER(group_name
, const char *, GROUP_NAME
);
492 static enum lttng_error_code
handle_status_to_error_code(
493 enum lttng_process_attr_tracker_handle_status handle_status
)
495 switch (handle_status
) {
496 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
:
497 return LTTNG_ERR_INVALID
;
498 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_SESSION_DOES_NOT_EXIST
:
499 return LTTNG_ERR_SESSION_NOT_EXIST
;
500 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_COMMUNICATION_ERROR
:
501 return LTTNG_ERR_INVALID_PROTOCOL
;
502 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_EXISTS
:
503 return LTTNG_ERR_PID_TRACKED
;
504 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_MISSING
:
505 return LTTNG_ERR_PID_NOT_TRACKED
;
506 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
:
508 case LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_ERROR
:
511 return LTTNG_ERR_UNK
;
516 * Add PID to session tracker.
517 * Return 0 on success else a negative LTTng error code.
519 int lttng_track_pid(struct lttng_handle
*handle
, int pid
)
521 enum lttng_error_code ret_code
;
522 struct lttng_process_attr_tracker_handle
*tracker_handle
= NULL
;
523 enum lttng_process_attr_tracker_handle_status handle_status
;
524 enum lttng_tracking_policy policy
;
525 enum lttng_process_attr process_attr
;
528 ret_code
= LTTNG_ERR_INVALID
;
532 process_attr
= handle
->domain
.type
== LTTNG_DOMAIN_KERNEL
?
533 LTTNG_PROCESS_ATTR_PROCESS_ID
:
534 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID
;
536 ret_code
= lttng_session_get_tracker_handle(handle
->session_name
,
538 process_attr
, &tracker_handle
);
539 if (ret_code
!= LTTNG_OK
) {
544 handle_status
= lttng_process_attr_tracker_handle_set_tracking_policy(
546 LTTNG_TRACKING_POLICY_INCLUDE_ALL
);
547 ret_code
= handle_status_to_error_code(handle_status
);
551 handle_status
= lttng_process_attr_tracker_handle_get_tracking_policy(
552 tracker_handle
, &policy
);
553 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
554 ret_code
= handle_status_to_error_code(handle_status
);
558 if (policy
!= LTTNG_TRACKING_POLICY_INCLUDE_SET
) {
559 handle_status
= lttng_process_attr_tracker_handle_set_tracking_policy(
561 LTTNG_TRACKING_POLICY_INCLUDE_SET
);
562 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
563 ret_code
= handle_status_to_error_code(handle_status
);
568 handle_status
= process_attr
== LTTNG_PROCESS_ATTR_PROCESS_ID
?
569 lttng_process_attr_process_id_tracker_handle_add_pid(
572 lttng_process_attr_virtual_process_id_tracker_handle_add_pid(
575 ret_code
= handle_status_to_error_code(handle_status
);
577 lttng_process_attr_tracker_handle_destroy(tracker_handle
);
578 return ret_code
== LTTNG_OK
? 0 : -ret_code
;
582 * Remove PID from session tracker.
583 * Return 0 on success else a negative LTTng error code.
585 int lttng_untrack_pid(struct lttng_handle
*handle
, int pid
)
587 enum lttng_error_code ret_code
;
588 struct lttng_process_attr_tracker_handle
*tracker_handle
= NULL
;
589 enum lttng_process_attr_tracker_handle_status handle_status
;
590 enum lttng_tracking_policy policy
;
591 enum lttng_process_attr process_attr
;
594 ret_code
= LTTNG_ERR_INVALID
;
598 process_attr
= handle
->domain
.type
== LTTNG_DOMAIN_KERNEL
?
599 LTTNG_PROCESS_ATTR_PROCESS_ID
:
600 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID
;
601 ret_code
= lttng_session_get_tracker_handle(handle
->session_name
,
602 handle
->domain
.type
, process_attr
, &tracker_handle
);
603 if (ret_code
!= LTTNG_OK
) {
608 handle_status
= lttng_process_attr_tracker_handle_set_tracking_policy(
610 LTTNG_TRACKING_POLICY_EXCLUDE_ALL
);
611 ret_code
= handle_status_to_error_code(handle_status
);
615 handle_status
= lttng_process_attr_tracker_handle_get_tracking_policy(
616 tracker_handle
, &policy
);
617 if (handle_status
!= LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
618 ret_code
= handle_status_to_error_code(handle_status
);
622 if (policy
== LTTNG_TRACKING_POLICY_EXCLUDE_ALL
) {
623 ret_code
= LTTNG_ERR_PID_NOT_TRACKED
;
625 } else if (policy
== LTTNG_TRACKING_POLICY_INCLUDE_ALL
) {
626 ret_code
= LTTNG_ERR_INVALID
;
630 handle_status
= process_attr
== LTTNG_PROCESS_ATTR_PROCESS_ID
?
631 lttng_process_attr_process_id_tracker_handle_remove_pid(
634 lttng_process_attr_virtual_process_id_tracker_handle_remove_pid(
637 if (handle_status
== LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
) {
638 ret_code
= LTTNG_ERR_PID_NOT_TRACKED
;
641 lttng_process_attr_tracker_handle_destroy(tracker_handle
);
642 return ret_code
== LTTNG_OK
? 0 : -ret_code
;
646 * List PIDs in the tracker.
648 * enabled is set to whether the PID tracker is enabled.
649 * pids is set to an allocated array of PIDs currently tracked. On
650 * success, pids must be freed by the caller.
651 * nr_pids is set to the number of entries contained by the pids array.
653 * Returns 0 on success, else a negative LTTng error code.
655 int lttng_list_tracker_pids(struct lttng_handle
*handle
,
660 enum lttng_error_code ret_code
;
661 struct lttng_process_attr_tracker_handle
*tracker_handle
= NULL
;
662 enum lttng_process_attr_tracker_handle_status handle_status
;
663 const struct lttng_process_attr_values
*values
;
664 enum lttng_tracking_policy policy
;
665 unsigned int pid_count
, i
;
666 int32_t *pid_array
= NULL
;
668 if (!handle
|| !_enabled
|| !_pids
|| !_nr_pids
) {
669 ret_code
= LTTNG_ERR_INVALID
;
673 ret_code
= lttng_session_get_tracker_handle(handle
->session_name
,
675 LTTNG_PROCESS_ATTR_VIRTUAL_PROCESS_ID
, &tracker_handle
);
676 if (ret_code
!= LTTNG_OK
) {
681 handle_status
= lttng_process_attr_tracker_handle_get_inclusion_set(
682 tracker_handle
, &values
);
684 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
685 policy
= LTTNG_TRACKING_POLICY_INCLUDE_SET
;
687 } else if (handle_status
!=
688 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_INVALID_TRACKING_POLICY
) {
689 ret_code
= handle_status_to_error_code(handle_status
);
693 handle_status
= lttng_process_attr_tracker_handle_get_tracking_policy(
694 tracker_handle
, &policy
);
696 LTTNG_PROCESS_ATTR_TRACKER_HANDLE_STATUS_OK
) {
697 ret_code
= handle_status_to_error_code(handle_status
);
701 /* Tracking policy changed in the meantime, retry. */
702 if (policy
== LTTNG_TRACKING_POLICY_INCLUDE_SET
) {
709 case LTTNG_TRACKING_POLICY_INCLUDE_ALL
:
712 case LTTNG_TRACKING_POLICY_EXCLUDE_ALL
:
716 case LTTNG_TRACKING_POLICY_INCLUDE_SET
:
718 const enum lttng_process_attr_values_status values_status
=
719 lttng_process_attr_values_get_count(
722 if (values_status
!= LTTNG_PROCESS_ATTR_VALUES_STATUS_OK
) {
723 ret_code
= LTTNG_ERR_UNK
;
729 ret_code
= LTTNG_ERR_INVALID_PROTOCOL
;
733 pid_array
= zmalloc(pid_count
* sizeof(int32_t));
735 ret_code
= LTTNG_ERR_NOMEM
;
739 /* Extract values to a raw array. */
740 for (i
= 0; i
< pid_count
; i
++) {
742 const enum lttng_process_attr_values_status values_status
=
743 lttng_process_attr_values_get_pid_at_index(
746 if (values_status
!= LTTNG_PROCESS_ATTR_VALUES_STATUS_OK
) {
747 ret_code
= LTTNG_ERR_UNK
;
750 pid_array
[i
] = (int32_t) pid
;
752 *_nr_pids
= (size_t) pid_count
;
756 lttng_process_attr_tracker_handle_destroy(tracker_handle
);
758 return ret_code
== LTTNG_OK
? 0 : -ret_code
;