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