diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2010-06-02 04:57:53 -0400 |
---|---|---|
committer | Steven Rostedt <rostedt@goodmis.org> | 2010-06-02 13:23:44 -0400 |
commit | 3be8a8ca324cb1c83e0a6d12604d8ae9c283276f (patch) | |
tree | e4ec513162e3ac2a1060e7fd6dec59b3c35358e4 | |
parent | c123207585e1a51b728667c8b661ce39113d0e46 (diff) |
trace-cmd: unify plugin loading
Introduce a new externally visible function
trace_util_load_plugins that takes a callback
to load a given plugin, and use it in both
the core to load .so plugins, and the python
plugin to load .py plugins.
Note that this changes the location from which
python plugins are loaded.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
[ cleaned up whitespace damage ]
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r-- | plugin_python.c | 64 | ||||
-rw-r--r-- | trace-cmd.h | 7 | ||||
-rw-r--r-- | trace-util.c | 66 |
3 files changed, 52 insertions, 85 deletions
diff --git a/plugin_python.c b/plugin_python.c index 164e774..dada5dc 100644 --- a/plugin_python.c +++ b/plugin_python.c | |||
@@ -1,10 +1,5 @@ | |||
1 | #include <Python.h> | 1 | #include <Python.h> |
2 | #ifndef _GNU_SOURCE | ||
3 | #define _GNU_SOURCE | ||
4 | #endif | ||
5 | #include <stdio.h> | 2 | #include <stdio.h> |
6 | #include <dirent.h> | ||
7 | #include <fnmatch.h> | ||
8 | #include "trace-cmd.h" | 3 | #include "trace-cmd.h" |
9 | 4 | ||
10 | static const char pyload[] = | 5 | static const char pyload[] = |
@@ -17,8 +12,10 @@ static const char pyload[] = | |||
17 | "finally:\n" | 12 | "finally:\n" |
18 | " file.close()\n"; | 13 | " file.close()\n"; |
19 | 14 | ||
20 | static void load_plugin(PyObject *globals, char *path, const char *name) | 15 | static void load_plugin(struct pevent *pevent, const char *path, |
16 | const char *name, void *data) | ||
21 | { | 17 | { |
18 | PyObject *globals = data; | ||
22 | int len = strlen(path) + strlen(name) + 2; | 19 | int len = strlen(path) + strlen(name) + 2; |
23 | int nlen = strlen(name) + 1; | 20 | int nlen = strlen(name) + 1; |
24 | char *full = malloc(len); | 21 | char *full = malloc(len); |
@@ -50,51 +47,10 @@ static void load_plugin(PyObject *globals, char *path, const char *name) | |||
50 | free(load); | 47 | free(load); |
51 | } | 48 | } |
52 | 49 | ||
53 | static int load_plugins(PyObject *globals, char *path) | ||
54 | { | ||
55 | struct dirent *dent; | ||
56 | struct stat st; | ||
57 | DIR *dir; | ||
58 | int ret; | ||
59 | |||
60 | ret = stat(path, &st); | ||
61 | if (ret < 0) | ||
62 | return -1; | ||
63 | |||
64 | if (!S_ISDIR(st.st_mode)) | ||
65 | return -1; | ||
66 | |||
67 | dir = opendir(path); | ||
68 | if (!dir) | ||
69 | return -1; | ||
70 | |||
71 | while ((dent = readdir(dir))) { | ||
72 | const char *name = dent->d_name; | ||
73 | |||
74 | if (fnmatch("*.py", name, FNM_PERIOD)) | ||
75 | continue; | ||
76 | |||
77 | load_plugin(globals, path, name); | ||
78 | } | ||
79 | |||
80 | closedir(dir); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | #define LOCAL_PLUGIN_DIR ".trace-cmd/python" | ||
86 | |||
87 | int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | 50 | int PEVENT_PLUGIN_LOADER(struct pevent *pevent) |
88 | { | 51 | { |
89 | char *home; | ||
90 | char *path; | ||
91 | int ret; | ||
92 | PyObject *globals, *m, *py_pevent, *str; | 52 | PyObject *globals, *m, *py_pevent, *str; |
93 | 53 | ||
94 | home = getenv("HOME"); | ||
95 | if (!home) | ||
96 | return 0; | ||
97 | |||
98 | Py_Initialize(); | 54 | Py_Initialize(); |
99 | 55 | ||
100 | m = PyImport_AddModule("__main__"); | 56 | m = PyImport_AddModule("__main__"); |
@@ -114,19 +70,9 @@ int PEVENT_PLUGIN_LOADER(struct pevent *pevent) | |||
114 | Py_DECREF(py_pevent); | 70 | Py_DECREF(py_pevent); |
115 | Py_DECREF(str); | 71 | Py_DECREF(str); |
116 | 72 | ||
117 | path = malloc(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2); | 73 | trace_util_load_plugins(pevent, ".py", load_plugin, globals); |
118 | if (!path) | ||
119 | return -1; | ||
120 | 74 | ||
121 | strcpy(path, home); | 75 | return 0; |
122 | strcat(path, "/"); | ||
123 | strcat(path, LOCAL_PLUGIN_DIR); | ||
124 | |||
125 | ret = load_plugins(globals, path); | ||
126 | |||
127 | free(path); | ||
128 | |||
129 | return ret; | ||
130 | } | 76 | } |
131 | 77 | ||
132 | int PEVENT_PLUGIN_UNLOADER(void) | 78 | int PEVENT_PLUGIN_UNLOADER(void) |
diff --git a/trace-cmd.h b/trace-cmd.h index 643d394..83e7a34 100644 --- a/trace-cmd.h +++ b/trace-cmd.h | |||
@@ -152,5 +152,12 @@ int tracecmd_start_recording(struct tracecmd_recorder *recorder, unsigned long s | |||
152 | void tracecmd_stop_recording(struct tracecmd_recorder *recorder); | 152 | void tracecmd_stop_recording(struct tracecmd_recorder *recorder); |
153 | void tracecmd_stat_cpu(struct trace_seq *s, int cpu); | 153 | void tracecmd_stat_cpu(struct trace_seq *s, int cpu); |
154 | 154 | ||
155 | /* --- Plugin handling --- */ | ||
156 | void trace_util_load_plugins(struct pevent *pevent, const char *suffix, | ||
157 | void (*load_plugin)(struct pevent *pevent, | ||
158 | const char *path, | ||
159 | const char *name, | ||
160 | void *data), | ||
161 | void *data); | ||
155 | 162 | ||
156 | #endif /* _TRACE_CMD_H */ | 163 | #endif /* _TRACE_CMD_H */ |
diff --git a/trace-util.c b/trace-util.c index 6007fb8..fba6a8d 100644 --- a/trace-util.c +++ b/trace-util.c | |||
@@ -196,15 +196,14 @@ void parse_ftrace_printk(struct pevent *pevent, | |||
196 | } | 196 | } |
197 | } | 197 | } |
198 | 198 | ||
199 | static struct plugin_list * | 199 | static void load_plugin(struct pevent *pevent, const char *path, |
200 | load_plugin(struct pevent *pevent, struct plugin_list *plugin_list, | 200 | const char *file, void *data) |
201 | const char *path, const char *file) | ||
202 | { | 201 | { |
202 | struct plugin_list **plugin_list = data; | ||
203 | pevent_plugin_load_func func; | 203 | pevent_plugin_load_func func; |
204 | struct plugin_list *list; | 204 | struct plugin_list *list; |
205 | char *plugin; | 205 | char *plugin; |
206 | void *handle; | 206 | void *handle; |
207 | int ret = -1; | ||
208 | 207 | ||
209 | plugin = malloc_or_die(strlen(path) + strlen(file) + 2); | 208 | plugin = malloc_or_die(strlen(path) + strlen(file) + 2); |
210 | 209 | ||
@@ -227,20 +226,17 @@ load_plugin(struct pevent *pevent, struct plugin_list *plugin_list, | |||
227 | } | 226 | } |
228 | 227 | ||
229 | list = malloc_or_die(sizeof(*list)); | 228 | list = malloc_or_die(sizeof(*list)); |
230 | list->next = plugin_list; | 229 | list->next = *plugin_list; |
231 | list->handle = handle; | 230 | list->handle = handle; |
232 | list->name = plugin; | 231 | list->name = plugin; |
233 | plugin_list = list; | 232 | *plugin_list = list; |
234 | 233 | ||
235 | pr_stat("registering plugin: %s", plugin); | 234 | pr_stat("registering plugin: %s", plugin); |
236 | ret = func(pevent); | 235 | func(pevent); |
237 | 236 | return; | |
238 | return plugin_list; | ||
239 | 237 | ||
240 | out_free: | 238 | out_free: |
241 | free(plugin); | 239 | free(plugin); |
242 | |||
243 | return plugin_list; | ||
244 | } | 240 | } |
245 | 241 | ||
246 | static int mount_debugfs(void) | 242 | static int mount_debugfs(void) |
@@ -298,8 +294,14 @@ char *tracecmd_find_tracing_dir(void) | |||
298 | return tracing_dir; | 294 | return tracing_dir; |
299 | } | 295 | } |
300 | 296 | ||
301 | static int load_plugins(struct pevent *pevent, struct plugin_list **list, | 297 | static void |
302 | char *path) | 298 | trace_util_load_plugins_dir(struct pevent *pevent, const char *suffix, |
299 | const char *path, | ||
300 | void (*load_plugin)(struct pevent *pevent, | ||
301 | const char *path, | ||
302 | const char *name, | ||
303 | void *data), | ||
304 | void *data) | ||
303 | { | 305 | { |
304 | struct dirent *dent; | 306 | struct dirent *dent; |
305 | struct stat st; | 307 | struct stat st; |
@@ -308,14 +310,14 @@ static int load_plugins(struct pevent *pevent, struct plugin_list **list, | |||
308 | 310 | ||
309 | ret = stat(path, &st); | 311 | ret = stat(path, &st); |
310 | if (ret < 0) | 312 | if (ret < 0) |
311 | return -1; | 313 | return; |
312 | 314 | ||
313 | if (!S_ISDIR(st.st_mode)) | 315 | if (!S_ISDIR(st.st_mode)) |
314 | return -1; | 316 | return; |
315 | 317 | ||
316 | dir = opendir(path); | 318 | dir = opendir(path); |
317 | if (!dir) | 319 | if (!dir) |
318 | return -1; | 320 | return; |
319 | 321 | ||
320 | while ((dent = readdir(dir))) { | 322 | while ((dent = readdir(dir))) { |
321 | const char *name = dent->d_name; | 323 | const char *name = dent->d_name; |
@@ -324,38 +326,43 @@ static int load_plugins(struct pevent *pevent, struct plugin_list **list, | |||
324 | strcmp(name, "..") == 0) | 326 | strcmp(name, "..") == 0) |
325 | continue; | 327 | continue; |
326 | 328 | ||
327 | /* Only load plugins that end in '.so' */ | 329 | /* Only load plugins that end in suffix */ |
328 | if (strcmp(name + (strlen(name) - 3), ".so") != 0) | 330 | if (strcmp(name + (strlen(name) - strlen(suffix)), suffix) != 0) |
329 | continue; | 331 | continue; |
330 | 332 | ||
331 | *list = load_plugin(pevent, *list, path, name); | 333 | load_plugin(pevent, path, name, data); |
332 | } | 334 | } |
333 | 335 | ||
334 | closedir(dir); | 336 | closedir(dir); |
335 | 337 | ||
336 | return 0; | 338 | return; |
337 | } | 339 | } |
338 | 340 | ||
339 | struct plugin_list *tracecmd_load_plugins(struct pevent *pevent) | 341 | void trace_util_load_plugins(struct pevent *pevent, const char *suffix, |
342 | void (*load_plugin)(struct pevent *pevent, | ||
343 | const char *path, | ||
344 | const char *name, | ||
345 | void *data), | ||
346 | void *data) | ||
340 | { | 347 | { |
341 | struct plugin_list *list = NULL; | ||
342 | char *home; | 348 | char *home; |
343 | char *path; | 349 | char *path; |
344 | 350 | ||
345 | if (tracecmd_disable_plugins) | 351 | if (tracecmd_disable_plugins) |
346 | return NULL; | 352 | return; |
347 | 353 | ||
348 | /* If a system plugin directory was defined, check that first */ | 354 | /* If a system plugin directory was defined, check that first */ |
349 | #ifdef PLUGIN_DIR | 355 | #ifdef PLUGIN_DIR |
350 | if (!tracecmd_disable_sys_plugins) | 356 | if (!tracecmd_disable_sys_plugins) |
351 | load_plugins(pevent, &list, MAKE_STR(PLUGIN_DIR)); | 357 | trace_util_load_plugins_dir(pevent, suffix, MAKE_STR(PLUGIN_DIR), |
358 | load_plugin, data); | ||
352 | #endif | 359 | #endif |
353 | 360 | ||
354 | /* Now let the home directory override the system defaults */ | 361 | /* Now let the home directory override the system defaults */ |
355 | home = getenv("HOME"); | 362 | home = getenv("HOME"); |
356 | 363 | ||
357 | if (!home) | 364 | if (!home) |
358 | return list; | 365 | return; |
359 | 366 | ||
360 | path = malloc_or_die(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2); | 367 | path = malloc_or_die(strlen(home) + strlen(LOCAL_PLUGIN_DIR) + 2); |
361 | 368 | ||
@@ -363,9 +370,16 @@ struct plugin_list *tracecmd_load_plugins(struct pevent *pevent) | |||
363 | strcat(path, "/"); | 370 | strcat(path, "/"); |
364 | strcat(path, LOCAL_PLUGIN_DIR); | 371 | strcat(path, LOCAL_PLUGIN_DIR); |
365 | 372 | ||
366 | load_plugins(pevent, &list, path); | 373 | trace_util_load_plugins_dir(pevent, suffix, path, load_plugin, data); |
367 | 374 | ||
368 | free(path); | 375 | free(path); |
376 | } | ||
377 | |||
378 | struct plugin_list *tracecmd_load_plugins(struct pevent *pevent) | ||
379 | { | ||
380 | struct plugin_list *list = NULL; | ||
381 | |||
382 | trace_util_load_plugins(pevent, ".so", load_plugin, &list); | ||
369 | 383 | ||
370 | return list; | 384 | return list; |
371 | } | 385 | } |