blob: 0c264bc685aceb94c544358c38caa8158d441b68 [file] [log] [blame]
Joerg Roedel1aed2672012-01-04 17:54:20 +01001#include "../perf.h"
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -02002#include "util.h"
Jiri Olsa84f5d362014-07-14 23:46:48 +02003#include "debug.h"
Borislav Petkovcd0cfad2013-12-09 17:14:24 +01004#include <api/fs/fs.h>
Frederic Weisbecker69e3f522010-01-16 14:21:15 +01005#include <sys/mman.h>
Ingo Molnar89fe8082013-09-30 12:07:11 +02006#ifdef HAVE_BACKTRACE_SUPPORT
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -03007#include <execinfo.h>
Irina Tirdeac9f08be2012-09-08 03:43:23 +03008#endif
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -03009#include <stdio.h>
10#include <stdlib.h>
Jiri Olsacef82c92013-12-03 14:09:22 +010011#include <string.h>
12#include <errno.h>
Adrian Hunter1a472452013-12-11 14:36:23 +020013#include <limits.h>
Adrian Hunter71db07b2013-12-11 14:36:32 +020014#include <byteswap.h>
Jiri Olsa838d1452013-11-28 11:30:15 +010015#include <linux/kernel.h>
Jiri Olsa9398c482014-08-11 10:50:02 +020016#include <unistd.h>
Jiri Olsa23aadb12014-10-01 18:00:26 +020017#include "callchain.h"
18
19struct callchain_param callchain_param = {
20 .mode = CHAIN_GRAPH_REL,
21 .min_percent = 0.5,
22 .order = ORDER_CALLEE,
23 .key = CCKEY_FUNCTION
24};
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020025
Joerg Roedel1aed2672012-01-04 17:54:20 +010026/*
27 * XXX We need to find a better place for these things...
28 */
Arnaldo Carvalho de Melo0c1fe6b2012-10-06 14:57:10 -030029unsigned int page_size;
Don Zickus2b1b7102014-05-30 16:10:05 -040030int cacheline_size;
Arnaldo Carvalho de Melo0c1fe6b2012-10-06 14:57:10 -030031
Arnaldo Carvalho de Melo0c6332e2012-12-13 16:43:04 -030032bool test_attr__enabled;
33
Joerg Roedel1aed2672012-01-04 17:54:20 +010034bool perf_host = true;
Joerg Roedelc4a7dca2012-02-10 18:05:05 +010035bool perf_guest = false;
Joerg Roedel1aed2672012-01-04 17:54:20 +010036
Borislav Petkov13559152013-02-20 16:32:31 +010037char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events";
38
Joerg Roedel1aed2672012-01-04 17:54:20 +010039void event_attr_init(struct perf_event_attr *attr)
40{
41 if (!perf_host)
42 attr->exclude_host = 1;
43 if (!perf_guest)
44 attr->exclude_guest = 1;
Stephane Eranian7e1ccd32012-02-09 16:12:38 +010045 /* to capture ABI version */
46 attr->size = sizeof(*attr);
Joerg Roedel1aed2672012-01-04 17:54:20 +010047}
48
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020049int mkdir_p(char *path, mode_t mode)
50{
51 struct stat st;
52 int err;
53 char *d = path;
54
55 if (*d != '/')
56 return -1;
57
58 if (stat(path, &st) == 0)
59 return 0;
60
61 while (*++d == '/');
62
63 while ((d = strchr(d, '/'))) {
64 *d = '\0';
65 err = stat(path, &st) && mkdir(path, mode);
66 *d++ = '/';
67 if (err)
68 return -1;
69 while (*d == '/')
70 ++d;
71 }
72 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
73}
74
Namhyung Kim0b1de0be2015-05-18 09:30:17 +090075int rm_rf(char *path)
76{
77 DIR *dir;
78 int ret = 0;
79 struct dirent *d;
80 char namebuf[PATH_MAX];
81
82 dir = opendir(path);
83 if (dir == NULL)
84 return 0;
85
86 while ((d = readdir(dir)) != NULL && !ret) {
87 struct stat statbuf;
88
89 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, ".."))
90 continue;
91
92 scnprintf(namebuf, sizeof(namebuf), "%s/%s",
93 path, d->d_name);
94
95 ret = stat(namebuf, &statbuf);
96 if (ret < 0) {
97 pr_debug("stat failed: %s\n", namebuf);
98 break;
99 }
100
101 if (S_ISREG(statbuf.st_mode))
102 ret = unlink(namebuf);
103 else if (S_ISDIR(statbuf.st_mode))
104 ret = rm_rf(namebuf);
105 else {
106 pr_debug("unknown file: %s\n", namebuf);
107 ret = -1;
108 }
109 }
110 closedir(dir);
111
112 if (ret < 0)
113 return ret;
114
115 return rmdir(path);
116}
117
Adrian Hunter9a17d722013-10-14 13:43:41 +0300118static int slow_copyfile(const char *from, const char *to, mode_t mode)
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200119{
Adrian Hunter9a17d722013-10-14 13:43:41 +0300120 int err = -1;
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200121 char *line = NULL;
122 size_t n;
123 FILE *from_fp = fopen(from, "r"), *to_fp;
Adrian Hunter9a17d722013-10-14 13:43:41 +0300124 mode_t old_umask;
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200125
126 if (from_fp == NULL)
127 goto out;
128
Adrian Hunter9a17d722013-10-14 13:43:41 +0300129 old_umask = umask(mode ^ 0777);
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200130 to_fp = fopen(to, "w");
Adrian Hunter9a17d722013-10-14 13:43:41 +0300131 umask(old_umask);
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200132 if (to_fp == NULL)
133 goto out_fclose_from;
134
135 while (getline(&line, &n, from_fp) > 0)
136 if (fputs(line, to_fp) == EOF)
137 goto out_fclose_to;
138 err = 0;
139out_fclose_to:
140 fclose(to_fp);
141 free(line);
142out_fclose_from:
143 fclose(from_fp);
144out:
145 return err;
146}
147
Namhyung Kim9c9f5a22015-05-18 09:30:18 +0900148int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size)
149{
150 void *ptr;
151 loff_t pgoff;
152
153 pgoff = off_in & ~(page_size - 1);
154 off_in -= pgoff;
155
156 ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff);
157 if (ptr == MAP_FAILED)
158 return -1;
159
160 while (size) {
161 ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out);
162 if (ret < 0 && errno == EINTR)
163 continue;
164 if (ret <= 0)
165 break;
166
167 size -= ret;
168 off_in += ret;
169 off_out -= ret;
170 }
171 munmap(ptr, off_in + size);
172
173 return size ? -1 : 0;
174}
175
Adrian Hunter9a17d722013-10-14 13:43:41 +0300176int copyfile_mode(const char *from, const char *to, mode_t mode)
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -0200177{
178 int fromfd, tofd;
179 struct stat st;
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -0200180 int err = -1;
181
182 if (stat(from, &st))
183 goto out;
184
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200185 if (st.st_size == 0) /* /proc? do it slowly... */
Adrian Hunter9a17d722013-10-14 13:43:41 +0300186 return slow_copyfile(from, to, mode);
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -0200187
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -0200188 fromfd = open(from, O_RDONLY);
189 if (fromfd < 0)
190 goto out;
191
Adrian Hunter9a17d722013-10-14 13:43:41 +0300192 tofd = creat(to, mode);
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -0200193 if (tofd < 0)
194 goto out_close_from;
195
Namhyung Kim9c9f5a22015-05-18 09:30:18 +0900196 err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size);
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -0200197
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -0200198 close(tofd);
199 if (err)
200 unlink(to);
201out_close_from:
202 close(fromfd);
203out:
204 return err;
205}
Arnaldo Carvalho de Meloc82ee822010-05-14 14:19:35 -0300206
Adrian Hunter9a17d722013-10-14 13:43:41 +0300207int copyfile(const char *from, const char *to)
208{
209 return copyfile_mode(from, to, 0755);
210}
211
Arnaldo Carvalho de Meloc82ee822010-05-14 14:19:35 -0300212unsigned long convert_unit(unsigned long value, char *unit)
213{
214 *unit = ' ';
215
216 if (value > 1000) {
217 value /= 1000;
218 *unit = 'K';
219 }
220
221 if (value > 1000) {
222 value /= 1000;
223 *unit = 'M';
224 }
225
226 if (value > 1000) {
227 value /= 1000;
228 *unit = 'G';
229 }
230
231 return value;
232}
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200233
Jiri Olsabc3a5022013-11-28 11:30:16 +0100234static ssize_t ion(bool is_read, int fd, void *buf, size_t n)
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200235{
236 void *buf_start = buf;
Jiri Olsa838d1452013-11-28 11:30:15 +0100237 size_t left = n;
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200238
Jiri Olsa838d1452013-11-28 11:30:15 +0100239 while (left) {
Jiri Olsabc3a5022013-11-28 11:30:16 +0100240 ssize_t ret = is_read ? read(fd, buf, left) :
241 write(fd, buf, left);
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200242
Namhyung Kime148c762014-04-24 22:27:32 +0900243 if (ret < 0 && errno == EINTR)
244 continue;
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200245 if (ret <= 0)
246 return ret;
247
Jiri Olsa838d1452013-11-28 11:30:15 +0100248 left -= ret;
249 buf += ret;
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200250 }
251
Jiri Olsa838d1452013-11-28 11:30:15 +0100252 BUG_ON((size_t)(buf - buf_start) != n);
253 return n;
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200254}
Arnaldo Carvalho de Melo61e04b32012-04-19 13:15:24 -0300255
Jiri Olsabc3a5022013-11-28 11:30:16 +0100256/*
257 * Read exactly 'n' bytes or return an error.
258 */
259ssize_t readn(int fd, void *buf, size_t n)
260{
261 return ion(true, fd, buf, n);
262}
263
264/*
265 * Write exactly 'n' bytes or return an error.
266 */
267ssize_t writen(int fd, void *buf, size_t n)
268{
269 return ion(false, fd, buf, n);
270}
271
Arnaldo Carvalho de Melo61e04b32012-04-19 13:15:24 -0300272size_t hex_width(u64 v)
273{
274 size_t n = 1;
275
276 while ((v >>= 4))
277 ++n;
278
279 return n;
280}
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300281
Jiri Olsab2aff5f2012-10-27 23:18:30 +0200282static int hex(char ch)
283{
284 if ((ch >= '0') && (ch <= '9'))
285 return ch - '0';
286 if ((ch >= 'a') && (ch <= 'f'))
287 return ch - 'a' + 10;
288 if ((ch >= 'A') && (ch <= 'F'))
289 return ch - 'A' + 10;
290 return -1;
291}
292
293/*
294 * While we find nice hex chars, build a long_val.
295 * Return number of chars processed.
296 */
297int hex2u64(const char *ptr, u64 *long_val)
298{
299 const char *p = ptr;
300 *long_val = 0;
301
302 while (*p) {
303 const int hex_val = hex(*p);
304
305 if (hex_val < 0)
306 break;
307
308 *long_val = (*long_val << 4) | hex_val;
309 p++;
310 }
311
312 return p - ptr;
313}
314
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300315/* Obtain a backtrace and print it to stdout. */
Ingo Molnar89fe8082013-09-30 12:07:11 +0200316#ifdef HAVE_BACKTRACE_SUPPORT
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300317void dump_stack(void)
318{
319 void *array[16];
320 size_t size = backtrace(array, ARRAY_SIZE(array));
321 char **strings = backtrace_symbols(array, size);
322 size_t i;
323
324 printf("Obtained %zd stack frames.\n", size);
325
326 for (i = 0; i < size; i++)
327 printf("%s\n", strings[i]);
328
329 free(strings);
330}
Irina Tirdeac9f08be2012-09-08 03:43:23 +0300331#else
332void dump_stack(void) {}
333#endif
David Ahern2c803e52013-01-14 10:48:01 -0700334
Arnaldo Carvalho de Melo07c1a0d2015-02-24 15:34:23 -0300335void sighandler_dump_stack(int sig)
336{
337 psignal(sig, "perf");
338 dump_stack();
339 exit(sig);
340}
341
David Ahern2c803e52013-01-14 10:48:01 -0700342void get_term_dimensions(struct winsize *ws)
343{
344 char *s = getenv("LINES");
345
346 if (s != NULL) {
347 ws->ws_row = atoi(s);
348 s = getenv("COLUMNS");
349 if (s != NULL) {
350 ws->ws_col = atoi(s);
351 if (ws->ws_row && ws->ws_col)
352 return;
353 }
354 }
355#ifdef TIOCGWINSZ
356 if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
357 ws->ws_row && ws->ws_col)
358 return;
359#endif
360 ws->ws_row = 25;
361 ws->ws_col = 80;
362}
Borislav Petkov13559152013-02-20 16:32:31 +0100363
Jiri Olsa9398c482014-08-11 10:50:02 +0200364void set_term_quiet_input(struct termios *old)
365{
366 struct termios tc;
367
368 tcgetattr(0, old);
369 tc = *old;
370 tc.c_lflag &= ~(ICANON | ECHO);
371 tc.c_cc[VMIN] = 0;
372 tc.c_cc[VTIME] = 0;
373 tcsetattr(0, TCSANOW, &tc);
374}
375
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500376static void set_tracing_events_path(const char *tracing, const char *mountpoint)
Borislav Petkov13559152013-02-20 16:32:31 +0100377{
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500378 snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s%s",
379 mountpoint, tracing, "events");
Borislav Petkov13559152013-02-20 16:32:31 +0100380}
381
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500382static const char *__perf_tracefs_mount(const char *mountpoint)
383{
384 const char *mnt;
385
386 mnt = tracefs_mount(mountpoint);
387 if (!mnt)
388 return NULL;
389
390 set_tracing_events_path("", mnt);
391
392 return mnt;
393}
394
395static const char *__perf_debugfs_mount(const char *mountpoint)
Borislav Petkov13559152013-02-20 16:32:31 +0100396{
397 const char *mnt;
398
399 mnt = debugfs_mount(mountpoint);
400 if (!mnt)
401 return NULL;
402
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500403 set_tracing_events_path("tracing/", mnt);
404
405 return mnt;
406}
407
408const char *perf_debugfs_mount(const char *mountpoint)
409{
410 const char *mnt;
411
412 mnt = __perf_tracefs_mount(mountpoint);
413 if (mnt)
414 return mnt;
415
416 mnt = __perf_debugfs_mount(mountpoint);
Borislav Petkov13559152013-02-20 16:32:31 +0100417
418 return mnt;
419}
420
421void perf_debugfs_set_path(const char *mntpt)
422{
423 snprintf(debugfs_mountpoint, strlen(debugfs_mountpoint), "%s", mntpt);
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500424 set_tracing_events_path("tracing/", mntpt);
425}
426
427static const char *find_tracefs(void)
428{
429 const char *path = __perf_tracefs_mount(NULL);
430
431 return path;
Borislav Petkov13559152013-02-20 16:32:31 +0100432}
Namhyung Kim167aedc2013-06-26 16:14:04 +0900433
434static const char *find_debugfs(void)
435{
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500436 const char *path = __perf_debugfs_mount(NULL);
Namhyung Kim167aedc2013-06-26 16:14:04 +0900437
438 if (!path)
439 fprintf(stderr, "Your kernel does not support the debugfs filesystem");
440
441 return path;
442}
443
444/*
445 * Finds the path to the debugfs/tracing
446 * Allocates the string and stores it.
447 */
448const char *find_tracing_dir(void)
449{
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500450 const char *tracing_dir = "";
Namhyung Kim167aedc2013-06-26 16:14:04 +0900451 static char *tracing;
452 static int tracing_found;
453 const char *debugfs;
454
455 if (tracing_found)
456 return tracing;
457
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500458 debugfs = find_tracefs();
459 if (!debugfs) {
460 tracing_dir = "/tracing";
461 debugfs = find_debugfs();
462 if (!debugfs)
463 return NULL;
464 }
Namhyung Kim167aedc2013-06-26 16:14:04 +0900465
Steven Rostedt (Red Hat)23773ca2015-02-02 14:35:07 -0500466 if (asprintf(&tracing, "%s%s", debugfs, tracing_dir) < 0)
Namhyung Kim167aedc2013-06-26 16:14:04 +0900467 return NULL;
468
Namhyung Kim167aedc2013-06-26 16:14:04 +0900469 tracing_found = 1;
470 return tracing;
471}
472
473char *get_tracing_file(const char *name)
474{
475 const char *tracing;
476 char *file;
477
478 tracing = find_tracing_dir();
479 if (!tracing)
480 return NULL;
481
Andy Shevchenkod400a682014-07-04 14:43:48 +0300482 if (asprintf(&file, "%s/%s", tracing, name) < 0)
Namhyung Kim167aedc2013-06-26 16:14:04 +0900483 return NULL;
484
Namhyung Kim167aedc2013-06-26 16:14:04 +0900485 return file;
486}
487
488void put_tracing_file(char *file)
489{
490 free(file);
491}
Namhyung Kim3b47abe2013-06-04 10:50:29 +0900492
493int parse_nsec_time(const char *str, u64 *ptime)
494{
495 u64 time_sec, time_nsec;
496 char *end;
497
498 time_sec = strtoul(str, &end, 10);
499 if (*end != '.' && *end != '\0')
500 return -1;
501
502 if (*end == '.') {
503 int i;
504 char nsec_buf[10];
505
506 if (strlen(++end) > 9)
507 return -1;
508
509 strncpy(nsec_buf, end, 9);
510 nsec_buf[9] = '\0';
511
512 /* make it nsec precision */
513 for (i = strlen(nsec_buf); i < 9; i++)
514 nsec_buf[i] = '0';
515
516 time_nsec = strtoul(nsec_buf, &end, 10);
517 if (*end != '\0')
518 return -1;
519 } else
520 time_nsec = 0;
521
522 *ptime = time_sec * NSEC_PER_SEC + time_nsec;
523 return 0;
524}
Jiri Olsa27050f52013-09-01 12:36:13 +0200525
526unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
527{
528 struct parse_tag *i = tags;
529
530 while (i->tag) {
531 char *s;
532
533 s = strchr(str, i->tag);
534 if (s) {
535 unsigned long int value;
536 char *endptr;
537
538 value = strtoul(str, &endptr, 10);
539 if (s != endptr)
540 break;
541
Adrian Hunter56921be2013-10-22 10:34:17 +0300542 if (value > ULONG_MAX / i->mult)
543 break;
Jiri Olsa27050f52013-09-01 12:36:13 +0200544 value *= i->mult;
545 return value;
546 }
547 i++;
548 }
549
550 return (unsigned long) -1;
551}
Arnaldo Carvalho de Melo97a07f12013-10-17 16:33:43 -0300552
Jiri Olsacef82c92013-12-03 14:09:22 +0100553int filename__read_str(const char *filename, char **buf, size_t *sizep)
554{
555 size_t size = 0, alloc_size = 0;
556 void *bf = NULL, *nbf;
557 int fd, n, err = 0;
Masami Hiramatsu6e81c742014-08-14 02:22:36 +0000558 char sbuf[STRERR_BUFSIZE];
Jiri Olsacef82c92013-12-03 14:09:22 +0100559
560 fd = open(filename, O_RDONLY);
561 if (fd < 0)
562 return -errno;
563
564 do {
565 if (size == alloc_size) {
566 alloc_size += BUFSIZ;
567 nbf = realloc(bf, alloc_size);
568 if (!nbf) {
569 err = -ENOMEM;
570 break;
571 }
572
573 bf = nbf;
574 }
575
576 n = read(fd, bf + size, alloc_size - size);
577 if (n < 0) {
578 if (size) {
Masami Hiramatsu6e81c742014-08-14 02:22:36 +0000579 pr_warning("read failed %d: %s\n", errno,
580 strerror_r(errno, sbuf, sizeof(sbuf)));
Jiri Olsacef82c92013-12-03 14:09:22 +0100581 err = 0;
582 } else
583 err = -errno;
584
585 break;
586 }
587
588 size += n;
589 } while (n > 0);
590
591 if (!err) {
592 *sizep = size;
593 *buf = bf;
594 } else
595 free(bf);
596
597 close(fd);
598 return err;
599}
Dongsheng Yange1a2b172013-12-06 17:25:51 -0500600
601const char *get_filename_for_perf_kvm(void)
602{
603 const char *filename;
604
605 if (perf_host && !perf_guest)
606 filename = strdup("perf.data.host");
607 else if (!perf_host && perf_guest)
608 filename = strdup("perf.data.guest");
609 else
610 filename = strdup("perf.data.kvm");
611
612 return filename;
613}
Adrian Hunter1a472452013-12-11 14:36:23 +0200614
615int perf_event_paranoid(void)
616{
Adrian Hunter1a472452013-12-11 14:36:23 +0200617 int value;
618
Arnaldo Carvalho de Meloce273092014-12-11 13:37:59 -0300619 if (sysctl__read_int("kernel/perf_event_paranoid", &value))
Adrian Hunter1a472452013-12-11 14:36:23 +0200620 return INT_MAX;
621
622 return value;
623}
Adrian Hunter71db07b2013-12-11 14:36:32 +0200624
625void mem_bswap_32(void *src, int byte_size)
626{
627 u32 *m = src;
628 while (byte_size > 0) {
629 *m = bswap_32(*m);
630 byte_size -= sizeof(u32);
631 ++m;
632 }
633}
634
635void mem_bswap_64(void *src, int byte_size)
636{
637 u64 *m = src;
638
639 while (byte_size > 0) {
640 *m = bswap_64(*m);
641 byte_size -= sizeof(u64);
642 ++m;
643 }
644}
Jiri Olsa63914ac2014-08-01 17:46:54 +0200645
646bool find_process(const char *name)
647{
648 size_t len = strlen(name);
649 DIR *dir;
650 struct dirent *d;
651 int ret = -1;
652
653 dir = opendir(procfs__mountpoint());
654 if (!dir)
655 return -1;
656
657 /* Walk through the directory. */
658 while (ret && (d = readdir(dir)) != NULL) {
659 char path[PATH_MAX];
660 char *data;
661 size_t size;
662
663 if ((d->d_type != DT_DIR) ||
664 !strcmp(".", d->d_name) ||
665 !strcmp("..", d->d_name))
666 continue;
667
668 scnprintf(path, sizeof(path), "%s/%s/comm",
669 procfs__mountpoint(), d->d_name);
670
671 if (filename__read_str(path, &data, &size))
672 continue;
673
674 ret = strncmp(name, data, len);
675 free(data);
676 }
677
678 closedir(dir);
679 return ret ? false : true;
680}