prepare the 0.3 release
[lttngtop.git] / src / lttng-session.c
1 #define _GNU_SOURCE /* See feature_test_macros(7) */
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <stdio.h>
6 #include <stdint.h>
7 #include <inttypes.h>
8 #include <string.h>
9
10 #define event_list "lttng_statedump_start,lttng_statedump_end," \
11 "lttng_statedump_process_state,lttng_statedump_file_descriptor," \
12 "lttng_statedump_vm_map,lttng_statedump_network_interface," \
13 "lttng_statedump_interrupt,sched_process_free," \
14 "sched_switch,sched_process_fork"
15 #define context_list "-t pid -t procname -t tid -t ppid "
16
17 static
18 int check_or_start_sessiond()
19 {
20 int ret;
21 int sudo = 0;
22
23 ret = system("pgrep -u root lttng-sessiond >/dev/null");
24 if (ret == 0)
25 goto end;
26
27 if (getuid() != 0) {
28 fprintf(stderr, "Trying to start lttng-sessiond with sudo\n");
29 ret = system("sudo -l lttng-sessiond >/dev/null");
30 if (ret < 0) {
31 fprintf(stderr, "[error] You are not root and not "
32 "allowed by sudo to start lttng-sessiond\n");
33 ret = -1;
34 goto end;
35 }
36 ret = system("sudo -l lttng >/dev/null");
37 if (ret < 0) {
38 fprintf(stderr, "[error] You are not root and not "
39 "allowed by sudo to use lttng\n");
40 ret = -1;
41 goto end;
42 }
43 sudo = 1;
44 }
45
46 if (sudo)
47 ret = system("sudo lttng-sessiond -d");
48 else
49 ret = system("lttng-sessiond -d");
50
51 if (ret != 0) {
52 fprintf(stderr, "Error starting lttng-sessiond as root\n");
53 ret = -1;
54 goto end;
55 }
56
57 end:
58 return ret;
59 }
60
61 static
62 int check_or_start_relayd()
63 {
64 int ret;
65
66 ret = system("pgrep lttng-relayd >/dev/null");
67 if (ret == 0)
68 goto end;
69
70 ret = system("lttng-relayd -d");
71 if (ret != 0) {
72 fprintf(stderr, "Error starting lttng-relayd\n");
73 ret = -1;
74 goto end;
75 }
76
77 end:
78 return ret;
79 }
80
81 /*
82 * Return 0 if in tracing group or root, 1 if sudo is needed (and working),
83 * a negative value on error.
84 */
85 static
86 int check_tracing_group()
87 {
88 int ret;
89
90 ret = getuid();
91 if (ret == 0)
92 goto end;
93
94 ret = system("groups|grep tracing >/dev/null");
95 if (ret == 0) {
96 goto end;
97 }
98
99 ret = system("sudo lttng --version >/dev/null");
100 if (ret != 0) {
101 fprintf(stderr, "Error executing lttng with sudo, you need to "
102 "be root or in the \"tracing\" group to start "
103 "kernel tracing\n");
104 ret = -1;
105 goto end;
106 } else {
107 ret = 1;
108 }
109
110 end:
111 return ret;
112 }
113
114 static
115 int check_lttng_modules(int sudo)
116 {
117 int ret;
118
119 if (sudo) {
120 ret = system("sudo lttng list -k | grep sched_switch >/dev/null");
121 } else {
122 ret = system("lttng list -k | grep sched_switch >/dev/null");
123 }
124 if (ret != 0) {
125 fprintf(stderr, "Error listing kernel events, "
126 "lttng-modules might not be installed\n");
127 goto end;
128 }
129
130 end:
131 return ret;
132 }
133
134 static
135 int check_requirements(int *sudo)
136 {
137 int ret;
138
139 ret = check_or_start_sessiond();
140 if (ret < 0)
141 goto end;
142 ret = check_or_start_relayd();
143 if (ret < 0)
144 goto end;
145 ret = check_tracing_group();
146 if (ret < 0)
147 goto end;
148 else if (ret == 1)
149 *sudo = 1;
150
151 ret = check_lttng_modules(*sudo);
152 if (ret < 0)
153 goto end;
154 end:
155 return ret;
156 }
157
158 /*
159 * Allocate a random string, must be freed by the caller.
160 */
161 static
162 char *random_session_name()
163 {
164 uint64_t id;
165 char *str = NULL;
166 int ret;
167
168 FILE *f = fopen( "/dev/urandom", "r");
169 if (!f) {
170 perror("fopen");
171 goto end;
172 }
173
174 ret = fread(&id, 1, sizeof(uint64_t), f);
175 if (ret < sizeof(id)) {
176 perror("fread");
177 goto end;
178 }
179
180 ret = asprintf(&str, "lttngtop-%" PRIu64, id);
181 if (ret < 0) {
182 fprintf(stderr, "Error allocating session name");
183 str = NULL;
184 goto end;
185 }
186
187 ret = fclose(f);
188 if (ret != 0) {
189 perror("fclose");
190 goto end;
191 }
192
193 end:
194 return str;
195 }
196
197 static
198 int check_session_name(char *name, int sudo)
199 {
200 int ret;
201 char cmd[1024];
202
203 ret = sprintf(cmd, "%s lttng list | grep %s >/dev/null",
204 (sudo) ? "sudo" : " ", name);
205 if (ret < 0) {
206 fprintf(stderr, "Allocating cmd\n");
207 goto end;
208 }
209
210 ret = (system(cmd));
211 if (ret == 0) {
212 fprintf(stderr, "Error: session %s already exist, either we "
213 "are not random enough or something is "
214 "really wrong\n", name);
215 ret = -1;
216 goto end;
217 }
218
219 end:
220 return ret;
221 }
222
223 static
224 int local_session(char *name, int sudo)
225 {
226 int ret;
227 char cmd[1024];
228
229 ret = sprintf(cmd, "%s lttng create %s >/dev/null",
230 (sudo) ? "sudo" : " ", name);
231 if (ret < 0) {
232 fprintf(stderr, "Allocating cmd\n");
233 goto end;
234 }
235 ret = (system(cmd));
236 if (ret != 0) {
237 fprintf(stderr, "Error: creating the session\n");
238 ret = -1;
239 goto end;
240 }
241
242 end:
243 return ret;
244 }
245
246 static
247 int live_local_session(char *name, int sudo)
248 {
249 int ret;
250 char cmd[1024];
251
252 ret = sprintf(cmd, "%s lttng create %s --live 1000000 -U net://localhost >/dev/null",
253 (sudo) ? "sudo" : " ", name);
254 if (ret < 0) {
255 fprintf(stderr, "Allocating cmd\n");
256 goto end;
257 }
258 ret = (system(cmd));
259 if (ret != 0) {
260 fprintf(stderr, "Error: creating the session\n");
261 ret = -1;
262 goto end;
263 }
264
265 end:
266 return ret;
267 }
268
269 static
270 int enable_events(char *name, int sudo)
271 {
272 int ret;
273 char cmd[1024];
274
275 ret = sprintf(cmd, "%s lttng enable-event -s %s -k %s >/dev/null;"
276 "lttng enable-event -k --syscall -a -s %s >/dev/null",
277 (sudo) ? "sudo" : " ", name, event_list, name);
278 if (ret < 0) {
279 fprintf(stderr, "Allocating cmd\n");
280 goto end;
281 }
282
283 ret = (system(cmd));
284 if (ret != 0) {
285 fprintf(stderr, "Error: enabling events\n");
286 ret = -1;
287 goto end;
288 }
289
290 end:
291 return ret;
292 }
293
294 static
295 int add_contexts(char *name, int sudo)
296 {
297 int ret;
298 char cmd[1024];
299
300 ret = sprintf(cmd, "%s lttng add-context -s %s -k %s >/dev/null",
301 (sudo) ? "sudo" : " ", name, context_list);
302 if (ret < 0) {
303 fprintf(stderr, "allocating cmd\n");
304 goto end;
305 }
306
307 ret = (system(cmd));
308 if (ret != 0) {
309 fprintf(stderr, "error: adding contexts\n");
310 ret = -1;
311 goto end;
312 }
313
314 end:
315 return ret;
316 }
317
318 static
319 int start(char *name, int sudo, int local, int print)
320 {
321 int ret;
322 char cmd[1024];
323
324 ret = sprintf(cmd, "%s lttng start %s >/dev/null",
325 (sudo) ? "sudo" : " ", name);
326 if (ret < 0) {
327 fprintf(stderr, "allocating cmd\n");
328 goto end;
329 }
330
331 ret = (system(cmd));
332 if (ret != 0) {
333 fprintf(stderr, "error: starting the session %s\n", name);
334 ret = -1;
335 goto end;
336 }
337
338 if (!print)
339 goto end;
340
341 if (local) {
342 ret = sprintf(cmd, "%s lttng list|grep %s|cut -d'(' -f2|cut -d ')' -f1",
343 (sudo) ? "sudo" : " ", name);
344 } else {
345 ret = sprintf(cmd, "babeltrace -i lttng-live net://localhost|grep %s|cut -d' ' -f1",
346 name);
347 }
348 if (ret < 0) {
349 fprintf(stderr, "allocating cmd\n");
350 goto end;
351 }
352 fprintf(stderr, "%s session started : ",
353 (local) ? "Local" : "Live");
354 ret = (system(cmd));
355 if (ret != 0) {
356 fprintf(stderr, "error: listing the sessions\n");
357 ret = -1;
358 goto end;
359 }
360
361 end:
362 return ret;
363 }
364
365 static
366 char *live_path(char *name)
367 {
368 FILE *fp;
369 int ret;
370 char path[1035];
371 char cmd[1024];
372 char *out = NULL;
373
374 ret = sprintf(cmd, "lttngtop -r net://localhost|grep %s|cut -d' ' -f1",
375 name);
376 if (ret < 0) {
377 fprintf(stderr, "allocating cmd\n");
378 goto end;
379 }
380
381 fp = popen(cmd, "r");
382 if (fp == NULL) {
383 printf("Failed to run command\n" );
384 goto end;
385 }
386
387 /* Read the output a line at a time - output it. */
388 out = fgets(path, sizeof(path)-1, fp);
389 if (out)
390 out = strdup(path);
391
392 /* close */
393 pclose(fp);
394
395 end:
396 return out;
397 }
398
399 static
400 int destroy(char *name)
401 {
402 int ret;
403 int sudo = 0;
404 char cmd[1024];
405
406 ret = system("groups|grep tracing >/dev/null");
407 if (ret != 0 && getuid() != 0) {
408 ret = system("sudo -l lttng >/dev/null");
409 if (ret < 0) {
410 fprintf(stderr, "[error] You are not root and not "
411 "allowed by sudo to use lttng\n");
412 ret = -1;
413 goto end;
414 }
415 sudo = 1;
416 }
417
418 ret = sprintf(cmd, "%s lttng destroy %s >/dev/null",
419 (sudo) ? "sudo" : " ", name);
420 if (ret < 0) {
421 fprintf(stderr, "allocating cmd\n");
422 goto end;
423 }
424
425 ret = (system(cmd));
426 if (ret != 0) {
427 fprintf(stderr, "error: destroying the session %s\n", name);
428 ret = -1;
429 goto end;
430 }
431
432 end:
433 return ret;
434 }
435
436 int create_local_session()
437 {
438 int ret;
439 char *name;
440 int sudo = 0;
441
442 ret = check_requirements(&sudo);
443
444 name = random_session_name();
445 if (!name) {
446 ret = -1;
447 goto end;
448 }
449
450 ret = check_session_name(name, sudo);
451 if (ret < 0) {
452 goto end_free;
453 }
454
455 ret = local_session(name, sudo);
456 if (ret < 0) {
457 goto end_free;
458 }
459
460 ret = enable_events(name, sudo);
461 if (ret < 0) {
462 goto end_free;
463 }
464
465 ret = add_contexts(name, sudo);
466 if (ret < 0) {
467 goto end_free;
468 }
469
470 ret = start(name, sudo, 1, 1);
471 if (ret < 0) {
472 goto end_free;
473 }
474
475 end_free:
476 free(name);
477 end:
478 return ret;
479 }
480
481 int destroy_live_local_session(char *name)
482 {
483 return destroy(name);
484 }
485
486 int create_live_local_session(char **session_path, char **session_name, int print)
487 {
488 int ret;
489 char *name;
490 int sudo = 0;
491
492 ret = check_requirements(&sudo);
493
494 name = random_session_name();
495 if (!name) {
496 ret = -1;
497 goto end;
498 }
499
500 ret = check_session_name(name, sudo);
501 if (ret < 0) {
502 goto end_free;
503 }
504
505 ret = live_local_session(name, sudo);
506 if (ret < 0) {
507 goto end_free;
508 }
509
510 ret = enable_events(name, sudo);
511 if (ret < 0) {
512 goto end_free;
513 }
514
515 ret = add_contexts(name, sudo);
516 if (ret < 0) {
517 goto end_free;
518 }
519
520 ret = start(name, sudo, 0, print);
521 if (ret < 0) {
522 goto end_free;
523 }
524
525 if (session_path)
526 *session_path = live_path(name);
527 if (session_name) {
528 *session_name = name;
529 goto end;
530 }
531
532 end_free:
533 free(name);
534 end:
535 return ret;
536 }
This page took 0.05929 seconds and 4 git commands to generate.