apply zhaolei updates
[ltt-control.git] / trunk / ltt-control / lttctl / lttctl.c
CommitLineData
2727692a 1/* lttctl
2 *
3 * Linux Trace Toolkit Control
4 *
5 * Small program that controls LTT through libltt.
6 *
7 * Copyright 2005 -
8 * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
b1f29379 9 *
10 * Copyright 2008 FUJITSU
11 * Zhao Lei <zhaolei@cn.fujitsu.com>
12 * Gui Jianfeng <guijianfeng@cn.fujitsu.com>
2727692a 13 */
14
15#ifdef HAVE_CONFIG_H
16#include <config.h>
17#endif
18
19#include <liblttctl/lttctl.h>
20#include <errno.h>
21#include <stdio.h>
22#include <stdlib.h>
2727692a 23#include <sys/wait.h>
24#include <unistd.h>
2727692a 25#include <string.h>
a9c10be2 26#include <limits.h>
c928825d 27#define _GNU_SOURCE
28#include <getopt.h>
29
30#define OPT_MAX (1024)
31#define OPT_NAMELEN (256)
32#define OPT_VALSTRINGLEN (256)
33
b1f29379 34enum opt_type {
35 CHANNEL,
36};
37
38struct channel_option {
39 char chan_name[OPT_NAMELEN];
40 int enable;
41 int overwrite;
42 int bufnum;
43 int bufsize;
2727692a 44};
45
c928825d 46struct lttctl_option {
c928825d 47 union {
b1f29379 48 struct channel_option chan_opt;
49 } opt_mode;
50 enum opt_type type;
51 struct lttctl_option *next;
c928825d 52};
53
b1f29379 54struct lttctl_option *opt_head, *last_opt;
55
c928825d 56static int opt_create;
57static int opt_destroy;
58static int opt_start;
59static int opt_pause;
60static int opt_help;
61static const char *opt_transport;
c928825d 62static const char *opt_write;
63static int opt_append;
64static unsigned int opt_dump_threads;
a9c10be2 65static char channel_root_default[PATH_MAX];
c928825d 66static const char *opt_channel_root;
67static const char *opt_tracename;
2727692a 68
2727692a 69/* Args :
70 *
71 */
c928825d 72static void show_arguments(void)
2727692a 73{
c928825d 74 printf("Linux Trace Toolkit Trace Control " VERSION"\n");
75 printf("\n");
76 printf("Usage: lttctl [OPTION]... [TRACENAME]\n");
77 printf("\n");
78 printf("Examples:\n");
79 printf(" lttctl -c trace1 "
80 "# Create a trace named trace1.\n");
81 printf(" lttctl -s trace1 "
82 "# start a trace named trace1.\n");
83 printf(" lttctl -p trace1 "
84 "# pause a trace named trace1.\n");
85 printf(" lttctl -d trace1 "
86 "# Destroy a trace named trace1.\n");
87 printf(" lttctl -C -w /tmp/trace1 trace1 "
88 "# Create a trace named trace1, start it and\n"
89 " "
90 "# write non-overwrite channels' data to\n"
91 " "
92 "# /tmp/trace1, debugfs must be mounted for\n"
93 " "
94 "# auto-find\n");
95 printf(" lttctl -D -w /tmp/trace1 trace1 "
96 "# Pause and destroy a trace named trace1 and\n"
97 " "
98 "# write overwrite channels' data to\n"
99 " "
100 "# /tmp/trace1, debugfs must be mounted for\n"
101 " "
102 "# auto-find\n");
103 printf("\n");
104 printf(" Basic options:\n");
105 printf(" -c, --create\n");
106 printf(" Create a trace.\n");
107 printf(" -d, --destroy\n");
108 printf(" Destroy a trace.\n");
109 printf(" -s, --start\n");
110 printf(" Start a trace.\n");
111 printf(" -p, --pause\n");
112 printf(" Pause a trace.\n");
113 printf(" -h, --help\n");
114 printf(" Show this help.\n");
2727692a 115 printf("\n");
c928825d 116 printf(" Advanced options:\n");
117 printf(" --transport TRANSPORT\n");
118 printf(" Set trace's transport. (ex. relay)\n");
119 printf(" -o, --option OPTION\n");
120 printf(" Set options, following operations are supported:\n");
121 printf(" channel.<channelname>.enable=\n");
122 printf(" channel.<channelname>.overwrite=\n");
123 printf(" channel.<channelname>.bufnum=\n");
124 printf(" channel.<channelname>.bufsize=\n");
125 printf(" <channelname> can be set to all for all channels\n");
126 printf("\n");
127 printf(" Integration options:\n");
128 printf(" -C, --create_start\n");
129 printf(" Create and start a trace.\n");
130 printf(" -D, --pause_destroy\n");
131 printf(" Pause and destroy a trace.\n");
132 printf(" -w, --write PATH\n");
133 printf(" Path for write trace datas.\n");
134 printf(" For -c, -C, -d, -D options\n");
135 printf(" -a, --append\n");
136 printf(" Append to trace, For -w option\n");
137 printf(" -n, --dump_threads NUMBER\n");
138 printf(" Number of lttd threads, For -w option\n");
139 printf(" --channel_root PATH\n");
140 printf(" Set channels root path, For -w option."
141 " (ex. /mnt/debugfs/ltt)\n");
2727692a 142 printf("\n");
143}
144
c928825d 145/*
146 * Separate option name to 3 fields
147 * Ex:
148 * Input: name = channel.cpu.bufsize
149 * Output: name1 = channel
150 * name2 = cpu
151 * name3 = bufsize
152 * Ret: 0 on success
153 * 1 on fail
154 *
155 * Note:
156 * Make sure that name1~3 longer than OPT_NAMELEN.
157 * name1~3 can be NULL to discard value
158 *
159 */
160static int separate_opt(const char *name, char *name1, char *name2, char *name3)
161{
162 char *p;
163
164 if (!name)
165 return 1;
166
167 /* segment1 */
168 p = strchr(name, '.');
169 if (!p)
170 return 1;
171 if (p - name >= OPT_NAMELEN)
172 return 1;
173 if (name1) {
174 memcpy(name1, name, p - name);
175 name1[p - name] = 0;
176 }
177 name = p + 1;
178
179 /* segment2 */
180 p = strchr(name, '.');
181 if (!p)
182 return 1;
183 if (p - name >= OPT_NAMELEN)
184 return 1;
185 if (name2) {
186 memcpy(name2, name, p - name);
187 name2[p - name] = 0;
188 }
189 name = p + 1;
190
191 /* segment3 */
192 if (strlen(name) >= OPT_NAMELEN)
193 return 1;
194 if (name3)
195 strcpy(name3, name);
196
197 return 0;
198}
199
b1f29379 200static void init_channel_opt(struct channel_option *opt, char *opt_name)
c928825d 201{
b1f29379 202 if (opt && opt_name) {
203 opt->enable = -1;
204 opt->overwrite = -1;
205 opt->bufnum = -1;
206 opt->bufsize = -1;
207 strcpy(opt->chan_name, opt_name);
c928825d 208 }
c928825d 209}
210
b1f29379 211static struct lttctl_option *find_insert_channel_opt(char *opt_name)
c928825d 212{
b1f29379 213 struct lttctl_option *iter, *new_opt;
214
215 if (!opt_head) {
216 opt_head = (struct lttctl_option *)malloc(sizeof(struct lttctl_option));
217 init_channel_opt(&opt_head->opt_mode.chan_opt, opt_name);
218 opt_head->type = CHANNEL;
219 opt_head->next = NULL;
220 last_opt = opt_head;
221 return opt_head;
222 }
c928825d 223
b1f29379 224 for (iter = opt_head; iter; iter = iter->next) {
225 if (iter->type != CHANNEL)
226 continue;
227 if (!strcmp(iter->opt_mode.chan_opt.chan_name, opt_name))
228 return iter;
c928825d 229 }
230
b1f29379 231 new_opt = (struct lttctl_option *)malloc(sizeof(struct lttctl_option));
232 init_channel_opt(&new_opt->opt_mode.chan_opt, opt_name);
233 new_opt->type = CHANNEL;
234 new_opt->next = NULL;
235 last_opt->next = new_opt;
236 last_opt = new_opt;
237 return new_opt;
c928825d 238}
239
b1f29379 240int set_channel_opt(struct channel_option *opt, char *opt_name, char *opt_valstr)
c928825d 241{
b1f29379 242 int opt_val, ret;
c928825d 243
b1f29379 244 if (!strcmp("enable", opt_name)) {
245 if (opt_valstr[1] != 0) {
246 return -EINVAL;
247 }
248 if (opt_valstr[0] == 'Y' || opt_valstr[0] == 'y'
249 || opt_valstr[0] == '1')
250 opt_val = 1;
251 else if (opt_valstr[0] == 'N' || opt_valstr[0] == 'n'
252 || opt_valstr[0] == '0')
253 opt_val = 0;
254 else {
255 return -EINVAL;
256 }
c928825d 257
b1f29379 258 opt->enable = opt_val;
259 return 0;
260 } else if (!strcmp("overwrite", opt_name)) {
261 if (opt_valstr[1] != 0) {
262 return -EINVAL;
263 }
264 if (opt_valstr[0] == 'Y' || opt_valstr[0] == 'y'
265 || opt_valstr[0] == '1')
266 opt_val = 1;
267 else if (opt_valstr[0] == 'N' || opt_valstr[0] == 'n'
268 || opt_valstr[0] == '0')
269 opt_val = 0;
270 else {
271 return -EINVAL;
272 }
c928825d 273
b1f29379 274 opt->overwrite = opt_val;
275 return 0;
c928825d 276
b1f29379 277 } else if (!strcmp("bufnum", opt_name)) {
278 ret = sscanf(opt_valstr, "%d", &opt_val);
279 if (ret != 1 || opt_val < 0) {
280 return -EINVAL;
281 }
282
283 opt->bufnum = opt_val;
284 return 0;
285 } else if (!strcmp("bufsize", opt_name)) {
286 ret = sscanf(opt_valstr, "%d", &opt_val);
287 if (ret != 1 || opt_val < 0) {
288 return -EINVAL;
289 }
290
291 opt->bufsize = opt_val;
292 return 0;
293 } else {
294 return -EINVAL;
c928825d 295 }
296
c928825d 297}
298
299static int parst_opt(const char *optarg)
300{
301 int ret;
302 char opt_name[OPT_NAMELEN * 3];
303 char opt_valstr[OPT_VALSTRINGLEN];
304 char *p;
305
306 char name1[OPT_NAMELEN];
307 char name2[OPT_NAMELEN];
308 char name3[OPT_NAMELEN];
309
c928825d 310 int opt_intval;
b1f29379 311 int opt_val;
c928825d 312 unsigned int opt_uintval;
b1f29379 313 struct lttctl_option *opt;
c928825d 314
315 if (!optarg) {
316 fprintf(stderr, "Option empty\n");
317 return -EINVAL;
318 }
319
320 /* Get option name and val_str */
321 p = strchr(optarg, '=');
322 if (!p) {
323 fprintf(stderr, "Option format error: %s\n", optarg);
324 return -EINVAL;
325 }
326
327 if (p - optarg >= sizeof(opt_name)/sizeof(opt_name[0])) {
328 fprintf(stderr, "Option name too long: %s\n", optarg);
329 return -EINVAL;
330 }
331
332 if (strlen(p+1) >= OPT_VALSTRINGLEN) {
333 fprintf(stderr, "Option value too long: %s\n", optarg);
334 return -EINVAL;
335 }
336
337 memcpy(opt_name, optarg, p - optarg);
338 opt_name[p - optarg] = 0;
339 strcpy(opt_valstr, p+1);
340
341 /* separate option name into 3 fields */
342 ret = separate_opt(opt_name, name1, name2, name3);
343 if (ret != 0) {
b1f29379 344 fprintf(stderr, "Option name error1: %s\n", optarg);
c928825d 345 return -EINVAL;
346 }
b1f29379 347
348 if (!strcmp("channel", name1)) {
349 opt = find_insert_channel_opt(name2);
350 if ((ret = set_channel_opt(&opt->opt_mode.chan_opt,
351 name3, opt_valstr) != 0)) {
352 fprintf(stderr, "Option name error2: %s\n", optarg);
353 return ret;
c928825d 354 }
b1f29379 355 } else {
356 fprintf(stderr, "Option name error3: %s\n", optarg);
c928825d 357 return -EINVAL;
358 }
b1f29379 359
360 return 0;
c928825d 361}
362
2727692a 363/* parse_arguments
364 *
365 * Parses the command line arguments.
366 *
367 * Returns -1 if the arguments were correct, but doesn't ask for program
368 * continuation. Returns EINVAL if the arguments are incorrect, or 0 if OK.
369 */
c928825d 370static int parse_arguments(int argc, char **argv)
2727692a 371{
372 int ret = 0;
b1f29379 373
c928825d 374 static struct option longopts[] = {
375 {"create", no_argument, NULL, 'c'},
376 {"destroy", no_argument, NULL, 'd'},
377 {"start", no_argument, NULL, 's'},
378 {"pause", no_argument, NULL, 'p'},
379 {"help", no_argument, NULL, 'h'},
380 {"transport", required_argument, NULL, 2},
381 {"option", required_argument, NULL, 'o'},
382 {"create_start", no_argument, NULL, 'C'},
383 {"pause_destroy", no_argument, NULL, 'D'},
384 {"write", required_argument, NULL, 'w'},
385 {"append", no_argument, NULL, 'a'},
386 {"dump_threads", required_argument, NULL, 'n'},
387 {"channel_root", required_argument, NULL, 3},
388 { NULL, 0, NULL, 0 },
389 };
390
391 /*
392 * Enable all channels in default
393 * To make novice users happy
394 */
395 parst_opt("channel.all.enable=1");
396
397 opterr = 1; /* Print error message on getopt_long */
398 while (1) {
399 int c;
400 c = getopt_long(argc, argv, "cdspho:CDw:an:", longopts, NULL);
401 if (-1 == c) {
402 /* parse end */
403 break;
2727692a 404 }
c928825d 405 switch (c) {
406 case 'c':
407 opt_create = 1;
408 break;
409 case 'd':
410 opt_destroy = 1;
411 break;
412 case 's':
413 opt_start = 1;
414 break;
415 case 'p':
416 opt_pause = 1;
417 break;
418 case 'h':
419 opt_help = 1;
420 break;
421 case 2:
422 if (!opt_transport) {
423 opt_transport = optarg;
424 } else {
425 fprintf(stderr,
426 "Please specify only 1 transport\n");
427 return -EINVAL;
428 }
429 break;
430 case 'o':
431 ret = parst_opt(optarg);
432 if (ret)
433 return ret;
434 break;
435 case 'C':
436 opt_create = 1;
437 opt_start = 1;
438 break;
439 case 'D':
440 opt_pause = 1;
441 opt_destroy = 1;
442 break;
443 case 'w':
444 if (!opt_write) {
445 opt_write = optarg;
446 } else {
447 fprintf(stderr,
448 "Please specify only 1 write dir\n");
449 return -EINVAL;
450 }
451 break;
452 case 'a':
453 opt_append = 1;
454 break;
455 case 'n':
456 if (opt_dump_threads) {
457 fprintf(stderr,
458 "Please specify only 1 dump threads\n");
459 return -EINVAL;
460 }
461
462 ret = sscanf(optarg, "%u", &opt_dump_threads);
463 if (ret != 1) {
464 fprintf(stderr,
465 "Dump threads not positive number\n");
466 return -EINVAL;
467 }
468 break;
469 case 3:
470 if (!opt_channel_root) {
471 opt_channel_root = optarg;
472 } else {
473 fprintf(stderr,
474 "Please specify only 1 channel root\n");
475 return -EINVAL;
476 }
477 break;
478 case '?':
479 return -EINVAL;
480 default:
481 break;
482 };
483 };
484
485 /* Don't check args when user needs help */
486 if (opt_help)
487 return 0;
488
489 /* Get tracename */
490 if (optind < argc - 1) {
491 fprintf(stderr, "Please specify only 1 trace name\n");
492 return -EINVAL;
493 }
494 if (optind > argc - 1) {
495 fprintf(stderr, "Please specify trace name\n");
496 return -EINVAL;
497 }
498 opt_tracename = argv[optind];
499
500 /*
501 * Check arguments
502 */
503 if (!opt_create && !opt_start && !opt_destroy && !opt_pause) {
504 fprintf(stderr,
505 "Please specify a option of "
506 "create, destroy, start, or pause\n");
507 return -EINVAL;
2727692a 508 }
509
c928825d 510 if ((opt_create || opt_start) && (opt_destroy || opt_pause)) {
511 fprintf(stderr,
512 "Create and start conflict with destroy and pause\n");
513 return -EINVAL;
2727692a 514 }
c928825d 515
516 if (opt_create) {
517 if (!opt_transport)
518 opt_transport = "relay";
2727692a 519 }
520
c928825d 521 if (opt_transport) {
522 if (!opt_create) {
523 fprintf(stderr,
524 "Transport option must be combine with create"
525 " option\n");
526 return -EINVAL;
527 }
2727692a 528 }
529
c928825d 530 if (opt_write) {
531 if (!opt_create && !opt_destroy) {
532 fprintf(stderr,
533 "Write option must be combine with create or"
534 " destroy option\n");
535 return -EINVAL;
2727692a 536 }
c928825d 537
538 if (!opt_channel_root)
a9c10be2 539 if (getdebugfsmntdir(channel_root_default) == 0) {
540 strcat(channel_root_default, "/ltt");
c928825d 541 opt_channel_root = channel_root_default;
354b34fd 542 } else {
543 fprintf(stderr,
544 "Channel_root is necessary for -w"
545 " option, but neither --channel_root"
546 " option\n"
547 "specified, nor debugfs's mount dir"
548 " found, mount debugfs also failed\n");
549 return -EINVAL;
a9c10be2 550 }
c928825d 551
552 if (opt_dump_threads == 0)
553 opt_dump_threads = 1;
2727692a 554 }
555
c928825d 556 if (opt_append) {
557 if (!opt_write) {
558 fprintf(stderr,
559 "Append option must be combine with write"
560 " option\n");
561 return -EINVAL;
562 }
563 }
564
565 if (opt_dump_threads) {
566 if (!opt_write) {
567 fprintf(stderr,
568 "Dump_threads option must be combine with write"
569 " option\n");
570 return -EINVAL;
571 }
572 }
573
574 if (opt_channel_root) {
575 if (!opt_write) {
576 fprintf(stderr,
577 "Channel_root option must be combine with write"
578 " option\n");
579 return -EINVAL;
580 }
581 }
582
583 return 0;
2727692a 584}
b1f29379 585
c928825d 586static void show_info(void)
2727692a 587{
15061ecb 588 printf("Linux Trace Toolkit Trace Control " VERSION"\n");
2727692a 589 printf("\n");
c928825d 590 if (opt_tracename != NULL) {
591 printf("Controlling trace : %s\n", opt_tracename);
900b24a9 592 printf("\n");
593 }
2727692a 594}
595
b1f29379 596static int lttctl_channel_setup(struct channel_option *opt)
597{
598 int ret;
599
600 if (opt->enable != -1) {
601 if ((ret = lttctl_set_channel_enable(opt_tracename,
602 opt->chan_name,
603 opt->enable)) != 0)
604 return ret;
605 }
606 if (opt->overwrite != -1) {
607 if ((ret = lttctl_set_channel_overwrite(opt_tracename,
608 opt->chan_name,
609 opt->overwrite)) != 0)
610 return ret;
611 }
612 if (opt->bufnum != -1) {
613 if ((ret = lttctl_set_channel_subbuf_num(opt_tracename,
614 opt->chan_name,
615 opt->bufnum)) != 0)
616 return ret;
617 }
618 if (opt->bufsize != -1) {
619 if ((ret = lttctl_set_channel_subbuf_size(opt_tracename,
620 opt->chan_name,
621 opt->bufsize)) != 0)
622 return ret;
623 }
624
625 return 0;
626}
627
c928825d 628static int lttctl_create_trace(void)
2727692a 629{
2727692a 630 int ret;
c928825d 631 int i;
b1f29379 632 struct lttctl_option *opt;
c928825d 633
634 ret = lttctl_setup_trace(opt_tracename);
635 if (ret)
636 goto setup_trace_fail;
637
b1f29379 638 for (opt = opt_head; opt; opt = opt->next) {
639 if (opt->type != CHANNEL)
c928825d 640 continue;
b1f29379 641 ret = lttctl_channel_setup(&opt->opt_mode.chan_opt);
642 if (ret)
643 goto set_option_fail;;
2727692a 644 }
645
c928825d 646 ret = lttctl_set_trans(opt_tracename, opt_transport);
647 if (ret)
648 goto set_option_fail;
649
650 ret = lttctl_alloc_trace(opt_tracename);
651 if (ret)
652 goto alloc_trace_fail;
2727692a 653
654 return 0;
655
c928825d 656alloc_trace_fail:
657set_option_fail:
658 lttctl_destroy_trace(opt_tracename);
659setup_trace_fail:
2727692a 660 return ret;
661}
662
c928825d 663/*
664 * Start a lttd daemon to write trace datas
665 * Dump overwrite channels on overwrite!=0
666 * Dump normal(non-overwrite) channels on overwrite=0
667 *
668 * ret: 0 on success
669 * !0 on fail
670 */
671static int lttctl_daemon(int overwrite)
89565b43 672{
89565b43 673 pid_t pid;
c928825d 674 int status;
89565b43 675
676 pid = fork();
c928825d 677 if (pid < 0) {
678 perror("Error in forking for lttd daemon");
679 return errno;
680 }
89565b43 681
c928825d 682 if (pid == 0) {
683 /* child */
684 char *argv[16];
685 int argc = 0;
686 char channel_path[PATH_MAX];
687 char thread_num[16];
688
689 /* prog path */
690 argv[argc] = getenv("LTT_DAEMON");
691 if (argv[argc] == NULL)
692 argv[argc] = PACKAGE_BIN_DIR "/lttd";
693 argc++;
694
695 /* -t option */
696 argv[argc] = "-t";
697 argc++;
698 /*
699 * we allow modify of opt_write's content in new process
700 * for get rid of warning of assign char * to const char *
701 */
702 argv[argc] = (char *)opt_write;
703 argc++;
704
705 /* -c option */
706 strcpy(channel_path, opt_channel_root);
707 strcat(channel_path, "/");
708 strcat(channel_path, opt_tracename);
709 argv[argc] = "-c";
710 argc++;
711 argv[argc] = channel_path;
712 argc++;
713
714 /* -N option */
715 sprintf(thread_num, "%u", opt_dump_threads);
716 argv[argc] = "-N";
717 argc++;
718 argv[argc] = thread_num;
719 argc++;
720
721 /* -a option */
722 if (opt_append) {
723 argv[argc] = "-a";
724 argc++;
89565b43 725 }
726
c928825d 727 /* -d option */
728 argv[argc] = "-d";
729 argc++;
89565b43 730
c928825d 731 /* overwrite option */
732 if (overwrite) {
733 argv[argc] = "-f";
734 argc++;
735 } else {
736 argv[argc] = "-n";
737 argc++;
89565b43 738 }
89565b43 739
c928825d 740 argv[argc] = NULL;
89565b43 741
c928825d 742 execvp(argv[0], argv);
89565b43 743
c928825d 744 perror("Error in executing the lttd daemon");
745 exit(errno);
746 }
89565b43 747
c928825d 748 /* parent */
749 if (waitpid(pid, &status, 0) == -1) {
750 perror("Error in waitpid\n");
751 return errno;
752 }
89565b43 753
c928825d 754 if (!WIFEXITED(status)) {
755 fprintf(stderr, "lttd process interrupted\n");
756 return status;
757 }
758
759 if (WEXITSTATUS(status))
760 fprintf(stderr, "lttd process running failed\n");
89565b43 761
c928825d 762 return WEXITSTATUS(status);
763}
764
765int main(int argc, char **argv)
2727692a 766{
767 int ret;
c928825d 768
2727692a 769 ret = parse_arguments(argc, argv);
c928825d 770 /* If user needs show help, we disregard other options */
771 if (opt_help) {
772 show_arguments();
773 return 0;
774 }
2727692a 775
c928825d 776 /* exit program if arguments wrong */
777 if (ret)
778 return 1;
2727692a 779
780 show_info();
c928825d 781
782 ret = lttctl_init();
783 if (ret != 0)
784 return ret;
785
786 if (opt_create) {
787 printf("lttctl: Creating trace\n");
788 ret = lttctl_create_trace();
789 if (ret)
790 goto op_fail;
791
792 if (opt_write) {
793 printf("lttctl: Forking lttd\n");
794 ret = lttctl_daemon(0);
795 if (ret)
796 goto op_fail;
797 }
798 }
799
800 if (opt_start) {
801 printf("lttctl: Starting trace\n");
802 ret = lttctl_start(opt_tracename);
803 if (ret)
804 goto op_fail;
805 }
806
807 if (opt_pause) {
808 printf("lttctl: Pausing trace\n");
809 ret = lttctl_pause(opt_tracename);
810 if (ret)
811 goto op_fail;
2727692a 812 }
813
c928825d 814 if (opt_destroy) {
815 if (opt_write) {
816 printf("lttctl: Forking lttd\n");
817 ret = lttctl_daemon(1);
818 if (ret)
819 goto op_fail;
820 }
821
822 printf("lttctl: Destroying trace\n");
823 ret = lttctl_destroy_trace(opt_tracename);
824 if (ret)
825 goto op_fail;
826 }
827
828op_fail:
829 lttctl_destroy();
830
2727692a 831 return ret;
832}
This page took 0.057202 seconds and 4 git commands to generate.