error-query: add lttng_action_path to express the location of an action
[lttng-tools.git] / src / common / actions / path.c
1 /*
2 * Copyright (C) 2021 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <lttng/action/path-internal.h>
9
10 struct lttng_action_path_comm {
11 uint32_t index_count;
12 uint64_t indexes[];
13 } LTTNG_PACKED;
14
15 struct lttng_action_path *lttng_action_path_create(
16 const uint64_t *indexes, size_t index_count)
17 {
18 int ret;
19 size_t i;
20 struct lttng_action_path *path = NULL;
21
22 if (!indexes && index_count > 0) {
23 goto error;
24 }
25
26 path = zmalloc(sizeof(*path));
27 if (!path) {
28 goto error;
29 }
30
31 lttng_dynamic_array_init(&path->indexes, sizeof(uint64_t), NULL);
32 ret = lttng_dynamic_array_set_count(&path->indexes, index_count);
33 if (ret) {
34 goto error;
35 }
36
37 for (i = 0; i < index_count; i++) {
38 ret = lttng_dynamic_array_add_element(
39 &path->indexes, &indexes[i]);
40 if (ret) {
41 goto error;
42 }
43 }
44
45 goto end;
46 error:
47 lttng_action_path_destroy(path);
48 path = NULL;
49 end:
50 return path;
51 }
52
53 enum lttng_action_path_status lttng_action_path_get_index_count(
54 const struct lttng_action_path *path, size_t *index_count)
55 {
56 enum lttng_action_path_status status;
57
58 if (!path || !index_count) {
59 status = LTTNG_ACTION_PATH_STATUS_INVALID;
60 goto end;
61 }
62
63 *index_count = lttng_dynamic_array_get_count(&path->indexes);
64 status = LTTNG_ACTION_PATH_STATUS_OK;
65 end:
66 return status;
67 }
68
69 enum lttng_action_path_status lttng_action_path_get_index_at_index(
70 const struct lttng_action_path *path,
71 size_t path_index,
72 uint64_t *out_index)
73 {
74 enum lttng_action_path_status status;
75
76 if (!path || !out_index ||
77 path_index >= lttng_dynamic_array_get_count(
78 &path->indexes)) {
79 status = LTTNG_ACTION_PATH_STATUS_INVALID;
80 goto end;
81 }
82
83 *out_index = *((typeof(out_index)) lttng_dynamic_array_get_element(
84 &path->indexes, path_index));
85 status = LTTNG_ACTION_PATH_STATUS_OK;
86 end:
87 return status;
88 }
89
90 void lttng_action_path_destroy(struct lttng_action_path *action_path)
91 {
92 if (!action_path) {
93 goto end;
94 }
95
96 lttng_dynamic_array_reset(&action_path->indexes);
97 free(action_path);
98 end:
99 return;
100 }
101
102 LTTNG_HIDDEN
103 int lttng_action_path_copy(const struct lttng_action_path *src,
104 struct lttng_action_path *dst)
105 {
106 int ret;
107 size_t i, src_count;
108
109 assert(src);
110 assert(dst);
111
112 lttng_dynamic_array_init(&dst->indexes, sizeof(uint64_t), NULL);
113 src_count = lttng_dynamic_array_get_count(&src->indexes);
114
115 ret = lttng_dynamic_array_set_count(&dst->indexes, src_count);
116 if (ret) {
117 goto error;
118 }
119
120 for (i = 0; i < src_count; i++) {
121 const void *index = lttng_dynamic_array_get_element(
122 &src->indexes, i);
123
124 ret = lttng_dynamic_array_add_element(&dst->indexes, index);
125 if (ret) {
126 goto error;
127 }
128 }
129
130 ret = 0;
131 goto end;
132 error:
133 lttng_dynamic_array_reset(&dst->indexes);
134 end:
135 return ret;
136 }
137
138 LTTNG_HIDDEN
139 ssize_t lttng_action_path_create_from_payload(
140 struct lttng_payload_view *view,
141 struct lttng_action_path **_action_path)
142 {
143 ssize_t consumed_size = 0, ret = -1;
144 const struct lttng_action_path_comm *header;
145 struct lttng_action_path *action_path = NULL;
146 const struct lttng_payload_view header_view =
147 lttng_payload_view_from_view(view, 0, sizeof(*header));
148
149 if (!lttng_payload_view_is_valid(&header_view)) {
150 goto end;
151 }
152
153 header = (typeof(header)) header_view.buffer.data;
154 consumed_size += header_view.buffer.size;
155 {
156 const struct lttng_payload_view indexes_view =
157 lttng_payload_view_from_view(view,
158 consumed_size,
159 header->index_count *
160 sizeof(uint64_t));
161
162 if (!lttng_payload_view_is_valid(&indexes_view)) {
163 goto end;
164 }
165
166 consumed_size += indexes_view.buffer.size;
167 action_path = lttng_action_path_create(
168 (const uint64_t *) indexes_view.buffer.data,
169 header->index_count);
170 if (!action_path) {
171 goto end;
172 }
173 }
174
175 ret = consumed_size;
176 end:
177 return ret;
178 }
179
180 LTTNG_HIDDEN
181 int lttng_action_path_serialize(const struct lttng_action_path *action_path,
182 struct lttng_payload *payload)
183 {
184 int ret;
185 size_t index_count, i;
186 enum lttng_action_path_status status;
187
188 status = lttng_action_path_get_index_count(action_path, &index_count);
189 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
190 ret = -1;
191 goto end;
192 }
193
194 ret = lttng_dynamic_buffer_append(&payload->buffer,
195 &((struct lttng_action_path_comm) {
196 .index_count = index_count
197 }),
198 sizeof(struct lttng_action_path_comm));
199
200 for (i = 0; i < index_count; i++) {
201 uint64_t path_index;
202
203 status = lttng_action_path_get_index_at_index(
204 action_path, i, &path_index);
205 if (status != LTTNG_ACTION_PATH_STATUS_OK) {
206 ret = -1;
207 goto end;
208 }
209
210 ret = lttng_dynamic_buffer_append(&payload->buffer, &path_index,
211 sizeof(path_index));
212 if (ret) {
213 goto end;
214 }
215 }
216
217 ret = 0;
218 end:
219 return ret;
220 }
This page took 0.033649 seconds and 5 git commands to generate.