diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | parse-events.h | 5 | ||||
-rw-r--r-- | test_plugin.c | 11 | ||||
-rw-r--r-- | trace-cmd.h | 2 | ||||
-rw-r--r-- | trace-read.c | 2 | ||||
-rw-r--r-- | trace-util.c | 86 |
6 files changed, 114 insertions, 2 deletions
@@ -4,12 +4,12 @@ EXT = -std=gnu99 | |||
4 | CFLAGS = -g -Wall # -O2 | 4 | CFLAGS = -g -Wall # -O2 |
5 | INCLUDES = -I. -I/usr/local/include | 5 | INCLUDES = -I. -I/usr/local/include |
6 | 6 | ||
7 | LIBS = -L. -lparsevent | 7 | LIBS = -L. -lparsevent -ldl |
8 | 8 | ||
9 | %.o: %.c | 9 | %.o: %.c |
10 | $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ | 10 | $(CC) -c $(CFLAGS) $(EXT) $(INCLUDES) $< -o $@ |
11 | 11 | ||
12 | TARGETS = libparsevent.a trace-cmd | 12 | TARGETS = libparsevent.a trace-cmd test_plugin |
13 | 13 | ||
14 | all: $(TARGETS) | 14 | all: $(TARGETS) |
15 | 15 | ||
@@ -35,6 +35,12 @@ libparsevent.so: $(LIB_OBJS) | |||
35 | libparsevent.a: $(LIB_OBJS) | 35 | libparsevent.a: $(LIB_OBJS) |
36 | $(RM) $@; $(AR) rcs $@ $^ | 36 | $(RM) $@; $(AR) rcs $@ $^ |
37 | 37 | ||
38 | test_plugin.o: test_plugin.c parse-events.h | ||
39 | $(CC) -c $(CFLAGS) -fPIC -o $@ $< | ||
40 | |||
41 | test_plugin: test_plugin.o | ||
42 | $(CC) -shared -nostartfiles -o $@ $< | ||
43 | |||
38 | .PHONY: force | 44 | .PHONY: force |
39 | force: | 45 | force: |
40 | 46 | ||
diff --git a/parse-events.h b/parse-events.h index 2f950dd..ceffef2 100644 --- a/parse-events.h +++ b/parse-events.h | |||
@@ -45,6 +45,11 @@ extern int trace_seq_do_printf(struct trace_seq *s); | |||
45 | 45 | ||
46 | /* ----------------------- pevent ----------------------- */ | 46 | /* ----------------------- pevent ----------------------- */ |
47 | 47 | ||
48 | typedef int (*pevent_plugin_load_func)(void); | ||
49 | #define PEVENT_PLUGIN_LOADER pevent_plugin_loader | ||
50 | #define MAKE_STR(x) #x | ||
51 | #define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(pevent_plugin_loader) | ||
52 | |||
48 | #define NSECS_PER_SEC 1000000000ULL | 53 | #define NSECS_PER_SEC 1000000000ULL |
49 | #define NSECS_PER_USEC 1000ULL | 54 | #define NSECS_PER_USEC 1000ULL |
50 | 55 | ||
diff --git a/test_plugin.c b/test_plugin.c new file mode 100644 index 0000000..fd62c27 --- /dev/null +++ b/test_plugin.c | |||
@@ -0,0 +1,11 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | |||
5 | #include "parse-events.h" | ||
6 | |||
7 | int PEVENT_PLUGIN_LOADER(void) | ||
8 | { | ||
9 | printf("HELLO WORLD!!!\n"); | ||
10 | return 0; | ||
11 | } | ||
diff --git a/trace-cmd.h b/trace-cmd.h index 369e796..1a33d04 100644 --- a/trace-cmd.h +++ b/trace-cmd.h | |||
@@ -20,6 +20,8 @@ void parse_cmdlines(char *file, int size); | |||
20 | void parse_proc_kallsyms(char *file, unsigned int size); | 20 | void parse_proc_kallsyms(char *file, unsigned int size); |
21 | void parse_ftrace_printk(char *file, unsigned int size); | 21 | void parse_ftrace_printk(char *file, unsigned int size); |
22 | 22 | ||
23 | int trace_load_plugins(void); | ||
24 | |||
23 | enum { | 25 | enum { |
24 | RINGBUF_TYPE_PADDING = 29, | 26 | RINGBUF_TYPE_PADDING = 29, |
25 | RINGBUF_TYPE_TIME_EXTEND = 30, | 27 | RINGBUF_TYPE_TIME_EXTEND = 30, |
diff --git a/trace-read.c b/trace-read.c index 1c62c4b..3f76833 100644 --- a/trace-read.c +++ b/trace-read.c | |||
@@ -735,6 +735,8 @@ int read_trace_files(void) | |||
735 | read_proc_kallsyms(); | 735 | read_proc_kallsyms(); |
736 | read_ftrace_printk(); | 736 | read_ftrace_printk(); |
737 | 737 | ||
738 | trace_load_plugins(); | ||
739 | |||
738 | return 0; | 740 | return 0; |
739 | } | 741 | } |
740 | 742 | ||
diff --git a/trace-util.c b/trace-util.c index 1ff5d5f..b60b680 100644 --- a/trace-util.c +++ b/trace-util.c | |||
@@ -2,10 +2,17 @@ | |||
2 | #include <stdio.h> | 2 | #include <stdio.h> |
3 | #include <stdlib.h> | 3 | #include <stdlib.h> |
4 | #include <string.h> | 4 | #include <string.h> |
5 | #include <dirent.h> | ||
5 | #include <ctype.h> | 6 | #include <ctype.h> |
6 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <dlfcn.h> | ||
9 | #include <sys/types.h> | ||
10 | #include <sys/stat.h> | ||
7 | 11 | ||
8 | #include "parse-events.h" | 12 | #include "parse-events.h" |
13 | #include "trace-cmd.h" | ||
14 | |||
15 | #define PLUGIN_DIR ".trace-cmd/plugins" | ||
9 | 16 | ||
10 | void parse_cmdlines(char *file, int size __unused) | 17 | void parse_cmdlines(char *file, int size __unused) |
11 | { | 18 | { |
@@ -73,3 +80,82 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) | |||
73 | line = strtok_r(NULL, "\n", &next); | 80 | line = strtok_r(NULL, "\n", &next); |
74 | } | 81 | } |
75 | } | 82 | } |
83 | |||
84 | static int load_plugin(const char *path, const char *file) | ||
85 | { | ||
86 | char *plugin; | ||
87 | void *handle; | ||
88 | pevent_plugin_load_func func; | ||
89 | int ret; | ||
90 | |||
91 | plugin = malloc_or_die(strlen(path) + strlen(file) + 2); | ||
92 | |||
93 | strcpy(plugin, path); | ||
94 | strcat(plugin, "/"); | ||
95 | strcat(plugin, file); | ||
96 | |||
97 | handle = dlopen(plugin, RTLD_NOW); | ||
98 | if (!handle) { | ||
99 | warning("cound not load plugin '%s'", plugin); | ||
100 | return -1; | ||
101 | } | ||
102 | |||
103 | func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME); | ||
104 | if (!func) { | ||
105 | warning("cound not find func '%s' in plugin '%s'", | ||
106 | PEVENT_PLUGIN_LOADER_NAME, plugin); | ||
107 | return -1; | ||
108 | } | ||
109 | |||
110 | ret = func(); | ||
111 | |||
112 | /* dlclose ?? */ | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | int trace_load_plugins(void) | ||
117 | { | ||
118 | struct dirent *dent; | ||
119 | struct stat st; | ||
120 | DIR *dir; | ||
121 | char *home; | ||
122 | char *path; | ||
123 | int ret; | ||
124 | |||
125 | |||
126 | home = getenv("HOME"); | ||
127 | |||
128 | if (!home) | ||
129 | return -1; | ||
130 | |||
131 | path = malloc_or_die(strlen(home) + strlen(PLUGIN_DIR) + 2); | ||
132 | |||
133 | strcpy(path, home); | ||
134 | strcat(path, "/"); | ||
135 | strcat(path, PLUGIN_DIR); | ||
136 | |||
137 | ret = stat(path, &st); | ||
138 | if (ret < 0) | ||
139 | goto fail; | ||
140 | |||
141 | if (!S_ISDIR(st.st_mode)) | ||
142 | goto fail; | ||
143 | |||
144 | dir = opendir(path); | ||
145 | if (!dir) | ||
146 | goto fail; | ||
147 | |||
148 | while ((dent = readdir(dir))) { | ||
149 | const char *name = dent->d_name; | ||
150 | |||
151 | if (strcmp(name, ".") == 0 || | ||
152 | strcmp(name, "..") == 0) | ||
153 | continue; | ||
154 | |||
155 | load_plugin(path, name); | ||
156 | } | ||
157 | |||
158 | fail: | ||
159 | free(path); | ||
160 | return -1; | ||
161 | } | ||