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