Move to kernel style SPDX license identifiers
[lttng-tools.git] / src / common / tracker.c
1 /*
2 * Copyright (C) 2019 Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
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
18 struct 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;
31 error:
32 lttng_tracker_id_destroy(id);
33 return NULL;
34 }
35
36 enum 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
50 enum 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;
64 error:
65 return LTTNG_TRACKER_ID_STATUS_INVALID;
66 }
67
68 enum 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
78 static void lttng_tracker_id_reset(struct lttng_tracker_id *id)
79 {
80 if (id == NULL) {
81 return;
82 }
83
84 if (id->string != NULL) {
85 free(id->string);
86 id->string = NULL;
87 }
88
89 id->type = LTTNG_ID_UNKNOWN;
90 id->value = -1;
91 }
92
93 void lttng_tracker_id_destroy(struct lttng_tracker_id *id)
94 {
95 if (id == NULL) {
96 return;
97 }
98
99 lttng_tracker_id_reset(id);
100
101 free(id);
102 }
103
104 enum 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
111 enum 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
127 bool 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
157 int lttng_tracker_id_copy(struct lttng_tracker_id *dest,
158 const struct lttng_tracker_id *orig)
159 {
160 int ret = 0;
161 enum lttng_tracker_id_status status;
162
163 assert(dest);
164 assert(orig);
165
166 switch (orig->type) {
167 case LTTNG_ID_ALL:
168 status = lttng_tracker_id_set_all(dest);
169 break;
170 case LTTNG_ID_VALUE:
171 status = lttng_tracker_id_set_value(dest, orig->value);
172 break;
173 case LTTNG_ID_STRING:
174 status = lttng_tracker_id_set_string(dest, orig->string);
175 break;
176 default:
177 status = LTTNG_TRACKER_ID_STATUS_OK;
178 break;
179 }
180
181 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
182 ret = -1;
183 goto error;
184 }
185 error:
186 return ret;
187 }
188
189 struct 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) {
202 goto error;
203 }
204
205 return copy;
206 error:
207 lttng_tracker_id_destroy(copy);
208 return NULL;
209 }
210
211 enum 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 }
228
229 struct 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;
246 error:
247 free(ids);
248 return NULL;
249 }
250
251 LTTNG_HIDDEN
252 struct 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
263 const 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
270 enum lttng_tracker_id_status lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids, unsigned int *count)
271 {
272
273 enum lttng_tracker_id_status status = LTTNG_TRACKER_ID_STATUS_OK;
274
275 if (!ids || !count) {
276 status = LTTNG_TRACKER_ID_STATUS_INVALID;
277 goto end;
278 }
279
280 *count = ids->count;
281 end:
282 return status;
283 }
284
285 void 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 }
297
298 int 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 }
365 error:
366 return ret;
367 }
This page took 0.036921 seconds and 5 git commands to generate.