diff options
author | Borislav Petkov <bp@suse.de> | 2013-02-20 10:32:30 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-03-15 12:06:00 -0400 |
commit | 85c66be101e1847f0eb46dcb48d5738572129694 (patch) | |
tree | 96900665b0edb1466da7b82bd7ca619858f4ba4d /tools/lib | |
parent | 9687b89d21999301ed386855c04b60d00ed1ec02 (diff) |
perf tools: Introduce tools/lib/lk library
This introduces the tools/lib/lk library, that will gradually have the
routines that now are used in tools/perf/ and other tools and that can
be shared.
Start by carving out debugfs routines for general use.
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1361374353-30385-5-git-send-email-bp@alien8.de
[ committer note: Add tools/lib/lk/ to perf's MANIFEST so that its tarballs continue to build ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/lk/Makefile | 35 | ||||
-rw-r--r-- | tools/lib/lk/debugfs.c | 116 | ||||
-rw-r--r-- | tools/lib/lk/debugfs.h | 31 |
3 files changed, 182 insertions, 0 deletions
diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile new file mode 100644 index 000000000000..8cf576f1a003 --- /dev/null +++ b/tools/lib/lk/Makefile | |||
@@ -0,0 +1,35 @@ | |||
1 | include ../../scripts/Makefile.include | ||
2 | |||
3 | # guard against environment variables | ||
4 | LIB_H= | ||
5 | LIB_OBJS= | ||
6 | |||
7 | LIB_H += debugfs.h | ||
8 | |||
9 | LIB_OBJS += $(OUTPUT)debugfs.o | ||
10 | |||
11 | LIBFILE = liblk.a | ||
12 | |||
13 | CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC | ||
14 | EXTLIBS = -lpthread -lrt -lelf -lm | ||
15 | ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 | ||
16 | ALL_LDFLAGS = $(LDFLAGS) | ||
17 | |||
18 | RM = rm -f | ||
19 | |||
20 | $(LIBFILE): $(LIB_OBJS) | ||
21 | $(QUIET_AR)$(RM) $@ && $(AR) rcs $(OUTPUT)$@ $(LIB_OBJS) | ||
22 | |||
23 | $(LIB_OBJS): $(LIB_H) | ||
24 | |||
25 | $(OUTPUT)%.o: %.c | ||
26 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< | ||
27 | $(OUTPUT)%.s: %.c | ||
28 | $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< | ||
29 | $(OUTPUT)%.o: %.S | ||
30 | $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< | ||
31 | |||
32 | clean: | ||
33 | $(RM) $(LIB_OBJS) $(LIBFILE) | ||
34 | |||
35 | .PHONY: clean | ||
diff --git a/tools/lib/lk/debugfs.c b/tools/lib/lk/debugfs.c new file mode 100644 index 000000000000..9cda7a6f5917 --- /dev/null +++ b/tools/lib/lk/debugfs.c | |||
@@ -0,0 +1,116 @@ | |||
1 | #include <errno.h> | ||
2 | #include <stdio.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <string.h> | ||
5 | #include <stdbool.h> | ||
6 | #include <sys/vfs.h> | ||
7 | #include <sys/mount.h> | ||
8 | #include <linux/magic.h> | ||
9 | #include <linux/kernel.h> | ||
10 | |||
11 | #include "debugfs.h" | ||
12 | |||
13 | char debugfs_mountpoint[PATH_MAX + 1] = "/sys/kernel/debug"; | ||
14 | char tracing_events_path[PATH_MAX + 1] = "/sys/kernel/debug/tracing/events"; | ||
15 | |||
16 | static const char * const debugfs_known_mountpoints[] = { | ||
17 | "/sys/kernel/debug/", | ||
18 | "/debug/", | ||
19 | 0, | ||
20 | }; | ||
21 | |||
22 | static bool debugfs_found; | ||
23 | |||
24 | /* find the path to the mounted debugfs */ | ||
25 | const char *debugfs_find_mountpoint(void) | ||
26 | { | ||
27 | const char * const *ptr; | ||
28 | char type[100]; | ||
29 | FILE *fp; | ||
30 | |||
31 | if (debugfs_found) | ||
32 | return (const char *)debugfs_mountpoint; | ||
33 | |||
34 | ptr = debugfs_known_mountpoints; | ||
35 | while (*ptr) { | ||
36 | if (debugfs_valid_mountpoint(*ptr) == 0) { | ||
37 | debugfs_found = true; | ||
38 | strcpy(debugfs_mountpoint, *ptr); | ||
39 | return debugfs_mountpoint; | ||
40 | } | ||
41 | ptr++; | ||
42 | } | ||
43 | |||
44 | /* give up and parse /proc/mounts */ | ||
45 | fp = fopen("/proc/mounts", "r"); | ||
46 | if (fp == NULL) | ||
47 | return NULL; | ||
48 | |||
49 | while (fscanf(fp, "%*s %" STR(PATH_MAX) "s %99s %*s %*d %*d\n", | ||
50 | debugfs_mountpoint, type) == 2) { | ||
51 | if (strcmp(type, "debugfs") == 0) | ||
52 | break; | ||
53 | } | ||
54 | fclose(fp); | ||
55 | |||
56 | if (strcmp(type, "debugfs") != 0) | ||
57 | return NULL; | ||
58 | |||
59 | debugfs_found = true; | ||
60 | |||
61 | return debugfs_mountpoint; | ||
62 | } | ||
63 | |||
64 | /* verify that a mountpoint is actually a debugfs instance */ | ||
65 | |||
66 | int debugfs_valid_mountpoint(const char *debugfs) | ||
67 | { | ||
68 | struct statfs st_fs; | ||
69 | |||
70 | if (statfs(debugfs, &st_fs) < 0) | ||
71 | return -ENOENT; | ||
72 | else if (st_fs.f_type != (long) DEBUGFS_MAGIC) | ||
73 | return -ENOENT; | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static void debugfs_set_tracing_events_path(const char *mountpoint) | ||
79 | { | ||
80 | snprintf(tracing_events_path, sizeof(tracing_events_path), "%s/%s", | ||
81 | mountpoint, "tracing/events"); | ||
82 | } | ||
83 | |||
84 | /* mount the debugfs somewhere if it's not mounted */ | ||
85 | |||
86 | char *debugfs_mount(const char *mountpoint) | ||
87 | { | ||
88 | /* see if it's already mounted */ | ||
89 | if (debugfs_find_mountpoint()) | ||
90 | goto out; | ||
91 | |||
92 | /* if not mounted and no argument */ | ||
93 | if (mountpoint == NULL) { | ||
94 | /* see if environment variable set */ | ||
95 | mountpoint = getenv(PERF_DEBUGFS_ENVIRONMENT); | ||
96 | /* if no environment variable, use default */ | ||
97 | if (mountpoint == NULL) | ||
98 | mountpoint = "/sys/kernel/debug"; | ||
99 | } | ||
100 | |||
101 | if (mount(NULL, mountpoint, "debugfs", 0, NULL) < 0) | ||
102 | return NULL; | ||
103 | |||
104 | /* save the mountpoint */ | ||
105 | debugfs_found = true; | ||
106 | strncpy(debugfs_mountpoint, mountpoint, sizeof(debugfs_mountpoint)); | ||
107 | out: | ||
108 | debugfs_set_tracing_events_path(debugfs_mountpoint); | ||
109 | return debugfs_mountpoint; | ||
110 | } | ||
111 | |||
112 | void debugfs_set_path(const char *mountpoint) | ||
113 | { | ||
114 | snprintf(debugfs_mountpoint, sizeof(debugfs_mountpoint), "%s", mountpoint); | ||
115 | debugfs_set_tracing_events_path(mountpoint); | ||
116 | } | ||
diff --git a/tools/lib/lk/debugfs.h b/tools/lib/lk/debugfs.h new file mode 100644 index 000000000000..bc5ad2df7c0a --- /dev/null +++ b/tools/lib/lk/debugfs.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #ifndef __LK_DEBUGFS_H__ | ||
2 | #define __LK_DEBUGFS_H__ | ||
3 | |||
4 | #define _STR(x) #x | ||
5 | #define STR(x) _STR(x) | ||
6 | |||
7 | /* | ||
8 | * On most systems <limits.h> would have given us this, but not on some systems | ||
9 | * (e.g. GNU/Hurd). | ||
10 | */ | ||
11 | #ifndef PATH_MAX | ||
12 | #define PATH_MAX 4096 | ||
13 | #endif | ||
14 | |||
15 | #ifndef DEBUGFS_MAGIC | ||
16 | #define DEBUGFS_MAGIC 0x64626720 | ||
17 | #endif | ||
18 | |||
19 | #ifndef PERF_DEBUGFS_ENVIRONMENT | ||
20 | #define PERF_DEBUGFS_ENVIRONMENT "PERF_DEBUGFS_DIR" | ||
21 | #endif | ||
22 | |||
23 | const char *debugfs_find_mountpoint(void); | ||
24 | int debugfs_valid_mountpoint(const char *debugfs); | ||
25 | char *debugfs_mount(const char *mountpoint); | ||
26 | void debugfs_set_path(const char *mountpoint); | ||
27 | |||
28 | extern char debugfs_mountpoint[]; | ||
29 | extern char tracing_events_path[]; | ||
30 | |||
31 | #endif /* __LK_DEBUGFS_H__ */ | ||