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