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