Fix: relayd: register listener threads as rcu readers
[lttng-tools.git] / src / common / tracker.c
CommitLineData
2d97a006 1/*
ab5be9fa 2 * Copyright (C) 2019 Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
2d97a006 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
2d97a006 5 *
2d97a006
JR
6 */
7
8#include <assert.h>
9#include <common/defaults.h>
10#include <common/error.h>
11#include <common/macros.h>
12#include <common/sessiond-comm/sessiond-comm.h>
13#include <common/uri.h>
14#include <lttng/tracker-internal.h>
15#include <stdio.h>
16#include <time.h>
17
18struct lttng_tracker_id *lttng_tracker_id_create(void)
19{
20 struct lttng_tracker_id *id;
21
22 id = zmalloc(sizeof(*id));
23 if (!id) {
24 goto error;
25 }
26
27 id->type = LTTNG_ID_UNKNOWN;
28 id->string = NULL;
29 id->value = -1;
30 return id;
31error:
32 lttng_tracker_id_destroy(id);
33 return NULL;
34}
35
36enum lttng_tracker_id_status lttng_tracker_id_set_value(
37 struct lttng_tracker_id *id, int value)
38{
39 assert(id);
40
41 if (value < 0) {
42 return LTTNG_TRACKER_ID_STATUS_INVALID;
43 }
44
45 id->type = LTTNG_ID_VALUE;
46 id->value = value;
47 return LTTNG_TRACKER_ID_STATUS_OK;
48}
49
50enum lttng_tracker_id_status lttng_tracker_id_set_string(
51 struct lttng_tracker_id *id, const char *value)
52{
53 assert(id);
54 assert(value);
55
56 id->type = LTTNG_ID_STRING;
57 id->string = strdup(value);
58 if (id->string == NULL) {
59 /* No memory left */
60 goto error;
61 }
62
63 return LTTNG_TRACKER_ID_STATUS_OK;
64error:
65 return LTTNG_TRACKER_ID_STATUS_INVALID;
66}
67
68enum lttng_tracker_id_status lttng_tracker_id_set_all(
69 struct lttng_tracker_id *id)
70{
71 assert(id);
72
73 id->type = LTTNG_ID_ALL;
74
75 return LTTNG_TRACKER_ID_STATUS_OK;
76}
77
a7a533cd 78static void lttng_tracker_id_reset(struct lttng_tracker_id *id)
2d97a006
JR
79{
80 if (id == NULL) {
81 return;
82 }
83
84 if (id->string != NULL) {
85 free(id->string);
a7a533cd 86 id->string = NULL;
2d97a006
JR
87 }
88
a7a533cd
JR
89 id->type = LTTNG_ID_UNKNOWN;
90 id->value = -1;
2d97a006
JR
91}
92
a7a533cd 93void lttng_tracker_id_destroy(struct lttng_tracker_id *id)
2d97a006 94{
a7a533cd 95 if (id == NULL) {
2d97a006
JR
96 return;
97 }
98
a7a533cd
JR
99 lttng_tracker_id_reset(id);
100
101 free(id);
2d97a006
JR
102}
103
104enum lttng_tracker_id_type lttng_tracker_id_get_type(
105 const struct lttng_tracker_id *id)
106{
107 assert(id);
108 return id->type;
109}
110
111enum lttng_tracker_id_status lttng_tracker_id_get_value(
112 const struct lttng_tracker_id *id, int *value)
113{
114 assert(id);
115 if (id->type == LTTNG_ID_UNKNOWN) {
116 return LTTNG_TRACKER_ID_STATUS_UNSET;
117 }
118
119 if (id->type != LTTNG_ID_VALUE) {
120 return LTTNG_TRACKER_ID_STATUS_INVALID;
121 }
122
123 *value = id->value;
124 return LTTNG_TRACKER_ID_STATUS_OK;
125}
126
127bool lttng_tracker_id_is_equal(const struct lttng_tracker_id *left,
128 const struct lttng_tracker_id *right)
129{
130 if (left->type != right->type) {
131 return 0;
132 }
133
134 switch (left->type) {
135 case LTTNG_ID_ALL:
136 return 1;
137 case LTTNG_ID_VALUE:
138 if (left->value != right->value) {
139 return 0;
140 }
141 break;
142 case LTTNG_ID_STRING:
143 if (strcmp(left->string, right->string) != 0) {
144 return 0;
145 }
146 break;
147 default:
148 /*
149 * Normally this should return true, but comparing unset tracker
150 * id is "invalid".
151 */
152 return 0;
153 }
154 return 1;
155}
156
a7a533cd 157int lttng_tracker_id_copy(struct lttng_tracker_id *dest,
2d97a006
JR
158 const struct lttng_tracker_id *orig)
159{
a7a533cd 160 int ret = 0;
2d97a006
JR
161 enum lttng_tracker_id_status status;
162
a7a533cd
JR
163 assert(dest);
164 assert(orig);
2d97a006
JR
165
166 switch (orig->type) {
167 case LTTNG_ID_ALL:
a7a533cd 168 status = lttng_tracker_id_set_all(dest);
2d97a006
JR
169 break;
170 case LTTNG_ID_VALUE:
a7a533cd 171 status = lttng_tracker_id_set_value(dest, orig->value);
2d97a006
JR
172 break;
173 case LTTNG_ID_STRING:
a7a533cd 174 status = lttng_tracker_id_set_string(dest, orig->string);
2d97a006
JR
175 break;
176 default:
177 status = LTTNG_TRACKER_ID_STATUS_OK;
178 break;
179 }
180
181 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
a7a533cd
JR
182 ret = -1;
183 goto error;
184 }
185error:
186 return ret;
187}
188
189struct lttng_tracker_id *lttng_tracker_id_duplicate(
190 const struct lttng_tracker_id *orig)
191{
192 int ret;
193 struct lttng_tracker_id *copy = NULL;
194
195 copy = lttng_tracker_id_create();
196 if (copy == NULL) {
197 goto error;
198 }
199
200 ret = lttng_tracker_id_copy(copy, orig);
201 if (ret) {
2d97a006
JR
202 goto error;
203 }
204
205 return copy;
206error:
207 lttng_tracker_id_destroy(copy);
208 return NULL;
209}
210
211enum lttng_tracker_id_status lttng_tracker_id_get_string(
212 const struct lttng_tracker_id *id, const char **value)
213{
214 assert(id);
215 if (id->type == LTTNG_ID_UNKNOWN) {
216 *value = NULL;
217 return LTTNG_TRACKER_ID_STATUS_UNSET;
218 }
219
220 if (id->type != LTTNG_ID_STRING) {
221 *value = NULL;
222 return LTTNG_TRACKER_ID_STATUS_INVALID;
223 }
224
225 *value = id->string;
226 return LTTNG_TRACKER_ID_STATUS_OK;
227}
a7a533cd
JR
228
229struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int count)
230{
231 struct lttng_tracker_ids *ids = NULL;
232
233 ids = zmalloc(sizeof(*ids));
234 if (!ids) {
235 goto error;
236 }
237
238 ids->id_array = zmalloc(sizeof(struct lttng_tracker_id) * count);
239 if (!ids->id_array) {
240 goto error;
241 }
242
243 ids->count = count;
244
245 return ids;
246error:
247 free(ids);
248 return NULL;
249}
250
251LTTNG_HIDDEN
252struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index(
253 const struct lttng_tracker_ids *ids, unsigned int index)
254{
255 assert(ids);
256 if (index >= ids->count) {
257 return NULL;
258 }
259
260 return &ids->id_array[index];
261}
262
263const struct lttng_tracker_id *lttng_tracker_ids_get_at_index(
264 const struct lttng_tracker_ids *ids, unsigned int index)
265{
266 assert(ids);
267 return lttng_tracker_ids_get_pointer_of_index(ids, index);
268}
269
79408a2b 270enum lttng_tracker_id_status lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids, unsigned int *count)
a7a533cd 271{
e283e4a0 272
79408a2b 273 enum lttng_tracker_id_status status = LTTNG_TRACKER_ID_STATUS_OK;
e283e4a0
JR
274
275 if (!ids || !count) {
79408a2b 276 status = LTTNG_TRACKER_ID_STATUS_INVALID;
e283e4a0
JR
277 goto end;
278 }
279
280 *count = ids->count;
281end:
282 return status;
a7a533cd
JR
283}
284
285void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids)
286{
287 if (!ids) {
288 return;
289 }
290
291 for (int i = 0; i < ids->count; i++) {
292 lttng_tracker_id_reset(&ids->id_array[i]);
293 }
294 free(ids->id_array);
295 free(ids);
296}
f19f5c96
JR
297
298int lttng_tracker_ids_serialize(const struct lttng_tracker_ids *ids,
299 struct lttng_dynamic_buffer *buffer)
300{
301 int ret;
302 int value;
303 const char *string;
304 unsigned int count;
305 enum lttng_tracker_id_status status;
306 const struct lttng_tracker_id *id;
307
308 status = lttng_tracker_ids_get_count(ids, &count);
309 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
310 ret = LTTNG_ERR_INVALID;
311 goto error;
312 }
313
314 for (unsigned int i = 0; i < count; i++) {
315 struct lttcomm_tracker_id_header id_hdr;
316 size_t var_data_len = 0;
317
318 id = lttng_tracker_ids_get_at_index(ids, i);
319 if (!id) {
320 ret = -LTTNG_ERR_INVALID;
321 goto error;
322 }
323
324 memset(&id_hdr, 0, sizeof(id_hdr));
325 id_hdr.type = lttng_tracker_id_get_type(id);
326 switch (id_hdr.type) {
327 case LTTNG_ID_ALL:
328 break;
329 case LTTNG_ID_VALUE:
330 status = lttng_tracker_id_get_value(id, &value);
331 id_hdr.u.value = value;
332 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
333 ret = -LTTNG_ERR_INVALID;
334 goto error;
335 }
336 break;
337 case LTTNG_ID_STRING:
338 status = lttng_tracker_id_get_string(
339 id, &string);
340 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
341 ret = -LTTNG_ERR_INVALID;
342 goto error;
343 }
344
345 id_hdr.u.var_data_len = var_data_len =
346 strlen(string) + 1;
347 break;
348 default:
349 ret = -LTTNG_ERR_INVALID;
350 goto error;
351 }
352 ret = lttng_dynamic_buffer_append(
353 buffer, &id_hdr, sizeof(id_hdr));
354 if (ret) {
355 ret = -LTTNG_ERR_NOMEM;
356 goto error;
357 }
358 ret = lttng_dynamic_buffer_append(
359 buffer, string, var_data_len);
360 if (ret) {
361 ret = -LTTNG_ERR_NOMEM;
362 goto error;
363 }
364 }
365error:
366 return ret;
367}
This page took 0.05773 seconds and 4 git commands to generate.