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