Refactor: lttng-ctl: follow terminology of the tracker documentation
[lttng-tools.git] / src / bin / lttng-sessiond / tracker.c
CommitLineData
a8c3ad3e 1/*
ab5be9fa 2 * Copyright (C) 2018 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
159b042f 3 * Copyright (C) 2020 Jérémie Galarneau <jeremie.galarneau@efficios.com>
a8c3ad3e 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
a8c3ad3e 6 *
a8c3ad3e
MD
7 */
8
159b042f
JG
9#include "lttng/tracker.h"
10#include "common/dynamic-array.h"
11#include "common/macros.h"
a8c3ad3e
MD
12#define _LGPL_SOURCE
13#include <grp.h>
14#include <pwd.h>
15#include <sys/types.h>
16#include <unistd.h>
159b042f
JG
17#include <urcu.h>
18#include <urcu/list.h>
19#include <urcu/rculfhash.h>
a8c3ad3e
MD
20
21#include "tracker.h"
22#include <common/defaults.h>
23#include <common/error.h>
24#include <common/hashtable/hashtable.h>
25#include <common/hashtable/utils.h>
159b042f 26#include <common/tracker.h>
a8c3ad3e
MD
27#include <lttng/lttng-error.h>
28
159b042f
JG
29struct process_attr_tracker_value_node {
30 struct process_attr_value *value;
31 struct cds_lfht_node inclusion_set_ht_node;
32 struct rcu_head rcu_head;
33};
a8c3ad3e 34
159b042f
JG
35struct process_attr_tracker {
36 enum lttng_tracking_policy policy;
37 struct cds_lfht *inclusion_set_ht;
38};
39
40static void process_attr_tracker_value_node_rcu_free(struct rcu_head *rcu_head)
41{
42 struct process_attr_tracker_value_node *node =
43 container_of(rcu_head, typeof(*node), rcu_head);
44
45 free(node);
46}
47
48struct process_attr_tracker *process_attr_tracker_create(void)
a8c3ad3e 49{
159b042f 50 struct process_attr_tracker *tracker;
a8c3ad3e 51
159b042f
JG
52 tracker = zmalloc(sizeof(*tracker));
53 if (!tracker) {
a8c3ad3e
MD
54 return NULL;
55 }
159b042f
JG
56
57 (void) process_attr_tracker_set_tracking_policy(
58 tracker, LTTNG_TRACKING_POLICY_INCLUDE_ALL);
59
60 tracker->inclusion_set_ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
a8c3ad3e 61 CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
159b042f 62 if (!tracker->inclusion_set_ht) {
a8c3ad3e
MD
63 goto error;
64 }
a8c3ad3e 65
159b042f 66 return tracker;
a8c3ad3e 67error:
159b042f 68 process_attr_tracker_destroy(tracker);
a8c3ad3e
MD
69 return NULL;
70}
71
159b042f
JG
72static void process_attr_tracker_remove_value_node(
73 struct process_attr_tracker *tracker,
74 struct process_attr_tracker_value_node *value_node)
a8c3ad3e 75{
159b042f
JG
76 cds_lfht_del(tracker->inclusion_set_ht,
77 &value_node->inclusion_set_ht_node);
78 process_attr_value_destroy(value_node->value);
79 call_rcu(&value_node->rcu_head,
80 process_attr_tracker_value_node_rcu_free);
a8c3ad3e
MD
81}
82
159b042f
JG
83static void process_attr_tracker_clear_inclusion_set(
84 struct process_attr_tracker *tracker)
a8c3ad3e 85{
159b042f
JG
86 int ret;
87 struct lttng_ht_iter iter;
88 struct process_attr_tracker_value_node *value_node;
a8c3ad3e 89
159b042f
JG
90 if (!tracker->inclusion_set_ht) {
91 return;
92 }
a8c3ad3e 93
159b042f
JG
94 rcu_read_lock();
95 cds_lfht_for_each_entry (tracker->inclusion_set_ht, &iter.iter,
96 value_node, inclusion_set_ht_node) {
97 process_attr_tracker_remove_value_node(tracker, value_node);
a8c3ad3e 98 }
159b042f
JG
99 rcu_read_unlock();
100 ret = cds_lfht_destroy(tracker->inclusion_set_ht, NULL);
101 assert(ret == 0);
102 tracker->inclusion_set_ht = NULL;
a8c3ad3e
MD
103}
104
159b042f
JG
105static int process_attr_tracker_create_inclusion_set(
106 struct process_attr_tracker *tracker)
a8c3ad3e 107{
159b042f
JG
108 assert(!tracker->inclusion_set_ht);
109 tracker->inclusion_set_ht = cds_lfht_new(DEFAULT_HT_SIZE, 1, 0,
110 CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
111 return tracker->inclusion_set_ht ? 0 : -1;
a8c3ad3e
MD
112}
113
159b042f 114void process_attr_tracker_destroy(struct process_attr_tracker *tracker)
a8c3ad3e 115{
159b042f
JG
116 if (!tracker) {
117 return;
118 }
a8c3ad3e 119
159b042f
JG
120 process_attr_tracker_clear_inclusion_set(tracker);
121 free(tracker);
a8c3ad3e
MD
122}
123
159b042f
JG
124enum lttng_tracking_policy process_attr_tracker_get_tracking_policy(
125 const struct process_attr_tracker *tracker)
a8c3ad3e 126{
159b042f 127 return tracker->policy;
a8c3ad3e
MD
128}
129
159b042f
JG
130int process_attr_tracker_set_tracking_policy(
131 struct process_attr_tracker *tracker,
132 enum lttng_tracking_policy tracking_policy)
a8c3ad3e 133{
159b042f 134 int ret = 0;
a8c3ad3e 135
159b042f
JG
136 if (tracker->policy == tracking_policy) {
137 goto end;
a8c3ad3e 138 }
2d97a006 139
159b042f
JG
140 process_attr_tracker_clear_inclusion_set(tracker);
141 ret = process_attr_tracker_create_inclusion_set(tracker);
142 if (ret) {
143 goto end;
a8c3ad3e 144 }
159b042f
JG
145 tracker->policy = tracking_policy;
146end:
a8c3ad3e
MD
147 return ret;
148}
149
159b042f
JG
150static int match_inclusion_set_value(
151 struct cds_lfht_node *node, const void *key)
a8c3ad3e 152{
159b042f
JG
153 const struct process_attr_value *value_key = key;
154 const struct process_attr_tracker_value_node *value_node =
155 caa_container_of(node,
156 struct process_attr_tracker_value_node,
157 inclusion_set_ht_node);
a8c3ad3e 158
159b042f
JG
159 return process_attr_tracker_value_equal(value_node->value, value_key);
160}
a8c3ad3e 161
159b042f
JG
162static struct process_attr_tracker_value_node *process_attr_tracker_lookup(
163 const struct process_attr_tracker *tracker,
164 const struct process_attr_value *value)
165{
166 struct cds_lfht_iter iter;
167 struct cds_lfht_node *node;
a8c3ad3e 168
159b042f
JG
169 assert(tracker->policy == LTTNG_TRACKING_POLICY_INCLUDE_SET);
170
171 rcu_read_lock();
172 cds_lfht_lookup(tracker->inclusion_set_ht,
173 process_attr_value_hash(value),
174 match_inclusion_set_value, value, &iter);
175 node = cds_lfht_iter_get_node(&iter);
a8c3ad3e 176 rcu_read_unlock();
159b042f
JG
177
178 return node ? container_of(node, struct process_attr_tracker_value_node,
179 inclusion_set_ht_node) :
180 NULL;
a8c3ad3e
MD
181}
182
159b042f
JG
183/* Protected by session mutex held by caller. */
184enum process_attr_tracker_status process_attr_tracker_inclusion_set_add_value(
185 struct process_attr_tracker *tracker,
186 const struct process_attr_value *value)
a8c3ad3e 187{
159b042f
JG
188 enum process_attr_tracker_status status =
189 PROCESS_ATTR_TRACKER_STATUS_OK;
190 struct process_attr_value *value_copy = NULL;
191 struct process_attr_tracker_value_node *value_node = NULL;
b7e1aba3 192
159b042f
JG
193 rcu_read_lock();
194 if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
195 status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
196 goto end;
a8c3ad3e 197 }
a8c3ad3e 198
159b042f
JG
199 if (process_attr_tracker_lookup(tracker, value)) {
200 status = PROCESS_ATTR_TRACKER_STATUS_EXISTS;
a8c3ad3e
MD
201 goto end;
202 }
a8c3ad3e 203
159b042f
JG
204 value_node = zmalloc(sizeof(*value_node));
205 if (!value_node) {
206 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
207 goto end;
a8c3ad3e 208 }
159b042f
JG
209
210 value_copy = process_attr_value_copy(value);
211 if (!value_copy) {
212 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
a8c3ad3e
MD
213 goto end;
214 }
159b042f
JG
215
216 value_node->value = value_copy;
217 cds_lfht_add(tracker->inclusion_set_ht,
218 process_attr_value_hash(value_copy),
219 &value_node->inclusion_set_ht_node);
220 value_copy = NULL;
221 value_node = NULL;
222end:
223 if (value_copy) {
224 process_attr_value_destroy(value_copy);
a8c3ad3e 225 }
159b042f
JG
226 if (value_node) {
227 free(value_node);
a8c3ad3e 228 }
159b042f
JG
229 rcu_read_unlock();
230 return status;
a8c3ad3e
MD
231}
232
159b042f
JG
233/* Protected by session mutex held by caller. */
234enum process_attr_tracker_status
235process_attr_tracker_inclusion_set_remove_value(
236 struct process_attr_tracker *tracker,
237 const struct process_attr_value *value)
a8c3ad3e 238{
159b042f
JG
239 struct process_attr_tracker_value_node *value_node;
240 enum process_attr_tracker_status status =
241 PROCESS_ATTR_TRACKER_STATUS_OK;
a8c3ad3e 242
159b042f
JG
243 rcu_read_lock();
244 if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
245 status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
246 goto end;
247 }
a7a533cd 248
159b042f
JG
249 value_node = process_attr_tracker_lookup(tracker, value);
250 if (!value_node) {
251 status = PROCESS_ATTR_TRACKER_STATUS_MISSING;
252 goto end;
a8c3ad3e 253 }
a7a533cd 254
159b042f 255 process_attr_tracker_remove_value_node(tracker, value_node);
a8c3ad3e 256end:
159b042f
JG
257 rcu_read_unlock();
258 return status;
a8c3ad3e
MD
259}
260
159b042f
JG
261enum process_attr_tracker_status process_attr_tracker_get_inclusion_set(
262 const struct process_attr_tracker *tracker,
263 struct lttng_process_attr_values **_values)
a8c3ad3e 264{
159b042f
JG
265 struct lttng_ht_iter iter;
266 struct process_attr_tracker_value_node *value_node;
267 enum process_attr_tracker_status status =
268 PROCESS_ATTR_TRACKER_STATUS_OK;
269 struct lttng_process_attr_values *values;
270 struct process_attr_value *new_value = NULL;
271
272 values = lttng_process_attr_values_create();
273 if (!values) {
274 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
275 goto error;
e283e4a0 276 }
a7a533cd 277
159b042f
JG
278 if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
279 status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
280 goto error;
a8c3ad3e 281 }
a7a533cd 282
159b042f
JG
283 rcu_read_lock();
284 cds_lfht_for_each_entry (tracker->inclusion_set_ht, &iter.iter,
285 value_node, inclusion_set_ht_node) {
286 int ret;
287
288 new_value = process_attr_value_copy(value_node->value);
289 if (!new_value) {
290 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
291 goto error_unlock;
a7a533cd 292 }
a7a533cd 293
159b042f
JG
294 ret = lttng_dynamic_pointer_array_add_pointer(
295 &values->array, new_value);
296 if (ret) {
297 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
298 goto error_unlock;
a8c3ad3e 299 }
159b042f
JG
300
301 new_value = NULL;
a8c3ad3e 302 }
159b042f
JG
303 rcu_read_unlock();
304 *_values = values;
305 return status;
306error_unlock:
307 rcu_read_unlock();
308error:
309 lttng_process_attr_values_destroy(values);
310 process_attr_value_destroy(new_value);
311 return status;
a8c3ad3e 312}
This page took 0.03807 seconds and 4 git commands to generate.