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