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