liblttd cleanup and error handling fixes
[ltt-control.git] / lttd / lttd.c
CommitLineData
8ba26eae
MD
1/*
2 * lttd
617de8e1 3 *
4 * Linux Trace Toolkit Daemon
5 *
8ba26eae
MD
6 * This is a simple daemon that reads a few LTTng debugfs channels and saves
7 * them in a trace on the virtual file system.
617de8e1 8 *
31482529 9 * CPU hot-plugging is supported using inotify.
617de8e1 10 *
ed2849af 11 * Copyright 2009-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
d9cbca27
MSL
12 * Copyright 2010 - Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
13 * Copyright 2010 - Oumarou Dicko <oumarou.dicko@polymtl.ca>
ed2849af
MD
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
617de8e1 28 */
29
0bb647f5 30#ifdef HAVE_CONFIG_H
469206ed 31#include <config.h>
0bb647f5 32#endif
33
e54e1d5d 34#define _REENTRANT
0bb647f5 35#define _GNU_SOURCE
008e2515 36
617de8e1 37#include <stdio.h>
617de8e1 38#include <stdlib.h>
1d483eea 39#include <signal.h>
008e2515 40#include <errno.h>
1d483eea 41
008e2515 42#include <liblttd/liblttd.h>
8ba26eae 43#include <liblttd/liblttdvfs.h>
357915bb 44
d9cbca27 45struct liblttd_instance* instance;
357915bb 46
89565b43 47static char *trace_name = NULL;
48static char *channel_name = NULL;
49static int daemon_mode = 0;
50static int append_mode = 0;
51static unsigned long num_threads = 1;
89565b43 52static int dump_flight_only = 0;
53static int dump_normal_only = 0;
083518b7 54static int verbose_mode = 0;
55
617de8e1 56
57/* Args :
58 *
59 * -t directory Directory name of the trace to write to. Will be created.
c2ffa20f 60 * -c directory Root directory of the debugfs trace channels.
617de8e1 61 * -d Run in background (daemon).
083518b7 62 * -a Trace append mode.
63 * -s Send SIGUSR1 to parent when ready for IO.
617de8e1 64 */
65void show_arguments(void)
66{
67 printf("Please use the following arguments :\n");
68 printf("\n");
69 printf("-t directory Directory name of the trace to write to.\n"
70 " It will be created.\n");
c2ffa20f 71 printf("-c directory Root directory of the debugfs trace channels.\n");
617de8e1 72 printf("-d Run in background (daemon).\n");
90ccaa9a 73 printf("-a Append to an possibly existing trace.\n");
5ffb77aa 74 printf("-N Number of threads to start.\n");
89565b43 75 printf("-f Dump only flight recorder channels.\n");
76 printf("-n Dump only normal channels.\n");
083518b7 77 printf("-v Verbose mode.\n");
617de8e1 78 printf("\n");
79}
80
81
82/* parse_arguments
83 *
84 * Parses the command line arguments.
85 *
86 * Returns 1 if the arguments were correct, but doesn't ask for program
87 * continuation. Returns -1 if the arguments are incorrect, or 0 if OK.
88 */
89int parse_arguments(int argc, char **argv)
90{
91 int ret = 0;
92 int argn = 1;
008e2515 93
617de8e1 94 if(argc == 2) {
95 if(strcmp(argv[1], "-h") == 0) {
96 return 1;
97 }
98 }
99
90ccaa9a 100 while(argn < argc) {
617de8e1 101
102 switch(argv[argn][0]) {
103 case '-':
104 switch(argv[argn][1]) {
105 case 't':
90ccaa9a 106 if(argn+1 < argc) {
107 trace_name = argv[argn+1];
108 argn++;
109 }
617de8e1 110 break;
111 case 'c':
90ccaa9a 112 if(argn+1 < argc) {
113 channel_name = argv[argn+1];
114 argn++;
115 }
617de8e1 116 break;
117 case 'd':
118 daemon_mode = 1;
119 break;
90ccaa9a 120 case 'a':
121 append_mode = 1;
122 break;
5ffb77aa 123 case 'N':
e54e1d5d 124 if(argn+1 < argc) {
125 num_threads = strtoul(argv[argn+1], NULL, 0);
126 argn++;
127 }
128 break;
89565b43 129 case 'f':
130 dump_flight_only = 1;
131 break;
132 case 'n':
133 dump_normal_only = 1;
134 break;
083518b7 135 case 'v':
136 verbose_mode = 1;
137 break;
617de8e1 138 default:
139 printf("Invalid argument '%s'.\n", argv[argn]);
140 printf("\n");
141 ret = -1;
142 }
143 break;
144 default:
145 printf("Invalid argument '%s'.\n", argv[argn]);
146 printf("\n");
147 ret = -1;
148 }
149 argn++;
150 }
008e2515 151
617de8e1 152 if(trace_name == NULL) {
153 printf("Please specify a trace name.\n");
154 printf("\n");
155 ret = -1;
156 }
008e2515 157
617de8e1 158 if(channel_name == NULL) {
159 printf("Please specify a channel name.\n");
160 printf("\n");
161 ret = -1;
162 }
008e2515 163
617de8e1 164 return ret;
165}
166
167void show_info(void)
168{
15061ecb 169 printf("Linux Trace Toolkit Trace Daemon " VERSION "\n");
617de8e1 170 printf("\n");
c2ffa20f 171 printf("Reading from debugfs directory : %s\n", channel_name);
617de8e1 172 printf("Writing to trace directory : %s\n", trace_name);
173 printf("\n");
174}
175
176
1d483eea 177/* signal handling */
178
179static void handler(int signo)
180{
181 printf("Signal %d received : exiting cleanly\n", signo);
d6d516b7 182 liblttd_stop_instance(instance);
1d483eea 183}
184
617de8e1 185int main(int argc, char ** argv)
186{
e54e1d5d 187 int ret = 0;
1d483eea 188 struct sigaction act;
008e2515 189
617de8e1 190 ret = parse_arguments(argc, argv);
191
192 if(ret != 0) show_arguments();
193 if(ret < 0) return EINVAL;
194 if(ret > 0) return 0;
195
196 show_info();
197
1d483eea 198 /* Connect the signal handlers */
199 act.sa_handler = handler;
200 act.sa_flags = 0;
201 sigemptyset(&(act.sa_mask));
202 sigaddset(&(act.sa_mask), SIGTERM);
203 sigaddset(&(act.sa_mask), SIGQUIT);
204 sigaddset(&(act.sa_mask), SIGINT);
205 sigaction(SIGTERM, &act, NULL);
206 sigaction(SIGQUIT, &act, NULL);
207 sigaction(SIGINT, &act, NULL);
208
06cb3ad3 209 if(daemon_mode) {
210 ret = daemon(0, 0);
211
212 if(ret == -1) {
213 perror("An error occured while daemonizing.");
214 exit(-1);
215 }
216 }
617de8e1 217
8ba26eae
MD
218 struct liblttd_callbacks* callbacks =
219 liblttdvfs_new_callbacks(trace_name, append_mode, verbose_mode);
d9cbca27
MSL
220
221 instance = liblttd_new_instance(callbacks, channel_name, num_threads,
8ba26eae
MD
222 dump_flight_only, dump_normal_only,
223 verbose_mode);
d9cbca27 224
d6d516b7
MSL
225 if(!instance) {
226 perror("An error occured while creating the liblttd instance");
227 return ret;
228 }
229
230 liblttd_start_instance(instance);
5ffb77aa 231
617de8e1 232 return ret;
233}
008e2515 234
This page took 0.036799 seconds and 4 git commands to generate.