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 (!location_comm_view
.data
) {
147 offset
+= location_comm_view
.size
;
148 location_comm
= (const struct lttng_trace_archive_location_comm
*) view
->data
;
150 switch ((enum lttng_trace_archive_location_type
) location_comm
->type
) {
151 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
153 const struct lttng_buffer_view absolute_path_view
=
154 lttng_buffer_view_from_view(view
, offset
,
155 location_comm
->types
.local
.absolute_path_len
);
157 if (!absolute_path_view
.data
) {
160 if (absolute_path_view
.data
[absolute_path_view
.size
- 1] != '\0') {
163 offset
+= absolute_path_view
.size
;
165 *location
= lttng_trace_archive_location_local_create(
166 absolute_path_view
.data
);
172 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
174 const struct lttng_buffer_view hostname_view
=
175 lttng_buffer_view_from_view(view
, offset
,
176 location_comm
->types
.relay
.hostname_len
);
177 const struct lttng_buffer_view relative_path_view
=
178 lttng_buffer_view_from_view(view
,
179 offset
+ hostname_view
.size
,
180 location_comm
->types
.relay
.relative_path_len
);
182 if (!hostname_view
.data
|| !relative_path_view
.data
) {
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
);
214 ssize_t
lttng_trace_archive_location_serialize(
215 const struct lttng_trace_archive_location
*location
,
216 struct lttng_dynamic_buffer
*buffer
)
219 struct lttng_trace_archive_location_comm location_comm
;
221 location_comm
.type
= (int8_t) location
->type
;
223 switch (location
->type
) {
224 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
225 location_comm
.types
.local
.absolute_path_len
=
226 strlen(location
->types
.local
.absolute_path
) + 1;
228 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
229 location_comm
.types
.relay
.hostname_len
=
230 strlen(location
->types
.relay
.host
) + 1;
231 location_comm
.types
.relay
.protocol
=
232 (int8_t) location
->types
.relay
.protocol
;
233 location_comm
.types
.relay
.ports
.control
=
234 location
->types
.relay
.ports
.control
;
235 location_comm
.types
.relay
.ports
.data
=
236 location
->types
.relay
.ports
.data
;
237 location_comm
.types
.relay
.relative_path_len
=
238 strlen(location
->types
.relay
.relative_path
) + 1;
244 ret
= lttng_dynamic_buffer_append(buffer
, &location_comm
,
245 sizeof(location_comm
));
250 switch (location
->type
) {
251 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
:
252 ret
= lttng_dynamic_buffer_append(buffer
,
253 location
->types
.local
.absolute_path
,
254 location_comm
.types
.local
.absolute_path_len
);
259 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
:
260 ret
= lttng_dynamic_buffer_append(buffer
,
261 location
->types
.relay
.host
,
262 location_comm
.types
.relay
.hostname_len
);
266 ret
= lttng_dynamic_buffer_append(buffer
,
267 location
->types
.relay
.relative_path
,
268 location_comm
.types
.relay
.relative_path_len
);
282 enum lttng_trace_archive_location_type
lttng_trace_archive_location_get_type(
283 const struct lttng_trace_archive_location
*location
)
285 enum lttng_trace_archive_location_type type
;
288 type
= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN
;
292 type
= location
->type
;
297 enum lttng_trace_archive_location_status
298 lttng_trace_archive_location_local_get_absolute_path(
299 const struct lttng_trace_archive_location
*location
,
300 const char **absolute_path
)
302 enum lttng_trace_archive_location_status status
=
303 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
305 if (!location
|| !absolute_path
||
306 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL
) {
307 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
311 *absolute_path
= location
->types
.local
.absolute_path
;
316 enum lttng_trace_archive_location_status
317 lttng_trace_archive_location_relay_get_host(
318 const struct lttng_trace_archive_location
*location
,
319 const char **relay_host
)
321 enum lttng_trace_archive_location_status status
=
322 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
324 if (!location
|| !relay_host
||
325 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
326 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
330 *relay_host
= location
->types
.relay
.host
;
335 enum lttng_trace_archive_location_status
336 lttng_trace_archive_location_relay_get_relative_path(
337 const struct lttng_trace_archive_location
*location
,
338 const char **relative_path
)
340 enum lttng_trace_archive_location_status status
=
341 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
343 if (!location
|| !relative_path
||
344 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
345 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
349 *relative_path
= location
->types
.relay
.relative_path
;
354 enum lttng_trace_archive_location_status
355 lttng_trace_archive_location_relay_get_control_port(
356 const struct lttng_trace_archive_location
*location
,
357 uint16_t *control_port
)
359 enum lttng_trace_archive_location_status status
=
360 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
362 if (!location
|| !control_port
||
363 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
364 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
368 *control_port
= location
->types
.relay
.ports
.control
;
373 enum lttng_trace_archive_location_status
374 lttng_trace_archive_location_relay_get_data_port(
375 const struct lttng_trace_archive_location
*location
,
378 enum lttng_trace_archive_location_status status
=
379 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
381 if (!location
|| !data_port
||
382 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
383 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
387 *data_port
= location
->types
.relay
.ports
.data
;
392 enum lttng_trace_archive_location_status
393 lttng_trace_archive_location_relay_get_protocol_type(
394 const struct lttng_trace_archive_location
*location
,
395 enum lttng_trace_archive_location_relay_protocol_type
*protocol
)
397 enum lttng_trace_archive_location_status status
=
398 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK
;
400 if (!location
|| !protocol
||
401 location
->type
!= LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY
) {
402 status
= LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID
;
406 *protocol
= location
->types
.relay
.protocol
;