diff options
| author | Steven Rostedt <srostedt@redhat.com> | 2010-01-13 17:41:58 -0500 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2010-01-13 17:50:13 -0500 |
| commit | b986d5fa1acac1697189653e2d1e2c80e89cc4ac (patch) | |
| tree | d27bf42d262a884dd79326ed69763539025d7a2e | |
| parent | fbcffdca80d8bb63eee394251f41b1daf8609981 (diff) | |
trace-cmd: Unload plugins on tracecmd_close()
When the handle is freed, we need to unload the plugins, otherwise
we will keep loading them if an app closes and opens a new handle.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
| -rw-r--r-- | parse-events.h | 8 | ||||
| -rw-r--r-- | trace-cmd.h | 4 | ||||
| -rw-r--r-- | trace-input.c | 4 | ||||
| -rw-r--r-- | trace-util.c | 47 |
4 files changed, 49 insertions, 14 deletions
diff --git a/parse-events.h b/parse-events.h index e148e7f..1866299 100644 --- a/parse-events.h +++ b/parse-events.h | |||
| @@ -67,10 +67,14 @@ typedef int (*pevent_event_handler_func)(struct trace_seq *s, | |||
| 67 | struct event_format *event); | 67 | struct event_format *event); |
| 68 | 68 | ||
| 69 | typedef int (*pevent_plugin_load_func)(struct pevent *pevent); | 69 | typedef int (*pevent_plugin_load_func)(struct pevent *pevent); |
| 70 | typedef int (*pevent_plugin_unload_func)(void); | ||
| 70 | 71 | ||
| 71 | #define PEVENT_PLUGIN_LOADER pevent_plugin_loader | 72 | #define PEVENT_PLUGIN_LOADER pevent_plugin_loader |
| 72 | #define MAKE_STR(x) #x | 73 | #define PEVENT_PLUGIN_UNLOADER pevent_plugin_unloader |
| 73 | #define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(pevent_plugin_loader) | 74 | #define _MAKE_STR(x) #x |
| 75 | #define MAKE_STR(x) _MAKE_STR(x) | ||
| 76 | #define PEVENT_PLUGIN_LOADER_NAME MAKE_STR(PEVENT_PLUGIN_LOADER) | ||
| 77 | #define PEVENT_PLUGIN_UNLOADER_NAME MAKE_STR(PEVENT_PLUGIN_UNLOADER) | ||
| 74 | 78 | ||
| 75 | #define NSECS_PER_SEC 1000000000ULL | 79 | #define NSECS_PER_SEC 1000000000ULL |
| 76 | #define NSECS_PER_USEC 1000ULL | 80 | #define NSECS_PER_USEC 1000ULL |
diff --git a/trace-cmd.h b/trace-cmd.h index 98b4dec..eda7181 100644 --- a/trace-cmd.h +++ b/trace-cmd.h | |||
| @@ -8,7 +8,9 @@ void parse_cmdlines(struct pevent *pevent, char *file, int size); | |||
| 8 | void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); | 8 | void parse_proc_kallsyms(struct pevent *pevent, char *file, unsigned int size); |
| 9 | void parse_ftrace_printk(char *file, unsigned int size); | 9 | void parse_ftrace_printk(char *file, unsigned int size); |
| 10 | 10 | ||
| 11 | int trace_load_plugins(struct pevent *pevent); | 11 | struct plugin_list; |
| 12 | struct plugin_list *tracecmd_load_plugins(struct pevent *pevent); | ||
| 13 | void tracecmd_unload_plugins(struct plugin_list *list); | ||
| 12 | 14 | ||
| 13 | enum { | 15 | enum { |
| 14 | RINGBUF_TYPE_PADDING = 29, | 16 | RINGBUF_TYPE_PADDING = 29, |
diff --git a/trace-input.c b/trace-input.c index 0f2f7d8..af15634 100644 --- a/trace-input.c +++ b/trace-input.c | |||
| @@ -47,6 +47,7 @@ struct cpu_data { | |||
| 47 | 47 | ||
| 48 | struct tracecmd_input { | 48 | struct tracecmd_input { |
| 49 | struct pevent *pevent; | 49 | struct pevent *pevent; |
| 50 | struct plugin_list *plugin_list; | ||
| 50 | int fd; | 51 | int fd; |
| 51 | int long_size; | 52 | int long_size; |
| 52 | int page_size; | 53 | int page_size; |
| @@ -456,7 +457,7 @@ int tracecmd_read_headers(struct tracecmd_input *handle) | |||
| 456 | /* register default ftrace functions first */ | 457 | /* register default ftrace functions first */ |
| 457 | tracecmd_ftrace_overrides(handle); | 458 | tracecmd_ftrace_overrides(handle); |
| 458 | 459 | ||
| 459 | trace_load_plugins(pevent); | 460 | handle->plugin_list = tracecmd_load_plugins(pevent); |
| 460 | 461 | ||
| 461 | return 0; | 462 | return 0; |
| 462 | } | 463 | } |
| @@ -1711,6 +1712,7 @@ void tracecmd_close(struct tracecmd_input *handle) | |||
| 1711 | 1712 | ||
| 1712 | close(handle->fd); | 1713 | close(handle->fd); |
| 1713 | pevent_free(handle->pevent); | 1714 | pevent_free(handle->pevent); |
| 1715 | tracecmd_unload_plugins(handle->plugin_list); | ||
| 1714 | free(handle); | 1716 | free(handle); |
| 1715 | } | 1717 | } |
| 1716 | 1718 | ||
diff --git a/trace-util.c b/trace-util.c index 7a75056..7d168f9 100644 --- a/trace-util.c +++ b/trace-util.c | |||
| @@ -22,6 +22,11 @@ | |||
| 22 | # define MAX_PATH 1024 | 22 | # define MAX_PATH 1024 |
| 23 | #endif | 23 | #endif |
| 24 | 24 | ||
| 25 | struct plugin_list { | ||
| 26 | struct plugin_list *next; | ||
| 27 | void *handle; | ||
| 28 | }; | ||
| 29 | |||
| 25 | void __weak die(char *fmt, ...) | 30 | void __weak die(char *fmt, ...) |
| 26 | { | 31 | { |
| 27 | va_list ap; | 32 | va_list ap; |
| @@ -148,12 +153,14 @@ void parse_ftrace_printk(char *file, unsigned int size __unused) | |||
| 148 | } | 153 | } |
| 149 | } | 154 | } |
| 150 | 155 | ||
| 151 | static int load_plugin(struct pevent *pevent, | 156 | static struct plugin_list * |
| 152 | const char *path, const char *file) | 157 | load_plugin(struct pevent *pevent, struct plugin_list *plugin_list, |
| 158 | const char *path, const char *file) | ||
| 153 | { | 159 | { |
| 160 | pevent_plugin_load_func func; | ||
| 161 | struct plugin_list *list; | ||
| 154 | char *plugin; | 162 | char *plugin; |
| 155 | void *handle; | 163 | void *handle; |
| 156 | pevent_plugin_load_func func; | ||
| 157 | int ret = -1; | 164 | int ret = -1; |
| 158 | 165 | ||
| 159 | plugin = malloc_or_die(strlen(path) + strlen(file) + 2); | 166 | plugin = malloc_or_die(strlen(path) + strlen(file) + 2); |
| @@ -169,6 +176,11 @@ static int load_plugin(struct pevent *pevent, | |||
| 169 | goto out; | 176 | goto out; |
| 170 | } | 177 | } |
| 171 | 178 | ||
| 179 | list = malloc_or_die(sizeof(*list)); | ||
| 180 | list->next = plugin_list; | ||
| 181 | list->handle = handle; | ||
| 182 | plugin_list = list; | ||
| 183 | |||
| 172 | func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME); | 184 | func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME); |
| 173 | if (!func) { | 185 | if (!func) { |
| 174 | warning("cound not find func '%s' in plugin '%s'\n%s\n", | 186 | warning("cound not find func '%s' in plugin '%s'\n%s\n", |
| @@ -182,8 +194,7 @@ static int load_plugin(struct pevent *pevent, | |||
| 182 | out: | 194 | out: |
| 183 | free(plugin); | 195 | free(plugin); |
| 184 | 196 | ||
| 185 | /* dlclose ?? */ | 197 | return plugin_list; |
| 186 | return ret; | ||
| 187 | } | 198 | } |
| 188 | 199 | ||
| 189 | char *tracecmd_find_tracing_dir(void) | 200 | char *tracecmd_find_tracing_dir(void) |
| @@ -221,8 +232,9 @@ char *tracecmd_find_tracing_dir(void) | |||
| 221 | return tracing_dir; | 232 | return tracing_dir; |
| 222 | } | 233 | } |
| 223 | 234 | ||
| 224 | int trace_load_plugins(struct pevent *pevent) | 235 | struct plugin_list *tracecmd_load_plugins(struct pevent *pevent) |
| 225 | { | 236 | { |
| 237 | struct plugin_list *list = NULL; | ||
| 226 | struct dirent *dent; | 238 | struct dirent *dent; |
| 227 | struct stat st; | 239 | struct stat st; |
| 228 | DIR *dir; | 240 | DIR *dir; |
| @@ -230,11 +242,10 @@ int trace_load_plugins(struct pevent *pevent) | |||
| 230 | char *path; | 242 | char *path; |
| 231 | int ret; | 243 | int ret; |
| 232 | 244 | ||
| 233 | |||
| 234 | home = getenv("HOME"); | 245 | home = getenv("HOME"); |
| 235 | 246 | ||
| 236 | if (!home) | 247 | if (!home) |
| 237 | return -1; | 248 | return NULL; |
| 238 | 249 | ||
| 239 | path = malloc_or_die(strlen(home) + strlen(PLUGIN_DIR) + 2); | 250 | path = malloc_or_die(strlen(home) + strlen(PLUGIN_DIR) + 2); |
| 240 | 251 | ||
| @@ -260,12 +271,28 @@ int trace_load_plugins(struct pevent *pevent) | |||
| 260 | strcmp(name, "..") == 0) | 271 | strcmp(name, "..") == 0) |
| 261 | continue; | 272 | continue; |
| 262 | 273 | ||
| 263 | load_plugin(pevent, path, name); | 274 | list = load_plugin(pevent, list, path, name); |
| 264 | } | 275 | } |
| 265 | 276 | ||
| 266 | closedir(dir); | 277 | closedir(dir); |
| 267 | fail: | 278 | fail: |
| 268 | free(path); | 279 | free(path); |
| 269 | 280 | ||
| 270 | return -1; | 281 | return list; |
| 282 | } | ||
| 283 | |||
| 284 | void tracecmd_unload_plugins(struct plugin_list *plugin_list) | ||
| 285 | { | ||
| 286 | pevent_plugin_unload_func func; | ||
| 287 | struct plugin_list *list; | ||
| 288 | |||
| 289 | while (plugin_list) { | ||
| 290 | list = plugin_list; | ||
| 291 | plugin_list = list->next; | ||
| 292 | func = dlsym(list->handle, PEVENT_PLUGIN_UNLOADER_NAME); | ||
| 293 | if (func) | ||
| 294 | func(); | ||
| 295 | dlclose(list->handle); | ||
| 296 | free(list); | ||
| 297 | } | ||
| 271 | } | 298 | } |
