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