b43b63765edf97252f26f6866fca4b31e922807d
[ltt-control.git] / lttd / lttd.c
1 /* lttd
2 *
3 * Linux Trace Toolkit Daemon
4 *
5 * This is a simple daemon that reads a few relay+debugfs channels and save
6 * them in a trace.
7 *
8 * CPU hot-plugging is supported using inotify.
9 *
10 * Copyright 2009-2010 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
11 * Copyright 2010 - Michael Sills-Lavoie <michael.sills-lavoie@polymtl.ca>
12 * Copyright 2010 - Oumarou Dicko <oumarou.dicko@polymtl.ca>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 *
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33
34 #define _REENTRANT
35 #define _GNU_SOURCE
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <signal.h>
40 #include <errno.h>
41
42 #include <liblttd/liblttd.h>
43 #include <liblttd/liblttdutils.h>
44
45 struct liblttd_instance* instance;
46
47 static char *trace_name = NULL;
48 static char *channel_name = NULL;
49 static int daemon_mode = 0;
50 static int append_mode = 0;
51 static unsigned long num_threads = 1;
52 static int dump_flight_only = 0;
53 static int dump_normal_only = 0;
54 static int verbose_mode = 0;
55
56
57 /* Args :
58 *
59 * -t directory Directory name of the trace to write to. Will be created.
60 * -c directory Root directory of the debugfs trace channels.
61 * -d Run in background (daemon).
62 * -a Trace append mode.
63 * -s Send SIGUSR1 to parent when ready for IO.
64 */
65 void 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");
71 printf("-c directory Root directory of the debugfs trace channels.\n");
72 printf("-d Run in background (daemon).\n");
73 printf("-a Append to an possibly existing trace.\n");
74 printf("-N Number of threads to start.\n");
75 printf("-f Dump only flight recorder channels.\n");
76 printf("-n Dump only normal channels.\n");
77 printf("-v Verbose mode.\n");
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 */
89 int parse_arguments(int argc, char **argv)
90 {
91 int ret = 0;
92 int argn = 1;
93
94 if(argc == 2) {
95 if(strcmp(argv[1], "-h") == 0) {
96 return 1;
97 }
98 }
99
100 while(argn < argc) {
101
102 switch(argv[argn][0]) {
103 case '-':
104 switch(argv[argn][1]) {
105 case 't':
106 if(argn+1 < argc) {
107 trace_name = argv[argn+1];
108 argn++;
109 }
110 break;
111 case 'c':
112 if(argn+1 < argc) {
113 channel_name = argv[argn+1];
114 argn++;
115 }
116 break;
117 case 'd':
118 daemon_mode = 1;
119 break;
120 case 'a':
121 append_mode = 1;
122 break;
123 case 'N':
124 if(argn+1 < argc) {
125 num_threads = strtoul(argv[argn+1], NULL, 0);
126 argn++;
127 }
128 break;
129 case 'f':
130 dump_flight_only = 1;
131 break;
132 case 'n':
133 dump_normal_only = 1;
134 break;
135 case 'v':
136 verbose_mode = 1;
137 break;
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 }
151
152 if(trace_name == NULL) {
153 printf("Please specify a trace name.\n");
154 printf("\n");
155 ret = -1;
156 }
157
158 if(channel_name == NULL) {
159 printf("Please specify a channel name.\n");
160 printf("\n");
161 ret = -1;
162 }
163
164 return ret;
165 }
166
167 void show_info(void)
168 {
169 printf("Linux Trace Toolkit Trace Daemon " VERSION "\n");
170 printf("\n");
171 printf("Reading from debugfs directory : %s\n", channel_name);
172 printf("Writing to trace directory : %s\n", trace_name);
173 printf("\n");
174 }
175
176
177 /* signal handling */
178
179 static void handler(int signo)
180 {
181 printf("Signal %d received : exiting cleanly\n", signo);
182 liblttd_stop_instance(instance);
183 }
184
185 int main(int argc, char ** argv)
186 {
187 int ret = 0;
188 struct sigaction act;
189
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
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
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 }
217
218 struct liblttd_callbacks* callbacks = liblttdutils_local_new_callbacks(
219 trace_name, append_mode, verbose_mode);
220
221 instance = liblttd_new_instance(callbacks, channel_name, num_threads,
222 dump_flight_only, dump_normal_only, verbose_mode);
223
224 if(!instance) {
225 perror("An error occured while creating the liblttd instance");
226 return ret;
227 }
228
229 liblttd_start_instance(instance);
230
231 return ret;
232 }
233
This page took 0.032681 seconds and 3 git commands to generate.