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