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