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