Run clang-format on the whole tree
[lttng-tools.git] / src / bin / lttng / commands / create.cpp
CommitLineData
f3ed775e 1/*
21cf9b6b 2 * Copyright (C) 2011 EfficiOS Inc.
ab5be9fa 3 * Copyright (C) 2019 Jérémie Galarneau <jeremie.galarneau@efficios.com>
f3ed775e 4 *
ab5be9fa 5 * SPDX-License-Identifier: GPL-2.0-only
f3ed775e 6 *
f3ed775e
DG
7 */
8
6c1c0768 9#define _LGPL_SOURCE
c9e313bc
SM
10#include "../command.hpp"
11#include "../utils.hpp"
f3ed775e 12
28ab034a 13#include <common/compat/time.hpp>
c9e313bc 14#include <common/defaults.hpp>
28ab034a
JG
15#include <common/mi-lttng.hpp>
16#include <common/path.hpp>
c9e313bc
SM
17#include <common/sessiond-comm/sessiond-comm.hpp>
18#include <common/uri.hpp>
19#include <common/utils.hpp>
28ab034a 20
050dd639 21#include <lttng/lttng.h>
42224349 22
28ab034a
JG
23#include <ctype.h>
24#include <popt.h>
25#include <signal.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include <sys/stat.h>
30#include <sys/types.h>
31#include <sys/wait.h>
32#include <unistd.h>
33
f3ed775e 34static char *opt_output_path;
a4b92340
DG
35static char *opt_url;
36static char *opt_ctrl_url;
37static char *opt_data_url;
d7ba1388 38static char *opt_shm_path;
a4b92340 39static int opt_no_consumer;
96fe6b8d 40static int opt_no_output;
16f6f820 41static int opt_snapshot;
c7219617 42static uint32_t opt_live_timer;
f3ed775e 43
4fc83d94
PP
44#ifdef LTTNG_EMBED_HELP
45static const char help_msg[] =
46#include <lttng-create.1.h>
28ab034a 47 ;
4fc83d94
PP
48#endif
49
f3ed775e
DG
50enum {
51 OPT_HELP = 1,
679b4943 52 OPT_LIST_OPTIONS,
ecc48a90 53 OPT_LIVE_TIMER,
f3ed775e
DG
54};
55
b178f53e
JG
56enum output_type {
57 OUTPUT_NONE,
58 OUTPUT_LOCAL,
59 OUTPUT_NETWORK,
60 OUTPUT_UNSPECIFIED,
61};
37d03ff7 62
b178f53e 63static struct mi_writer *writer;
f3ed775e
DG
64static struct poptOption long_options[] = {
65 /* longName, shortName, argInfo, argPtr, value, descrip, argDesc */
28ab034a
JG
66 { "help", 'h', POPT_ARG_NONE, NULL, OPT_HELP, NULL, NULL },
67 { "output", 'o', POPT_ARG_STRING, &opt_output_path, 0, NULL, NULL },
68 { "list-options", 0, POPT_ARG_NONE, NULL, OPT_LIST_OPTIONS, NULL, NULL },
69 { "set-url", 'U', POPT_ARG_STRING, &opt_url, 0, 0, 0 },
70 { "ctrl-url", 'C', POPT_ARG_STRING, &opt_ctrl_url, 0, 0, 0 },
71 { "data-url", 'D', POPT_ARG_STRING, &opt_data_url, 0, 0, 0 },
72 { "no-output", 0, POPT_ARG_VAL, &opt_no_output, 1, 0, 0 },
73 { "no-consumer", 0, POPT_ARG_VAL, &opt_no_consumer, 1, 0, 0 },
74 { "snapshot", 0, POPT_ARG_VAL, &opt_snapshot, 1, 0, 0 },
75 { "live", 0, POPT_ARG_INT | POPT_ARGFLAG_OPTIONAL, 0, OPT_LIVE_TIMER, 0, 0 },
76 { "shm-path", 0, POPT_ARG_STRING, &opt_shm_path, 0, 0, 0 },
77 { 0, 0, 0, 0, 0, 0, 0 }
f3ed775e
DG
78};
79
37d03ff7 80/*
485ca16f 81 * Retrieve the created session and mi output it based on provided argument
37d03ff7
JRJ
82 * This is currently a summary of what was pretty printed and is subject to
83 * enhancements.
37d03ff7
JRJ
84 */
85static int mi_created_session(const char *session_name)
86{
87 int ret, i, count, found;
88 struct lttng_session *sessions;
89
90 /* session_name should not be null */
a0377dfe
FD
91 LTTNG_ASSERT(session_name);
92 LTTNG_ASSERT(writer);
37d03ff7
JRJ
93
94 count = lttng_list_sessions(&sessions);
95 if (count < 0) {
96 ret = count;
97 ERR("%s", lttng_strerror(ret));
98 goto error;
99 }
100
101 if (count == 0) {
102 ERR("Error session creation failed: session %s not found", session_name);
103 ret = -LTTNG_ERR_SESS_NOT_FOUND;
104 goto end;
105 }
106
107 found = 0;
108 for (i = 0; i < count; i++) {
109 if (strncmp(sessions[i].name, session_name, NAME_MAX) == 0) {
110 found = 1;
111 ret = mi_lttng_session(writer, &sessions[i], 0);
112 if (ret) {
113 goto error;
114 }
115 break;
116 }
117 }
118
119 if (!found) {
120 ret = -LTTNG_ERR_SESS_NOT_FOUND;
121 } else {
122 ret = CMD_SUCCESS;
123 }
124
125error:
126 free(sessions);
127end:
128 return ret;
129}
130
28ab034a 131static struct lttng_session_descriptor *create_session_descriptor(const char *session_name)
16f6f820 132{
b178f53e
JG
133 ssize_t uri_count;
134 enum output_type output_type;
135 struct lttng_uri *uris = NULL;
136 struct lttng_session_descriptor *descriptor = NULL;
137 const char *uri_str1 = NULL, *uri_str2 = NULL;
138 char local_output_path[LTTNG_PATH_MAX] = {};
139
140 if (opt_no_output) {
141 output_type = OUTPUT_NONE;
142 } else if (opt_output_path) {
143 char *expanded_output_path;
21a4b056 144 int ret;
b178f53e
JG
145
146 output_type = OUTPUT_LOCAL;
147 expanded_output_path = utils_expand_path(opt_output_path);
148 if (!expanded_output_path) {
149 ERR("Failed to expand output path.");
150 goto end;
151 }
28ab034a
JG
152 ret = lttng_strncpy(
153 local_output_path, expanded_output_path, sizeof(local_output_path));
b178f53e
JG
154 free(expanded_output_path);
155 if (ret) {
156 ERR("Output path exceeds the maximal supported length (%zu bytes)",
28ab034a 157 sizeof(local_output_path));
b178f53e
JG
158 goto end;
159 }
160 } else if (opt_url || opt_ctrl_url) {
21a4b056
SM
161 int ret;
162
b178f53e
JG
163 uri_str1 = opt_ctrl_url ? opt_ctrl_url : opt_url;
164 uri_str2 = opt_data_url;
165
166 uri_count = uri_parse_str_urls(uri_str1, uri_str2, &uris);
167 if (uri_count != 1 && uri_count != 2) {
168 ERR("Unrecognized URL format.");
169 goto end;
170 }
16f6f820 171
b178f53e
JG
172 switch (uri_count) {
173 case 1:
174 output_type = OUTPUT_LOCAL;
175 if (uris[0].dtype != LTTNG_DST_PATH) {
176 ERR("Unrecognized URL format.");
177 goto end;
178 }
28ab034a
JG
179 ret = lttng_strncpy(
180 local_output_path, uris[0].dst.path, sizeof(local_output_path));
b178f53e
JG
181 if (ret) {
182 ERR("Output path exceeds the maximal supported length (%zu bytes)",
28ab034a 183 sizeof(local_output_path));
b178f53e
JG
184 }
185 break;
186 case 2:
187 output_type = OUTPUT_NETWORK;
188 break;
189 default:
190 /* Already checked. */
191 abort();
192 }
193 } else {
194 output_type = OUTPUT_UNSPECIFIED;
16f6f820
DG
195 }
196
b178f53e
JG
197 if (opt_snapshot) {
198 /* Snapshot session. */
199 switch (output_type) {
200 case OUTPUT_UNSPECIFIED:
201 case OUTPUT_LOCAL:
202 descriptor = lttng_session_descriptor_snapshot_local_create(
28ab034a
JG
203 session_name,
204 output_type == OUTPUT_LOCAL ? local_output_path : NULL);
b178f53e
JG
205 break;
206 case OUTPUT_NONE:
28ab034a 207 descriptor = lttng_session_descriptor_snapshot_create(session_name);
b178f53e
JG
208 break;
209 case OUTPUT_NETWORK:
210 descriptor = lttng_session_descriptor_snapshot_network_create(
28ab034a 211 session_name, uri_str1, uri_str2);
b178f53e
JG
212 break;
213 default:
214 abort();
16f6f820 215 }
b178f53e
JG
216 } else if (opt_live_timer) {
217 /* Live session. */
28ab034a 218 if (output_type != OUTPUT_UNSPECIFIED && output_type != OUTPUT_NETWORK) {
b178f53e
JG
219 ERR("Unsupported output type specified for live session.");
220 goto end;
221 }
222 descriptor = lttng_session_descriptor_live_network_create(
28ab034a 223 session_name, uri_str1, uri_str2, opt_live_timer);
b178f53e
JG
224 } else {
225 /* Regular session. */
226 switch (output_type) {
227 case OUTPUT_UNSPECIFIED:
228 case OUTPUT_LOCAL:
229 descriptor = lttng_session_descriptor_local_create(
28ab034a
JG
230 session_name,
231 output_type == OUTPUT_LOCAL ? local_output_path : NULL);
b178f53e
JG
232 break;
233 case OUTPUT_NONE:
28ab034a 234 descriptor = lttng_session_descriptor_create(session_name);
b178f53e
JG
235 break;
236 case OUTPUT_NETWORK:
237 descriptor = lttng_session_descriptor_network_create(
28ab034a 238 session_name, uri_str1, uri_str2);
b178f53e
JG
239 break;
240 default:
241 abort();
16f6f820
DG
242 }
243 }
b178f53e
JG
244 if (!descriptor) {
245 ERR("Failed to initialize session creation command.");
973ad93e
JG
246 } else {
247 /*
248 * Auto-launch the relay daemon when a live session
249 * is created using default URLs.
250 */
28ab034a
JG
251 if (!opt_url && !opt_ctrl_url && !opt_data_url && opt_live_timer &&
252 !check_relayd()) {
973ad93e 253 int ret;
28ab034a 254 const char *pathname = opt_relayd_path ?: INSTALL_BIN_PATH "/lttng-relayd";
973ad93e
JG
255
256 ret = spawn_relayd(pathname, 0);
257 if (ret < 0) {
258 lttng_session_descriptor_destroy(descriptor);
259 descriptor = NULL;
260 }
261 }
16f6f820 262 }
b178f53e
JG
263end:
264 free(uris);
265 return descriptor;
16f6f820
DG
266}
267
f3ed775e 268/*
1c8d13c8
TD
269 * Create a tracing session.
270 * If no name is specified, a default name is generated.
f3ed775e 271 *
1c8d13c8 272 * Returns one of the CMD_* result constants.
f3ed775e 273 */
5b915816 274static int create_session(const char *session_name)
f3ed775e 275{
b178f53e
JG
276 int ret, i;
277 char shm_path[LTTNG_PATH_MAX] = {};
278 struct lttng_session_descriptor *session_descriptor = NULL;
279 enum lttng_session_descriptor_status descriptor_status;
280 enum lttng_error_code ret_code;
281 struct lttng_session *sessions = NULL;
282 const struct lttng_session *created_session = NULL;
283 const char *created_session_name;
284
285 /* Validate options. */
5b915816
MJ
286 if (session_name) {
287 if (strlen(session_name) > NAME_MAX) {
28ab034a 288 ERR("Session name too long. Length must be lower or equal to %d", NAME_MAX);
b178f53e 289 ret = CMD_ERROR;
487b253b
DG
290 goto error;
291 }
4b861950
DG
292 /*
293 * Check if the session name begins with "auto-" or is exactly "auto".
294 * Both are reserved for the default session name. See bug #449 to
295 * understand why we need to check both here.
296 */
28ab034a
JG
297 if ((strncmp(session_name,
298 DEFAULT_SESSION_NAME "-",
299 strlen(DEFAULT_SESSION_NAME) + 1) == 0) ||
300 (strncmp(session_name, DEFAULT_SESSION_NAME, strlen(DEFAULT_SESSION_NAME)) ==
301 0 &&
302 strlen(session_name) == strlen(DEFAULT_SESSION_NAME))) {
61b35a5a 303 ERR("%s is a reserved keyword for default session(s)",
28ab034a 304 DEFAULT_SESSION_NAME);
61b35a5a
DG
305 ret = CMD_ERROR;
306 goto error;
307 }
f3ed775e
DG
308 }
309
b178f53e
JG
310 if (opt_snapshot && opt_live_timer) {
311 ERR("Snapshot and live modes are mutually exclusive.");
1a241656
DG
312 ret = CMD_ERROR;
313 goto error;
314 }
315
b178f53e
JG
316 if ((!opt_ctrl_url && opt_data_url) || (opt_ctrl_url && !opt_data_url)) {
317 ERR("Both control and data URLs must be specified.");
318 ret = CMD_ERROR;
319 goto error;
00e2e675
DG
320 }
321
5b915816 322 session_descriptor = create_session_descriptor(session_name);
b178f53e
JG
323 if (!session_descriptor) {
324 ret = CMD_ERROR;
325 goto error;
ecc48a90 326 }
b178f53e
JG
327 ret_code = lttng_create_session_ext(session_descriptor);
328 if (ret_code != LTTNG_OK) {
329 ERR("%s", lttng_strerror(-ret_code));
ecc48a90
JD
330 ret = CMD_ERROR;
331 goto error;
332 }
333
28ab034a
JG
334 descriptor_status = lttng_session_descriptor_get_session_name(session_descriptor,
335 &created_session_name);
b178f53e
JG
336 if (descriptor_status != LTTNG_SESSION_DESCRIPTOR_STATUS_OK) {
337 ERR("Failed to obtain created session name");
338 ret = CMD_ERROR;
339 goto error;
16f6f820 340 }
b178f53e
JG
341
342 ret = lttng_list_sessions(&sessions);
f3ed775e 343 if (ret < 0) {
28ab034a 344 ERR("Failed to fetch properties of created session: %s", lttng_strerror(ret));
b178f53e
JG
345 ret = CMD_ERROR;
346 goto error;
347 }
348 for (i = 0; i < ret; i++) {
349 if (!strcmp(created_session_name, sessions[i].name)) {
350 created_session = &sessions[i];
60e835ca 351 break;
42224349 352 }
b178f53e
JG
353 }
354 if (!created_session) {
355 ERR("Failed to fetch properties of created session");
356 ret = CMD_ERROR;
f3ed775e
DG
357 goto error;
358 }
359
b178f53e
JG
360 if (opt_shm_path) {
361 char datetime_suffix[17] = {};
362
363 /*
364 * An auto-generated session name already includes the creation
365 * timestamp.
366 */
5b915816 367 if (session_name) {
b178f53e
JG
368 uint64_t creation_time;
369 struct tm *timeinfo;
370 time_t creation_time_t;
371 size_t strftime_ret;
372
28ab034a 373 ret_code = lttng_session_get_creation_time(created_session, &creation_time);
b178f53e
JG
374 if (ret_code != LTTNG_OK) {
375 ERR("%s", lttng_strerror(-ret_code));
376 ret = CMD_ERROR;
377 goto error;
378 }
379 creation_time_t = (time_t) creation_time;
380 timeinfo = localtime(&creation_time_t);
381 if (!timeinfo) {
382 PERROR("Failed to interpret session creation time");
383 ret = CMD_ERROR;
384 goto error;
385 }
386 strftime_ret = strftime(datetime_suffix,
28ab034a
JG
387 sizeof(datetime_suffix),
388 "-%Y%m%d-%H%M%S",
389 timeinfo);
b178f53e
JG
390 if (strftime_ret == 0) {
391 ERR("Failed to format session creation time.");
392 ret = CMD_ERROR;
393 goto error;
394 }
a4b92340 395 }
4f50c803 396
28ab034a
JG
397 ret = snprintf(shm_path,
398 sizeof(shm_path),
399 "%s/%s%s",
400 opt_shm_path,
401 created_session_name,
402 datetime_suffix);
b178f53e
JG
403 if (ret < 0 || ret >= sizeof(shm_path)) {
404 ERR("Failed to format the shared memory path.");
405 ret = CMD_ERROR;
d7ba1388
MD
406 goto error;
407 }
28ab034a 408 ret = lttng_set_session_shm_path(created_session_name, shm_path);
d7ba1388 409 if (ret < 0) {
b178f53e
JG
410 lttng_destroy_session(created_session_name);
411 ret = CMD_ERROR;
d7ba1388
MD
412 goto error;
413 }
414 }
415
b178f53e
JG
416 if (opt_snapshot) {
417 MSG("Snapshot session %s created.", created_session_name);
418 } else if (opt_live_timer) {
419 MSG("Live session %s created.", created_session_name);
420 } else {
421 MSG("Session %s created.", created_session_name);
422 }
423
424 if (*created_session->path && !opt_snapshot) {
425 MSG("Traces will be output to %s", created_session->path);
d73c5802
DG
426
427 if (opt_live_timer) {
28ab034a 428 MSG("Live timer interval set to %u %s", opt_live_timer, USEC_UNIT);
d73c5802 429 }
16f6f820 430 } else if (opt_snapshot) {
b178f53e
JG
431 struct lttng_snapshot_output_list *list;
432 struct lttng_snapshot_output *iter;
433 char snapshot_url[LTTNG_PATH_MAX] = {};
434
435 ret = lttng_snapshot_list_output(created_session_name, &list);
436 if (ret < 0) {
437 ERR("Failed to list snapshot outputs.");
438 ret = CMD_ERROR;
439 goto error;
16f6f820 440 }
b178f53e
JG
441
442 while ((iter = lttng_snapshot_output_list_get_next(list))) {
443 const char *url = NULL;
444
28ab034a
JG
445 url = lttng_snapshot_output_get_ctrl_url(iter);
446 ret = lttng_strncpy(snapshot_url, url, sizeof(snapshot_url));
b178f53e
JG
447 if (ret) {
448 snapshot_url[0] = '\0';
449 ERR("Failed to retrieve snapshot output destination");
450 }
451 break;
452 }
453 lttng_snapshot_output_list_destroy(list);
454
455 if (*snapshot_url) {
28ab034a 456 MSG("Default snapshot output set to %s", snapshot_url);
b178f53e
JG
457 }
458 MSG("Every channel enabled for this session will be set to mmap output and default to overwrite mode.");
a4b92340 459 }
d7ba1388 460 if (opt_shm_path) {
b178f53e 461 MSG("Shared memory path set to %s", shm_path);
d7ba1388 462 }
a4b92340 463
37d03ff7
JRJ
464 /* Mi output */
465 if (lttng_opt_mi) {
b178f53e 466 ret = mi_created_session(created_session_name);
37d03ff7
JRJ
467 if (ret) {
468 ret = CMD_ERROR;
469 goto error;
470 }
471 }
472
58a97671 473 /* Init lttng session config */
b178f53e 474 ret = config_init(created_session_name);
f3ed775e 475 if (ret < 0) {
27089920 476 ret = CMD_ERROR;
f3ed775e
DG
477 goto error;
478 }
479
f3ed775e 480 ret = CMD_SUCCESS;
f3ed775e 481error:
b178f53e
JG
482 lttng_session_descriptor_destroy(session_descriptor);
483 free(sessions);
f3ed775e
DG
484 return ret;
485}
486
92360082
JG
487/*
488 * spawn_sessiond
489 *
490 * Spawn a session daemon by forking and execv.
491 */
b53d4e59 492static int spawn_sessiond(const char *pathname)
92360082
JG
493{
494 int ret = 0;
495 pid_t pid;
496
497 MSG("Spawning a session daemon");
92360082
JG
498 pid = fork();
499 if (pid == 0) {
500 /*
bbd44cae 501 * Spawn session daemon in daemon mode.
92360082 502 */
28ab034a 503 execlp(pathname, "lttng-sessiond", "--daemonize", NULL);
92360082
JG
504 /* execlp only returns if error happened */
505 if (errno == ENOENT) {
506 ERR("No session daemon found. Use --sessiond-path.");
507 } else {
508 PERROR("execlp");
509 }
28ab034a 510 kill(getppid(), SIGTERM); /* wake parent */
92360082
JG
511 exit(EXIT_FAILURE);
512 } else if (pid > 0) {
92360082 513 /*
bbd44cae
PP
514 * In daemon mode (--daemonize), sessiond only exits when
515 * it's ready to accept commands.
92360082 516 */
bbd44cae 517 for (;;) {
81527d36
JG
518 int status;
519 pid_t wait_pid_ret = waitpid(pid, &status, 0);
520
521 if (wait_pid_ret < 0) {
522 if (errno == EINTR) {
523 continue;
524 }
525 PERROR("waitpid");
526 ret = -errno;
527 goto end;
528 }
bbd44cae
PP
529
530 if (WIFSIGNALED(status)) {
28ab034a 531 ERR("Session daemon was killed by signal %d", WTERMSIG(status));
bbd44cae 532 ret = -1;
28ab034a 533 goto end;
bbd44cae
PP
534 } else if (WIFEXITED(status)) {
535 DBG("Session daemon terminated normally (exit status: %d)",
28ab034a 536 WEXITSTATUS(status));
bbd44cae
PP
537
538 if (WEXITSTATUS(status) != 0) {
539 ERR("Session daemon terminated with an error (exit status: %d)",
28ab034a 540 WEXITSTATUS(status));
bbd44cae 541 ret = -1;
28ab034a 542 goto end;
bbd44cae
PP
543 }
544 break;
545 }
92360082 546 }
bbd44cae 547
92360082
JG
548 goto end;
549 } else {
550 PERROR("fork");
551 ret = -1;
552 goto end;
553 }
554
555end:
556 return ret;
557}
558
559/*
560 * launch_sessiond
561 *
562 * Check if the session daemon is available using
563 * the liblttngctl API for the check. If not, try to
564 * spawn a daemon.
565 */
566static int launch_sessiond(void)
567{
568 int ret;
b53d4e59 569 const char *pathname = NULL;
92360082
JG
570
571 ret = lttng_session_daemon_alive();
572 if (ret) {
573 /* Sessiond is alive, not an error */
574 ret = 0;
575 goto end;
576 }
577
578 /* Try command line option path */
579 pathname = opt_sessiond_path;
580
581 /* Try LTTNG_SESSIOND_PATH env variable */
582 if (pathname == NULL) {
583 pathname = getenv(DEFAULT_SESSIOND_PATH_ENV);
584 }
585
586 /* Try with configured path */
587 if (pathname == NULL) {
588 if (CONFIG_SESSIOND_BIN[0] != '\0') {
589 pathname = CONFIG_SESSIOND_BIN;
590 }
591 }
592
593 /* Try the default path */
594 if (pathname == NULL) {
595 pathname = INSTALL_BIN_PATH "/lttng-sessiond";
596 }
597
598 DBG("Session daemon binary path: %s", pathname);
599
600 /* Check existence and permissions */
601 ret = access(pathname, F_OK | X_OK);
602 if (ret < 0) {
603 ERR("No such file or access denied: %s", pathname);
604 goto end;
605 }
606
607 ret = spawn_sessiond(pathname);
92360082 608end:
0f4fa0d2 609 if (ret) {
28ab034a 610 ERR("Problem occurred while launching session daemon (%s)", pathname);
0f4fa0d2 611 }
92360082
JG
612 return ret;
613}
614
28ab034a 615static int validate_url_option_combination(void)
a8d119b5
JG
616{
617 int ret = 0;
618 int used_count = 0;
619
620 used_count += !!opt_url;
621 used_count += !!opt_output_path;
622 used_count += (opt_data_url || opt_ctrl_url);
623 if (used_count > 1) {
624 ERR("Only one of the --set-url, --ctrl-url/data-url, or --output options may be used at once.");
625 ret = -1;
626 }
627
628 return ret;
629}
630
f3ed775e 631/*
74cc1d0f 632 * The 'create <options>' first level command
1c8d13c8
TD
633 *
634 * Returns one of the CMD_* result constants.
f3ed775e
DG
635 */
636int cmd_create(int argc, const char **argv)
637{
37d03ff7 638 int opt, ret = CMD_SUCCESS, command_ret = CMD_SUCCESS, success = 1;
ecc48a90 639 char *opt_arg = NULL;
5b915816 640 const char *arg_session_name = NULL;
68c7f6e5 641 const char *leftover = NULL;
f3ed775e
DG
642 static poptContext pc;
643
644 pc = poptGetContext(NULL, argc, argv, long_options, 0);
645 poptReadDefaultConfig(pc, 0);
646
647 while ((opt = poptGetNextOpt(pc)) != -1) {
648 switch (opt) {
649 case OPT_HELP:
4ba92f18 650 SHOW_HELP();
f3ed775e 651 goto end;
679b4943
SM
652 case OPT_LIST_OPTIONS:
653 list_cmd_options(stdout, long_options);
679b4943 654 goto end;
ecc48a90
JD
655 case OPT_LIVE_TIMER:
656 {
c7219617 657 uint64_t v;
ecc48a90
JD
658
659 errno = 0;
e2ecf532
JG
660 if (opt_arg) {
661 free(opt_arg);
662 opt_arg = nullptr;
663 }
664
ecc48a90 665 opt_arg = poptGetOptArg(pc);
d73c5802
DG
666 if (!opt_arg) {
667 /* Set up default values. */
668 opt_live_timer = (uint32_t) DEFAULT_LTTNG_LIVE_TIMER;
669 DBG("Session live timer interval set to default value %d",
28ab034a 670 opt_live_timer);
d73c5802
DG
671 break;
672 }
673
c7219617
SM
674 if (utils_parse_time_suffix(opt_arg, &v) < 0) {
675 ERR("Wrong value for --live parameter: %s", opt_arg);
ecc48a90
JD
676 ret = CMD_ERROR;
677 goto end;
678 }
c7219617 679
ecc48a90
JD
680 if (v != (uint32_t) v) {
681 ERR("32-bit overflow in --live parameter: %s", opt_arg);
682 ret = CMD_ERROR;
683 goto end;
684 }
c7219617 685
0ed9e0be
JG
686 if (v == 0) {
687 ERR("Live timer interval must be greater than zero");
688 ret = CMD_ERROR;
689 goto end;
690 }
c7219617 691
ecc48a90
JD
692 opt_live_timer = (uint32_t) v;
693 DBG("Session live timer interval set to %d", opt_live_timer);
694 break;
695 }
f3ed775e 696 default:
f3ed775e
DG
697 ret = CMD_UNDEFINED;
698 goto end;
699 }
700 }
701
785d2d0d 702 if (opt_no_consumer) {
96fe6b8d 703 MSG("The option --no-consumer is obsolete. Use --no-output now.");
785d2d0d
DG
704 ret = CMD_WARNING;
705 goto end;
706 }
707
a8d119b5
JG
708 ret = validate_url_option_combination();
709 if (ret) {
710 ret = CMD_ERROR;
711 goto end;
712 }
713
92360082
JG
714 /* Spawn a session daemon if needed */
715 if (!opt_no_sessiond) {
716 ret = launch_sessiond();
717 if (ret) {
718 ret = CMD_ERROR;
719 goto end;
720 }
721 }
722
acc09215 723 /* MI initialization */
37d03ff7
JRJ
724 if (lttng_opt_mi) {
725 writer = mi_lttng_writer_create(fileno(stdout), lttng_opt_mi);
726 if (!writer) {
727 ret = -LTTNG_ERR_NOMEM;
728 goto end;
729 }
730
731 /* Open command element */
28ab034a 732 ret = mi_lttng_writer_command_open(writer, mi_lttng_element_command_create);
37d03ff7
JRJ
733 if (ret) {
734 ret = CMD_ERROR;
735 goto end;
736 }
737
738 /* Open output element */
28ab034a 739 ret = mi_lttng_writer_open_element(writer, mi_lttng_element_command_output);
37d03ff7
JRJ
740 if (ret) {
741 ret = CMD_ERROR;
742 goto end;
743 }
744 }
5b915816
MJ
745
746 /* Get the optional session name argument. */
747 arg_session_name = poptGetArg(pc);
f3ed775e 748
68c7f6e5
JD
749 leftover = poptGetArg(pc);
750 if (leftover) {
751 ERR("Unknown argument: %s", leftover);
752 ret = CMD_ERROR;
753 goto end;
754 }
755
5b915816 756 command_ret = create_session(arg_session_name);
37d03ff7
JRJ
757 if (command_ret) {
758 success = 0;
759 }
760
761 if (lttng_opt_mi) {
762 /* Close output element */
763 ret = mi_lttng_writer_close_element(writer);
764 if (ret) {
765 ret = CMD_ERROR;
766 goto end;
767 }
768
769 /* Success ? */
28ab034a
JG
770 ret = mi_lttng_writer_write_element_bool(
771 writer, mi_lttng_element_command_success, success);
37d03ff7
JRJ
772 if (ret) {
773 ret = CMD_ERROR;
774 goto end;
775 }
776
777 /* Command element close */
778 ret = mi_lttng_writer_command_close(writer);
779 if (ret) {
780 ret = CMD_ERROR;
781 goto end;
782 }
783 }
f3ed775e
DG
784
785end:
37d03ff7
JRJ
786 /* Mi clean-up */
787 if (writer && mi_lttng_writer_destroy(writer)) {
788 /* Preserve original error code */
789 ret = ret ? ret : -LTTNG_ERR_MI_IO_FAIL;
790 }
791
acc09215 792 /* Overwrite ret if an error occurred in create_session() */
37d03ff7
JRJ
793 ret = command_ret ? command_ret : ret;
794
e2ecf532 795 free(opt_arg);
ca1c3607 796 poptFreeContext(pc);
f3ed775e
DG
797 return ret;
798}
This page took 0.107148 seconds and 4 git commands to generate.