Move to kernel style SPDX license identifiers
[lttng-tools.git] / src / common / session-consumed-size.c
CommitLineData
e8360425 1/*
ab5be9fa 2 * Copyright (C) 2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
e8360425 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
e8360425 5 *
e8360425
JD
6 */
7
8#include <lttng/condition/condition-internal.h>
9#include <lttng/condition/session-consumed-size-internal.h>
319370bd 10#include <lttng/constant.h>
e8360425
JD
11#include <common/macros.h>
12#include <common/error.h>
13#include <assert.h>
14#include <math.h>
15#include <float.h>
16#include <time.h>
17
18#define IS_CONSUMED_SIZE_CONDITION(condition) ( \
19 lttng_condition_get_type(condition) == LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE \
20 )
21
22#define IS_CONSUMED_SIZE_EVALUATION(evaluation) ( \
23 lttng_evaluation_get_type(evaluation) == LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE \
24 )
25
26static
27void lttng_condition_session_consumed_size_destroy(struct lttng_condition *condition)
28{
29 struct lttng_condition_session_consumed_size *consumed_size;
30
31 consumed_size = container_of(condition,
32 struct lttng_condition_session_consumed_size, parent);
33
34 free(consumed_size->session_name);
35 free(consumed_size);
36}
37
38static
39bool lttng_condition_session_consumed_size_validate(
40 const struct lttng_condition *condition)
41{
42 bool valid = false;
43 struct lttng_condition_session_consumed_size *consumed;
44
45 if (!condition) {
46 goto end;
47 }
48
49 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
50 parent);
51 if (!consumed->session_name) {
9ef5b6be 52 ERR("Invalid session consumed size condition: a target session name must be set.");
e8360425
JD
53 goto end;
54 }
55 if (!consumed->consumed_threshold_bytes.set) {
9ef5b6be 56 ERR("Invalid session consumed size condition: a threshold must be set.");
e8360425
JD
57 goto end;
58 }
59
60 valid = true;
61end:
62 return valid;
63}
64
65static
3647288f
JG
66int lttng_condition_session_consumed_size_serialize(
67 const struct lttng_condition *condition,
68 struct lttng_dynamic_buffer *buf)
e8360425 69{
3647288f 70 int ret;
e8360425 71 size_t session_name_len;
3647288f
JG
72 struct lttng_condition_session_consumed_size *consumed;
73 struct lttng_condition_session_consumed_size_comm consumed_comm;
e8360425
JD
74
75 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
76 ret = -1;
77 goto end;
78 }
79
3647288f
JG
80 DBG("Serializing session consumed size condition");
81 consumed = container_of(condition,
82 struct lttng_condition_session_consumed_size,
e8360425 83 parent);
3647288f 84
e8360425
JD
85 session_name_len = strlen(consumed->session_name) + 1;
86 if (session_name_len > LTTNG_NAME_MAX) {
87 ret = -1;
88 goto end;
89 }
3647288f
JG
90
91 consumed_comm.consumed_threshold_bytes =
92 consumed->consumed_threshold_bytes.value;
93 consumed_comm.session_name_len = (uint32_t) session_name_len;
94
95 ret = lttng_dynamic_buffer_append(buf, &consumed_comm,
96 sizeof(consumed_comm));
97 if (ret) {
98 goto end;
99 }
100 ret = lttng_dynamic_buffer_append(buf, consumed->session_name,
101 session_name_len);
102 if (ret) {
103 goto end;
e8360425 104 }
e8360425
JD
105end:
106 return ret;
107}
108
109static
110bool lttng_condition_session_consumed_size_is_equal(const struct lttng_condition *_a,
111 const struct lttng_condition *_b)
112{
113 bool is_equal = false;
114 struct lttng_condition_session_consumed_size *a, *b;
115
116 a = container_of(_a, struct lttng_condition_session_consumed_size, parent);
117 b = container_of(_b, struct lttng_condition_session_consumed_size, parent);
118
119 if (a->consumed_threshold_bytes.set && b->consumed_threshold_bytes.set) {
120 uint64_t a_value, b_value;
121
122 a_value = a->consumed_threshold_bytes.value;
123 b_value = b->consumed_threshold_bytes.value;
124 if (a_value != b_value) {
125 goto end;
126 }
127 }
128
821d5e92
JG
129 assert(a->session_name);
130 assert(b->session_name);
131 if (strcmp(a->session_name, b->session_name)) {
e8360425
JD
132 goto end;
133 }
134
135 is_equal = true;
136end:
137 return is_equal;
138}
139
140struct lttng_condition *lttng_condition_session_consumed_size_create(void)
141{
142 struct lttng_condition_session_consumed_size *condition;
143
144 condition = zmalloc(sizeof(struct lttng_condition_session_consumed_size));
145 if (!condition) {
146 return NULL;
147 }
148
149 lttng_condition_init(&condition->parent, LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE);
150 condition->parent.validate = lttng_condition_session_consumed_size_validate;
151 condition->parent.serialize = lttng_condition_session_consumed_size_serialize;
152 condition->parent.equal = lttng_condition_session_consumed_size_is_equal;
153 condition->parent.destroy = lttng_condition_session_consumed_size_destroy;
154 return &condition->parent;
155}
156
157static
158ssize_t init_condition_from_buffer(struct lttng_condition *condition,
159 const struct lttng_buffer_view *src_view)
160{
161 ssize_t ret, condition_size;
162 enum lttng_condition_status status;
163 const struct lttng_condition_session_consumed_size_comm *condition_comm;
164 const char *session_name;
165 struct lttng_buffer_view names_view;
166
167 if (src_view->size < sizeof(*condition_comm)) {
168 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain header");
169 ret = -1;
170 goto end;
171 }
172
173 condition_comm = (const struct lttng_condition_session_consumed_size_comm *) src_view->data;
174 names_view = lttng_buffer_view_from_view(src_view,
175 sizeof(*condition_comm), -1);
176
177 if (condition_comm->session_name_len > LTTNG_NAME_MAX) {
178 ERR("Failed to initialize from malformed condition buffer: name exceeds LTTNG_MAX_NAME");
179 ret = -1;
180 goto end;
181 }
182
183 if (names_view.size < condition_comm->session_name_len) {
184 ERR("Failed to initialize from malformed condition buffer: buffer too short to contain element names");
185 ret = -1;
186 goto end;
187 }
188
189 status = lttng_condition_session_consumed_size_set_threshold(condition,
190 condition_comm->consumed_threshold_bytes);
191 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 192 ERR("Failed to initialize session consumed size condition threshold");
e8360425
JD
193 ret = -1;
194 goto end;
195 }
196
197 session_name = names_view.data;
198 if (*(session_name + condition_comm->session_name_len - 1) != '\0') {
199 ERR("Malformed session name encountered in condition buffer");
200 ret = -1;
201 goto end;
202 }
203
204 status = lttng_condition_session_consumed_size_set_session_name(condition,
205 session_name);
206 if (status != LTTNG_CONDITION_STATUS_OK) {
9ef5b6be 207 ERR("Failed to set session consumed size condition's session name");
e8360425
JD
208 ret = -1;
209 goto end;
210 }
211
212 if (!lttng_condition_validate(condition)) {
213 ret = -1;
214 goto end;
215 }
216
217 condition_size = sizeof(*condition_comm) +
218 (ssize_t) condition_comm->session_name_len;
219 ret = condition_size;
220end:
221 return ret;
222}
223
224LTTNG_HIDDEN
225ssize_t lttng_condition_session_consumed_size_create_from_buffer(
226 const struct lttng_buffer_view *view,
227 struct lttng_condition **_condition)
228{
229 ssize_t ret;
230 struct lttng_condition *condition =
231 lttng_condition_session_consumed_size_create();
232
233 if (!_condition || !condition) {
234 ret = -1;
235 goto error;
236 }
237
238 ret = init_condition_from_buffer(condition, view);
239 if (ret < 0) {
240 goto error;
241 }
242
243 *_condition = condition;
244 return ret;
245error:
246 lttng_condition_destroy(condition);
247 return ret;
248}
249
250static
251struct lttng_evaluation *create_evaluation_from_buffer(
e8360425
JD
252 const struct lttng_buffer_view *view)
253{
254 const struct lttng_evaluation_session_consumed_size_comm *comm =
255 (const struct lttng_evaluation_session_consumed_size_comm *) view->data;
256 struct lttng_evaluation *evaluation = NULL;
257
258 if (view->size < sizeof(*comm)) {
259 goto end;
260 }
261
5f2c1c0f 262 evaluation = lttng_evaluation_session_consumed_size_create(
e8360425
JD
263 comm->session_consumed);
264end:
265 return evaluation;
266}
267
268LTTNG_HIDDEN
269ssize_t lttng_evaluation_session_consumed_size_create_from_buffer(
270 const struct lttng_buffer_view *view,
271 struct lttng_evaluation **_evaluation)
272{
273 ssize_t ret;
274 struct lttng_evaluation *evaluation = NULL;
275
276 if (!_evaluation) {
277 ret = -1;
278 goto error;
279 }
280
5f2c1c0f 281 evaluation = create_evaluation_from_buffer(view);
e8360425
JD
282 if (!evaluation) {
283 ret = -1;
284 goto error;
285 }
286
287 *_evaluation = evaluation;
288 ret = sizeof(struct lttng_evaluation_session_consumed_size_comm);
289 return ret;
290error:
291 lttng_evaluation_destroy(evaluation);
292 return ret;
293}
294
295enum lttng_condition_status
296lttng_condition_session_consumed_size_get_threshold(
297 const struct lttng_condition *condition,
298 uint64_t *consumed_threshold_bytes)
299{
300 struct lttng_condition_session_consumed_size *consumed;
301 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
302
303 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !consumed_threshold_bytes) {
304 status = LTTNG_CONDITION_STATUS_INVALID;
305 goto end;
306 }
307
308 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
309 parent);
310 if (!consumed->consumed_threshold_bytes.set) {
311 status = LTTNG_CONDITION_STATUS_UNSET;
312 goto end;
313 }
314 *consumed_threshold_bytes = consumed->consumed_threshold_bytes.value;
315end:
316 return status;
317}
318
319enum lttng_condition_status
320lttng_condition_session_consumed_size_set_threshold(
321 struct lttng_condition *condition, uint64_t consumed_threshold_bytes)
322{
323 struct lttng_condition_session_consumed_size *consumed;
324 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
325
326 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition)) {
327 status = LTTNG_CONDITION_STATUS_INVALID;
328 goto end;
329 }
330
331 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
332 parent);
333 consumed->consumed_threshold_bytes.set = true;
334 consumed->consumed_threshold_bytes.value = consumed_threshold_bytes;
335end:
336 return status;
337}
338
339enum lttng_condition_status
340lttng_condition_session_consumed_size_get_session_name(
341 const struct lttng_condition *condition,
342 const char **session_name)
343{
344 struct lttng_condition_session_consumed_size *consumed;
345 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
346
347 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) || !session_name) {
348 status = LTTNG_CONDITION_STATUS_INVALID;
349 goto end;
350 }
351
352 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
353 parent);
354 if (!consumed->session_name) {
355 status = LTTNG_CONDITION_STATUS_UNSET;
356 goto end;
357 }
358 *session_name = consumed->session_name;
359end:
360 return status;
361}
362
363enum lttng_condition_status
364lttng_condition_session_consumed_size_set_session_name(
365 struct lttng_condition *condition, const char *session_name)
366{
367 char *session_name_copy;
368 struct lttng_condition_session_consumed_size *consumed;
369 enum lttng_condition_status status = LTTNG_CONDITION_STATUS_OK;
370
371 if (!condition || !IS_CONSUMED_SIZE_CONDITION(condition) ||
372 !session_name || strlen(session_name) == 0) {
373 status = LTTNG_CONDITION_STATUS_INVALID;
374 goto end;
375 }
376
377 consumed = container_of(condition, struct lttng_condition_session_consumed_size,
378 parent);
379 session_name_copy = strdup(session_name);
380 if (!session_name_copy) {
381 status = LTTNG_CONDITION_STATUS_ERROR;
382 goto end;
383 }
384
385 if (consumed->session_name) {
386 free(consumed->session_name);
387 }
388 consumed->session_name = session_name_copy;
389end:
390 return status;
391}
392
393static
3647288f 394int lttng_evaluation_session_consumed_size_serialize(
9b63a4aa 395 const struct lttng_evaluation *evaluation,
3647288f 396 struct lttng_dynamic_buffer *buf)
e8360425 397{
e8360425 398 struct lttng_evaluation_session_consumed_size *consumed;
3647288f 399 struct lttng_evaluation_session_consumed_size_comm comm;
e8360425
JD
400
401 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
402 parent);
3647288f
JG
403 comm.session_consumed = consumed->session_consumed;
404 return lttng_dynamic_buffer_append(buf, &comm, sizeof(comm));
e8360425
JD
405}
406
407static
408void lttng_evaluation_session_consumed_size_destroy(
409 struct lttng_evaluation *evaluation)
410{
411 struct lttng_evaluation_session_consumed_size *consumed;
412
413 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
414 parent);
415 free(consumed);
416}
417
418LTTNG_HIDDEN
419struct lttng_evaluation *lttng_evaluation_session_consumed_size_create(
5f2c1c0f 420 uint64_t consumed)
e8360425
JD
421{
422 struct lttng_evaluation_session_consumed_size *consumed_eval;
423
424 consumed_eval = zmalloc(sizeof(struct lttng_evaluation_session_consumed_size));
425 if (!consumed_eval) {
426 goto end;
427 }
428
5f2c1c0f 429 consumed_eval->parent.type = LTTNG_CONDITION_TYPE_SESSION_CONSUMED_SIZE;
e8360425
JD
430 consumed_eval->session_consumed = consumed;
431 consumed_eval->parent.serialize = lttng_evaluation_session_consumed_size_serialize;
432 consumed_eval->parent.destroy = lttng_evaluation_session_consumed_size_destroy;
433end:
434 return &consumed_eval->parent;
435}
436
437enum lttng_evaluation_status
438lttng_evaluation_session_consumed_size_get_consumed_size(
439 const struct lttng_evaluation *evaluation,
440 uint64_t *session_consumed)
441{
442 struct lttng_evaluation_session_consumed_size *consumed;
443 enum lttng_evaluation_status status = LTTNG_EVALUATION_STATUS_OK;
444
445 if (!evaluation || !IS_CONSUMED_SIZE_EVALUATION(evaluation) ||
446 !session_consumed) {
447 status = LTTNG_EVALUATION_STATUS_INVALID;
448 goto end;
449 }
450
451 consumed = container_of(evaluation, struct lttng_evaluation_session_consumed_size,
452 parent);
453 *session_consumed = consumed->session_consumed;
454end:
455 return status;
456}
This page took 0.053556 seconds and 5 git commands to generate.