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