cd4b03a47cdb7c76c0e1928c76e8b25a30f72cba
[lttng-tools.git] / src / common / location.cpp
1 /*
2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #include <common/error.hpp>
9 #include <common/macros.hpp>
10
11 #include <lttng/location-internal.hpp>
12
13 #include <stdlib.h>
14
15 static struct lttng_trace_archive_location *
16 lttng_trace_archive_location_create(enum lttng_trace_archive_location_type type)
17 {
18 struct lttng_trace_archive_location *location;
19
20 location = zmalloc<lttng_trace_archive_location>();
21 if (!location) {
22 goto end;
23 }
24
25 urcu_ref_init(&location->ref);
26 location->type = type;
27 end:
28 return location;
29 }
30
31 static void trace_archive_location_destroy_ref(struct urcu_ref *ref)
32 {
33 struct lttng_trace_archive_location *location =
34 lttng::utils::container_of(ref, &lttng_trace_archive_location::ref);
35
36 switch (location->type) {
37 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
38 free(location->types.local.absolute_path);
39 break;
40 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
41 free(location->types.relay.host);
42 free(location->types.relay.relative_path);
43 break;
44 default:
45 abort();
46 }
47
48 free(location);
49 }
50
51 void lttng_trace_archive_location_get(struct lttng_trace_archive_location *location)
52 {
53 urcu_ref_get(&location->ref);
54 }
55
56 void lttng_trace_archive_location_put(struct lttng_trace_archive_location *location)
57 {
58 if (!location) {
59 return;
60 }
61
62 urcu_ref_put(&location->ref, trace_archive_location_destroy_ref);
63 }
64
65 struct lttng_trace_archive_location *
66 lttng_trace_archive_location_local_create(const char *absolute_path)
67 {
68 struct lttng_trace_archive_location *location = nullptr;
69
70 if (!absolute_path) {
71 goto end;
72 }
73
74 location = lttng_trace_archive_location_create(LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL);
75 if (!location) {
76 goto end;
77 }
78
79 location->types.local.absolute_path = strdup(absolute_path);
80 if (!location->types.local.absolute_path) {
81 goto error;
82 }
83
84 end:
85 return location;
86 error:
87 lttng_trace_archive_location_put(location);
88 return nullptr;
89 }
90
91 struct lttng_trace_archive_location *lttng_trace_archive_location_relay_create(
92 const char *host,
93 enum lttng_trace_archive_location_relay_protocol_type protocol,
94 uint16_t control_port,
95 uint16_t data_port,
96 const char *relative_path)
97 {
98 struct lttng_trace_archive_location *location = nullptr;
99
100 if (!host || !relative_path) {
101 goto end;
102 }
103
104 location = lttng_trace_archive_location_create(LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY);
105 if (!location) {
106 goto end;
107 }
108
109 location->types.relay.host = strdup(host);
110 if (!location->types.relay.host) {
111 goto error;
112 }
113 location->types.relay.relative_path = strdup(relative_path);
114 if (!location->types.relay.relative_path) {
115 goto error;
116 }
117
118 location->types.relay.protocol = protocol;
119 location->types.relay.ports.control = control_port;
120 location->types.relay.ports.data = data_port;
121 end:
122 return location;
123 error:
124 lttng_trace_archive_location_put(location);
125 return nullptr;
126 }
127
128 ssize_t
129 lttng_trace_archive_location_create_from_buffer(const struct lttng_buffer_view *view,
130 struct lttng_trace_archive_location **location)
131 {
132 size_t offset = 0;
133 const struct lttng_trace_archive_location_comm *location_comm;
134 struct lttng_buffer_view location_comm_view;
135
136 location_comm_view = lttng_buffer_view_from_view(view, 0, sizeof(*location_comm));
137 if (!lttng_buffer_view_is_valid(&location_comm_view)) {
138 goto error;
139 }
140
141 offset += location_comm_view.size;
142 location_comm = (const struct lttng_trace_archive_location_comm *) location_comm_view.data;
143
144 switch ((enum lttng_trace_archive_location_type) location_comm->type) {
145 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
146 {
147 const struct lttng_buffer_view absolute_path_view = lttng_buffer_view_from_view(
148 view, offset, location_comm->types.local.absolute_path_len);
149
150 if (!lttng_buffer_view_is_valid(&absolute_path_view)) {
151 goto error;
152 }
153
154 if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
155 goto error;
156 }
157 offset += absolute_path_view.size;
158
159 *location = lttng_trace_archive_location_local_create(absolute_path_view.data);
160 if (!*location) {
161 goto error;
162 }
163 break;
164 }
165 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
166 {
167 const struct lttng_buffer_view hostname_view = lttng_buffer_view_from_view(
168 view, offset, location_comm->types.relay.hostname_len);
169 const struct lttng_buffer_view relative_path_view =
170 lttng_buffer_view_from_view(view,
171 offset + hostname_view.size,
172 location_comm->types.relay.relative_path_len);
173
174 if (!lttng_buffer_view_is_valid(&hostname_view) ||
175 !lttng_buffer_view_is_valid(&relative_path_view)) {
176 goto error;
177 }
178
179 if (hostname_view.data[hostname_view.size - 1] != '\0') {
180 goto error;
181 }
182 if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
183 goto error;
184 }
185 offset += hostname_view.size + relative_path_view.size;
186
187 *location = lttng_trace_archive_location_relay_create(
188 hostname_view.data,
189 (enum lttng_trace_archive_location_relay_protocol_type)
190 location_comm->types.relay.protocol,
191 location_comm->types.relay.ports.control,
192 location_comm->types.relay.ports.data,
193 relative_path_view.data);
194 if (!*location) {
195 goto error;
196 }
197 break;
198 }
199 default:
200 goto error;
201 }
202
203 return offset;
204 error:
205 return -1;
206 }
207
208 ssize_t lttng_trace_archive_location_serialize(const struct lttng_trace_archive_location *location,
209 struct lttng_dynamic_buffer *buffer)
210 {
211 int ret;
212 struct lttng_trace_archive_location_comm location_comm;
213
214 location_comm.type = (int8_t) location->type;
215
216 switch (location->type) {
217 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
218 location_comm.types.local.absolute_path_len =
219 strlen(location->types.local.absolute_path) + 1;
220 break;
221 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
222 location_comm.types.relay.hostname_len = strlen(location->types.relay.host) + 1;
223 location_comm.types.relay.protocol = (int8_t) location->types.relay.protocol;
224 location_comm.types.relay.ports.control = location->types.relay.ports.control;
225 location_comm.types.relay.ports.data = location->types.relay.ports.data;
226 location_comm.types.relay.relative_path_len =
227 strlen(location->types.relay.relative_path) + 1;
228 break;
229 default:
230 abort();
231 }
232
233 ret = lttng_dynamic_buffer_append(buffer, &location_comm, sizeof(location_comm));
234 if (ret) {
235 goto error;
236 }
237
238 switch (location->type) {
239 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
240 ret = lttng_dynamic_buffer_append(buffer,
241 location->types.local.absolute_path,
242 location_comm.types.local.absolute_path_len);
243 if (ret) {
244 goto error;
245 }
246 break;
247 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
248 ret = lttng_dynamic_buffer_append(
249 buffer, location->types.relay.host, location_comm.types.relay.hostname_len);
250 if (ret) {
251 goto error;
252 }
253 ret = lttng_dynamic_buffer_append(buffer,
254 location->types.relay.relative_path,
255 location_comm.types.relay.relative_path_len);
256 if (ret) {
257 goto error;
258 }
259 break;
260 default:
261 abort();
262 }
263
264 return 0;
265 error:
266 return -1;
267 }
268
269 enum lttng_trace_archive_location_type
270 lttng_trace_archive_location_get_type(const struct lttng_trace_archive_location *location)
271 {
272 enum lttng_trace_archive_location_type type;
273
274 if (!location) {
275 type = LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN;
276 goto end;
277 }
278
279 type = location->type;
280 end:
281 return type;
282 }
283
284 enum lttng_trace_archive_location_status lttng_trace_archive_location_local_get_absolute_path(
285 const struct lttng_trace_archive_location *location, const char **absolute_path)
286 {
287 enum lttng_trace_archive_location_status status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
288
289 if (!location || !absolute_path ||
290 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL) {
291 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
292 goto end;
293 }
294
295 *absolute_path = location->types.local.absolute_path;
296 end:
297 return status;
298 }
299
300 enum lttng_trace_archive_location_status
301 lttng_trace_archive_location_relay_get_host(const struct lttng_trace_archive_location *location,
302 const char **relay_host)
303 {
304 enum lttng_trace_archive_location_status status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
305
306 if (!location || !relay_host || location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
307 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
308 goto end;
309 }
310
311 *relay_host = location->types.relay.host;
312 end:
313 return status;
314 }
315
316 enum lttng_trace_archive_location_status lttng_trace_archive_location_relay_get_relative_path(
317 const struct lttng_trace_archive_location *location, const char **relative_path)
318 {
319 enum lttng_trace_archive_location_status status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
320
321 if (!location || !relative_path ||
322 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
323 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
324 goto end;
325 }
326
327 *relative_path = location->types.relay.relative_path;
328 end:
329 return status;
330 }
331
332 enum lttng_trace_archive_location_status lttng_trace_archive_location_relay_get_control_port(
333 const struct lttng_trace_archive_location *location, uint16_t *control_port)
334 {
335 enum lttng_trace_archive_location_status status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
336
337 if (!location || !control_port ||
338 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
339 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
340 goto end;
341 }
342
343 *control_port = location->types.relay.ports.control;
344 end:
345 return status;
346 }
347
348 enum lttng_trace_archive_location_status lttng_trace_archive_location_relay_get_data_port(
349 const struct lttng_trace_archive_location *location, uint16_t *data_port)
350 {
351 enum lttng_trace_archive_location_status status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
352
353 if (!location || !data_port || location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
354 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
355 goto end;
356 }
357
358 *data_port = location->types.relay.ports.data;
359 end:
360 return status;
361 }
362
363 enum lttng_trace_archive_location_status lttng_trace_archive_location_relay_get_protocol_type(
364 const struct lttng_trace_archive_location *location,
365 enum lttng_trace_archive_location_relay_protocol_type *protocol)
366 {
367 enum lttng_trace_archive_location_status status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
368
369 if (!location || !protocol || location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
370 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
371 goto end;
372 }
373
374 *protocol = location->types.relay.protocol;
375 end:
376 return status;
377 }
This page took 0.036642 seconds and 4 git commands to generate.