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