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 /trace-util.c | |
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>
Diffstat (limited to 'trace-util.c')
-rw-r--r-- | trace-util.c | 47 |
1 files changed, 37 insertions, 10 deletions
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 | } |