xref: /linux/tools/perf/util/util.c (revision 30614cf34105c5b5b9a39c65a2ea32c58b03aa8e)
1 #include "../perf.h"
2 #include "util.h"
3 #include "debug.h"
4 #include <api/fs/fs.h>
5 #include <sys/mman.h>
6 #ifdef HAVE_BACKTRACE_SUPPORT
7 #include <execinfo.h>
8 #endif
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <errno.h>
13 #include <limits.h>
14 #include <byteswap.h>
15 #include <linux/kernel.h>
16 #include <unistd.h>
17 
18 /*
19  * XXX We need to find a better place for these things...
20  */
21 unsigned int page_size;
22 int cacheline_size;
23 
24 bool test_attr__enabled;
25 
26 bool perf_host  = true;
27 bool perf_guest = false;
28 
29 char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events";
30 
31 void event_attr_init(struct perf_event_attr *attr)
32 {
33 	if (!perf_host)
34 		attr->exclude_host  = 1;
35 	if (!perf_guest)
36 		attr->exclude_guest = 1;
37 	/* to capture ABI version */
38 	attr->size = sizeof(*attr);
39 }
40 
41 int mkdir_p(char *path, mode_t mode)
42 {
43 	struct stat st;
44 	int err;
45 	char *d = path;
46 
47 	if (*d != '/')
48 		return -1;
49 
50 	if (stat(path, &st) == 0)
51 		return 0;
52 
53 	while (*++d == '/');
54 
55 	while ((d = strchr(d, '/'))) {
56 		*d = '\0';
57 		err = stat(path, &st) && mkdir(path, mode);
58 		*d++ = '/';
59 		if (err)
60 			return -1;
61 		while (*d == '/')
62 			++d;
63 	}
64 	return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
65 }
66 
67 static int slow_copyfile(const char *from, const char *to, mode_t mode)
68 {
69 	int err = -1;
70 	char *line = NULL;
71 	size_t n;
72 	FILE *from_fp = fopen(from, "r"), *to_fp;
73 	mode_t old_umask;
74 
75 	if (from_fp == NULL)
76 		goto out;
77 
78 	old_umask = umask(mode ^ 0777);
79 	to_fp = fopen(to, "w");
80 	umask(old_umask);
81 	if (to_fp == NULL)
82 		goto out_fclose_from;
83 
84 	while (getline(&line, &n, from_fp) > 0)
85 		if (fputs(line, to_fp) == EOF)
86 			goto out_fclose_to;
87 	err = 0;
88 out_fclose_to:
89 	fclose(to_fp);
90 	free(line);
91 out_fclose_from:
92 	fclose(from_fp);
93 out:
94 	return err;
95 }
96 
97 int copyfile_mode(const char *from, const char *to, mode_t mode)
98 {
99 	int fromfd, tofd;
100 	struct stat st;
101 	void *addr;
102 	int err = -1;
103 
104 	if (stat(from, &st))
105 		goto out;
106 
107 	if (st.st_size == 0) /* /proc? do it slowly... */
108 		return slow_copyfile(from, to, mode);
109 
110 	fromfd = open(from, O_RDONLY);
111 	if (fromfd < 0)
112 		goto out;
113 
114 	tofd = creat(to, mode);
115 	if (tofd < 0)
116 		goto out_close_from;
117 
118 	addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
119 	if (addr == MAP_FAILED)
120 		goto out_close_to;
121 
122 	if (write(tofd, addr, st.st_size) == st.st_size)
123 		err = 0;
124 
125 	munmap(addr, st.st_size);
126 out_close_to:
127 	close(tofd);
128 	if (err)
129 		unlink(to);
130 out_close_from:
131 	close(fromfd);
132 out:
133 	return err;
134 }
135 
136 int copyfile(const char *from, const char *to)
137 {
138 	return copyfile_mode(from, to, 0755);
139 }
140 
141 unsigned long convert_unit(unsigned long value, char *unit)
142 {
143 	*unit = ' ';
144 
145 	if (value > 1000) {
146 		value /= 1000;
147 		*unit = 'K';
148 	}
149 
150 	if (value > 1000) {
151 		value /= 1000;
152 		*unit = 'M';
153 	}
154 
155 	if (value > 1000) {
156 		value /= 1000;
157 		*unit = 'G';
158 	}
159 
160 	return value;
161 }
162 
163 static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
164 {
165 	void *buf_start = buf;
166 	size_t left = n;
167 
168 	while (left) {
169 		ssize_t ret = is_read ? read(fd, buf, left) :
170 					write(fd, buf, left);
171 
172 		if (ret < 0 && errno == EINTR)
173 			continue;
174 		if (ret <= 0)
175 			return ret;
176 
177 		left -= ret;
178 		buf  += ret;
179 	}
180 
181 	BUG_ON((size_t)(buf - buf_start) != n);
182 	return n;
183 }
184 
185 /*
186  * Read exactly 'n' bytes or return an error.
187  */
188 ssize_t readn(int fd, void *buf, size_t n)
189 {
190 	return ion(true, fd, buf, n);
191 }
192 
193 /*
194  * Write exactly 'n' bytes or return an error.
195  */
196 ssize_t writen(int fd, void *buf, size_t n)
197 {
198 	return ion(false, fd, buf, n);
199 }
200 
201 size_t hex_width(u64 v)
202 {
203 	size_t n = 1;
204 
205 	while ((v >>= 4))
206 		++n;
207 
208 	return n;
209 }
210 
211 static int hex(char ch)
212 {
213 	if ((ch >= '0') && (ch <= '9'))
214 		return ch - '0';
215 	if ((ch >= 'a') && (ch <= 'f'))
216 		return ch - 'a' + 10;
217 	if ((ch >= 'A') && (ch <= 'F'))
218 		return ch - 'A' + 10;
219 	return -1;
220 }
221 
222 /*
223  * While we find nice hex chars, build a long_val.
224  * Return number of chars processed.
225  */
226 int hex2u64(const char *ptr, u64 *long_val)
227 {
228 	const char *p = ptr;
229 	*long_val = 0;
230 
231 	while (*p) {
232 		const int hex_val = hex(*p);
233 
234 		if (hex_val < 0)
235 			break;
236 
237 		*long_val = (*long_val << 4) | hex_val;
238 		p++;
239 	}
240 
241 	return p - ptr;
242 }
243 
244 /* Obtain a backtrace and print it to stdout. */
245 #ifdef HAVE_BACKTRACE_SUPPORT
246 void dump_stack(void)
247 {
248 	void *array[16];
249 	size_t size = backtrace(array, ARRAY_SIZE(array));
250 	char **strings = backtrace_symbols(array, size);
251 	size_t i;
252 
253 	printf("Obtained %zd stack frames.\n", size);
254 
255 	for (i = 0; i < size; i++)
256 		printf("%s\n", strings[i]);
257 
258 	free(strings);
259 }
260 #else
261 void dump_stack(void) {}
262 #endif
263 
264 void get_term_dimensions(struct winsize *ws)
265 {
266 	char *s = getenv("LINES");
267 
268 	if (s != NULL) {
269 		ws->ws_row = atoi(s);
270 		s = getenv("COLUMNS");
271 		if (s != NULL) {
272 			ws->ws_col = atoi(s);
273 			if (ws->ws_row && ws->ws_col)
274 				return;
275 		}
276 	}
277 #ifdef TIOCGWINSZ
278 	if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
279 	    ws->ws_row && ws->ws_col)
280 		return;
281 #endif
282 	ws->ws_row = 25;
283 	ws->ws_col = 80;
284 }
285 
286 void set_term_quiet_input(struct termios *old)
287 {
288 	struct termios tc;
289 
290 	tcgetattr(0, old);
291 	tc = *old;
292 	tc.c_lflag &= ~(ICANON | ECHO);
293 	tc.c_cc[VMIN] = 0;
294 	tc.c_cc[VTIME] = 0;
295 	tcsetattr(0, TCSANOW, &tc);
296 }
297 
298 static void set_tracing_events_path(const char *mountpoint)
299 {
300 	snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s",
301 		 mountpoint, "tracing/events");
302 }
303 
304 const char *perf_debugfs_mount(const char *mountpoint)
305 {
306 	const char *mnt;
307 
308 	mnt = debugfs_mount(mountpoint);
309 	if (!mnt)
310 		return NULL;
311 
312 	set_tracing_events_path(mnt);
313 
314 	return mnt;
315 }
316 
317 void perf_debugfs_set_path(const char *mntpt)
318 {
319 	snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt);
320 	set_tracing_events_path(mntpt);
321 }
322 
323 static const char *find_debugfs(void)
324 {
325 	const char *path = perf_debugfs_mount(NULL);
326 
327 	if (!path)
328 		fprintf(stderr, "Your kernel does not support the debugfs filesystem");
329 
330 	return path;
331 }
332 
333 /*
334  * Finds the path to the debugfs/tracing
335  * Allocates the string and stores it.
336  */
337 const char *find_tracing_dir(void)
338 {
339 	static char *tracing;
340 	static int tracing_found;
341 	const char *debugfs;
342 
343 	if (tracing_found)
344 		return tracing;
345 
346 	debugfs = find_debugfs();
347 	if (!debugfs)
348 		return NULL;
349 
350 	if (asprintf(&tracing, "%s/tracing", debugfs) < 0)
351 		return NULL;
352 
353 	tracing_found = 1;
354 	return tracing;
355 }
356 
357 char *get_tracing_file(const char *name)
358 {
359 	const char *tracing;
360 	char *file;
361 
362 	tracing = find_tracing_dir();
363 	if (!tracing)
364 		return NULL;
365 
366 	if (asprintf(&file, "%s/%s", tracing, name) < 0)
367 		return NULL;
368 
369 	return file;
370 }
371 
372 void put_tracing_file(char *file)
373 {
374 	free(file);
375 }
376 
377 int parse_nsec_time(const char *str, u64 *ptime)
378 {
379 	u64 time_sec, time_nsec;
380 	char *end;
381 
382 	time_sec = strtoul(str, &end, 10);
383 	if (*end != '.' && *end != '\0')
384 		return -1;
385 
386 	if (*end == '.') {
387 		int i;
388 		char nsec_buf[10];
389 
390 		if (strlen(++end) > 9)
391 			return -1;
392 
393 		strncpy(nsec_buf, end, 9);
394 		nsec_buf[9] = '\0';
395 
396 		/* make it nsec precision */
397 		for (i = strlen(nsec_buf); i < 9; i++)
398 			nsec_buf[i] = '0';
399 
400 		time_nsec = strtoul(nsec_buf, &end, 10);
401 		if (*end != '\0')
402 			return -1;
403 	} else
404 		time_nsec = 0;
405 
406 	*ptime = time_sec * NSEC_PER_SEC + time_nsec;
407 	return 0;
408 }
409 
410 unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
411 {
412 	struct parse_tag *i = tags;
413 
414 	while (i->tag) {
415 		char *s;
416 
417 		s = strchr(str, i->tag);
418 		if (s) {
419 			unsigned long int value;
420 			char *endptr;
421 
422 			value = strtoul(str, &endptr, 10);
423 			if (s != endptr)
424 				break;
425 
426 			if (value > ULONG_MAX / i->mult)
427 				break;
428 			value *= i->mult;
429 			return value;
430 		}
431 		i++;
432 	}
433 
434 	return (unsigned long) -1;
435 }
436 
437 int filename__read_int(const char *filename, int *value)
438 {
439 	char line[64];
440 	int fd = open(filename, O_RDONLY), err = -1;
441 
442 	if (fd < 0)
443 		return -1;
444 
445 	if (read(fd, line, sizeof(line)) > 0) {
446 		*value = atoi(line);
447 		err = 0;
448 	}
449 
450 	close(fd);
451 	return err;
452 }
453 
454 int filename__read_str(const char *filename, char **buf, size_t *sizep)
455 {
456 	size_t size = 0, alloc_size = 0;
457 	void *bf = NULL, *nbf;
458 	int fd, n, err = 0;
459 	char sbuf[STRERR_BUFSIZE];
460 
461 	fd = open(filename, O_RDONLY);
462 	if (fd < 0)
463 		return -errno;
464 
465 	do {
466 		if (size == alloc_size) {
467 			alloc_size += BUFSIZ;
468 			nbf = realloc(bf, alloc_size);
469 			if (!nbf) {
470 				err = -ENOMEM;
471 				break;
472 			}
473 
474 			bf = nbf;
475 		}
476 
477 		n = read(fd, bf + size, alloc_size - size);
478 		if (n < 0) {
479 			if (size) {
480 				pr_warning("read failed %d: %s\n", errno,
481 					 strerror_r(errno, sbuf, sizeof(sbuf)));
482 				err = 0;
483 			} else
484 				err = -errno;
485 
486 			break;
487 		}
488 
489 		size += n;
490 	} while (n > 0);
491 
492 	if (!err) {
493 		*sizep = size;
494 		*buf   = bf;
495 	} else
496 		free(bf);
497 
498 	close(fd);
499 	return err;
500 }
501 
502 const char *get_filename_for_perf_kvm(void)
503 {
504 	const char *filename;
505 
506 	if (perf_host && !perf_guest)
507 		filename = strdup("perf.data.host");
508 	else if (!perf_host && perf_guest)
509 		filename = strdup("perf.data.guest");
510 	else
511 		filename = strdup("perf.data.kvm");
512 
513 	return filename;
514 }
515 
516 int perf_event_paranoid(void)
517 {
518 	char path[PATH_MAX];
519 	const char *procfs = procfs__mountpoint();
520 	int value;
521 
522 	if (!procfs)
523 		return INT_MAX;
524 
525 	scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs);
526 
527 	if (filename__read_int(path, &value))
528 		return INT_MAX;
529 
530 	return value;
531 }
532 
533 void mem_bswap_32(void *src, int byte_size)
534 {
535 	u32 *m = src;
536 	while (byte_size > 0) {
537 		*m = bswap_32(*m);
538 		byte_size -= sizeof(u32);
539 		++m;
540 	}
541 }
542 
543 void mem_bswap_64(void *src, int byte_size)
544 {
545 	u64 *m = src;
546 
547 	while (byte_size > 0) {
548 		*m = bswap_64(*m);
549 		byte_size -= sizeof(u64);
550 		++m;
551 	}
552 }
553 
554 bool find_process(const char *name)
555 {
556 	size_t len = strlen(name);
557 	DIR *dir;
558 	struct dirent *d;
559 	int ret = -1;
560 
561 	dir = opendir(procfs__mountpoint());
562 	if (!dir)
563 		return -1;
564 
565 	/* Walk through the directory. */
566 	while (ret && (d = readdir(dir)) != NULL) {
567 		char path[PATH_MAX];
568 		char *data;
569 		size_t size;
570 
571 		if ((d->d_type != DT_DIR) ||
572 		     !strcmp(".", d->d_name) ||
573 		     !strcmp("..", d->d_name))
574 			continue;
575 
576 		scnprintf(path, sizeof(path), "%s/%s/comm",
577 			  procfs__mountpoint(), d->d_name);
578 
579 		if (filename__read_str(path, &data, &size))
580 			continue;
581 
582 		ret = strncmp(name, data, len);
583 		free(data);
584 	}
585 
586 	closedir(dir);
587 	return ret ? false : true;
588 }
589