8b0f6414539eb5b20f52d4c0b0af18f004736e06
[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 (sudo) ? "sudo" : " ", name, event_list);
277 if (ret < 0) {
278 fprintf(stderr, "Allocating cmd\n");
279 goto end;
280 }
281
282 ret = (system(cmd));
283 if (ret != 0) {
284 fprintf(stderr, "Error: enabling events\n");
285 ret = -1;
286 goto end;
287 }
288
289 end:
290 return ret;
291 }
292
293 static
294 int add_contexts(char *name, int sudo)
295 {
296 int ret;
297 char cmd[1024];
298
299 ret = sprintf(cmd, "%s lttng add-context -s %s -k %s >/dev/null",
300 (sudo) ? "sudo" : " ", name, context_list);
301 if (ret < 0) {
302 fprintf(stderr, "allocating cmd\n");
303 goto end;
304 }
305
306 ret = (system(cmd));
307 if (ret != 0) {
308 fprintf(stderr, "error: adding contexts\n");
309 ret = -1;
310 goto end;
311 }
312
313 end:
314 return ret;
315 }
316
317 static
318 int start(char *name, int sudo, int local, int print)
319 {
320 int ret;
321 char cmd[1024];
322
323 ret = sprintf(cmd, "%s lttng start %s >/dev/null",
324 (sudo) ? "sudo" : " ", name);
325 if (ret < 0) {
326 fprintf(stderr, "allocating cmd\n");
327 goto end;
328 }
329
330 ret = (system(cmd));
331 if (ret != 0) {
332 fprintf(stderr, "error: starting the session %s\n", name);
333 ret = -1;
334 goto end;
335 }
336
337 if (!print)
338 goto end;
339
340 if (local) {
341 ret = sprintf(cmd, "%s lttng list|grep %s|cut -d'(' -f2|cut -d ')' -f1",
342 (sudo) ? "sudo" : " ", name);
343 } else {
344 ret = sprintf(cmd, "babeltrace -i lttng-live net://localhost|grep %s|cut -d' ' -f1",
345 name);
346 }
347 if (ret < 0) {
348 fprintf(stderr, "allocating cmd\n");
349 goto end;
350 }
351 fprintf(stderr, "%s session started : ",
352 (local) ? "Local" : "Live");
353 ret = (system(cmd));
354 if (ret != 0) {
355 fprintf(stderr, "error: listing the sessions\n");
356 ret = -1;
357 goto end;
358 }
359
360 end:
361 return ret;
362 }
363
364 static
365 char *live_path(char *name)
366 {
367 FILE *fp;
368 int ret;
369 char path[1035];
370 char cmd[1024];
371 char *out = NULL;
372
373 ret = sprintf(cmd, "lttngtop -r net://localhost|grep %s|cut -d' ' -f1",
374 name);
375 if (ret < 0) {
376 fprintf(stderr, "allocating cmd\n");
377 goto end;
378 }
379
380 fp = popen(cmd, "r");
381 if (fp == NULL) {
382 printf("Failed to run command\n" );
383 goto end;
384 }
385
386 /* Read the output a line at a time - output it. */
387 out = fgets(path, sizeof(path)-1, fp);
388 if (out)
389 out = strdup(path);
390
391 /* close */
392 pclose(fp);
393
394 end:
395 return out;
396 }
397
398 static
399 int destroy(char *name)
400 {
401 int ret;
402 int sudo = 0;
403 char cmd[1024];
404
405 if (getuid() != 0) {
406 ret = system("sudo -l lttng >/dev/null");
407 if (ret < 0) {
408 fprintf(stderr, "[error] You are not root and not "
409 "allowed by sudo to use lttng\n");
410 ret = -1;
411 goto end;
412 }
413 sudo = 1;
414 }
415
416 ret = sprintf(cmd, "%s lttng destroy %s >/dev/null",
417 (sudo) ? "sudo" : " ", name);
418 if (ret < 0) {
419 fprintf(stderr, "allocating cmd\n");
420 goto end;
421 }
422
423 ret = (system(cmd));
424 if (ret != 0) {
425 fprintf(stderr, "error: destroying the session %s\n", name);
426 ret = -1;
427 goto end;
428 }
429
430 end:
431 return ret;
432 }
433
434 int create_local_session()
435 {
436 int ret;
437 char *name;
438 int sudo = 0;
439
440 ret = check_requirements(&sudo);
441
442 name = random_session_name();
443 if (!name) {
444 ret = -1;
445 goto end;
446 }
447
448 ret = check_session_name(name, sudo);
449 if (ret < 0) {
450 goto end_free;
451 }
452
453 ret = local_session(name, sudo);
454 if (ret < 0) {
455 goto end_free;
456 }
457
458 ret = enable_events(name, sudo);
459 if (ret < 0) {
460 goto end_free;
461 }
462
463 ret = add_contexts(name, sudo);
464 if (ret < 0) {
465 goto end_free;
466 }
467
468 ret = start(name, sudo, 1, 1);
469 if (ret < 0) {
470 goto end_free;
471 }
472
473 end_free:
474 free(name);
475 end:
476 return ret;
477 }
478
479 int destroy_live_local_session(char *name)
480 {
481 return destroy(name);
482 }
483
484 int create_live_local_session(char **session_path, char **session_name, int print)
485 {
486 int ret;
487 char *name;
488 int sudo = 0;
489
490 ret = check_requirements(&sudo);
491
492 name = random_session_name();
493 if (!name) {
494 ret = -1;
495 goto end;
496 }
497
498 ret = check_session_name(name, sudo);
499 if (ret < 0) {
500 goto end_free;
501 }
502
503 ret = live_local_session(name, sudo);
504 if (ret < 0) {
505 goto end_free;
506 }
507
508 ret = enable_events(name, sudo);
509 if (ret < 0) {
510 goto end_free;
511 }
512
513 ret = add_contexts(name, sudo);
514 if (ret < 0) {
515 goto end_free;
516 }
517
518 ret = start(name, sudo, 0, print);
519 if (ret < 0) {
520 goto end_free;
521 }
522
523 if (session_path)
524 *session_path = live_path(name);
525 if (session_name) {
526 *session_name = name;
527 goto end;
528 }
529
530 end_free:
531 free(name);
532 end:
533 return ret;
534 }
This page took 0.039371 seconds and 4 git commands to generate.