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.hpp>
9 #include <common/macros.hpp>
11 #include <common/error.hpp>
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
<lttng_trace_archive_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 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
*lttng_trace_archive_location_local_create(
66 const char *absolute_path
)
68 struct lttng_trace_archive_location
*location
= NULL
;
74 location
= lttng_trace_archive_location_create(
75 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
);
80 location
->types
.local
.absolute_path
= strdup(absolute_path
);
81 if (!location
->types
.local
.absolute_path
) {
88 lttng_trace_archive_location_put(location
);
92 struct lttng_trace_archive_location
*lttng_trace_archive_location_relay_create(
94 enum lttng_trace_archive_location_relay_protocol_type protocol
,
95 uint16_t control_port
, uint16_t data_port
,
96 const char *relative_path
)
98 struct lttng_trace_archive_location
*location
= NULL
;
100 if (!host
|| !relative_path
) {
104 location
= lttng_trace_archive_location_create(
105 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
);
110 location
->types
.relay
.host
= strdup(host
);
111 if (!location
->types
.relay
.host
) {
114 location
->types
.relay
.relative_path
= strdup(relative_path
);
115 if (!location
->types
.relay
.relative_path
) {
119 location
->types
.relay
.protocol
= protocol
;
120 location
->types
.relay
.ports
.control
= control_port
;
121 location
->types
.relay
.ports
.data
= data_port
;
125 lttng_trace_archive_location_put(location
);
129 ssize_t
lttng_trace_archive_location_create_from_buffer(
130 const struct lttng_buffer_view
*view
,
131 struct lttng_trace_archive_location
**location
)
134 const struct lttng_trace_archive_location_comm
*location_comm
;
135 struct lttng_buffer_view location_comm_view
;
137 location_comm_view
= lttng_buffer_view_from_view(view
, 0,
138 sizeof(*location_comm
));
139 if (!lttng_buffer_view_is_valid(&location_comm_view
)) {
143 offset
+= location_comm_view
.size
;
144 location_comm
= (const struct lttng_trace_archive_location_comm
*) location_comm_view
.data
;
146 switch ((enum lttng_trace_archive_location_type
) location_comm
->type
) {
147 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
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
);
153 if (!lttng_buffer_view_is_valid(&absolute_path_view
)) {
157 if (absolute_path_view
.data
[absolute_path_view
.size
- 1] != '\0') {
160 offset
+= absolute_path_view
.size
;
162 *location
= lttng_trace_archive_location_local_create(
163 absolute_path_view
.data
);
169 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
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
);
179 if (!lttng_buffer_view_is_valid(&hostname_view
) ||
180 !lttng_buffer_view_is_valid(
181 &relative_path_view
)) {
185 if (hostname_view
.data
[hostname_view
.size
- 1] != '\0') {
188 if (relative_path_view
.data
[relative_path_view
.size
- 1] != '\0') {
191 offset
+= hostname_view
.size
+ relative_path_view
.size
;
193 *location
= lttng_trace_archive_location_relay_create(
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
);
213 ssize_t
lttng_trace_archive_location_serialize(
214 const struct lttng_trace_archive_location
*location
,
215 struct lttng_dynamic_buffer
*buffer
)
218 struct lttng_trace_archive_location_comm location_comm
;
220 location_comm
.type
= (int8_t) location
->type
;
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;
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;
243 ret
= lttng_dynamic_buffer_append(buffer
, &location_comm
,
244 sizeof(location_comm
));
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
);
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
);
265 ret
= lttng_dynamic_buffer_append(buffer
,
266 location
->types
.relay
.relative_path
,
267 location_comm
.types
.relay
.relative_path_len
);
281 enum lttng_trace_archive_location_type
lttng_trace_archive_location_get_type(
282 const struct lttng_trace_archive_location
*location
)
284 enum lttng_trace_archive_location_type type
;
287 type
= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN
;
291 type
= location
->type
;
296 enum lttng_trace_archive_location_status
297 lttng_trace_archive_location_local_get_absolute_path(
298 const struct lttng_trace_archive_location
*location
,
299 const char **absolute_path
)
301 enum lttng_trace_archive_location_status status
=
302 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
304 if (!location
|| !absolute_path
||
305 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
) {
306 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
310 *absolute_path
= location
->types
.local
.absolute_path
;
315 enum lttng_trace_archive_location_status
316 lttng_trace_archive_location_relay_get_host(
317 const struct lttng_trace_archive_location
*location
,
318 const char **relay_host
)
320 enum lttng_trace_archive_location_status status
=
321 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
323 if (!location
|| !relay_host
||
324 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
325 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
329 *relay_host
= location
->types
.relay
.host
;
334 enum lttng_trace_archive_location_status
335 lttng_trace_archive_location_relay_get_relative_path(
336 const struct lttng_trace_archive_location
*location
,
337 const char **relative_path
)
339 enum lttng_trace_archive_location_status status
=
340 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
342 if (!location
|| !relative_path
||
343 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
344 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
348 *relative_path
= location
->types
.relay
.relative_path
;
353 enum lttng_trace_archive_location_status
354 lttng_trace_archive_location_relay_get_control_port(
355 const struct lttng_trace_archive_location
*location
,
356 uint16_t *control_port
)
358 enum lttng_trace_archive_location_status status
=
359 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
361 if (!location
|| !control_port
||
362 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
363 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
367 *control_port
= location
->types
.relay
.ports
.control
;
372 enum lttng_trace_archive_location_status
373 lttng_trace_archive_location_relay_get_data_port(
374 const struct lttng_trace_archive_location
*location
,
377 enum lttng_trace_archive_location_status status
=
378 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
380 if (!location
|| !data_port
||
381 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
382 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
386 *data_port
= location
->types
.relay
.ports
.data
;
391 enum lttng_trace_archive_location_status
392 lttng_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
)
396 enum lttng_trace_archive_location_status status
=
397 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
399 if (!location
|| !protocol
||
400 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
401 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
405 *protocol
= location
->types
.relay
.protocol
;