docs: Add supported versions and fix-backport policy
[lttng-tools.git] / src / common / session-descriptor.cpp
CommitLineData
b178f53e 1/*
ab5be9fa 2 * Copyright (C) 2019 Jérémie Galarneau <jeremie.galarneau@efficios.com>
b178f53e 3 *
c922647d 4 * SPDX-License-Identifier: LGPL-2.1-only
b178f53e
JG
5 */
6
c9e313bc
SM
7#include <common/defaults.hpp>
8#include <common/error.hpp>
28ab034a
JG
9#include <common/macros.hpp>
10#include <common/uri.hpp>
11
12#include <lttng/session-descriptor-internal.hpp>
13
b178f53e 14#include <stdio.h>
28ab034a 15#include <time.h>
b178f53e 16
f1494934 17namespace {
b178f53e
JG
18struct lttng_session_descriptor_network_location {
19 struct lttng_uri *control;
20 struct lttng_uri *data;
21};
f1494934 22} /* namespace */
b178f53e
JG
23
24struct lttng_session_descriptor {
25 enum lttng_session_descriptor_type type;
26 /*
27 * If an output type that is not OUTPUT_TYPE_NONE is specified,
28 * it means that an output of that type must be generated at
29 * session-creation time.
30 */
31 enum lttng_session_descriptor_output_type output_type;
32 char *name;
33 union {
34 struct lttng_session_descriptor_network_location network;
35 struct lttng_uri *local;
36 } output;
37};
38
f1494934 39namespace {
b178f53e
JG
40struct lttng_session_descriptor_snapshot {
41 struct lttng_session_descriptor base;
42 /*
43 * Assumes at-most one snapshot output is supported. Uses
44 * the output field of the base class.
45 */
46};
47
48struct lttng_session_descriptor_live {
49 struct lttng_session_descriptor base;
50 unsigned long long live_timer_us;
51};
52
53struct lttng_session_descriptor_comm {
54 /* enum lttng_session_descriptor_type */
55 uint8_t type;
56 /* enum lttng_session_descriptor_output_type */
57 uint8_t output_type;
58 /* Includes trailing null. */
59 uint32_t name_len;
60 /* Name follows, followed by URIs */
61 uint8_t uri_count;
62} LTTNG_PACKED;
63
64struct lttng_session_descriptor_live_comm {
65 struct lttng_session_descriptor_comm base;
66 /* Live-specific parameters. */
67 uint64_t live_timer_us;
68} LTTNG_PACKED;
f1494934 69} /* namespace */
b178f53e 70
28ab034a 71static struct lttng_uri *uri_copy(const struct lttng_uri *uri)
b178f53e 72{
cd9adb8b 73 struct lttng_uri *new_uri = nullptr;
b178f53e
JG
74
75 if (!uri) {
76 goto end;
77 }
78
64803277 79 new_uri = zmalloc<lttng_uri>();
b178f53e
JG
80 if (!new_uri) {
81 goto end;
82 }
83 memcpy(new_uri, uri, sizeof(*new_uri));
84end:
85 return new_uri;
86}
87
28ab034a 88static struct lttng_uri *uri_from_path(const char *path)
b178f53e 89{
cd9adb8b 90 struct lttng_uri *uris = nullptr;
b178f53e 91 ssize_t uri_count;
28ab034a 92 char local_protocol_string[LTTNG_PATH_MAX + sizeof("file://")] = "file://";
b178f53e
JG
93
94 if (strlen(path) >= LTTNG_PATH_MAX) {
95 goto end;
96 }
97
98 if (path[0] != '/') {
99 /* Not an absolute path. */
100 goto end;
101 }
102
103 strncat(local_protocol_string, path, LTTNG_PATH_MAX);
104 uri_count = uri_parse(local_protocol_string, &uris);
105 if (uri_count != 1) {
106 goto error;
107 }
108 if (uris[0].dtype != LTTNG_DST_PATH) {
109 goto error;
110 }
111
112end:
113 return uris;
114error:
115 free(uris);
cd9adb8b 116 return nullptr;
b178f53e
JG
117}
118
28ab034a 119static void network_location_fini(struct lttng_session_descriptor_network_location *location)
b178f53e
JG
120{
121 free(location->control);
122 free(location->data);
123}
124
125/* Assumes ownership of control and data. */
28ab034a
JG
126static int
127network_location_set_from_lttng_uris(struct lttng_session_descriptor_network_location *location,
128 struct lttng_uri *control,
129 struct lttng_uri *data)
b178f53e
JG
130{
131 int ret = 0;
132
133 if (!control && !data) {
134 goto end;
135 }
136
137 if (!(control && data)) {
138 /* None or both must be set. */
139 ret = -1;
140 goto end;
141 }
142
28ab034a 143 if (control->stype != LTTNG_STREAM_CONTROL || data->stype != LTTNG_STREAM_DATA) {
b178f53e
JG
144 ret = -1;
145 goto end;
146 }
147
148 free(location->control);
149 free(location->data);
150 location->control = control;
151 location->data = data;
cd9adb8b
JG
152 control = nullptr;
153 data = nullptr;
b178f53e
JG
154end:
155 free(control);
156 free(data);
157 return ret;
158}
159
28ab034a
JG
160static int
161network_location_set_from_uri_strings(struct lttng_session_descriptor_network_location *location,
162 const char *control,
163 const char *data)
b178f53e
JG
164{
165 int ret = 0;
166 ssize_t uri_count;
cd9adb8b
JG
167 struct lttng_uri *parsed_uris = nullptr;
168 struct lttng_uri *control_uri = nullptr;
169 struct lttng_uri *data_uri = nullptr;
b178f53e
JG
170
171 uri_count = uri_parse_str_urls(control, data, &parsed_uris);
172 if (uri_count != 2 && uri_count != 0) {
173 ret = -1;
174 goto end;
175 }
176
177 /*
178 * uri_parse_str_urls returns a contiguous array of lttng_uris whereas
179 * session descriptors expect individually allocated lttng_uris.
180 */
181 if (uri_count == 2) {
64803277
SM
182 control_uri = zmalloc<lttng_uri>();
183 data_uri = zmalloc<lttng_uri>();
b178f53e
JG
184 if (!control_uri || !data_uri) {
185 ret = -1;
186 goto end;
187 }
188 memcpy(control_uri, &parsed_uris[0], sizeof(*control_uri));
189 memcpy(data_uri, &parsed_uris[1], sizeof(*data_uri));
190 }
191
192 /* Ownership of control and data uris is transferred. */
28ab034a 193 ret = network_location_set_from_lttng_uris(location, control_uri, data_uri);
cd9adb8b
JG
194 control_uri = nullptr;
195 data_uri = nullptr;
b178f53e
JG
196end:
197 free(parsed_uris);
198 free(control_uri);
199 free(data_uri);
200 return ret;
201}
202
28ab034a 203struct lttng_session_descriptor *lttng_session_descriptor_create(const char *name)
b178f53e
JG
204{
205 struct lttng_session_descriptor *descriptor;
206
64803277 207 descriptor = zmalloc<lttng_session_descriptor>();
b178f53e
JG
208 if (!descriptor) {
209 goto error;
210 }
211
212 descriptor->type = LTTNG_SESSION_DESCRIPTOR_TYPE_REGULAR;
28ab034a 213 descriptor->output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE;
b178f53e
JG
214 if (lttng_session_descriptor_set_session_name(descriptor, name)) {
215 goto error;
216 }
217 return descriptor;
218error:
219 lttng_session_descriptor_destroy(descriptor);
cd9adb8b 220 return nullptr;
b178f53e
JG
221}
222
223/* Ownership of uri is transferred. */
28ab034a
JG
224static struct lttng_session_descriptor *
225_lttng_session_descriptor_local_create(const char *name, struct lttng_uri *uri)
b178f53e
JG
226{
227 struct lttng_session_descriptor *descriptor;
228
229 descriptor = lttng_session_descriptor_create(name);
230 if (!descriptor) {
231 goto error;
232 }
233 descriptor->type = LTTNG_SESSION_DESCRIPTOR_TYPE_REGULAR;
28ab034a 234 descriptor->output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL;
b178f53e
JG
235 if (uri) {
236 if (uri->dtype != LTTNG_DST_PATH) {
237 goto error;
238 }
239 descriptor->output.local = uri;
cd9adb8b 240 uri = nullptr;
b178f53e
JG
241 }
242 return descriptor;
243error:
244 free(uri);
245 lttng_session_descriptor_destroy(descriptor);
cd9adb8b 246 return nullptr;
b178f53e
JG
247}
248
28ab034a
JG
249struct lttng_session_descriptor *lttng_session_descriptor_local_create(const char *name,
250 const char *path)
b178f53e 251{
cd9adb8b 252 struct lttng_uri *uri = nullptr;
b178f53e
JG
253 struct lttng_session_descriptor *descriptor;
254
255 if (path) {
256 uri = uri_from_path(path);
257 if (!uri) {
258 goto error;
259 }
260 }
261 descriptor = _lttng_session_descriptor_local_create(name, uri);
262 return descriptor;
263error:
cd9adb8b 264 return nullptr;
b178f53e
JG
265}
266
267/* Assumes the ownership of both uris. */
28ab034a
JG
268static struct lttng_session_descriptor *_lttng_session_descriptor_network_create(
269 const char *name, struct lttng_uri *control, struct lttng_uri *data)
b178f53e
JG
270{
271 int ret;
272 struct lttng_session_descriptor *descriptor;
273
274 descriptor = lttng_session_descriptor_create(name);
275 if (!descriptor) {
276 goto error;
277 }
278
279 descriptor->type = LTTNG_SESSION_DESCRIPTOR_TYPE_REGULAR;
280 descriptor->output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK;
281 /* Assumes the ownership of both uris. */
28ab034a 282 ret = network_location_set_from_lttng_uris(&descriptor->output.network, control, data);
cd9adb8b
JG
283 control = nullptr;
284 data = nullptr;
b178f53e
JG
285 if (ret) {
286 goto error;
287 }
288 return descriptor;
289error:
290 lttng_session_descriptor_destroy(descriptor);
291 free(control);
292 free(data);
cd9adb8b 293 return nullptr;
b178f53e
JG
294}
295
28ab034a
JG
296struct lttng_session_descriptor *lttng_session_descriptor_network_create(const char *name,
297 const char *control_url,
298 const char *data_url)
b178f53e
JG
299{
300 int ret;
301 struct lttng_session_descriptor *descriptor;
302
cd9adb8b 303 descriptor = _lttng_session_descriptor_network_create(name, nullptr, nullptr);
b178f53e
JG
304 if (!descriptor) {
305 goto error;
306 }
307
28ab034a
JG
308 ret = network_location_set_from_uri_strings(
309 &descriptor->output.network, control_url, data_url);
b178f53e
JG
310 if (ret) {
311 goto error;
312 }
313 return descriptor;
314error:
315 lttng_session_descriptor_destroy(descriptor);
cd9adb8b 316 return nullptr;
b178f53e
JG
317}
318
28ab034a 319static struct lttng_session_descriptor_snapshot *
b178f53e
JG
320_lttng_session_descriptor_snapshot_create(const char *name)
321{
322 struct lttng_session_descriptor_snapshot *descriptor;
323
64803277 324 descriptor = zmalloc<lttng_session_descriptor_snapshot>();
b178f53e
JG
325 if (!descriptor) {
326 goto error;
327 }
328
329 descriptor->base.type = LTTNG_SESSION_DESCRIPTOR_TYPE_SNAPSHOT;
28ab034a
JG
330 descriptor->base.output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE;
331 if (lttng_session_descriptor_set_session_name(&descriptor->base, name)) {
b178f53e
JG
332 goto error;
333 }
334 return descriptor;
335error:
cd9adb8b
JG
336 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
337 return nullptr;
b178f53e
JG
338}
339
340/* Ownership of control and data is transferred. */
28ab034a
JG
341static struct lttng_session_descriptor_snapshot *_lttng_session_descriptor_snapshot_network_create(
342 const char *name, struct lttng_uri *control, struct lttng_uri *data)
b178f53e
JG
343{
344 int ret;
345 struct lttng_session_descriptor_snapshot *descriptor;
346
347 descriptor = _lttng_session_descriptor_snapshot_create(name);
348 if (!descriptor) {
349 goto error;
350 }
351
28ab034a 352 descriptor->base.output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK;
b178f53e 353 /* Ownership of control and data is transferred. */
28ab034a 354 ret = network_location_set_from_lttng_uris(&descriptor->base.output.network, control, data);
cd9adb8b
JG
355 control = nullptr;
356 data = nullptr;
b178f53e
JG
357 if (ret) {
358 goto error;
359 }
360 return descriptor;
361error:
362 free(control);
363 free(data);
cd9adb8b
JG
364 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
365 return nullptr;
b178f53e
JG
366}
367
28ab034a 368struct lttng_session_descriptor *lttng_session_descriptor_snapshot_create(const char *name)
b178f53e
JG
369{
370 struct lttng_session_descriptor_snapshot *descriptor;
371
372 descriptor = _lttng_session_descriptor_snapshot_create(name);
cd9adb8b 373 return descriptor ? &descriptor->base : nullptr;
b178f53e
JG
374}
375
28ab034a
JG
376struct lttng_session_descriptor *lttng_session_descriptor_snapshot_network_create(
377 const char *name, const char *control_url, const char *data_url)
b178f53e
JG
378{
379 int ret;
380 struct lttng_session_descriptor_snapshot *descriptor;
381
cd9adb8b 382 descriptor = _lttng_session_descriptor_snapshot_network_create(name, nullptr, nullptr);
b178f53e
JG
383 if (!descriptor) {
384 goto error;
385 }
386
387 ret = network_location_set_from_uri_strings(
28ab034a 388 &descriptor->base.output.network, control_url, data_url);
b178f53e
JG
389 if (ret) {
390 goto error;
391 }
392 return &descriptor->base;
393error:
cd9adb8b
JG
394 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
395 return nullptr;
b178f53e
JG
396}
397
398/* Ownership of uri is transferred. */
28ab034a
JG
399static struct lttng_session_descriptor_snapshot *
400_lttng_session_descriptor_snapshot_local_create(const char *name, struct lttng_uri *uri)
b178f53e
JG
401{
402 struct lttng_session_descriptor_snapshot *descriptor;
403
404 descriptor = _lttng_session_descriptor_snapshot_create(name);
405 if (!descriptor) {
406 goto error;
407 }
28ab034a 408 descriptor->base.output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL;
b178f53e
JG
409 if (uri) {
410 if (uri->dtype != LTTNG_DST_PATH) {
411 goto error;
412 }
413 descriptor->base.output.local = uri;
cd9adb8b 414 uri = nullptr;
b178f53e
JG
415 }
416 return descriptor;
417error:
418 free(uri);
cd9adb8b
JG
419 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
420 return nullptr;
b178f53e
JG
421}
422
28ab034a
JG
423struct lttng_session_descriptor *lttng_session_descriptor_snapshot_local_create(const char *name,
424 const char *path)
b178f53e 425{
cd9adb8b 426 struct lttng_uri *path_uri = nullptr;
b178f53e
JG
427 struct lttng_session_descriptor_snapshot *descriptor;
428
429 if (path) {
430 path_uri = uri_from_path(path);
431 if (!path_uri) {
432 goto error;
433 }
434 }
28ab034a 435 descriptor = _lttng_session_descriptor_snapshot_local_create(name, path_uri);
cd9adb8b 436 return descriptor ? &descriptor->base : nullptr;
b178f53e 437error:
cd9adb8b 438 return nullptr;
b178f53e
JG
439}
440
28ab034a
JG
441static struct lttng_session_descriptor_live *
442_lttng_session_descriptor_live_create(const char *name, unsigned long long live_timer_interval_us)
b178f53e 443{
cd9adb8b 444 struct lttng_session_descriptor_live *descriptor = nullptr;
b178f53e
JG
445
446 if (live_timer_interval_us == 0) {
447 goto error;
448 }
64803277 449 descriptor = zmalloc<lttng_session_descriptor_live>();
b178f53e
JG
450 if (!descriptor) {
451 goto error;
452 }
453
454 descriptor->base.type = LTTNG_SESSION_DESCRIPTOR_TYPE_LIVE;
28ab034a 455 descriptor->base.output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE;
b178f53e 456 descriptor->live_timer_us = live_timer_interval_us;
28ab034a 457 if (lttng_session_descriptor_set_session_name(&descriptor->base, name)) {
b178f53e
JG
458 goto error;
459 }
460
461 return descriptor;
462error:
cd9adb8b
JG
463 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
464 return nullptr;
b178f53e
JG
465}
466
467/* Ownership of control and data is transferred. */
28ab034a
JG
468static struct lttng_session_descriptor_live *
469_lttng_session_descriptor_live_network_create(const char *name,
470 struct lttng_uri *control,
471 struct lttng_uri *data,
472 unsigned long long live_timer_interval_us)
b178f53e
JG
473{
474 int ret;
475 struct lttng_session_descriptor_live *descriptor;
476
28ab034a 477 descriptor = _lttng_session_descriptor_live_create(name, live_timer_interval_us);
ca258a7d
FD
478 if (!descriptor) {
479 goto error;
480 }
481
28ab034a 482 descriptor->base.output_type = LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK;
b178f53e
JG
483
484 /* Ownerwhip of control and data is transferred. */
28ab034a 485 ret = network_location_set_from_lttng_uris(&descriptor->base.output.network, control, data);
cd9adb8b
JG
486 control = nullptr;
487 data = nullptr;
b178f53e
JG
488 if (ret) {
489 goto error;
490 }
491 return descriptor;
492error:
493 free(control);
494 free(data);
cd9adb8b
JG
495 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
496 return nullptr;
b178f53e
JG
497}
498
499struct lttng_session_descriptor *
28ab034a 500lttng_session_descriptor_live_create(const char *name, unsigned long long live_timer_us)
b178f53e
JG
501{
502 struct lttng_session_descriptor_live *descriptor;
503
504 descriptor = _lttng_session_descriptor_live_create(name, live_timer_us);
b178f53e 505
cd9adb8b 506 return descriptor ? &descriptor->base : nullptr;
b178f53e
JG
507}
508
509struct lttng_session_descriptor *
28ab034a
JG
510lttng_session_descriptor_live_network_create(const char *name,
511 const char *control_url,
512 const char *data_url,
513 unsigned long long live_timer_us)
b178f53e
JG
514{
515 int ret;
516 struct lttng_session_descriptor_live *descriptor;
517
cd9adb8b
JG
518 descriptor = _lttng_session_descriptor_live_network_create(
519 name, nullptr, nullptr, live_timer_us);
b178f53e
JG
520 if (!descriptor) {
521 goto error;
522 }
523
524 ret = network_location_set_from_uri_strings(
28ab034a 525 &descriptor->base.output.network, control_url, data_url);
b178f53e
JG
526 if (ret) {
527 goto error;
528 }
529 return &descriptor->base;
530error:
cd9adb8b
JG
531 lttng_session_descriptor_destroy(descriptor ? &descriptor->base : nullptr);
532 return nullptr;
b178f53e
JG
533}
534
28ab034a 535void lttng_session_descriptor_destroy(struct lttng_session_descriptor *descriptor)
b178f53e
JG
536{
537 if (!descriptor) {
538 return;
539 }
540
541 switch (descriptor->output_type) {
542 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
543 break;
544 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
545 free(descriptor->output.local);
546 break;
547 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
548 network_location_fini(&descriptor->output.network);
549 break;
550 default:
551 abort();
552 }
553
554 free(descriptor->name);
555 free(descriptor);
556}
557
28ab034a
JG
558ssize_t lttng_session_descriptor_create_from_buffer(const struct lttng_buffer_view *payload,
559 struct lttng_session_descriptor **descriptor)
b178f53e
JG
560{
561 int i;
562 ssize_t offset = 0, ret;
563 struct lttng_buffer_view current_view;
cd9adb8b 564 const char *name = nullptr;
b178f53e
JG
565 const struct lttng_session_descriptor_comm *base_header;
566 size_t max_expected_uri_count;
567 uint64_t live_timer_us = 0;
568 struct lttng_uri *uris[2] = {};
569 enum lttng_session_descriptor_type type;
570 enum lttng_session_descriptor_output_type output_type;
571
28ab034a 572 current_view = lttng_buffer_view_from_view(payload, offset, sizeof(*base_header));
3e6e0df2 573 if (!lttng_buffer_view_is_valid(&current_view)) {
b178f53e
JG
574 ret = -1;
575 goto end;
576 }
577
3e6e0df2 578 base_header = (typeof(base_header)) current_view.data;
b178f53e
JG
579 switch (base_header->type) {
580 case LTTNG_SESSION_DESCRIPTOR_TYPE_REGULAR:
581 case LTTNG_SESSION_DESCRIPTOR_TYPE_SNAPSHOT:
582 break;
583 case LTTNG_SESSION_DESCRIPTOR_TYPE_LIVE:
584 {
585 const struct lttng_session_descriptor_live_comm *live_header;
586
28ab034a 587 current_view = lttng_buffer_view_from_view(payload, offset, sizeof(*live_header));
3e6e0df2 588 if (!lttng_buffer_view_is_valid(&current_view)) {
b178f53e
JG
589 ret = -1;
590 goto end;
591 }
592
3e6e0df2 593 live_header = (typeof(live_header)) current_view.data;
b178f53e
JG
594 live_timer_us = live_header->live_timer_us;
595 break;
596 }
597 default:
598 ret = -1;
599 goto end;
600 }
601 /* type has been validated. */
a6bc4ca9 602 type = (lttng_session_descriptor_type) base_header->type;
b178f53e
JG
603
604 switch (base_header->output_type) {
605 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
606 max_expected_uri_count = 0;
607 break;
608 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
609 max_expected_uri_count = 1;
610 break;
611 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
612 max_expected_uri_count = 2;
613 break;
614 default:
615 ret = -1;
616 goto end;
617 }
618 /* output_type has been validated. */
a6bc4ca9 619 output_type = (lttng_session_descriptor_output_type) base_header->output_type;
b178f53e
JG
620
621 /* Skip after header. */
622 offset += current_view.size;
623 if (!base_header->name_len) {
624 goto skip_name;
625 }
626
627 /* Map the name. */
28ab034a 628 current_view = lttng_buffer_view_from_view(payload, offset, base_header->name_len);
3e6e0df2 629 if (!lttng_buffer_view_is_valid(&current_view)) {
b178f53e
JG
630 ret = -1;
631 goto end;
632 }
633
3e6e0df2 634 name = current_view.data;
28ab034a
JG
635 if (base_header->name_len == 1 || name[base_header->name_len - 1] ||
636 strlen(name) != base_header->name_len - 1) {
b178f53e
JG
637 /*
638 * Check that the name is not NULL, is NULL-terminated, and
639 * does not contain a NULL before the last byte.
640 */
641 ret = -1;
642 goto end;
643 }
644
645 /* Skip after the name. */
646 offset += base_header->name_len;
647skip_name:
648 if (base_header->uri_count > max_expected_uri_count) {
649 ret = -1;
650 goto end;
651 }
652
653 for (i = 0; i < base_header->uri_count; i++) {
654 struct lttng_uri *uri;
655
656 /* Map a URI. */
28ab034a 657 current_view = lttng_buffer_view_from_view(payload, offset, sizeof(*uri));
3e6e0df2 658 if (!lttng_buffer_view_is_valid(&current_view)) {
b178f53e
JG
659 ret = -1;
660 goto end;
661 }
3e6e0df2
JG
662
663 uri = (typeof(uri)) current_view.data;
64803277 664 uris[i] = zmalloc<lttng_uri>();
b178f53e
JG
665 if (!uris[i]) {
666 ret = -1;
667 goto end;
668 }
669 memcpy(uris[i], uri, sizeof(*uri));
670 offset += sizeof(*uri);
671 }
672
673 switch (type) {
674 case LTTNG_SESSION_DESCRIPTOR_TYPE_REGULAR:
675 switch (output_type) {
676 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
677 *descriptor = lttng_session_descriptor_create(name);
678 break;
679 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
28ab034a 680 *descriptor = _lttng_session_descriptor_local_create(name, uris[0]);
b178f53e
JG
681 break;
682 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
28ab034a
JG
683 *descriptor =
684 _lttng_session_descriptor_network_create(name, uris[0], uris[1]);
b178f53e
JG
685 break;
686 default:
687 /* Already checked. */
688 abort();
689 }
690 break;
691 case LTTNG_SESSION_DESCRIPTOR_TYPE_SNAPSHOT:
692 {
693 struct lttng_session_descriptor_snapshot *snapshot;
694 switch (output_type) {
695 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
28ab034a 696 snapshot = _lttng_session_descriptor_snapshot_create(name);
b178f53e
JG
697 break;
698 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
28ab034a 699 snapshot = _lttng_session_descriptor_snapshot_local_create(name, uris[0]);
b178f53e
JG
700 break;
701 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
702 snapshot = _lttng_session_descriptor_snapshot_network_create(
28ab034a 703 name, uris[0], uris[1]);
b178f53e
JG
704 break;
705 default:
706 /* Already checked. */
707 abort();
708 }
cd9adb8b 709 *descriptor = snapshot ? &snapshot->base : nullptr;
b178f53e
JG
710 break;
711 }
712 case LTTNG_SESSION_DESCRIPTOR_TYPE_LIVE:
713 {
714 struct lttng_session_descriptor_live *live;
715
716 switch (output_type) {
717 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
28ab034a 718 live = _lttng_session_descriptor_live_create(name, live_timer_us);
b178f53e
JG
719 break;
720 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
721 live = _lttng_session_descriptor_live_network_create(
28ab034a 722 name, uris[0], uris[1], live_timer_us);
b178f53e
JG
723 break;
724 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
725 ret = -1;
726 goto end;
727 default:
728 /* Already checked. */
729 abort();
730 }
cd9adb8b 731 *descriptor = live ? &live->base : nullptr;
b178f53e
JG
732 break;
733 }
734 default:
735 /* Already checked. */
736 abort();
737 }
738 memset(uris, 0, sizeof(uris));
739 if (!*descriptor) {
740 ret = -1;
741 goto end;
742 }
743
744 ret = offset;
745end:
746 free(uris[0]);
747 free(uris[1]);
748 return ret;
749}
750
28ab034a
JG
751int lttng_session_descriptor_serialize(const struct lttng_session_descriptor *descriptor,
752 struct lttng_dynamic_buffer *buffer)
b178f53e
JG
753{
754 int ret, i;
755 /* There are, at most, two URIs to serialize. */
756 struct lttng_uri *uris[2] = {};
757 size_t uri_count = 0;
758 /* The live header is a superset of all headers. */
759 struct lttng_session_descriptor_live_comm header = {
a6bc4ca9
SM
760 .base = {
761 .type = (uint8_t) descriptor->type,
762 .output_type = (uint8_t) descriptor->output_type,
763 .name_len = (uint32_t) (descriptor->name ?
764 strlen(descriptor->name) + 1 : 0),
1c9a0b0e
MJ
765 .uri_count = 0,
766 },
767 .live_timer_us = 0,
768
b178f53e 769 };
cd9adb8b 770 const void *header_ptr = nullptr;
b178f53e
JG
771 size_t header_size;
772
773 switch (descriptor->output_type) {
774 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
775 break;
776 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
777 uris[0] = descriptor->output.local;
778 break;
779 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
780 uris[0] = descriptor->output.network.control;
781 uris[1] = descriptor->output.network.data;
782 break;
783 default:
784 ret = -1;
785 goto end;
786 }
787 uri_count += !!uris[0];
788 uri_count += !!uris[1];
789
790 header.base.uri_count = uri_count;
791 if (descriptor->type == LTTNG_SESSION_DESCRIPTOR_TYPE_LIVE) {
0114db0e 792 const struct lttng_session_descriptor_live *live = lttng::utils::container_of(
28ab034a 793 descriptor, &lttng_session_descriptor_live::base);
b178f53e
JG
794
795 header.live_timer_us = live->live_timer_us;
796 header_ptr = &header;
797 header_size = sizeof(header);
798 } else {
799 header_ptr = &header.base;
800 header_size = sizeof(header.base);
801 }
802
803 ret = lttng_dynamic_buffer_append(buffer, header_ptr, header_size);
804 if (ret) {
805 goto end;
806 }
807 if (header.base.name_len) {
28ab034a 808 ret = lttng_dynamic_buffer_append(buffer, descriptor->name, header.base.name_len);
b178f53e
JG
809 if (ret) {
810 goto end;
811 }
812 }
813
814 for (i = 0; i < uri_count; i++) {
28ab034a 815 ret = lttng_dynamic_buffer_append(buffer, uris[i], sizeof(struct lttng_uri));
b178f53e
JG
816 if (ret) {
817 goto end;
818 }
819 }
820end:
821 return ret;
822}
823
b178f53e 824enum lttng_session_descriptor_type
28ab034a 825lttng_session_descriptor_get_type(const struct lttng_session_descriptor *descriptor)
b178f53e
JG
826{
827 return descriptor->type;
828}
829
b178f53e 830enum lttng_session_descriptor_output_type
28ab034a 831lttng_session_descriptor_get_output_type(const struct lttng_session_descriptor *descriptor)
b178f53e
JG
832{
833 return descriptor->output_type;
834}
835
b178f53e 836void lttng_session_descriptor_get_local_output_uri(
28ab034a 837 const struct lttng_session_descriptor *descriptor, struct lttng_uri *local_uri)
b178f53e
JG
838{
839 memcpy(local_uri, descriptor->output.local, sizeof(*local_uri));
840}
841
b178f53e 842void lttng_session_descriptor_get_network_output_uris(
28ab034a
JG
843 const struct lttng_session_descriptor *descriptor,
844 struct lttng_uri *control,
845 struct lttng_uri *data)
b178f53e
JG
846{
847 memcpy(control, descriptor->output.network.control, sizeof(*control));
848 memcpy(data, descriptor->output.network.data, sizeof(*data));
849}
850
b178f53e 851unsigned long long
28ab034a 852lttng_session_descriptor_live_get_timer_interval(const struct lttng_session_descriptor *descriptor)
b178f53e
JG
853{
854 struct lttng_session_descriptor_live *live;
855
0114db0e 856 live = lttng::utils::container_of(descriptor, &lttng_session_descriptor_live::base);
b178f53e
JG
857 return live->live_timer_us;
858}
859
860enum lttng_session_descriptor_status
28ab034a
JG
861lttng_session_descriptor_get_session_name(const struct lttng_session_descriptor *descriptor,
862 const char **session_name)
b178f53e
JG
863{
864 enum lttng_session_descriptor_status status;
865
866 if (!descriptor || !session_name) {
867 status = LTTNG_SESSION_DESCRIPTOR_STATUS_INVALID;
868 goto end;
869 }
870
871 *session_name = descriptor->name;
28ab034a
JG
872 status = descriptor->name ? LTTNG_SESSION_DESCRIPTOR_STATUS_OK :
873 LTTNG_SESSION_DESCRIPTOR_STATUS_UNSET;
b178f53e
JG
874end:
875 return status;
876}
877
28ab034a
JG
878int lttng_session_descriptor_set_session_name(struct lttng_session_descriptor *descriptor,
879 const char *name)
b178f53e
JG
880{
881 int ret = 0;
882 char *new_name;
883
884 if (!name) {
885 goto end;
886 }
887 if (strlen(name) >= LTTNG_NAME_MAX) {
888 ret = -1;
889 goto end;
890 }
891 new_name = strdup(name);
892 if (!new_name) {
893 ret = -1;
894 goto end;
895 }
896 free(descriptor->name);
897 descriptor->name = new_name;
898end:
899 return ret;
900}
901
b178f53e 902bool lttng_session_descriptor_is_output_destination_initialized(
28ab034a 903 const struct lttng_session_descriptor *descriptor)
b178f53e
JG
904{
905 switch (descriptor->output_type) {
906 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
907 return true;
908 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
909 return descriptor->output.local;
910 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
911 return descriptor->output.network.control;
912 default:
913 abort();
914 }
915}
916
28ab034a 917bool lttng_session_descriptor_has_output_directory(const struct lttng_session_descriptor *descriptor)
b178f53e
JG
918{
919 switch (descriptor->output_type) {
920 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
921 break;
922 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
923 if (descriptor->output.local) {
924 return *descriptor->output.local->dst.path;
925 }
926 break;
927 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
928 if (descriptor->output.network.control) {
929 return *descriptor->output.network.control->subdir;
930 }
931 break;
932 default:
933 abort();
934 }
935 return false;
936}
937
28ab034a
JG
938enum lttng_error_code
939lttng_session_descriptor_set_default_output(struct lttng_session_descriptor *descriptor,
940 time_t *session_creation_time,
941 const char *absolute_home_path)
b178f53e
JG
942{
943 enum lttng_error_code ret_code = LTTNG_OK;
cd9adb8b 944 struct lttng_uri *uris = nullptr;
b178f53e
JG
945
946 switch (descriptor->output_type) {
947 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
948 goto end;
949 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
950 {
951 int ret;
952 ssize_t uri_ret;
953 char local_uri[LTTNG_PATH_MAX];
954 char creation_datetime_suffix[17] = {};
955
956 if (session_creation_time) {
957 size_t strftime_ret;
958 struct tm *timeinfo;
959
960 timeinfo = localtime(session_creation_time);
961 if (!timeinfo) {
962 ret_code = LTTNG_ERR_FATAL;
963 goto end;
964 }
965 strftime_ret = strftime(creation_datetime_suffix,
28ab034a
JG
966 sizeof(creation_datetime_suffix),
967 "-%Y%m%d-%H%M%S",
968 timeinfo);
b178f53e
JG
969 if (strftime_ret == 0) {
970 ERR("Failed to format session creation timestamp while setting default local output destination");
971 ret_code = LTTNG_ERR_FATAL;
972 goto end;
973 }
974 }
a0377dfe 975 LTTNG_ASSERT(descriptor->name);
28ab034a
JG
976 ret = snprintf(local_uri,
977 sizeof(local_uri),
978 "file://%s/%s/%s%s",
979 absolute_home_path,
980 DEFAULT_TRACE_DIR_NAME,
981 descriptor->name,
982 creation_datetime_suffix);
b178f53e
JG
983 if (ret >= sizeof(local_uri)) {
984 ERR("Truncation occurred while setting default local output destination");
985 ret_code = LTTNG_ERR_SET_URL;
986 goto end;
987 } else if (ret < 0) {
988 PERROR("Failed to format default local output URI");
989 ret_code = LTTNG_ERR_SET_URL;
990 goto end;
991 }
992
993 uri_ret = uri_parse(local_uri, &uris);
994 if (uri_ret != 1) {
995 ret_code = LTTNG_ERR_SET_URL;
996 goto end;
997 }
998 free(descriptor->output.local);
999 descriptor->output.local = &uris[0];
cd9adb8b 1000 uris = nullptr;
b178f53e
JG
1001 break;
1002 }
1003 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
1004 {
1005 int ret;
1006 ssize_t uri_ret;
cd9adb8b 1007 struct lttng_uri *control = nullptr, *data = nullptr;
b178f53e 1008
cd9adb8b 1009 uri_ret = uri_parse_str_urls("net://127.0.0.1", nullptr, &uris);
b178f53e
JG
1010 if (uri_ret != 2) {
1011 ret_code = LTTNG_ERR_SET_URL;
1012 goto end;
1013 }
1014
1015 control = uri_copy(&uris[0]);
1016 data = uri_copy(&uris[1]);
1017 if (!control || !data) {
1018 free(control);
1019 free(data);
1020 ret_code = LTTNG_ERR_SET_URL;
1021 goto end;
1022 }
1023
1024 /* Ownership of uris is transferred. */
1025 ret = network_location_set_from_lttng_uris(
28ab034a 1026 &descriptor->output.network, control, data);
b178f53e
JG
1027 if (ret) {
1028 abort();
1029 ret_code = LTTNG_ERR_SET_URL;
1030 goto end;
1031 }
1032 break;
1033 }
1034 default:
1035 abort();
1036 }
1037end:
1038 free(uris);
1039 return ret_code;
1040}
1041
1042/*
1043 * Note that only properties that can be populated by the session daemon
1044 * (output destination and name) are assigned.
1045 */
28ab034a
JG
1046int lttng_session_descriptor_assign(struct lttng_session_descriptor *dst,
1047 const struct lttng_session_descriptor *src)
b178f53e
JG
1048{
1049 int ret = 0;
1050
1051 if (dst->type != src->type) {
1052 ret = -1;
1053 goto end;
1054 }
1055 if (dst->output_type != src->output_type) {
1056 ret = -1;
1057 goto end;
1058 }
1059 ret = lttng_session_descriptor_set_session_name(dst, src->name);
1060 if (ret) {
1061 goto end;
1062 }
1063 switch (dst->output_type) {
1064 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_LOCAL:
1065 free(dst->output.local);
1066 dst->output.local = uri_copy(src->output.local);
1067 if (!dst->output.local) {
1068 ret = -1;
1069 goto end;
1070 }
1071 break;
1072 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NETWORK:
1073 {
cd9adb8b 1074 struct lttng_uri *control_copy = nullptr, *data_copy = nullptr;
b178f53e
JG
1075
1076 control_copy = uri_copy(dst->output.network.control);
1077 if (!control_copy && dst->output.network.control) {
1078 ret = -1;
1079 goto end;
1080 }
1081 data_copy = uri_copy(dst->output.network.data);
1082 if (!data_copy && dst->output.network.data) {
1083 free(control_copy);
1084 ret = -1;
1085 goto end;
1086 }
28ab034a
JG
1087 ret = network_location_set_from_lttng_uris(
1088 &dst->output.network, control_copy, data_copy);
b178f53e
JG
1089 break;
1090 }
1091 case LTTNG_SESSION_DESCRIPTOR_OUTPUT_TYPE_NONE:
1092 goto end;
1093 }
1094end:
1095 return ret;
1096}
This page took 0.110567 seconds and 4 git commands to generate.