Tests: Add test to check shared-memory FD leaks after relayd dies
[lttng-tools.git] / src / lib / lttng-ctl / load.c
1 /*
2 * Copyright (C) 2014 David Goulet <dgoulet@efficios.com>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 *
6 */
7
8 #define _LGPL_SOURCE
9 #include <string.h>
10 #include <limits.h>
11
12 #include <lttng/lttng-error.h>
13 #include <lttng/load.h>
14 #include <lttng/load-internal.h>
15 #include <common/sessiond-comm/sessiond-comm.h>
16 #include <common/config/session-config.h>
17 #include <common/uri.h>
18 #include <common/macros.h>
19 #include <common/compat/string.h>
20
21 #include "lttng-ctl-helper.h"
22
23 struct lttng_load_session_attr *lttng_load_session_attr_create(void)
24 {
25 return zmalloc(sizeof(struct lttng_load_session_attr));
26 }
27
28 static
29 void reset_load_session_attr_urls(struct lttng_load_session_attr *attr)
30 {
31 free(attr->raw_override_url);
32 free(attr->raw_override_path_url);
33 free(attr->raw_override_ctrl_url);
34 free(attr->raw_override_data_url);
35 if (attr->override_attr) {
36 free(attr->override_attr->path_url);
37 free(attr->override_attr->ctrl_url);
38 free(attr->override_attr->data_url);
39 free(attr->override_attr->session_name);
40 }
41 }
42
43 void lttng_load_session_attr_destroy(struct lttng_load_session_attr *attr)
44 {
45 if (attr) {
46 reset_load_session_attr_urls(attr);
47 free(attr->override_attr);
48 free(attr);
49 }
50 }
51
52 static int validate_attr(const struct lttng_load_session_attr *attr)
53 {
54 int ret = 0;
55
56 if (!attr) {
57 ret = -LTTNG_ERR_INVALID;
58 goto end;
59 }
60
61 if (!attr->override_attr) {
62 goto end;
63 }
64
65 /*
66 * Refuse override name if the objective is to load multiple session
67 * since this operation is ambiguous while loading multiple session.
68 */
69 if (attr->override_attr->session_name
70 && attr->session_name[0] == '\0') {
71 ret = -LTTNG_ERR_INVALID;
72 goto end;
73 }
74 end:
75 return ret;
76 }
77
78 const char *lttng_load_session_attr_get_session_name(
79 struct lttng_load_session_attr *attr)
80 {
81 const char *ret = NULL;
82
83 if (attr && attr->session_name[0]) {
84 ret = attr->session_name;
85 }
86
87 return ret;
88 }
89
90 const char *lttng_load_session_attr_get_input_url(
91 struct lttng_load_session_attr *attr)
92 {
93 const char *ret = NULL;
94
95 if (attr && attr->input_url[0]) {
96 ret = attr->input_url;
97 }
98
99 return ret;
100 }
101
102 int lttng_load_session_attr_get_overwrite(
103 struct lttng_load_session_attr *attr)
104 {
105 return attr ? attr->overwrite : -LTTNG_ERR_INVALID;
106 }
107
108 const char *lttng_load_session_attr_get_override_ctrl_url(
109 struct lttng_load_session_attr *attr)
110 {
111 const char *ret = NULL;
112
113 if (!attr || !attr->override_attr) {
114 goto end;
115 }
116
117 ret = attr->raw_override_ctrl_url;
118 end:
119 return ret;
120 }
121
122 const char *lttng_load_session_attr_get_override_data_url(
123 struct lttng_load_session_attr *attr)
124 {
125 const char *ret = NULL;
126
127 if (!attr || !attr->override_attr) {
128 goto end;
129 }
130
131 ret = attr->raw_override_data_url;
132 end:
133 return ret;
134 }
135
136 const char *lttng_load_session_attr_get_override_url(
137 struct lttng_load_session_attr *attr)
138 {
139 const char *ret = NULL;
140
141 if (!attr || !attr->override_attr) {
142 goto end;
143 }
144
145 if ((attr->override_attr->path_url ||
146 (attr->override_attr->ctrl_url &&
147 attr->override_attr->data_url))) {
148 ret = attr->raw_override_url;
149 }
150 end:
151 return ret;
152 }
153
154 const char *lttng_load_session_attr_get_override_session_name(
155 struct lttng_load_session_attr *attr)
156 {
157 const char *ret = NULL;
158
159 if (!attr || !attr->override_attr) {
160 goto end;
161 }
162
163 ret = attr->override_attr->session_name;
164 end:
165 return ret;
166 }
167
168 int lttng_load_session_attr_set_session_name(
169 struct lttng_load_session_attr *attr, const char *session_name)
170 {
171 int ret = 0;
172
173 if (!attr) {
174 ret = -LTTNG_ERR_INVALID;
175 goto error;
176 }
177
178 if (session_name) {
179 size_t len;
180
181 len = strlen(session_name);
182 if (len >= LTTNG_NAME_MAX) {
183 ret = -LTTNG_ERR_INVALID;
184 goto error;
185 }
186
187 ret = lttng_strncpy(attr->session_name, session_name,
188 sizeof(attr->session_name));
189 if (ret) {
190 ret = -LTTNG_ERR_INVALID;
191 goto error;
192 }
193 } else {
194 attr->session_name[0] = '\0';
195 }
196 error:
197 return ret;
198 }
199
200 int lttng_load_session_attr_set_input_url(
201 struct lttng_load_session_attr *attr, const char *url)
202 {
203 int ret = 0;
204 size_t len;
205 ssize_t size;
206 struct lttng_uri *uris = NULL;
207
208 if (!attr) {
209 ret = -LTTNG_ERR_INVALID;
210 goto error;
211 }
212
213 if (!url) {
214 attr->input_url[0] = '\0';
215 ret = 0;
216 goto end;
217 }
218
219 len = strlen(url);
220 if (len >= PATH_MAX) {
221 ret = -LTTNG_ERR_INVALID;
222 goto error;
223 }
224
225 size = uri_parse_str_urls(url, NULL, &uris);
226 if (size <= 0 || uris[0].dtype != LTTNG_DST_PATH) {
227 ret = -LTTNG_ERR_INVALID;
228 goto error;
229 }
230
231 /* Copy string plus the NULL terminated byte. */
232 ret = lttng_strncpy(attr->input_url, uris[0].dst.path,
233 sizeof(attr->input_url));
234 if (ret) {
235 ret = -LTTNG_ERR_INVALID;
236 goto error;
237 }
238
239 end:
240 error:
241 free(uris);
242 return ret;
243 }
244
245 int lttng_load_session_attr_set_overwrite(
246 struct lttng_load_session_attr *attr, int overwrite)
247 {
248 int ret = 0;
249
250 if (!attr) {
251 ret = -LTTNG_ERR_INVALID;
252 goto end;
253 }
254
255 attr->overwrite = !!overwrite;
256 end:
257 return ret;
258 }
259
260 int lttng_load_session_attr_set_override_ctrl_url(
261 struct lttng_load_session_attr *attr, const char *url)
262 {
263 int ret = 0;
264 ssize_t ret_size;
265 struct lttng_uri *uri = NULL;
266 char *url_str = NULL;
267 char *raw_str = NULL;
268
269 if (!attr) {
270 ret = -LTTNG_ERR_INVALID;
271 goto end;
272 }
273
274 if (!attr->override_attr) {
275 attr->override_attr = zmalloc(
276 sizeof(struct config_load_session_override_attr));
277 if (!attr->override_attr) {
278 ret = -LTTNG_ERR_NOMEM;
279 goto end;
280 }
281 }
282
283 if (attr->override_attr->path_url) {
284 /*
285 * Setting a ctrl override after a path override makes no sense.
286 */
287 ret = -LTTNG_ERR_INVALID;
288 goto end;
289 }
290
291 /*
292 * FIXME: uri_parse should be able to take as parameter the protocol
293 * type to validate "url". For now only check the parsing goes through;
294 * it will fail later on.
295 */
296 ret_size = uri_parse(url, &uri);
297 if (ret_size < 0) {
298 ret = -LTTNG_ERR_INVALID;
299 goto end;
300 }
301
302 if (uri[0].port == 0) {
303 uri[0].port = DEFAULT_NETWORK_CONTROL_PORT;
304 }
305
306 url_str = zmalloc(PATH_MAX);
307 if (!url_str) {
308 /* FIXME: return valid error */
309 ret = -LTTNG_ERR_NOMEM;
310 goto end;
311 }
312
313 ret = uri_to_str_url(&uri[0], url_str, PATH_MAX);
314 if (ret < 0) {
315 ret = -LTTNG_ERR_INVALID;
316 goto end;
317 }
318 ret = 0;
319
320 raw_str = lttng_strndup(url, PATH_MAX);
321 if (!raw_str) {
322 ret = -LTTNG_ERR_NOMEM;
323 goto end;
324 }
325
326 /* Squash old value if any */
327 free(attr->override_attr->ctrl_url);
328 free(attr->raw_override_ctrl_url);
329
330 /* Populate the object */
331 attr->override_attr->ctrl_url = url_str;
332 attr->raw_override_ctrl_url = raw_str;
333
334 /* Ownership passed to attr. */
335 url_str = NULL;
336 raw_str = NULL;
337
338 end:
339 free(raw_str);
340 free(url_str);
341 free(uri);
342 return ret;
343 }
344
345 int lttng_load_session_attr_set_override_data_url(
346 struct lttng_load_session_attr *attr, const char *url)
347 {
348 int ret = 0;
349 ssize_t ret_size;
350 struct lttng_uri *uri = NULL;
351 char *url_str = NULL;
352 char *raw_str = NULL;
353
354 if (!attr) {
355 ret = -LTTNG_ERR_INVALID;
356 goto end;
357 }
358
359 if (!attr->override_attr) {
360 attr->override_attr = zmalloc(
361 sizeof(struct config_load_session_override_attr));
362 if (!attr->override_attr) {
363 ret = -LTTNG_ERR_NOMEM;
364 goto end;
365 }
366 }
367
368 if (attr->override_attr->path_url) {
369 /*
370 * Setting a data override after a path override makes no sense.
371 */
372 ret = -LTTNG_ERR_INVALID;
373 goto end;
374 }
375
376 /*
377 * FIXME: uri_parse should be able to take as parameter the protocol
378 * type to validate "url". For now only check the parsing goes through;
379 * it will fail later on.
380 */
381 ret_size = uri_parse(url, &uri);
382 if (ret_size < 0) {
383 ret = -LTTNG_ERR_INVALID;
384 goto end;
385 }
386
387 if (uri[0].port == 0) {
388 uri[0].port = DEFAULT_NETWORK_DATA_PORT;
389 }
390
391 url_str = zmalloc(PATH_MAX);
392 if (!url_str) {
393 ret = -LTTNG_ERR_NOMEM;
394 goto end;
395 }
396
397 ret = uri_to_str_url(&uri[0], url_str, PATH_MAX);
398 if (ret < 0) {
399 ret = -LTTNG_ERR_INVALID;
400 goto end;
401 }
402 ret = 0;
403
404 raw_str = lttng_strndup(url, PATH_MAX);
405 if (!raw_str) {
406 ret = -LTTNG_ERR_NOMEM;
407 goto end;
408 }
409
410 /* Squash old value if any */
411 free(attr->override_attr->data_url);
412 free(attr->raw_override_data_url);
413
414 /* Populate the object */
415 attr->override_attr->data_url = url_str;
416 attr->raw_override_data_url = raw_str;
417
418 /* Ownership passed to attr. */
419 url_str = NULL;
420 raw_str = NULL;
421 end:
422 free(raw_str);
423 free(url_str);
424 free(uri);
425 return ret;
426 }
427
428 int lttng_load_session_attr_set_override_url(
429 struct lttng_load_session_attr *attr, const char *url)
430 {
431 int ret = 0;
432 ssize_t ret_size;
433 struct lttng_uri *uri = NULL;
434 char *raw_url_str = NULL;
435 char *raw_path_str = NULL;
436 char *path_str = NULL;
437 char *raw_ctrl_str = NULL;
438 char *ctrl_str = NULL;
439 char *raw_data_str = NULL;
440 char *data_str = NULL;
441 char buffer[PATH_MAX];
442
443 if (!attr || !url || strlen(url) >= PATH_MAX) {
444 ret = -LTTNG_ERR_INVALID;
445 goto end;
446 }
447
448 if (!attr->override_attr) {
449 attr->override_attr = zmalloc(
450 sizeof(struct config_load_session_override_attr));
451 if (!attr->override_attr) {
452 ret = -LTTNG_ERR_NOMEM;
453 goto end;
454 }
455 }
456
457 /*
458 * FIXME: uri_parse should be able to take as parameter the protocol
459 * type to validate "url". For now only check the parsing goes through;
460 * it will fail later on.
461 */
462 ret_size = uri_parse_str_urls(url, NULL, &uri);
463 if (ret_size < 0 || ret_size > 2) {
464 /* Unexpected URL format. */
465 ret = -LTTNG_ERR_INVALID;
466 goto end;
467 }
468
469 raw_url_str = lttng_strndup(url, PATH_MAX);
470 if (!raw_url_str) {
471 ret = -LTTNG_ERR_NOMEM;
472 goto end;
473 }
474
475 /* Get path | ctrl && data string URL. */
476 ret = uri_to_str_url(&uri[0], buffer, sizeof(buffer));
477 if (ret < 0 || ret >= PATH_MAX) {
478 ret = -LTTNG_ERR_INVALID;
479 goto end;
480 }
481 ret = 0;
482
483 switch (uri[0].dtype) {
484 case LTTNG_DST_PATH:
485 raw_path_str = lttng_strndup(buffer, PATH_MAX);
486 if (!raw_path_str) {
487 ret = -LTTNG_ERR_NOMEM;
488 goto end;
489 }
490
491 path_str = lttng_strndup(raw_path_str, PATH_MAX);
492 if (!path_str) {
493 ret = -LTTNG_ERR_NOMEM;
494 goto end;
495 }
496 break;
497 case LTTNG_DST_IPV4:
498 case LTTNG_DST_IPV6:
499 if (ret_size != 2) {
500 ret = -LTTNG_ERR_INVALID;
501 goto end;
502 }
503
504 raw_ctrl_str = lttng_strndup(buffer, PATH_MAX);
505 if (!raw_ctrl_str) {
506 ret = -LTTNG_ERR_NOMEM;
507 goto end;
508 }
509
510 ctrl_str = lttng_strndup(raw_ctrl_str, PATH_MAX);
511 if (!ctrl_str) {
512 ret = -LTTNG_ERR_NOMEM;
513 goto end;
514 }
515
516 /* Get the data uri. */
517 ret = uri_to_str_url(&uri[1], buffer, sizeof(buffer));
518 if (ret < 0) {
519 ret = -LTTNG_ERR_INVALID;
520 goto end;
521 }
522 ret = 0;
523
524 raw_data_str = lttng_strndup(buffer, PATH_MAX);
525 if (!raw_data_str) {
526 ret = -LTTNG_ERR_NOMEM;
527 goto end;
528 }
529
530 data_str = lttng_strndup(raw_data_str, PATH_MAX);
531 if (!data_str) {
532 ret = -LTTNG_ERR_NOMEM;
533 goto end;
534 }
535
536 break;
537 default:
538 ret = -LTTNG_ERR_INVALID;
539 goto end;
540 }
541
542 reset_load_session_attr_urls(attr);
543
544 attr->override_attr->path_url = path_str;
545 attr->override_attr->ctrl_url = ctrl_str;
546 attr->override_attr->data_url = data_str;
547
548 attr->raw_override_url = raw_url_str;
549 attr->raw_override_path_url = raw_path_str;
550 attr->raw_override_ctrl_url = raw_ctrl_str;
551 attr->raw_override_data_url = raw_data_str;
552
553 /* Pass data ownership to attr. */
554 raw_url_str = NULL;
555 raw_path_str = NULL;
556 path_str = NULL;
557 raw_ctrl_str = NULL;
558 ctrl_str = NULL;
559 raw_data_str = NULL;
560 data_str = NULL;
561
562 end:
563 free(raw_path_str);
564 free(path_str);
565 free(raw_ctrl_str);
566 free(ctrl_str);
567 free(raw_data_str);
568 free(data_str);
569 free(raw_url_str);
570 free(uri);
571 return ret;
572 }
573
574 int lttng_load_session_attr_set_override_session_name(
575 struct lttng_load_session_attr *attr, const char *session_name)
576 {
577 int ret = 0;
578 size_t len;
579
580 if (!attr ||!session_name) {
581 ret = -LTTNG_ERR_INVALID;
582 goto end;
583 }
584
585 if (!attr->override_attr) {
586 attr->override_attr = zmalloc(
587 sizeof(struct config_load_session_override_attr));
588 if (!attr->override_attr) {
589 ret = -LTTNG_ERR_NOMEM;
590 goto end;
591 }
592 }
593
594 len = strlen(session_name);
595 if (len >= LTTNG_NAME_MAX) {
596 ret = -LTTNG_ERR_INVALID;
597 goto end;
598 }
599
600 attr->override_attr->session_name = lttng_strndup(session_name,
601 len);
602 if (!attr->override_attr->session_name) {
603 ret = -LTTNG_ERR_NOMEM;
604 goto end;
605 }
606 end:
607 return ret;
608 }
609
610 int lttng_load_session(struct lttng_load_session_attr *attr)
611 {
612 int ret;
613 const char *url, *session_name;
614
615 if (!attr) {
616 ret = -LTTNG_ERR_INVALID;
617 goto end;
618 }
619
620 ret = validate_attr(attr);
621 if (ret) {
622 goto end;
623 }
624
625 url = attr->input_url[0] != '\0' ? attr->input_url : NULL;
626 session_name = attr->session_name[0] != '\0' ?
627 attr->session_name : NULL;
628
629 ret = config_load_session(url, session_name, attr->overwrite, 0,
630 attr->override_attr);
631
632 end:
633 return ret;
634 }
This page took 0.040529 seconds and 4 git commands to generate.