aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-03-18 15:04:31 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-03-18 15:04:31 -0400
commit3e3c3b167e44d701b338dd83c789752948d9fb87 (patch)
tree35c667d875863cb9dad0a0f6a6039c4f8b6cf9b5
parentce457d3364f1db3b0dbab9b2744d10e6be1d80c2 (diff)
trace-cmd: Add utility to add options to plugins
Added trace_util_add_option() and trace_util_read_plugin_options(); Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--trace-cmd.h3
-rw-r--r--trace-util.c183
2 files changed, 186 insertions, 0 deletions
diff --git a/trace-cmd.h b/trace-cmd.h
index 9063c8c..b8137b5 100644
--- a/trace-cmd.h
+++ b/trace-cmd.h
@@ -207,12 +207,15 @@ void tracecmd_stop_recording(struct tracecmd_recorder *recorder);
207void tracecmd_stat_cpu(struct trace_seq *s, int cpu); 207void tracecmd_stat_cpu(struct trace_seq *s, int cpu);
208 208
209/* --- Plugin handling --- */ 209/* --- Plugin handling --- */
210void trace_util_add_option(const char *name, const char *val);
210void trace_util_load_plugins(struct pevent *pevent, const char *suffix, 211void trace_util_load_plugins(struct pevent *pevent, const char *suffix,
211 void (*load_plugin)(struct pevent *pevent, 212 void (*load_plugin)(struct pevent *pevent,
212 const char *path, 213 const char *path,
213 const char *name, 214 const char *name,
214 void *data), 215 void *data),
215 void *data); 216 void *data);
217struct plugin_option *trace_util_read_plugin_options(void);
218void trace_util_free_options(struct plugin_option *options);
216 219
217/* --- Hack! --- */ 220/* --- Hack! --- */
218int tracecmd_blk_hack(struct tracecmd_input *handle); 221int tracecmd_blk_hack(struct tracecmd_input *handle);
diff --git a/trace-util.c b/trace-util.c
index 970e6bc..04cb087 100644
--- a/trace-util.c
+++ b/trace-util.c
@@ -40,6 +40,14 @@
40int tracecmd_disable_sys_plugins; 40int tracecmd_disable_sys_plugins;
41int tracecmd_disable_plugins; 41int tracecmd_disable_plugins;
42 42
43
44static struct trace_plugin_options {
45 struct trace_plugin_options *next;
46 char *plugin;
47 char *option;
48 char *value;
49} *trace_plugin_options;
50
43#define _STR(x) #x 51#define _STR(x) #x
44#define STR(x) _STR(x) 52#define STR(x) _STR(x)
45 53
@@ -53,6 +61,35 @@ struct plugin_list {
53 void *handle; 61 void *handle;
54}; 62};
55 63
64void trace_util_add_option(const char *name, const char *val)
65{
66 struct trace_plugin_options *option;
67 char *p;
68
69 option = malloc_or_die(sizeof(*option));
70 memset(option, 0, sizeof(*option));
71 option->next = trace_plugin_options;
72 trace_plugin_options = option;
73
74 option->option = strdup(name);
75 if (!option->option)
76 die("malloc");
77
78 if ((p = strstr(option->option, ":"))) {
79 option->plugin = option->option;
80 *p = '\0';
81 option->option = strdup(p + 1);
82 if (!option->option)
83 die("malloc");
84 }
85
86 if (val) {
87 option->value = strdup(val);
88 if (!option->value)
89 die("malloc");
90 }
91}
92
56void parse_cmdlines(struct pevent *pevent, 93void parse_cmdlines(struct pevent *pevent,
57 char *file, int size __unused) 94 char *file, int size __unused)
58{ 95{
@@ -131,12 +168,63 @@ void parse_ftrace_printk(struct pevent *pevent,
131 } 168 }
132} 169}
133 170
171static void update_option(const char *file, struct plugin_option *option)
172{
173 struct trace_plugin_options *op;
174 char *plugin;
175
176 if (option->plugin_alias) {
177 plugin = strdup(option->plugin_alias);
178 if (!plugin)
179 die("malloc");
180 } else {
181 char *p;
182 plugin = strdup(file);
183 if (!plugin)
184 die("malloc");
185 p = strstr(plugin, ".");
186 if (p)
187 *p = '\0';
188 }
189
190 /* first look for named options */
191 for (op = trace_plugin_options; op; op = op->next) {
192 if (!op->plugin)
193 continue;
194 if (strcmp(op->plugin, plugin) != 0)
195 continue;
196 if (strcmp(op->option, option->name) != 0)
197 continue;
198
199 option->value = op->value;
200 option->set = 1;
201 goto out;
202 }
203
204 /* first look for unnamed options */
205 for (op = trace_plugin_options; op; op = op->next) {
206 if (op->plugin)
207 continue;
208 if (strcmp(op->option, option->name) != 0)
209 continue;
210
211 option->value = op->value;
212 option->set = 1;
213 break;
214 }
215
216 out:
217 free(plugin);
218}
219
134static void load_plugin(struct pevent *pevent, const char *path, 220static void load_plugin(struct pevent *pevent, const char *path,
135 const char *file, void *data) 221 const char *file, void *data)
136{ 222{
137 struct plugin_list **plugin_list = data; 223 struct plugin_list **plugin_list = data;
138 pevent_plugin_load_func func; 224 pevent_plugin_load_func func;
139 struct plugin_list *list; 225 struct plugin_list *list;
226 struct plugin_option *options;
227 const char *alias;
140 char *plugin; 228 char *plugin;
141 void *handle; 229 void *handle;
142 230
@@ -153,6 +241,18 @@ static void load_plugin(struct pevent *pevent, const char *path,
153 goto out_free; 241 goto out_free;
154 } 242 }
155 243
244 alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
245 if (!alias)
246 alias = file;
247
248 options = dlsym(handle, PEVENT_PLUGIN_OPTIONS_NAME);
249 if (options) {
250 while (options->name) {
251 update_option(alias, options);
252 options++;
253 }
254 }
255
156 func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME); 256 func = dlsym(handle, PEVENT_PLUGIN_LOADER_NAME);
157 if (!func) { 257 if (!func) {
158 warning("cound not find func '%s' in plugin '%s'\n%s\n", 258 warning("cound not find func '%s' in plugin '%s'\n%s\n",
@@ -805,6 +905,89 @@ void trace_util_load_plugins(struct pevent *pevent, const char *suffix,
805 free(path); 905 free(path);
806} 906}
807 907
908struct plugin_option_read {
909 struct plugin_option *options;
910};
911
912static void read_options(struct pevent *pevent, const char *path,
913 const char *file, void *data)
914{
915 struct plugin_option_read *option = data;
916 struct plugin_option *options;
917 struct plugin_option *op;
918 const char *alias;
919 int unload = 0;
920 char *plugin;
921 void *handle;
922
923 plugin = malloc_or_die(strlen(path) + strlen(file) + 2);
924
925 strcpy(plugin, path);
926 strcat(plugin, "/");
927 strcat(plugin, file);
928
929 handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
930 if (!handle) {
931 warning("cound not load plugin '%s'\n%s\n",
932 plugin, dlerror());
933 goto out_free;
934 }
935
936 alias = dlsym(handle, PEVENT_PLUGIN_ALIAS_NAME);
937 if (!alias)
938 alias = file;
939
940 options = dlsym(handle, PEVENT_PLUGIN_OPTIONS_NAME);
941 if (!options) {
942 unload = 1;
943 goto out_unload;
944 }
945
946 while (options->name) {
947 op = malloc_or_die(sizeof(*op));
948 *op = *options;
949 op->next = option->options;
950 option->options = op;
951 op->file = strdup(alias);
952 op->handle = handle;
953 options++;
954 }
955
956 out_unload:
957 if (unload)
958 dlclose(handle);
959 out_free:
960 free(plugin);
961}
962
963struct plugin_option *trace_util_read_plugin_options(void)
964{
965 struct plugin_option_read option = {
966 .options = NULL,
967 };
968
969 trace_util_load_plugins(NULL, ".so", read_options, &option);
970
971 return option.options;
972}
973
974void trace_util_free_options(struct plugin_option *options)
975{
976 struct plugin_option *op;
977 void *last_handle = NULL;
978
979 while (options) {
980 op = options;
981 options = op->next;
982 if (op->handle && op->handle != last_handle) {
983 last_handle = op->handle;
984 dlclose(op->handle);
985 }
986 free(op->file);
987 free(op);
988 }
989}
990
808struct plugin_list *tracecmd_load_plugins(struct pevent *pevent) 991struct plugin_list *tracecmd_load_plugins(struct pevent *pevent)
809{ 992{
810 struct plugin_list *list = NULL; 993 struct plugin_list *list = NULL;