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