0fdbd60f9eaacce380478be6b3dc9b68e77b3944
[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 int i;
288
289 if (!ids) {
290 return;
291 }
292
293 for (i = 0; i < ids->count; i++) {
294 lttng_tracker_id_reset(&ids->id_array[i]);
295 }
296 free(ids->id_array);
297 free(ids);
298 }
299
300 int lttng_tracker_ids_serialize(const struct lttng_tracker_ids *ids,
301 struct lttng_dynamic_buffer *buffer)
302 {
303 int ret = 0;
304 int value;
305 const char *string;
306 unsigned int count;
307 enum lttng_tracker_id_status status;
308 const struct lttng_tracker_id *id;
309 unsigned int i;
310
311 status = lttng_tracker_ids_get_count(ids, &count);
312 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
313 ret = LTTNG_ERR_INVALID;
314 goto error;
315 }
316
317 for (i = 0; i < count; i++) {
318 struct lttcomm_tracker_id_header id_hdr;
319 size_t var_data_len = 0;
320
321 id = lttng_tracker_ids_get_at_index(ids, i);
322 if (!id) {
323 ret = -LTTNG_ERR_INVALID;
324 goto error;
325 }
326
327 memset(&id_hdr, 0, sizeof(id_hdr));
328 id_hdr.type = lttng_tracker_id_get_type(id);
329 switch (id_hdr.type) {
330 case LTTNG_ID_ALL:
331 break;
332 case LTTNG_ID_VALUE:
333 status = lttng_tracker_id_get_value(id, &value);
334 id_hdr.u.value = value;
335 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
336 ret = -LTTNG_ERR_INVALID;
337 goto error;
338 }
339 break;
340 case LTTNG_ID_STRING:
341 status = lttng_tracker_id_get_string(
342 id, &string);
343 if (status != LTTNG_TRACKER_ID_STATUS_OK) {
344 ret = -LTTNG_ERR_INVALID;
345 goto error;
346 }
347
348 id_hdr.u.var_data_len = var_data_len =
349 strlen(string) + 1;
350 break;
351 default:
352 ret = -LTTNG_ERR_INVALID;
353 goto error;
354 }
355 ret = lttng_dynamic_buffer_append(
356 buffer, &id_hdr, sizeof(id_hdr));
357 if (ret) {
358 ret = -LTTNG_ERR_NOMEM;
359 goto error;
360 }
361 ret = lttng_dynamic_buffer_append(
362 buffer, string, var_data_len);
363 if (ret) {
364 ret = -LTTNG_ERR_NOMEM;
365 goto error;
366 }
367 }
368 error:
369 return ret;
370 }
This page took 0.053549 seconds and 4 git commands to generate.