Clean-up: modernize pretty_xml.cpp
[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 "lttng/tracker.h"
10#include "common/dynamic-array.hpp"
11#include "common/macros.hpp"
12#define _LGPL_SOURCE
13#include <grp.h>
14#include <pwd.h>
15#include <sys/types.h>
16#include <unistd.h>
17#include <urcu.h>
18#include <urcu/list.h>
19#include <urcu/rculfhash.h>
20
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>
27#include <lttng/lttng-error.h>
28
29struct process_attr_tracker {
30 enum lttng_tracking_policy policy;
31 struct cds_lfht *inclusion_set_ht;
32};
33
34namespace {
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};
40} /* namespace */
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)
51{
52 struct process_attr_tracker *tracker;
53
54 tracker = zmalloc<process_attr_tracker>();
55 if (!tracker) {
56 return NULL;
57 }
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,
63 CDS_LFHT_AUTO_RESIZE | CDS_LFHT_ACCOUNTING, NULL);
64 if (!tracker->inclusion_set_ht) {
65 goto error;
66 }
67
68 return tracker;
69error:
70 process_attr_tracker_destroy(tracker);
71 return NULL;
72}
73
74static void process_attr_tracker_remove_value_node(
75 struct process_attr_tracker *tracker,
76 struct process_attr_tracker_value_node *value_node)
77{
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);
83}
84
85static void process_attr_tracker_clear_inclusion_set(
86 struct process_attr_tracker *tracker)
87{
88 int ret;
89 struct lttng_ht_iter iter;
90 struct process_attr_tracker_value_node *value_node;
91
92 if (!tracker->inclusion_set_ht) {
93 return;
94 }
95
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);
100 }
101 rcu_read_unlock();
102 ret = cds_lfht_destroy(tracker->inclusion_set_ht, NULL);
103 LTTNG_ASSERT(ret == 0);
104 tracker->inclusion_set_ht = NULL;
105}
106
107static int process_attr_tracker_create_inclusion_set(
108 struct process_attr_tracker *tracker)
109{
110 LTTNG_ASSERT(!tracker->inclusion_set_ht);
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;
114}
115
116void process_attr_tracker_destroy(struct process_attr_tracker *tracker)
117{
118 if (!tracker) {
119 return;
120 }
121
122 process_attr_tracker_clear_inclusion_set(tracker);
123 free(tracker);
124}
125
126enum lttng_tracking_policy process_attr_tracker_get_tracking_policy(
127 const struct process_attr_tracker *tracker)
128{
129 return tracker->policy;
130}
131
132int process_attr_tracker_set_tracking_policy(
133 struct process_attr_tracker *tracker,
134 enum lttng_tracking_policy tracking_policy)
135{
136 int ret = 0;
137
138 if (tracker->policy == tracking_policy) {
139 goto end;
140 }
141
142 process_attr_tracker_clear_inclusion_set(tracker);
143 ret = process_attr_tracker_create_inclusion_set(tracker);
144 if (ret) {
145 goto end;
146 }
147 tracker->policy = tracking_policy;
148end:
149 return ret;
150}
151
152static int match_inclusion_set_value(
153 struct cds_lfht_node *node, const void *key)
154{
155 const struct process_attr_value *value_key = (process_attr_value *) key;
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);
160
161 return process_attr_tracker_value_equal(value_node->value, value_key);
162}
163
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;
170
171 LTTNG_ASSERT(tracker->policy == LTTNG_TRACKING_POLICY_INCLUDE_SET);
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);
178 rcu_read_unlock();
179
180 return node ? container_of(node, struct process_attr_tracker_value_node,
181 inclusion_set_ht_node) :
182 NULL;
183}
184
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)
189{
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;
194
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;
199 }
200
201 if (process_attr_tracker_lookup(tracker, value)) {
202 status = PROCESS_ATTR_TRACKER_STATUS_EXISTS;
203 goto end;
204 }
205
206 value_node = zmalloc<process_attr_tracker_value_node>();
207 if (!value_node) {
208 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
209 goto end;
210 }
211
212 value_copy = process_attr_value_copy(value);
213 if (!value_copy) {
214 status = PROCESS_ATTR_TRACKER_STATUS_ERROR;
215 goto end;
216 }
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);
227 }
228 if (value_node) {
229 free(value_node);
230 }
231 rcu_read_unlock();
232 return status;
233}
234
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)
240{
241 struct process_attr_tracker_value_node *value_node;
242 enum process_attr_tracker_status status =
243 PROCESS_ATTR_TRACKER_STATUS_OK;
244
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 }
250
251 value_node = process_attr_tracker_lookup(tracker, value);
252 if (!value_node) {
253 status = PROCESS_ATTR_TRACKER_STATUS_MISSING;
254 goto end;
255 }
256
257 process_attr_tracker_remove_value_node(tracker, value_node);
258end:
259 rcu_read_unlock();
260 return status;
261}
262
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)
266{
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;
278 }
279
280 if (tracker->policy != LTTNG_TRACKING_POLICY_INCLUDE_SET) {
281 status = PROCESS_ATTR_TRACKER_STATUS_INVALID_TRACKING_POLICY;
282 goto error;
283 }
284
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;
294 }
295
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;
301 }
302
303 new_value = NULL;
304 }
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;
314}
This page took 0.023125 seconds and 4 git commands to generate.