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