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