2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #include <common/error.hpp>
9 #include <common/macros.hpp>
11 #include <lttng/location-internal.hpp>
15 static struct lttng_trace_archive_location
*
16 lttng_trace_archive_location_create(enum lttng_trace_archive_location_type type
)
18 struct lttng_trace_archive_location
*location
;
20 location
= zmalloc
<lttng_trace_archive_location
>();
25 urcu_ref_init(&location
->ref
);
26 location
->type
= type
;
31 static void trace_archive_location_destroy_ref(struct urcu_ref
*ref
)
33 struct lttng_trace_archive_location
*location
=
34 lttng::utils::container_of(ref
, <tng_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
);
51 void lttng_trace_archive_location_get(struct lttng_trace_archive_location
*location
)
53 urcu_ref_get(&location
->ref
);
56 void lttng_trace_archive_location_put(struct lttng_trace_archive_location
*location
)
62 urcu_ref_put(&location
->ref
, trace_archive_location_destroy_ref
);
65 struct lttng_trace_archive_location
*
66 lttng_trace_archive_location_local_create(const char *absolute_path
)
68 struct lttng_trace_archive_location
*location
= nullptr;
74 location
= lttng_trace_archive_location_create(LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
);
79 location
->types
.local
.absolute_path
= strdup(absolute_path
);
80 if (!location
->types
.local
.absolute_path
) {
87 lttng_trace_archive_location_put(location
);
91 struct lttng_trace_archive_location
*lttng_trace_archive_location_relay_create(
93 enum lttng_trace_archive_location_relay_protocol_type protocol
,
94 uint16_t control_port
,
96 const char *relative_path
)
98 struct lttng_trace_archive_location
*location
= nullptr;
100 if (!host
|| !relative_path
) {
104 location
= lttng_trace_archive_location_create(LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
);
109 location
->types
.relay
.host
= strdup(host
);
110 if (!location
->types
.relay
.host
) {
113 location
->types
.relay
.relative_path
= strdup(relative_path
);
114 if (!location
->types
.relay
.relative_path
) {
118 location
->types
.relay
.protocol
= protocol
;
119 location
->types
.relay
.ports
.control
= control_port
;
120 location
->types
.relay
.ports
.data
= data_port
;
124 lttng_trace_archive_location_put(location
);
129 lttng_trace_archive_location_create_from_buffer(const struct lttng_buffer_view
*view
,
130 struct lttng_trace_archive_location
**location
)
133 const struct lttng_trace_archive_location_comm
*location_comm
;
134 struct lttng_buffer_view location_comm_view
;
136 location_comm_view
= lttng_buffer_view_from_view(view
, 0, sizeof(*location_comm
));
137 if (!lttng_buffer_view_is_valid(&location_comm_view
)) {
141 offset
+= location_comm_view
.size
;
142 location_comm
= (const struct lttng_trace_archive_location_comm
*) location_comm_view
.data
;
144 switch ((enum lttng_trace_archive_location_type
) location_comm
->type
) {
145 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
147 const struct lttng_buffer_view absolute_path_view
= lttng_buffer_view_from_view(
148 view
, offset
, location_comm
->types
.local
.absolute_path_len
);
150 if (!lttng_buffer_view_is_valid(&absolute_path_view
)) {
154 if (absolute_path_view
.data
[absolute_path_view
.size
- 1] != '\0') {
157 offset
+= absolute_path_view
.size
;
159 *location
= lttng_trace_archive_location_local_create(absolute_path_view
.data
);
165 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
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
);
174 if (!lttng_buffer_view_is_valid(&hostname_view
) ||
175 !lttng_buffer_view_is_valid(&relative_path_view
)) {
179 if (hostname_view
.data
[hostname_view
.size
- 1] != '\0') {
182 if (relative_path_view
.data
[relative_path_view
.size
- 1] != '\0') {
185 offset
+= hostname_view
.size
+ relative_path_view
.size
;
187 *location
= lttng_trace_archive_location_relay_create(
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
);
208 ssize_t
lttng_trace_archive_location_serialize(const struct lttng_trace_archive_location
*location
,
209 struct lttng_dynamic_buffer
*buffer
)
212 struct lttng_trace_archive_location_comm location_comm
;
214 location_comm
.type
= (int8_t) location
->type
;
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;
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;
233 ret
= lttng_dynamic_buffer_append(buffer
, &location_comm
, sizeof(location_comm
));
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
);
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
);
253 ret
= lttng_dynamic_buffer_append(buffer
,
254 location
->types
.relay
.relative_path
,
255 location_comm
.types
.relay
.relative_path_len
);
269 enum lttng_trace_archive_location_type
270 lttng_trace_archive_location_get_type(const struct lttng_trace_archive_location
*location
)
272 enum lttng_trace_archive_location_type type
;
275 type
= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN
;
279 type
= location
->type
;
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
)
287 enum lttng_trace_archive_location_status status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
289 if (!location
|| !absolute_path
||
290 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
) {
291 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
295 *absolute_path
= location
->types
.local
.absolute_path
;
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
)
304 enum lttng_trace_archive_location_status status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
306 if (!location
|| !relay_host
|| location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
307 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
311 *relay_host
= location
->types
.relay
.host
;
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
)
319 enum lttng_trace_archive_location_status status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
321 if (!location
|| !relative_path
||
322 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
323 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
327 *relative_path
= location
->types
.relay
.relative_path
;
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
)
335 enum lttng_trace_archive_location_status status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
337 if (!location
|| !control_port
||
338 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
339 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
343 *control_port
= location
->types
.relay
.ports
.control
;
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
)
351 enum lttng_trace_archive_location_status status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
353 if (!location
|| !data_port
|| location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
354 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
358 *data_port
= location
->types
.relay
.ports
.data
;
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
)
367 enum lttng_trace_archive_location_status status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
369 if (!location
|| !protocol
|| location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
370 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
374 *protocol
= location
->types
.relay
.protocol
;