Add condition-targeting error query
[lttng-tools.git] / src / common / error-query.c
CommitLineData
b99a0cb3
JG
1/*
2 * error-query.c
3 *
4 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 *
6 * SPDX-License-Identifier: GPL-2.1-only
7 *
8 */
9
10#include <common/dynamic-array.h>
11#include <common/error.h>
12#include <common/macros.h>
13#include <common/sessiond-comm/sessiond-comm.h>
14#include <lttng/action/action-internal.h>
ad63a966 15#include <lttng/action/list-internal.h>
27993cc2 16#include <lttng/action/path-internal.h>
b99a0cb3
JG
17#include <lttng/error-query-internal.h>
18#include <lttng/error-query.h>
19#include <lttng/trigger/trigger-internal.h>
20#include <stddef.h>
21
22struct lttng_error_query {
23 enum lttng_error_query_target_type target_type;
24};
25
26struct lttng_error_query_comm {
27 /* enum lttng_error_query_target_type */
28 int8_t target_type;
29 /* Target-specific payload. */
30 char payload[];
31};
32
33struct lttng_error_query_trigger {
34 struct lttng_error_query parent;
35 /* Mutable only because of the reference count. */
36 struct lttng_trigger *trigger;
37};
38
63dd3d7b
JG
39struct lttng_error_query_condition {
40 struct lttng_error_query parent;
41 /* Mutable only because of the reference count. */
42 struct lttng_trigger *trigger;
43};
44
b99a0cb3
JG
45struct lttng_error_query_action {
46 struct lttng_error_query parent;
47 /* Mutable only because of the reference count. */
48 struct lttng_trigger *trigger;
cb9222ff 49 struct lttng_action_path action_path;
b99a0cb3
JG
50};
51
52struct lttng_error_query_result {
53 enum lttng_error_query_result_type type;
54 char *name;
55 char *description;
56};
57
58struct lttng_error_query_result_comm {
59 /* enum lttng_error_query_result_type */
60 uint8_t type;
61 /* Length of name (including null-terminator). */
62 uint32_t name_len;
63 /* Length of description (including null-terminator). */
64 uint32_t description_len;
65 /* Name, description, and type-specific payload follow. */
66 char payload[];
67} LTTNG_PACKED;
68
69struct lttng_error_query_result_counter_comm {
70 uint64_t value;
71} LTTNG_PACKED;
72
73struct lttng_error_query_result_counter {
74 struct lttng_error_query_result parent;
75 uint64_t value;
76};
77
78struct lttng_error_query_results_comm {
79 uint32_t count;
80 /* `count` instances of `struct lttng_error_query_result` follow. */
81 char payload[];
82} LTTNG_PACKED;
83
84struct lttng_error_query_results {
85 struct lttng_dynamic_pointer_array results;
86};
87
88
89struct lttng_error_query *lttng_error_query_trigger_create(
90 const struct lttng_trigger *trigger)
91{
92 struct lttng_error_query_trigger *query = NULL;
3746c278 93 struct lttng_trigger *trigger_copy = NULL;
b99a0cb3 94
3746c278 95 if (!trigger) {
b99a0cb3
JG
96 goto end;
97 }
98
3746c278
JG
99 trigger_copy = lttng_trigger_copy(trigger);
100 if (!trigger_copy) {
b99a0cb3
JG
101 goto end;
102 }
103
104 query = zmalloc(sizeof(*query));
105 if (!query) {
106 PERROR("Failed to allocate trigger error query");
3746c278 107 goto error;
b99a0cb3
JG
108 }
109
110 query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER;
111 query->trigger = trigger_copy;
3746c278
JG
112 trigger_copy = NULL;
113
114error:
115 lttng_trigger_put(trigger_copy);
b99a0cb3
JG
116end:
117 return query ? &query->parent : NULL;
118}
119
63dd3d7b
JG
120struct lttng_error_query *lttng_error_query_condition_create(
121 const struct lttng_trigger *trigger)
122{
123 struct lttng_error_query_condition *query = NULL;
124 struct lttng_trigger *trigger_copy = NULL;
125
126 if (!trigger) {
127 goto end;
128 }
129
130 trigger_copy = lttng_trigger_copy(trigger);
131 if (!trigger_copy) {
132 goto end;
133 }
134
135 query = zmalloc(sizeof(*query));
136 if (!query) {
137 PERROR("Failed to allocate condition error query");
138 goto error;
139 }
140
141 query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION;
142 query->trigger = trigger_copy;
143 trigger_copy = NULL;
144
145error:
146 lttng_trigger_put(trigger_copy);
147end:
148 return query ? &query->parent : NULL;
149}
150
cb9222ff
JG
151static
152struct lttng_action *get_trigger_action_from_path(
153 struct lttng_trigger *trigger,
154 const struct lttng_action_path *action_path)
b99a0cb3 155{
cb9222ff
JG
156 size_t index_count, i;
157 enum lttng_action_path_status path_status;
158 struct lttng_action *current_action = NULL;
b99a0cb3 159
cb9222ff
JG
160 path_status = lttng_action_path_get_index_count(
161 action_path, &index_count);
162 if (path_status != LTTNG_ACTION_PATH_STATUS_OK) {
b99a0cb3
JG
163 goto end;
164 }
165
cb9222ff
JG
166 current_action = lttng_trigger_get_action(trigger);
167 for (i = 0; i < index_count; i++) {
168 uint64_t path_index;
169
170 path_status = lttng_action_path_get_index_at_index(
171 action_path, i, &path_index);
172 current_action = lttng_action_list_borrow_mutable_at_index(
173 current_action, path_index);
174 if (!current_action) {
175 /* Invalid action path. */
176 goto end;
177 }
b99a0cb3
JG
178 }
179
cb9222ff
JG
180end:
181 return current_action;
182}
183
184static
185bool is_valid_action_path(const struct lttng_trigger *trigger,
186 const struct lttng_action_path *action_path)
187{
b99a0cb3 188 /*
cb9222ff
JG
189 * While 'trigger's constness is casted-away, the trigger and resulting
190 * action are not modified; we merely check for the action's existence.
b99a0cb3 191 */
cb9222ff
JG
192 return !!get_trigger_action_from_path(
193 (struct lttng_trigger *) trigger, action_path);
194}
b99a0cb3 195
cb9222ff
JG
196struct lttng_error_query *lttng_error_query_action_create(
197 const struct lttng_trigger *trigger,
198 const struct lttng_action_path *action_path)
199{
200 struct lttng_error_query_action *query = NULL;
201 struct lttng_trigger *trigger_copy = NULL;
202 int ret_copy;
b99a0cb3 203
cb9222ff
JG
204 if (!trigger || !action_path ||
205 !is_valid_action_path(trigger, action_path)) {
206 goto end;
207 }
b99a0cb3 208
cb9222ff
JG
209 trigger_copy = lttng_trigger_copy(trigger);
210 if (!trigger_copy) {
211 goto end;
b99a0cb3
JG
212 }
213
214 query = zmalloc(sizeof(*query));
215 if (!query) {
216 PERROR("Failed to allocate action error query");
3746c278 217 goto error;
b99a0cb3
JG
218 }
219
cb9222ff
JG
220 ret_copy = lttng_action_path_copy(action_path, &query->action_path);
221 if (ret_copy) {
222 goto error;
223 }
224
b99a0cb3
JG
225 query->parent.target_type = LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION;
226 query->trigger = trigger_copy;
3746c278 227 trigger_copy = NULL;
cb9222ff
JG
228 goto end;
229
3746c278
JG
230error:
231 lttng_trigger_put(trigger_copy);
cb9222ff 232 lttng_error_query_destroy(query ? &query->parent : NULL);
b99a0cb3
JG
233end:
234 return query ? &query->parent : NULL;
235}
236
237void lttng_error_query_destroy(struct lttng_error_query *query)
238{
239 struct lttng_error_query_trigger *trigger_query;
240
241 if (!query) {
242 return;
243 }
244
245 trigger_query = container_of(query, typeof(*trigger_query), parent);
246 lttng_trigger_put(trigger_query->trigger);
247 free(trigger_query);
248}
249
250static
251int lttng_error_query_result_counter_serialize(
252 const struct lttng_error_query_result *result,
253 struct lttng_payload *payload)
254{
255 const struct lttng_error_query_result_counter *counter_result;
256
257 assert(result->type == LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER);
258 counter_result = container_of(result, typeof(*counter_result), parent);
259
260 return lttng_dynamic_buffer_append(&payload->buffer,
261 &(struct lttng_error_query_result_counter_comm) {
262 .value = counter_result->value
263 },
264 sizeof(struct lttng_error_query_result_counter_comm));
265}
266
267LTTNG_HIDDEN
268int lttng_error_query_result_serialize(
269 const struct lttng_error_query_result *result,
270 struct lttng_payload *payload)
271{
272 int ret;
273 struct lttng_error_query_result_comm header = {
274 .type = (uint8_t) result->type,
275 .name_len = (typeof(header.name_len)) strlen(result->name) + 1,
276 .description_len = (typeof(header.name_len)) strlen(result->description) + 1,
277 };
278
279 /* Header. */
280 ret = lttng_dynamic_buffer_append(
281 &payload->buffer, &header, sizeof(header));
282 if (ret) {
283 ERR("Failed to append error query result communication header to payload");
284 goto end;
285 }
286
287 /* Name. */
288 ret = lttng_dynamic_buffer_append(
289 &payload->buffer, result->name, header.name_len);
290 if (ret) {
291 ERR("Failed to append error query result name to payload");
292 goto end;
293 }
294
295 /* Description. */
296 ret = lttng_dynamic_buffer_append(&payload->buffer, result->description,
297 header.description_len);
298 if (ret) {
299 ERR("Failed to append error query result description to payload");
300 goto end;
301 }
302
303 /* Type-specific payload. */
304 switch (result->type) {
305 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
306 ret = lttng_error_query_result_counter_serialize(
307 result, payload);
308 if (ret) {
309 ERR("Failed to serialize counter error query result");
310 goto end;
311 }
312 break;
313 default:
314 abort();
315 }
316
317end:
318 return ret;
319}
320
321static
322int lttng_error_query_result_init(
323 struct lttng_error_query_result *result,
324 enum lttng_error_query_result_type result_type,
325 const char *name,
326 const char *description)
327{
328 int ret;
329
330 assert(name);
331 assert(description);
332
333 result->type = result_type;
334
335 result->name = strdup(name);
336 if (!result->name) {
337 PERROR("Failed to copy error query result name");
338 ret = -1;
339 goto end;
340 }
341
342 result->description = strdup(description);
343 if (!result->description) {
344 PERROR("Failed to copy error query result description");
345 ret = -1;
346 goto end;
347 }
348
349 ret = 0;
350end:
351 return ret;
352}
353
354LTTNG_HIDDEN
355void lttng_error_query_result_destroy(struct lttng_error_query_result *counter)
356{
357 if (!counter) {
358 return;
359 }
360
361 switch (counter->type) {
362 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
363 /* Nothing to tear down. */
364 break;
365 default:
366 abort();
367 }
368
369 free(counter->name);
370 free(counter->description);
371 free(counter);
372}
373
374LTTNG_HIDDEN
375struct lttng_error_query_result *
376lttng_error_query_result_counter_create(
377 const char *name, const char *description, uint64_t value)
378{
379 int init_ret;
380 struct lttng_error_query_result_counter *counter;
381
382 counter = zmalloc(sizeof(*counter));
383 if (!counter) {
384 PERROR("Failed to allocate error query counter result");
385 goto end;
386 }
387
388 init_ret = lttng_error_query_result_init(&counter->parent,
389 LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER, name,
390 description);
391 if (init_ret) {
392 goto error;
393 }
394
588c4b0d 395 counter->value = value;
b99a0cb3
JG
396 goto end;
397error:
398 lttng_error_query_result_destroy(&counter->parent);
399end:
400 return counter ? &counter->parent : NULL;
401}
402
403static
404void destroy_result(void *ptr)
405{
406 struct lttng_error_query_result *result = (typeof(result)) ptr;
407
408 lttng_error_query_result_destroy(result);
409}
410
411LTTNG_HIDDEN
412struct lttng_error_query_results *lttng_error_query_results_create(void)
413{
414 struct lttng_error_query_results *set = zmalloc(sizeof(*set));
415
416 if (!set) {
417 PERROR("Failed to allocate an error query result set");
418 goto end;
419 }
420
421 lttng_dynamic_pointer_array_init(&set->results, destroy_result);
422end:
423 return set;
424}
425
426LTTNG_HIDDEN
427int lttng_error_query_results_add_result(
428 struct lttng_error_query_results *results,
429 struct lttng_error_query_result *result)
430{
431 return lttng_dynamic_pointer_array_add_pointer(
432 &results->results, result);
433}
434
435LTTNG_HIDDEN
436ssize_t lttng_error_query_result_create_from_payload(
437 struct lttng_payload_view *view,
438 struct lttng_error_query_result **result)
439{
440 ssize_t used_size = 0;
441 struct lttng_error_query_result_comm *header;
442 struct lttng_payload_view header_view =
443 lttng_payload_view_from_view(view, 0, sizeof(*header));
444 const char *name;
445 const char *description;
446
447 if (!lttng_payload_view_is_valid(&header_view)) {
448 used_size = -1;
449 goto end;
450 }
451
452 header = (typeof(header)) header_view.buffer.data;
453 used_size += sizeof(*header);
454
455 {
456 struct lttng_payload_view name_view =
457 lttng_payload_view_from_view(view, used_size,
458 header->name_len);
459
460 if (!lttng_payload_view_is_valid(&name_view) ||
461 !lttng_buffer_view_contains_string(
462 &name_view.buffer,
463 name_view.buffer.data,
464 header->name_len)) {
465 used_size = -1;
466 goto end;
467 }
468
469 name = name_view.buffer.data;
470 used_size += header->name_len;
471 }
472
473 {
474 struct lttng_payload_view description_view =
475 lttng_payload_view_from_view(view, used_size,
476 header->description_len);
477
478 if (!lttng_payload_view_is_valid(&description_view) ||
479 !lttng_buffer_view_contains_string(
480 &description_view.buffer,
481 description_view.buffer.data,
482 header->description_len)) {
483 used_size = -1;
484 goto end;
485 }
486
487 description = description_view.buffer.data;
488 used_size += header->description_len;
489 }
490
491 switch (header->type) {
492 case LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER:
493 {
494 struct lttng_error_query_result_counter_comm *counter;
495 struct lttng_payload_view counter_payload_view =
496 lttng_payload_view_from_view(view, used_size,
497 sizeof(*counter));
498
499 if (!lttng_payload_view_is_valid(&counter_payload_view)) {
500 used_size = -1;
501 goto end;
502 }
503
504 counter = (typeof(counter)) counter_payload_view.buffer.data;
505 *result = lttng_error_query_result_counter_create(
506 name, description, counter->value);
507 if (!*result) {
508 used_size = -1;
509 goto end;
510 }
511
512 used_size += sizeof(*counter);
513 break;
514 }
515 default:
516 used_size = -1;
517 goto end;
518 }
519
520end:
521 return used_size;
522}
523
524LTTNG_HIDDEN
525int lttng_error_query_results_serialize(
526 const struct lttng_error_query_results *results,
527 struct lttng_payload *payload)
528{
529 int ret;
530 size_t result_index;
531 const size_t result_count = lttng_dynamic_pointer_array_get_count(
532 &results->results);
533 const struct lttng_error_query_results_comm header = {
534 .count = (typeof(header.count)) result_count,
535 };
536
537 /* Header. */
538 ret = lttng_dynamic_buffer_append(&payload->buffer, &header, sizeof(header));
539 if (ret) {
540 ERR("Failed to append error query result set header to payload");
541 goto end;
542 }
543
544 /* Results. */
545 for (result_index = 0; result_index < result_count; result_index++) {
546 const struct lttng_error_query_result *result = (typeof(result))
547 lttng_dynamic_pointer_array_get_pointer(
548 &results->results,
549 result_index);
550
551 ret = lttng_error_query_result_serialize(result, payload);
552 if (ret) {
553 ERR("Failed to append error query result to payload");
554 goto end;
555 }
556 }
557end:
558 return ret;
559}
560
561LTTNG_HIDDEN
562ssize_t lttng_error_query_results_create_from_payload(
563 struct lttng_payload_view *view,
564 struct lttng_error_query_results **_results)
565{
566 size_t result_index;
567 ssize_t total_used_size = 0;
568 struct lttng_error_query_results_comm *header;
569 struct lttng_payload_view header_view =
570 lttng_payload_view_from_view(view, 0, sizeof(*header));
571 struct lttng_error_query_results *results = NULL;
572
573 if (!lttng_payload_view_is_valid(&header_view)) {
574 ERR("Failed to map view to error query result set header");
575 total_used_size = -1;
576 goto end;
577 }
578
579 header = (typeof(header)) header_view.buffer.data;
580 total_used_size += sizeof(*header);
581 results = lttng_error_query_results_create();
582 if (!results) {
583 total_used_size = -1;
584 goto end;
585 }
586
587 for (result_index = 0; result_index < header->count; result_index++) {
588 ssize_t used_size;
589 struct lttng_error_query_result *result;
590 struct lttng_payload_view result_view =
591 lttng_payload_view_from_view(
592 view, total_used_size, -1);
593
594 if (!lttng_payload_view_is_valid(&result_view)) {
595 total_used_size = -1;
596 goto end;
597 }
598
599 used_size = lttng_error_query_result_create_from_payload(
600 &result_view, &result);
601 if (used_size < 0) {
602 total_used_size = -1;
603 goto end;
604 }
605
606 total_used_size += used_size;
607
608 if (lttng_dynamic_pointer_array_add_pointer(
609 &results->results, result)) {
610 lttng_error_query_result_destroy(result);
611 total_used_size = -1;
612 goto end;
613 }
614 }
615
616 *_results = results;
617 results = NULL;
618end:
619 lttng_error_query_results_destroy(results);
620 return total_used_size;
621}
622
623static
624int lttng_error_query_trigger_serialize(const struct lttng_error_query *query,
625 struct lttng_payload *payload)
626{
627 int ret;
628 const struct lttng_error_query_trigger *query_trigger =
629 container_of(query, typeof(*query_trigger), parent);
630
631 if (!lttng_trigger_validate(query_trigger->trigger)) {
632 ret = -1;
633 goto end;
634 }
635
636 ret = lttng_trigger_serialize(query_trigger->trigger, payload);
637 if (ret) {
638 goto end;
639 }
640
641end:
642 return ret;
643}
644
63dd3d7b
JG
645static
646int lttng_error_query_condition_serialize(const struct lttng_error_query *query,
647 struct lttng_payload *payload)
648{
649 int ret;
650 const struct lttng_error_query_condition *query_trigger =
651 container_of(query, typeof(*query_trigger), parent);
652
653 if (!lttng_trigger_validate(query_trigger->trigger)) {
654 ret = -1;
655 goto end;
656 }
657
658 ret = lttng_trigger_serialize(query_trigger->trigger, payload);
659 if (ret) {
660 goto end;
661 }
662
663end:
664 return ret;
665}
666
b99a0cb3
JG
667static
668int lttng_error_query_action_serialize(const struct lttng_error_query *query,
669 struct lttng_payload *payload)
670{
671 int ret;
672 const struct lttng_error_query_action *query_action =
673 container_of(query, typeof(*query_action), parent);
b99a0cb3
JG
674
675 if (!lttng_trigger_validate(query_action->trigger)) {
676 ret = -1;
677 goto end;
678 }
679
cb9222ff 680 ret = lttng_trigger_serialize(query_action->trigger, payload);
b99a0cb3
JG
681 if (ret) {
682 goto end;
683 }
684
cb9222ff 685 ret = lttng_action_path_serialize(&query_action->action_path, payload);
b99a0cb3
JG
686 if (ret) {
687 goto end;
688 }
cb9222ff 689
b99a0cb3
JG
690end:
691 return ret;
692}
693
694LTTNG_HIDDEN
695enum lttng_error_query_target_type lttng_error_query_get_target_type(
696 const struct lttng_error_query *query)
697{
698 return query->target_type;
699}
700
701LTTNG_HIDDEN
702const struct lttng_trigger *lttng_error_query_trigger_borrow_target(
703 const struct lttng_error_query *query)
704{
705 const struct lttng_error_query_trigger *query_trigger =
706 container_of(query, typeof(*query_trigger), parent);
707
708 return query_trigger->trigger;
709}
710
63dd3d7b
JG
711LTTNG_HIDDEN
712const struct lttng_trigger *lttng_error_query_condition_borrow_target(
713 const struct lttng_error_query *query)
714{
715 const struct lttng_error_query_condition *query_trigger =
716 container_of(query, typeof(*query_trigger), parent);
717
718 return query_trigger->trigger;
719}
720
b99a0cb3
JG
721LTTNG_HIDDEN
722const struct lttng_trigger *lttng_error_query_action_borrow_trigger_target(
723 const struct lttng_error_query *query)
724{
725 const struct lttng_error_query_action *query_action =
726 container_of(query, typeof(*query_action), parent);
727
728 return query_action->trigger;
729}
730
731LTTNG_HIDDEN
588c4b0d 732struct lttng_action *lttng_error_query_action_borrow_action_target(
b99a0cb3 733 const struct lttng_error_query *query,
588c4b0d 734 struct lttng_trigger *trigger)
b99a0cb3 735{
b99a0cb3
JG
736 const struct lttng_error_query_action *query_action =
737 container_of(query, typeof(*query_action), parent);
b99a0cb3 738
cb9222ff
JG
739 return get_trigger_action_from_path(
740 trigger, &query_action->action_path);
b99a0cb3
JG
741}
742
743LTTNG_HIDDEN
744int lttng_error_query_serialize(const struct lttng_error_query *query,
745 struct lttng_payload *payload)
746{
747 int ret;
748 struct lttng_error_query_comm header = {
749 .target_type = (typeof(header.target_type)) query->target_type,
750 };
751
752 ret = lttng_dynamic_buffer_append(
753 &payload->buffer, &header, sizeof(header));
754 if (ret) {
755 ERR("Failed to append error query header to payload");
756 goto end;
757 }
758
759 switch (query->target_type) {
760 case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
761 ret = lttng_error_query_trigger_serialize(query, payload);
762 if (ret) {
763 goto end;
764 }
765
63dd3d7b
JG
766 break;
767 case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
768 ret = lttng_error_query_condition_serialize(query, payload);
769 if (ret) {
770 goto end;
771 }
772
b99a0cb3
JG
773 break;
774 case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
775 ret = lttng_error_query_action_serialize(query, payload);
776 if (ret) {
777 goto end;
778 }
779
780 break;
781 default:
782 abort();
783 }
784end:
785 return ret;
786}
787
788LTTNG_HIDDEN
789ssize_t lttng_error_query_create_from_payload(struct lttng_payload_view *view,
790 struct lttng_error_query **query)
791{
792 ssize_t used_size = 0;
793 struct lttng_error_query_comm *header;
9de6375f 794 struct lttng_trigger *trigger = NULL;
b99a0cb3
JG
795 struct lttng_payload_view header_view =
796 lttng_payload_view_from_view(view, 0, sizeof(*header));
797
798 if (!lttng_payload_view_is_valid(&header_view)) {
799 ERR("Failed to map error query header");
800 used_size = -1;
801 goto end;
802 }
803
804 used_size = sizeof(*header);
805
806 header = (typeof(header)) header_view.buffer.data;
807 switch ((enum lttng_error_query_target_type) header->target_type) {
808 case LTTNG_ERROR_QUERY_TARGET_TYPE_TRIGGER:
809 {
b99a0cb3
JG
810 ssize_t trigger_used_size;
811 struct lttng_payload_view trigger_view =
812 lttng_payload_view_from_view(
813 view, used_size, -1);
814
815 if (!lttng_payload_view_is_valid(&trigger_view)) {
816 used_size = -1;
817 goto end;
818 }
819
820 trigger_used_size = lttng_trigger_create_from_payload(
821 &trigger_view, &trigger);
822 if (trigger_used_size < 0) {
823 used_size = -1;
824 goto end;
825 }
826
827 used_size += trigger_used_size;
828
829 *query = lttng_error_query_trigger_create(trigger);
b99a0cb3
JG
830 if (!*query) {
831 used_size = -1;
832 goto end;
833 }
834
835 break;
836 }
63dd3d7b
JG
837 case LTTNG_ERROR_QUERY_TARGET_TYPE_CONDITION:
838 {
839 ssize_t trigger_used_size;
840 struct lttng_payload_view trigger_view =
841 lttng_payload_view_from_view(
842 view, used_size, -1);
843
844 if (!lttng_payload_view_is_valid(&trigger_view)) {
845 used_size = -1;
846 goto end;
847 }
848
849 trigger_used_size = lttng_trigger_create_from_payload(
850 &trigger_view, &trigger);
851 if (trigger_used_size < 0) {
852 used_size = -1;
853 goto end;
854 }
855
856 used_size += trigger_used_size;
857
858 *query = lttng_error_query_condition_create(trigger);
859 if (!*query) {
860 used_size = -1;
861 goto end;
862 }
863
864 break;
865 }
b99a0cb3
JG
866 case LTTNG_ERROR_QUERY_TARGET_TYPE_ACTION:
867 {
cb9222ff 868 struct lttng_action_path *action_path = NULL;
b99a0cb3
JG
869
870 {
cb9222ff 871 ssize_t trigger_used_size;
b99a0cb3
JG
872 struct lttng_payload_view trigger_view =
873 lttng_payload_view_from_view(
874 view, used_size, -1);
875
876 if (!lttng_payload_view_is_valid(&trigger_view)) {
877 used_size = -1;
878 goto end;
879 }
880
881 trigger_used_size = lttng_trigger_create_from_payload(
882 &trigger_view, &trigger);
883 if (trigger_used_size < 0) {
884 used_size = -1;
885 goto end;
886 }
887
888 used_size += trigger_used_size;
889 }
890
cb9222ff
JG
891 {
892 ssize_t action_path_used_size;
893 struct lttng_payload_view action_path_view =
894 lttng_payload_view_from_view(
895 view, used_size, -1);
896
897 if (!lttng_payload_view_is_valid(&action_path_view)) {
898 used_size = -1;
899 goto end;
900 }
901
902 action_path_used_size = lttng_action_path_create_from_payload(
903 &action_path_view, &action_path);
904 if (action_path_used_size < 0) {
b99a0cb3
JG
905 used_size = -1;
906 goto end;
907 }
908
cb9222ff 909 used_size += action_path_used_size;
b99a0cb3
JG
910 }
911
912 *query = lttng_error_query_action_create(
cb9222ff
JG
913 trigger, action_path);
914 lttng_action_path_destroy(action_path);
b99a0cb3
JG
915 if (!*query) {
916 used_size = -1;
917 goto end;
918 }
919
920 break;
921 }
922 default:
923 used_size = -1;
924 goto end;
925 }
926
927end:
9de6375f 928 lttng_trigger_put(trigger);
b99a0cb3
JG
929 return used_size;
930}
931
932enum lttng_error_query_results_status lttng_error_query_results_get_count(
933 const struct lttng_error_query_results *results,
934 unsigned int *count)
935{
936 enum lttng_error_query_results_status status;
937
938 if (!results || !count) {
939 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER;
940 goto end;
941 }
942
943 *count = lttng_dynamic_pointer_array_get_count(&results->results);
944 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_OK;
945end:
946 return status;
947}
948
949enum lttng_error_query_results_status
950lttng_error_query_results_get_result(
951 const struct lttng_error_query_results *results,
952 const struct lttng_error_query_result **result,
953 unsigned int index)
954{
955 unsigned int result_count;
956 enum lttng_error_query_results_status status;
957
958 if (!results || !result) {
959 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER;
960 goto end;
961 }
962
963 status = lttng_error_query_results_get_count(results, &result_count);
964 if (status != LTTNG_ERROR_QUERY_RESULTS_STATUS_OK) {
965 goto end;
966 }
967
968 if (index >= result_count) {
969 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_INVALID_PARAMETER;
970 goto end;
971 }
972
973 *result = (typeof(*result)) lttng_dynamic_pointer_array_get_pointer(
974 &results->results, index);
975 assert(*result);
976 status = LTTNG_ERROR_QUERY_RESULTS_STATUS_OK;
977end:
978 return status;
979}
980
981void lttng_error_query_results_destroy(
982 struct lttng_error_query_results *results)
983{
984 if (!results) {
985 return;
986 }
987
988 lttng_dynamic_pointer_array_reset(&results->results);
989 free(results);
990}
991
992enum lttng_error_query_result_type
993lttng_error_query_result_get_type(const struct lttng_error_query_result *result)
994{
995 return result ? result->type : LTTNG_ERROR_QUERY_RESULT_TYPE_UNKNOWN;
996}
997
998enum lttng_error_query_result_status lttng_error_query_result_get_name(
999 const struct lttng_error_query_result *result,
1000 const char **name)
1001{
1002 enum lttng_error_query_result_status status;
1003
1004 if (!result || !name) {
1005 status = LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER;
1006 goto end;
1007 }
1008
1009 *name = result->name;
1010 status = LTTNG_ERROR_QUERY_RESULT_STATUS_OK;
1011end:
1012 return status;
1013}
1014
1015enum lttng_error_query_result_status lttng_error_query_result_get_description(
1016 const struct lttng_error_query_result *result,
1017 const char **description)
1018{
1019 enum lttng_error_query_result_status status;
1020
1021 if (!result || !description) {
1022 status = LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER;
1023 goto end;
1024 }
1025
1026 *description = result->description;
1027 status = LTTNG_ERROR_QUERY_RESULT_STATUS_OK;
1028end:
1029 return status;
1030}
1031
1032enum lttng_error_query_result_status lttng_error_query_result_counter_get_value(
1033 const struct lttng_error_query_result *result,
1034 uint64_t *value)
1035{
1036 enum lttng_error_query_result_status status;
1037 const struct lttng_error_query_result_counter *counter_result;
1038
1039 if (!result || !value ||
1040 result->type != LTTNG_ERROR_QUERY_RESULT_TYPE_COUNTER) {
1041 status = LTTNG_ERROR_QUERY_RESULT_STATUS_INVALID_PARAMETER;
1042 goto end;
1043 }
1044
1045 counter_result = container_of(result, typeof(*counter_result), parent);
1046
1047 *value = counter_result->value;
1048 status = LTTNG_ERROR_QUERY_RESULT_STATUS_OK;
1049end:
1050 return status;
1051}
This page took 0.071022 seconds and 4 git commands to generate.