clang-tidy: add Chrome-inspired checks
[lttng-tools.git] / src / bin / lttng-sessiond / tracker.cpp
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
c9e313bc
SM
9#include "common/dynamic-array.hpp"
10#include "common/macros.hpp"
28ab034a 11#include "lttng/tracker.h"
a8c3ad3e 12#define _LGPL_SOURCE
c9e313bc 13#include "tracker.hpp"
28ab034a 14
c9e313bc
SM
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>
28ab034a 20
a8c3ad3e
MD
21#include <lttng/lttng-error.h>
22
28ab034a
JG
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
f1494934
JG
31struct process_attr_tracker {
32 enum lttng_tracking_policy policy;
33 struct cds_lfht *inclusion_set_ht;
34};
35
36namespace {
159b042f
JG
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};
f1494934 42} /* namespace */
159b042f
JG
43
44static void process_attr_tracker_value_node_rcu_free(struct rcu_head *rcu_head)
45{
28ab034a
JG
46 struct process_attr_tracker_value_node *node =
47 lttng::utils::container_of(rcu_head, &process_attr_tracker_value_node::rcu_head);
159b042f
JG
48
49 free(node);
50}
51
cd9adb8b 52struct process_attr_tracker *process_attr_tracker_create()
a8c3ad3e 53{
159b042f 54 struct process_attr_tracker *tracker;
a8c3ad3e 55
64803277 56 tracker = zmalloc<process_attr_tracker>();
159b042f 57 if (!tracker) {
cd9adb8b 58 return nullptr;
a8c3ad3e 59 }
159b042f 60
28ab034a 61 (void) process_attr_tracker_set_tracking_policy(tracker, LTTNG_TRACKING_POLICY_INCLUDE_ALL);
159b042f 62
28ab034a 63 tracker->inclusion_set_ht = cds_lfht_new(
cd9adb8b 64 DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr);
159b042f 65 if (!tracker->inclusion_set_ht) {
a8c3ad3e
MD
66 goto error;
67 }
a8c3ad3e 68
159b042f 69 return tracker;
a8c3ad3e 70error:
159b042f 71 process_attr_tracker_destroy(tracker);
cd9adb8b 72 return nullptr;
a8c3ad3e
MD
73}
74
28ab034a
JG
75static void
76process_attr_tracker_remove_value_node(struct process_attr_tracker *tracker,
77 struct process_attr_tracker_value_node *value_node)
a8c3ad3e 78{
28ab034a 79 cds_lfht_del(tracker->inclusion_set_ht, &value_node->inclusion_set_ht_node);
159b042f 80 process_attr_value_destroy(value_node->value);
28ab034a 81 call_rcu(&value_node->rcu_head, process_attr_tracker_value_node_rcu_free);
a8c3ad3e
MD
82}
83
28ab034a 84static void process_attr_tracker_clear_inclusion_set(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 94 rcu_read_lock();
28ab034a
JG
95 cds_lfht_for_each_entry (
96 tracker->inclusion_set_ht, &iter.iter, value_node, inclusion_set_ht_node) {
159b042f 97 process_attr_tracker_remove_value_node(tracker, value_node);
a8c3ad3e 98 }
159b042f 99 rcu_read_unlock();
cd9adb8b 100 ret = cds_lfht_destroy(tracker->inclusion_set_ht, nullptr);
a0377dfe 101 LTTNG_ASSERT(ret == 0);
cd9adb8b 102 tracker->inclusion_set_ht = nullptr;
a8c3ad3e
MD
103}
104
28ab034a 105static int process_attr_tracker_create_inclusion_set(struct process_attr_tracker *tracker)
a8c3ad3e 106{
a0377dfe 107 LTTNG_ASSERT(!tracker->inclusion_set_ht);
28ab034a 108 tracker->inclusion_set_ht = cds_lfht_new(
cd9adb8b 109 DEFAULT_HT_SIZE, 1, 0, CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, nullptr);
159b042f 110 return tracker->inclusion_set_ht ? 0 : -1;
a8c3ad3e
MD
111}
112
159b042f 113void process_attr_tracker_destroy(struct process_attr_tracker *tracker)
a8c3ad3e 114{
159b042f
JG
115 if (!tracker) {
116 return;
117 }
a8c3ad3e 118
159b042f
JG
119 process_attr_tracker_clear_inclusion_set(tracker);
120 free(tracker);
a8c3ad3e
MD
121}
122
28ab034a
JG
123enum lttng_tracking_policy
124process_attr_tracker_get_tracking_policy(const struct process_attr_tracker *tracker)
a8c3ad3e 125{
159b042f 126 return tracker->policy;
a8c3ad3e
MD
127}
128
28ab034a
JG
129int process_attr_tracker_set_tracking_policy(struct process_attr_tracker *tracker,
130 enum lttng_tracking_policy tracking_policy)
a8c3ad3e 131{
159b042f 132 int ret = 0;
a8c3ad3e 133
159b042f
JG
134 if (tracker->policy == tracking_policy) {
135 goto end;
a8c3ad3e 136 }
2d97a006 137
159b042f
JG
138 process_attr_tracker_clear_inclusion_set(tracker);
139 ret = process_attr_tracker_create_inclusion_set(tracker);
140 if (ret) {
141 goto end;
a8c3ad3e 142 }
159b042f
JG
143 tracker->policy = tracking_policy;
144end:
a8c3ad3e
MD
145 return ret;
146}
147
28ab034a 148static int match_inclusion_set_value(struct cds_lfht_node *node, const void *key)
a8c3ad3e 149{
7966af57 150 const struct process_attr_value *value_key = (process_attr_value *) key;
28ab034a
JG
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);
a8c3ad3e 153
159b042f
JG
154 return process_attr_tracker_value_equal(value_node->value, value_key);
155}
a8c3ad3e 156
28ab034a
JG
157static struct process_attr_tracker_value_node *
158process_attr_tracker_lookup(const struct process_attr_tracker *tracker,
159 const struct process_attr_value *value)
159b042f
JG
160{
161 struct cds_lfht_iter iter;
162 struct cds_lfht_node *node;
a8c3ad3e 163
a0377dfe 164 LTTNG_ASSERT(tracker->policy == LTTNG_TRACKING_POLICY_INCLUDE_SET);
159b042f
JG
165
166 rcu_read_lock();
167 cds_lfht_lookup(tracker->inclusion_set_ht,
168 process_attr_value_hash(value),
28ab034a
JG
169 match_inclusion_set_value,
170 value,
171 &iter);
159b042f 172 node = cds_lfht_iter_get_node(&iter);
a8c3ad3e 173 rcu_read_unlock();
159b042f 174
28ab034a
JG
175 return node ? lttng::utils::container_of(
176 node, &process_attr_tracker_value_node::inclusion_set_ht_node) :
cd9adb8b 177 nullptr;
a8c3ad3e
MD
178}
179
159b042f 180/* Protected by session mutex held by caller. */
28ab034a
JG
181enum process_attr_tracker_status
182process_attr_tracker_inclusion_set_add_value(struct process_attr_tracker *tracker,
183 const struct process_attr_value *value)
a8c3ad3e 184{
28ab034a 185 enum process_attr_tracker_status status = PROCESS_ATTR_TRACKER_STATUS_OK;
cd9adb8b
JG
186 struct process_attr_value *value_copy = nullptr;
187 struct process_attr_tracker_value_node *value_node = nullptr;
b7e1aba3 188
159b042f
JG
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;
a8c3ad3e 193 }
a8c3ad3e 194
159b042f
JG
195 if (process_attr_tracker_lookup(tracker, value)) {
196 status = PROCESS_ATTR_TRACKER_STATUS_EXISTS;
a8c3ad3e
MD
197 goto end;
198 }
a8c3ad3e 199
64803277 200 value_node = zmalloc<process_attr_tracker_value_node>();
159b042f
JG
201 if (!value_node) {
202 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
203 goto end;
a8c3ad3e 204 }
159b042f
JG
205
206 value_copy = process_attr_value_copy(value);
207 if (!value_copy) {
208 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
a8c3ad3e
MD
209 goto end;
210 }
159b042f
JG
211
212 value_node->value = value_copy;
213 cds_lfht_add(tracker->inclusion_set_ht,
28ab034a
JG
214 process_attr_value_hash(value_copy),
215 &value_node->inclusion_set_ht_node);
cd9adb8b
JG
216 value_copy = nullptr;
217 value_node = nullptr;
159b042f
JG
218end:
219 if (value_copy) {
220 process_attr_value_destroy(value_copy);
a8c3ad3e 221 }
159b042f
JG
222 if (value_node) {
223 free(value_node);
a8c3ad3e 224 }
159b042f
JG
225 rcu_read_unlock();
226 return status;
a8c3ad3e
MD
227}
228
159b042f
JG
229/* Protected by session mutex held by caller. */
230enum process_attr_tracker_status
28ab034a
JG
231process_attr_tracker_inclusion_set_remove_value(struct process_attr_tracker *tracker,
232 const struct process_attr_value *value)
a8c3ad3e 233{
159b042f 234 struct process_attr_tracker_value_node *value_node;
28ab034a 235 enum process_attr_tracker_status status = PROCESS_ATTR_TRACKER_STATUS_OK;
a8c3ad3e 236
159b042f
JG
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 }
a7a533cd 242
159b042f
JG
243 value_node = process_attr_tracker_lookup(tracker, value);
244 if (!value_node) {
245 status = PROCESS_ATTR_TRACKER_STATUS_MISSING;
246 goto end;
a8c3ad3e 247 }
a7a533cd 248
159b042f 249 process_attr_tracker_remove_value_node(tracker, value_node);
a8c3ad3e 250end:
159b042f
JG
251 rcu_read_unlock();
252 return status;
a8c3ad3e
MD
253}
254
28ab034a
JG
255enum process_attr_tracker_status
256process_attr_tracker_get_inclusion_set(const struct process_attr_tracker *tracker,
257 struct lttng_process_attr_values **_values)
a8c3ad3e 258{
159b042f
JG
259 struct lttng_ht_iter iter;
260 struct process_attr_tracker_value_node *value_node;
28ab034a 261 enum process_attr_tracker_status status = PROCESS_ATTR_TRACKER_STATUS_OK;
159b042f 262 struct lttng_process_attr_values *values;
cd9adb8b 263 struct process_attr_value *new_value = nullptr;
159b042f
JG
264
265 values = lttng_process_attr_values_create();
266 if (!values) {
267 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
268 goto error;
e283e4a0 269 }
a7a533cd 270
159b042f
JG
271 if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
272 status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
273 goto error;
a8c3ad3e 274 }
a7a533cd 275
159b042f 276 rcu_read_lock();
28ab034a
JG
277 cds_lfht_for_each_entry (
278 tracker->inclusion_set_ht, &iter.iter, value_node, inclusion_set_ht_node) {
159b042f
JG
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;
a7a533cd 285 }
a7a533cd 286
28ab034a 287 ret = lttng_dynamic_pointer_array_add_pointer(&values->array, new_value);
159b042f
JG
288 if (ret) {
289 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
290 goto error_unlock;
a8c3ad3e 291 }
159b042f 292
cd9adb8b 293 new_value = nullptr;
a8c3ad3e 294 }
159b042f
JG
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;
a8c3ad3e 304}
This page took 0.061089 seconds and 4 git commands to generate.