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 | } | ||
