2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <lttng/location-internal.h>
9 #include <common/macros.h>
11 #include <common/error.h>
14 struct lttng_trace_archive_location
*lttng_trace_archive_location_create(
15 enum lttng_trace_archive_location_type type
)
17 struct lttng_trace_archive_location
*location
;
19 location
= zmalloc(sizeof(*location
));
24 urcu_ref_init(&location
->ref
);
25 location
->type
= type
;
31 void trace_archive_location_destroy_ref(struct urcu_ref
*ref
)
33 struct lttng_trace_archive_location
*location
=
34 container_of(ref
, struct lttng_trace_archive_location
, ref
);
36 switch (location
->type
) {
37 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
38 free(location
->types
.local
.absolute_path
);
40 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
41 free(location
->types
.relay
.host
);
42 free(location
->types
.relay
.relative_path
);
52 void lttng_trace_archive_location_get(struct lttng_trace_archive_location
*location
)
54 urcu_ref_get(&location
->ref
);
58 void lttng_trace_archive_location_put(struct lttng_trace_archive_location
*location
)
64 urcu_ref_put(&location
->ref
, trace_archive_location_destroy_ref
);
68 struct lttng_trace_archive_location
*lttng_trace_archive_location_local_create(
69 const char *absolute_path
)
71 struct lttng_trace_archive_location
*location
= NULL
;
77 location
= lttng_trace_archive_location_create(
78 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
);
83 location
->types
.local
.absolute_path
= strdup(absolute_path
);
84 if (!location
->types
.local
.absolute_path
) {
91 lttng_trace_archive_location_put(location
);
96 struct lttng_trace_archive_location
*lttng_trace_archive_location_relay_create(
98 enum lttng_trace_archive_location_relay_protocol_type protocol
,
99 uint16_t control_port
, uint16_t data_port
,
100 const char *relative_path
)
102 struct lttng_trace_archive_location
*location
= NULL
;
104 if (!host
|| !relative_path
) {
108 location
= lttng_trace_archive_location_create(
109 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
);
114 location
->types
.relay
.host
= strdup(host
);
115 if (!location
->types
.relay
.host
) {
118 location
->types
.relay
.relative_path
= strdup(relative_path
);
119 if (!location
->types
.relay
.relative_path
) {
123 location
->types
.relay
.protocol
= protocol
;
124 location
->types
.relay
.ports
.control
= control_port
;
125 location
->types
.relay
.ports
.data
= data_port
;
129 lttng_trace_archive_location_put(location
);
134 ssize_t
lttng_trace_archive_location_create_from_buffer(
135 const struct lttng_buffer_view
*view
,
136 struct lttng_trace_archive_location
**location
)
139 const struct lttng_trace_archive_location_comm
*location_comm
;
140 struct lttng_buffer_view location_comm_view
;
142 location_comm_view
= lttng_buffer_view_from_view(view
, 0,
143 sizeof(*location_comm
));
144 if (!lttng_buffer_view_is_valid(&location_comm_view
)) {
148 offset
+= location_comm_view
.size
;
149 location_comm
= (const struct lttng_trace_archive_location_comm
*) location_comm_view
.data
;
151 switch ((enum lttng_trace_archive_location_type
) location_comm
->type
) {
152 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
154 const struct lttng_buffer_view absolute_path_view
=
155 lttng_buffer_view_from_view(view
, offset
,
156 location_comm
->types
.local
.absolute_path_len
);
158 if (!lttng_buffer_view_is_valid(&absolute_path_view
)) {
162 if (absolute_path_view
.data
[absolute_path_view
.size
- 1] != '\0') {
165 offset
+= absolute_path_view
.size
;
167 *location
= lttng_trace_archive_location_local_create(
168 absolute_path_view
.data
);
174 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
176 const struct lttng_buffer_view hostname_view
=
177 lttng_buffer_view_from_view(view
, offset
,
178 location_comm
->types
.relay
.hostname_len
);
179 const struct lttng_buffer_view relative_path_view
=
180 lttng_buffer_view_from_view(view
,
181 offset
+ hostname_view
.size
,
182 location_comm
->types
.relay
.relative_path_len
);
184 if (!lttng_buffer_view_is_valid(&hostname_view
) ||
185 !lttng_buffer_view_is_valid(
186 &relative_path_view
)) {
190 if (hostname_view
.data
[hostname_view
.size
- 1] != '\0') {
193 if (relative_path_view
.data
[relative_path_view
.size
- 1] != '\0') {
196 offset
+= hostname_view
.size
+ relative_path_view
.size
;
198 *location
= lttng_trace_archive_location_relay_create(
200 (enum lttng_trace_archive_location_relay_protocol_type
) location_comm
->types
.relay
.protocol
,
201 location_comm
->types
.relay
.ports
.control
,
202 location_comm
->types
.relay
.ports
.data
,
203 relative_path_view
.data
);
219 ssize_t
lttng_trace_archive_location_serialize(
220 const struct lttng_trace_archive_location
*location
,
221 struct lttng_dynamic_buffer
*buffer
)
224 struct lttng_trace_archive_location_comm location_comm
;
226 location_comm
.type
= (int8_t) location
->type
;
228 switch (location
->type
) {
229 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
230 location_comm
.types
.local
.absolute_path_len
=
231 strlen(location
->types
.local
.absolute_path
) + 1;
233 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
234 location_comm
.types
.relay
.hostname_len
=
235 strlen(location
->types
.relay
.host
) + 1;
236 location_comm
.types
.relay
.protocol
=
237 (int8_t) location
->types
.relay
.protocol
;
238 location_comm
.types
.relay
.ports
.control
=
239 location
->types
.relay
.ports
.control
;
240 location_comm
.types
.relay
.ports
.data
=
241 location
->types
.relay
.ports
.data
;
242 location_comm
.types
.relay
.relative_path_len
=
243 strlen(location
->types
.relay
.relative_path
) + 1;
249 ret
= lttng_dynamic_buffer_append(buffer
, &location_comm
,
250 sizeof(location_comm
));
255 switch (location
->type
) {
256 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
257 ret
= lttng_dynamic_buffer_append(buffer
,
258 location
->types
.local
.absolute_path
,
259 location_comm
.types
.local
.absolute_path_len
);
264 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
265 ret
= lttng_dynamic_buffer_append(buffer
,
266 location
->types
.relay
.host
,
267 location_comm
.types
.relay
.hostname_len
);
271 ret
= lttng_dynamic_buffer_append(buffer
,
272 location
->types
.relay
.relative_path
,
273 location_comm
.types
.relay
.relative_path_len
);
287 enum lttng_trace_archive_location_type
lttng_trace_archive_location_get_type(
288 const struct lttng_trace_archive_location
*location
)
290 enum lttng_trace_archive_location_type type
;
293 type
= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN
;
297 type
= location
->type
;
302 enum lttng_trace_archive_location_status
303 lttng_trace_archive_location_local_get_absolute_path(
304 const struct lttng_trace_archive_location
*location
,
305 const char **absolute_path
)
307 enum lttng_trace_archive_location_status status
=
308 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
310 if (!location
|| !absolute_path
||
311 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
) {
312 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
316 *absolute_path
= location
->types
.local
.absolute_path
;
321 enum lttng_trace_archive_location_status
322 lttng_trace_archive_location_relay_get_host(
323 const struct lttng_trace_archive_location
*location
,
324 const char **relay_host
)
326 enum lttng_trace_archive_location_status status
=
327 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
329 if (!location
|| !relay_host
||
330 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
331 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
335 *relay_host
= location
->types
.relay
.host
;
340 enum lttng_trace_archive_location_status
341 lttng_trace_archive_location_relay_get_relative_path(
342 const struct lttng_trace_archive_location
*location
,
343 const char **relative_path
)
345 enum lttng_trace_archive_location_status status
=
346 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
348 if (!location
|| !relative_path
||
349 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
350 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
354 *relative_path
= location
->types
.relay
.relative_path
;
359 enum lttng_trace_archive_location_status
360 lttng_trace_archive_location_relay_get_control_port(
361 const struct lttng_trace_archive_location
*location
,
362 uint16_t *control_port
)
364 enum lttng_trace_archive_location_status status
=
365 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
367 if (!location
|| !control_port
||
368 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
369 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
373 *control_port
= location
->types
.relay
.ports
.control
;
378 enum lttng_trace_archive_location_status
379 lttng_trace_archive_location_relay_get_data_port(
380 const struct lttng_trace_archive_location
*location
,
383 enum lttng_trace_archive_location_status status
=
384 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
386 if (!location
|| !data_port
||
387 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
388 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
392 *data_port
= location
->types
.relay
.ports
.data
;
397 enum lttng_trace_archive_location_status
398 lttng_trace_archive_location_relay_get_protocol_type(
399 const struct lttng_trace_archive_location
*location
,
400 enum lttng_trace_archive_location_relay_protocol_type
*protocol
)
402 enum lttng_trace_archive_location_status status
=
403 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
405 if (!location
|| !protocol
||
406 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
407 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
411 *protocol
= location
->types
.relay
.protocol
;