1*436bf2bcSAndroid Build Coastguard Worker // SPDX-License-Identifier: LGPL-2.1
2*436bf2bcSAndroid Build Coastguard Worker /*
3*436bf2bcSAndroid Build Coastguard Worker * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <[email protected]>
4*436bf2bcSAndroid Build Coastguard Worker *
5*436bf2bcSAndroid Build Coastguard Worker */
6*436bf2bcSAndroid Build Coastguard Worker
7*436bf2bcSAndroid Build Coastguard Worker #include <ctype.h>
8*436bf2bcSAndroid Build Coastguard Worker #include <stdio.h>
9*436bf2bcSAndroid Build Coastguard Worker #include <string.h>
10*436bf2bcSAndroid Build Coastguard Worker #include <dlfcn.h>
11*436bf2bcSAndroid Build Coastguard Worker #include <stdlib.h>
12*436bf2bcSAndroid Build Coastguard Worker #include <sys/types.h>
13*436bf2bcSAndroid Build Coastguard Worker #include <sys/stat.h>
14*436bf2bcSAndroid Build Coastguard Worker #include <unistd.h>
15*436bf2bcSAndroid Build Coastguard Worker #include <dirent.h>
16*436bf2bcSAndroid Build Coastguard Worker #include <errno.h>
17*436bf2bcSAndroid Build Coastguard Worker #include "event-parse.h"
18*436bf2bcSAndroid Build Coastguard Worker #include "event-parse-local.h"
19*436bf2bcSAndroid Build Coastguard Worker #include "event-utils.h"
20*436bf2bcSAndroid Build Coastguard Worker #include "trace-seq.h"
21*436bf2bcSAndroid Build Coastguard Worker
22*436bf2bcSAndroid Build Coastguard Worker #define LOCAL_PLUGIN_DIR ".local/lib/traceevent/plugins/"
23*436bf2bcSAndroid Build Coastguard Worker
24*436bf2bcSAndroid Build Coastguard Worker static struct registered_plugin_options {
25*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options *next;
26*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *options;
27*436bf2bcSAndroid Build Coastguard Worker } *registered_options;
28*436bf2bcSAndroid Build Coastguard Worker
29*436bf2bcSAndroid Build Coastguard Worker static struct trace_plugin_options {
30*436bf2bcSAndroid Build Coastguard Worker struct trace_plugin_options *next;
31*436bf2bcSAndroid Build Coastguard Worker char *plugin;
32*436bf2bcSAndroid Build Coastguard Worker char *option;
33*436bf2bcSAndroid Build Coastguard Worker char *value;
34*436bf2bcSAndroid Build Coastguard Worker } *trace_plugin_options;
35*436bf2bcSAndroid Build Coastguard Worker
36*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list {
37*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list *next;
38*436bf2bcSAndroid Build Coastguard Worker char *name;
39*436bf2bcSAndroid Build Coastguard Worker void *handle;
40*436bf2bcSAndroid Build Coastguard Worker };
41*436bf2bcSAndroid Build Coastguard Worker
42*436bf2bcSAndroid Build Coastguard Worker struct tep_plugins_dir {
43*436bf2bcSAndroid Build Coastguard Worker struct tep_plugins_dir *next;
44*436bf2bcSAndroid Build Coastguard Worker char *path;
45*436bf2bcSAndroid Build Coastguard Worker enum tep_plugin_load_priority prio;
46*436bf2bcSAndroid Build Coastguard Worker };
47*436bf2bcSAndroid Build Coastguard Worker
lower_case(char * str)48*436bf2bcSAndroid Build Coastguard Worker static void lower_case(char *str)
49*436bf2bcSAndroid Build Coastguard Worker {
50*436bf2bcSAndroid Build Coastguard Worker if (!str)
51*436bf2bcSAndroid Build Coastguard Worker return;
52*436bf2bcSAndroid Build Coastguard Worker for (; *str; str++)
53*436bf2bcSAndroid Build Coastguard Worker *str = tolower(*str);
54*436bf2bcSAndroid Build Coastguard Worker }
55*436bf2bcSAndroid Build Coastguard Worker
update_option_value(struct tep_plugin_option * op,const char * val)56*436bf2bcSAndroid Build Coastguard Worker static int update_option_value(struct tep_plugin_option *op, const char *val)
57*436bf2bcSAndroid Build Coastguard Worker {
58*436bf2bcSAndroid Build Coastguard Worker char *op_val;
59*436bf2bcSAndroid Build Coastguard Worker
60*436bf2bcSAndroid Build Coastguard Worker if (!val) {
61*436bf2bcSAndroid Build Coastguard Worker /* toggle, only if option is boolean */
62*436bf2bcSAndroid Build Coastguard Worker if (op->value)
63*436bf2bcSAndroid Build Coastguard Worker /* Warn? */
64*436bf2bcSAndroid Build Coastguard Worker return 0;
65*436bf2bcSAndroid Build Coastguard Worker op->set ^= 1;
66*436bf2bcSAndroid Build Coastguard Worker return 0;
67*436bf2bcSAndroid Build Coastguard Worker }
68*436bf2bcSAndroid Build Coastguard Worker
69*436bf2bcSAndroid Build Coastguard Worker /*
70*436bf2bcSAndroid Build Coastguard Worker * If the option has a value then it takes a string
71*436bf2bcSAndroid Build Coastguard Worker * otherwise the option is a boolean.
72*436bf2bcSAndroid Build Coastguard Worker */
73*436bf2bcSAndroid Build Coastguard Worker if (op->value) {
74*436bf2bcSAndroid Build Coastguard Worker op->value = val;
75*436bf2bcSAndroid Build Coastguard Worker return 0;
76*436bf2bcSAndroid Build Coastguard Worker }
77*436bf2bcSAndroid Build Coastguard Worker
78*436bf2bcSAndroid Build Coastguard Worker /* Option is boolean, must be either "1", "0", "true" or "false" */
79*436bf2bcSAndroid Build Coastguard Worker
80*436bf2bcSAndroid Build Coastguard Worker op_val = strdup(val);
81*436bf2bcSAndroid Build Coastguard Worker if (!op_val)
82*436bf2bcSAndroid Build Coastguard Worker return -1;
83*436bf2bcSAndroid Build Coastguard Worker lower_case(op_val);
84*436bf2bcSAndroid Build Coastguard Worker
85*436bf2bcSAndroid Build Coastguard Worker if (strcmp(val, "1") == 0 || strcmp(val, "true") == 0)
86*436bf2bcSAndroid Build Coastguard Worker op->set = 1;
87*436bf2bcSAndroid Build Coastguard Worker else if (strcmp(val, "0") == 0 || strcmp(val, "false") == 0)
88*436bf2bcSAndroid Build Coastguard Worker op->set = 0;
89*436bf2bcSAndroid Build Coastguard Worker free(op_val);
90*436bf2bcSAndroid Build Coastguard Worker
91*436bf2bcSAndroid Build Coastguard Worker return 0;
92*436bf2bcSAndroid Build Coastguard Worker }
93*436bf2bcSAndroid Build Coastguard Worker
94*436bf2bcSAndroid Build Coastguard Worker /**
95*436bf2bcSAndroid Build Coastguard Worker * tep_plugin_list_options - get list of plugin options
96*436bf2bcSAndroid Build Coastguard Worker *
97*436bf2bcSAndroid Build Coastguard Worker * Returns an array of char strings that list the currently registered
98*436bf2bcSAndroid Build Coastguard Worker * plugin options in the format of <plugin>:<option>. This list can be
99*436bf2bcSAndroid Build Coastguard Worker * used by toggling the option.
100*436bf2bcSAndroid Build Coastguard Worker *
101*436bf2bcSAndroid Build Coastguard Worker * Returns NULL if there's no options registered. On error it returns
102*436bf2bcSAndroid Build Coastguard Worker * INVALID_PLUGIN_LIST_OPTION
103*436bf2bcSAndroid Build Coastguard Worker *
104*436bf2bcSAndroid Build Coastguard Worker * Must be freed with tep_plugin_free_options_list().
105*436bf2bcSAndroid Build Coastguard Worker */
tep_plugin_list_options(void)106*436bf2bcSAndroid Build Coastguard Worker char **tep_plugin_list_options(void)
107*436bf2bcSAndroid Build Coastguard Worker {
108*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options *reg;
109*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *op;
110*436bf2bcSAndroid Build Coastguard Worker char **list = NULL;
111*436bf2bcSAndroid Build Coastguard Worker char *name;
112*436bf2bcSAndroid Build Coastguard Worker int count = 0;
113*436bf2bcSAndroid Build Coastguard Worker
114*436bf2bcSAndroid Build Coastguard Worker for (reg = registered_options; reg; reg = reg->next) {
115*436bf2bcSAndroid Build Coastguard Worker for (op = reg->options; op->name; op++) {
116*436bf2bcSAndroid Build Coastguard Worker char *alias = op->plugin_alias ? op->plugin_alias : op->file;
117*436bf2bcSAndroid Build Coastguard Worker char **temp = list;
118*436bf2bcSAndroid Build Coastguard Worker int ret;
119*436bf2bcSAndroid Build Coastguard Worker
120*436bf2bcSAndroid Build Coastguard Worker ret = asprintf(&name, "%s:%s", alias, op->name);
121*436bf2bcSAndroid Build Coastguard Worker if (ret < 0)
122*436bf2bcSAndroid Build Coastguard Worker goto err;
123*436bf2bcSAndroid Build Coastguard Worker
124*436bf2bcSAndroid Build Coastguard Worker list = realloc(list, count + 2);
125*436bf2bcSAndroid Build Coastguard Worker if (!list) {
126*436bf2bcSAndroid Build Coastguard Worker list = temp;
127*436bf2bcSAndroid Build Coastguard Worker free(name);
128*436bf2bcSAndroid Build Coastguard Worker goto err;
129*436bf2bcSAndroid Build Coastguard Worker }
130*436bf2bcSAndroid Build Coastguard Worker list[count++] = name;
131*436bf2bcSAndroid Build Coastguard Worker list[count] = NULL;
132*436bf2bcSAndroid Build Coastguard Worker }
133*436bf2bcSAndroid Build Coastguard Worker }
134*436bf2bcSAndroid Build Coastguard Worker return list;
135*436bf2bcSAndroid Build Coastguard Worker
136*436bf2bcSAndroid Build Coastguard Worker err:
137*436bf2bcSAndroid Build Coastguard Worker while (--count >= 0)
138*436bf2bcSAndroid Build Coastguard Worker free(list[count]);
139*436bf2bcSAndroid Build Coastguard Worker free(list);
140*436bf2bcSAndroid Build Coastguard Worker
141*436bf2bcSAndroid Build Coastguard Worker return INVALID_PLUGIN_LIST_OPTION;
142*436bf2bcSAndroid Build Coastguard Worker }
143*436bf2bcSAndroid Build Coastguard Worker
tep_plugin_free_options_list(char ** list)144*436bf2bcSAndroid Build Coastguard Worker void tep_plugin_free_options_list(char **list)
145*436bf2bcSAndroid Build Coastguard Worker {
146*436bf2bcSAndroid Build Coastguard Worker int i;
147*436bf2bcSAndroid Build Coastguard Worker
148*436bf2bcSAndroid Build Coastguard Worker if (!list)
149*436bf2bcSAndroid Build Coastguard Worker return;
150*436bf2bcSAndroid Build Coastguard Worker
151*436bf2bcSAndroid Build Coastguard Worker if (list == INVALID_PLUGIN_LIST_OPTION)
152*436bf2bcSAndroid Build Coastguard Worker return;
153*436bf2bcSAndroid Build Coastguard Worker
154*436bf2bcSAndroid Build Coastguard Worker for (i = 0; list[i]; i++)
155*436bf2bcSAndroid Build Coastguard Worker free(list[i]);
156*436bf2bcSAndroid Build Coastguard Worker
157*436bf2bcSAndroid Build Coastguard Worker free(list);
158*436bf2bcSAndroid Build Coastguard Worker }
159*436bf2bcSAndroid Build Coastguard Worker
160*436bf2bcSAndroid Build Coastguard Worker static int
update_option(const char * file,struct tep_plugin_option * option)161*436bf2bcSAndroid Build Coastguard Worker update_option(const char *file, struct tep_plugin_option *option)
162*436bf2bcSAndroid Build Coastguard Worker {
163*436bf2bcSAndroid Build Coastguard Worker struct trace_plugin_options *op;
164*436bf2bcSAndroid Build Coastguard Worker char *plugin;
165*436bf2bcSAndroid Build Coastguard Worker int ret = 0;
166*436bf2bcSAndroid Build Coastguard Worker
167*436bf2bcSAndroid Build Coastguard Worker if (option->plugin_alias) {
168*436bf2bcSAndroid Build Coastguard Worker plugin = strdup(option->plugin_alias);
169*436bf2bcSAndroid Build Coastguard Worker if (!plugin)
170*436bf2bcSAndroid Build Coastguard Worker return -1;
171*436bf2bcSAndroid Build Coastguard Worker } else {
172*436bf2bcSAndroid Build Coastguard Worker char *p;
173*436bf2bcSAndroid Build Coastguard Worker plugin = strdup(file);
174*436bf2bcSAndroid Build Coastguard Worker if (!plugin)
175*436bf2bcSAndroid Build Coastguard Worker return -1;
176*436bf2bcSAndroid Build Coastguard Worker p = strstr(plugin, ".");
177*436bf2bcSAndroid Build Coastguard Worker if (p)
178*436bf2bcSAndroid Build Coastguard Worker *p = '\0';
179*436bf2bcSAndroid Build Coastguard Worker }
180*436bf2bcSAndroid Build Coastguard Worker
181*436bf2bcSAndroid Build Coastguard Worker /* first look for named options */
182*436bf2bcSAndroid Build Coastguard Worker for (op = trace_plugin_options; op; op = op->next) {
183*436bf2bcSAndroid Build Coastguard Worker if (!op->plugin)
184*436bf2bcSAndroid Build Coastguard Worker continue;
185*436bf2bcSAndroid Build Coastguard Worker if (strcmp(op->plugin, plugin) != 0)
186*436bf2bcSAndroid Build Coastguard Worker continue;
187*436bf2bcSAndroid Build Coastguard Worker if (strcmp(op->option, option->name) != 0)
188*436bf2bcSAndroid Build Coastguard Worker continue;
189*436bf2bcSAndroid Build Coastguard Worker
190*436bf2bcSAndroid Build Coastguard Worker ret = update_option_value(option, op->value);
191*436bf2bcSAndroid Build Coastguard Worker if (ret)
192*436bf2bcSAndroid Build Coastguard Worker goto out;
193*436bf2bcSAndroid Build Coastguard Worker break;
194*436bf2bcSAndroid Build Coastguard Worker }
195*436bf2bcSAndroid Build Coastguard Worker
196*436bf2bcSAndroid Build Coastguard Worker /* first look for unnamed options */
197*436bf2bcSAndroid Build Coastguard Worker for (op = trace_plugin_options; op; op = op->next) {
198*436bf2bcSAndroid Build Coastguard Worker if (op->plugin)
199*436bf2bcSAndroid Build Coastguard Worker continue;
200*436bf2bcSAndroid Build Coastguard Worker if (strcmp(op->option, option->name) != 0)
201*436bf2bcSAndroid Build Coastguard Worker continue;
202*436bf2bcSAndroid Build Coastguard Worker
203*436bf2bcSAndroid Build Coastguard Worker ret = update_option_value(option, op->value);
204*436bf2bcSAndroid Build Coastguard Worker break;
205*436bf2bcSAndroid Build Coastguard Worker }
206*436bf2bcSAndroid Build Coastguard Worker
207*436bf2bcSAndroid Build Coastguard Worker out:
208*436bf2bcSAndroid Build Coastguard Worker free(plugin);
209*436bf2bcSAndroid Build Coastguard Worker return ret;
210*436bf2bcSAndroid Build Coastguard Worker }
211*436bf2bcSAndroid Build Coastguard Worker
212*436bf2bcSAndroid Build Coastguard Worker /**
213*436bf2bcSAndroid Build Coastguard Worker * tep_plugin_add_options - Add a set of options by a plugin
214*436bf2bcSAndroid Build Coastguard Worker * @name: The name of the plugin adding the options
215*436bf2bcSAndroid Build Coastguard Worker * @options: The set of options being loaded
216*436bf2bcSAndroid Build Coastguard Worker *
217*436bf2bcSAndroid Build Coastguard Worker * Sets the options with the values that have been added by user.
218*436bf2bcSAndroid Build Coastguard Worker */
tep_plugin_add_options(const char * name,struct tep_plugin_option * options)219*436bf2bcSAndroid Build Coastguard Worker int tep_plugin_add_options(const char *name,
220*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *options)
221*436bf2bcSAndroid Build Coastguard Worker {
222*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options *reg;
223*436bf2bcSAndroid Build Coastguard Worker
224*436bf2bcSAndroid Build Coastguard Worker reg = malloc(sizeof(*reg));
225*436bf2bcSAndroid Build Coastguard Worker if (!reg)
226*436bf2bcSAndroid Build Coastguard Worker return -1;
227*436bf2bcSAndroid Build Coastguard Worker reg->next = registered_options;
228*436bf2bcSAndroid Build Coastguard Worker reg->options = options;
229*436bf2bcSAndroid Build Coastguard Worker registered_options = reg;
230*436bf2bcSAndroid Build Coastguard Worker
231*436bf2bcSAndroid Build Coastguard Worker while (options->name) {
232*436bf2bcSAndroid Build Coastguard Worker update_option(name, options);
233*436bf2bcSAndroid Build Coastguard Worker options++;
234*436bf2bcSAndroid Build Coastguard Worker }
235*436bf2bcSAndroid Build Coastguard Worker return 0;
236*436bf2bcSAndroid Build Coastguard Worker }
237*436bf2bcSAndroid Build Coastguard Worker
238*436bf2bcSAndroid Build Coastguard Worker /**
239*436bf2bcSAndroid Build Coastguard Worker * tep_plugin_remove_options - remove plugin options that were registered
240*436bf2bcSAndroid Build Coastguard Worker * @options: Options to removed that were registered with tep_plugin_add_options
241*436bf2bcSAndroid Build Coastguard Worker */
tep_plugin_remove_options(struct tep_plugin_option * options)242*436bf2bcSAndroid Build Coastguard Worker void tep_plugin_remove_options(struct tep_plugin_option *options)
243*436bf2bcSAndroid Build Coastguard Worker {
244*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options **last;
245*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options *reg;
246*436bf2bcSAndroid Build Coastguard Worker
247*436bf2bcSAndroid Build Coastguard Worker for (last = ®istered_options; *last; last = &(*last)->next) {
248*436bf2bcSAndroid Build Coastguard Worker if ((*last)->options == options) {
249*436bf2bcSAndroid Build Coastguard Worker reg = *last;
250*436bf2bcSAndroid Build Coastguard Worker *last = reg->next;
251*436bf2bcSAndroid Build Coastguard Worker free(reg);
252*436bf2bcSAndroid Build Coastguard Worker return;
253*436bf2bcSAndroid Build Coastguard Worker }
254*436bf2bcSAndroid Build Coastguard Worker }
255*436bf2bcSAndroid Build Coastguard Worker }
256*436bf2bcSAndroid Build Coastguard Worker
parse_option_name(char ** option,char ** plugin)257*436bf2bcSAndroid Build Coastguard Worker static int parse_option_name(char **option, char **plugin)
258*436bf2bcSAndroid Build Coastguard Worker {
259*436bf2bcSAndroid Build Coastguard Worker char *p;
260*436bf2bcSAndroid Build Coastguard Worker
261*436bf2bcSAndroid Build Coastguard Worker *plugin = NULL;
262*436bf2bcSAndroid Build Coastguard Worker
263*436bf2bcSAndroid Build Coastguard Worker if ((p = strstr(*option, ":"))) {
264*436bf2bcSAndroid Build Coastguard Worker *plugin = *option;
265*436bf2bcSAndroid Build Coastguard Worker *p = '\0';
266*436bf2bcSAndroid Build Coastguard Worker *option = strdup(p + 1);
267*436bf2bcSAndroid Build Coastguard Worker if (!*option)
268*436bf2bcSAndroid Build Coastguard Worker return -1;
269*436bf2bcSAndroid Build Coastguard Worker }
270*436bf2bcSAndroid Build Coastguard Worker return 0;
271*436bf2bcSAndroid Build Coastguard Worker }
272*436bf2bcSAndroid Build Coastguard Worker
273*436bf2bcSAndroid Build Coastguard Worker static struct tep_plugin_option *
find_registered_option(const char * plugin,const char * option)274*436bf2bcSAndroid Build Coastguard Worker find_registered_option(const char *plugin, const char *option)
275*436bf2bcSAndroid Build Coastguard Worker {
276*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options *reg;
277*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *op;
278*436bf2bcSAndroid Build Coastguard Worker const char *op_plugin;
279*436bf2bcSAndroid Build Coastguard Worker
280*436bf2bcSAndroid Build Coastguard Worker for (reg = registered_options; reg; reg = reg->next) {
281*436bf2bcSAndroid Build Coastguard Worker for (op = reg->options; op->name; op++) {
282*436bf2bcSAndroid Build Coastguard Worker if (op->plugin_alias)
283*436bf2bcSAndroid Build Coastguard Worker op_plugin = op->plugin_alias;
284*436bf2bcSAndroid Build Coastguard Worker else
285*436bf2bcSAndroid Build Coastguard Worker op_plugin = op->file;
286*436bf2bcSAndroid Build Coastguard Worker
287*436bf2bcSAndroid Build Coastguard Worker if (plugin && strcmp(plugin, op_plugin) != 0)
288*436bf2bcSAndroid Build Coastguard Worker continue;
289*436bf2bcSAndroid Build Coastguard Worker if (strcmp(option, op->name) != 0)
290*436bf2bcSAndroid Build Coastguard Worker continue;
291*436bf2bcSAndroid Build Coastguard Worker
292*436bf2bcSAndroid Build Coastguard Worker return op;
293*436bf2bcSAndroid Build Coastguard Worker }
294*436bf2bcSAndroid Build Coastguard Worker }
295*436bf2bcSAndroid Build Coastguard Worker
296*436bf2bcSAndroid Build Coastguard Worker return NULL;
297*436bf2bcSAndroid Build Coastguard Worker }
298*436bf2bcSAndroid Build Coastguard Worker
process_option(const char * plugin,const char * option,const char * val)299*436bf2bcSAndroid Build Coastguard Worker static int process_option(const char *plugin, const char *option, const char *val)
300*436bf2bcSAndroid Build Coastguard Worker {
301*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *op;
302*436bf2bcSAndroid Build Coastguard Worker
303*436bf2bcSAndroid Build Coastguard Worker op = find_registered_option(plugin, option);
304*436bf2bcSAndroid Build Coastguard Worker if (!op)
305*436bf2bcSAndroid Build Coastguard Worker return 0;
306*436bf2bcSAndroid Build Coastguard Worker
307*436bf2bcSAndroid Build Coastguard Worker return update_option_value(op, val);
308*436bf2bcSAndroid Build Coastguard Worker }
309*436bf2bcSAndroid Build Coastguard Worker
310*436bf2bcSAndroid Build Coastguard Worker /**
311*436bf2bcSAndroid Build Coastguard Worker * tep_plugin_add_option - add an option/val pair to set plugin options
312*436bf2bcSAndroid Build Coastguard Worker * @name: The name of the option (format: <plugin>:<option> or just <option>)
313*436bf2bcSAndroid Build Coastguard Worker * @val: (optional) the value for the option
314*436bf2bcSAndroid Build Coastguard Worker *
315*436bf2bcSAndroid Build Coastguard Worker * Modify a plugin option. If @val is given than the value of the option
316*436bf2bcSAndroid Build Coastguard Worker * is set (note, some options just take a boolean, so @val must be either
317*436bf2bcSAndroid Build Coastguard Worker * "1" or "0" or "true" or "false").
318*436bf2bcSAndroid Build Coastguard Worker */
tep_plugin_add_option(const char * name,const char * val)319*436bf2bcSAndroid Build Coastguard Worker int tep_plugin_add_option(const char *name, const char *val)
320*436bf2bcSAndroid Build Coastguard Worker {
321*436bf2bcSAndroid Build Coastguard Worker struct trace_plugin_options *op;
322*436bf2bcSAndroid Build Coastguard Worker char *option_str;
323*436bf2bcSAndroid Build Coastguard Worker char *plugin;
324*436bf2bcSAndroid Build Coastguard Worker
325*436bf2bcSAndroid Build Coastguard Worker option_str = strdup(name);
326*436bf2bcSAndroid Build Coastguard Worker if (!option_str)
327*436bf2bcSAndroid Build Coastguard Worker return -ENOMEM;
328*436bf2bcSAndroid Build Coastguard Worker
329*436bf2bcSAndroid Build Coastguard Worker if (parse_option_name(&option_str, &plugin) < 0)
330*436bf2bcSAndroid Build Coastguard Worker goto out_free;
331*436bf2bcSAndroid Build Coastguard Worker
332*436bf2bcSAndroid Build Coastguard Worker /* If the option exists, update the val */
333*436bf2bcSAndroid Build Coastguard Worker for (op = trace_plugin_options; op; op = op->next) {
334*436bf2bcSAndroid Build Coastguard Worker /* Both must be NULL or not NULL */
335*436bf2bcSAndroid Build Coastguard Worker if ((!plugin || !op->plugin) && plugin != op->plugin)
336*436bf2bcSAndroid Build Coastguard Worker continue;
337*436bf2bcSAndroid Build Coastguard Worker if (plugin && strcmp(plugin, op->plugin) != 0)
338*436bf2bcSAndroid Build Coastguard Worker continue;
339*436bf2bcSAndroid Build Coastguard Worker if (strcmp(op->option, option_str) != 0)
340*436bf2bcSAndroid Build Coastguard Worker continue;
341*436bf2bcSAndroid Build Coastguard Worker
342*436bf2bcSAndroid Build Coastguard Worker /* update option */
343*436bf2bcSAndroid Build Coastguard Worker free(op->value);
344*436bf2bcSAndroid Build Coastguard Worker if (val) {
345*436bf2bcSAndroid Build Coastguard Worker op->value = strdup(val);
346*436bf2bcSAndroid Build Coastguard Worker if (!op->value)
347*436bf2bcSAndroid Build Coastguard Worker goto out_free;
348*436bf2bcSAndroid Build Coastguard Worker } else
349*436bf2bcSAndroid Build Coastguard Worker op->value = NULL;
350*436bf2bcSAndroid Build Coastguard Worker
351*436bf2bcSAndroid Build Coastguard Worker /* plugin and option_str don't get freed at the end */
352*436bf2bcSAndroid Build Coastguard Worker free(plugin);
353*436bf2bcSAndroid Build Coastguard Worker free(option_str);
354*436bf2bcSAndroid Build Coastguard Worker
355*436bf2bcSAndroid Build Coastguard Worker plugin = op->plugin;
356*436bf2bcSAndroid Build Coastguard Worker option_str = op->option;
357*436bf2bcSAndroid Build Coastguard Worker break;
358*436bf2bcSAndroid Build Coastguard Worker }
359*436bf2bcSAndroid Build Coastguard Worker
360*436bf2bcSAndroid Build Coastguard Worker /* If not found, create */
361*436bf2bcSAndroid Build Coastguard Worker if (!op) {
362*436bf2bcSAndroid Build Coastguard Worker op = malloc(sizeof(*op));
363*436bf2bcSAndroid Build Coastguard Worker if (!op)
364*436bf2bcSAndroid Build Coastguard Worker goto out_free;
365*436bf2bcSAndroid Build Coastguard Worker memset(op, 0, sizeof(*op));
366*436bf2bcSAndroid Build Coastguard Worker op->plugin = plugin;
367*436bf2bcSAndroid Build Coastguard Worker op->option = option_str;
368*436bf2bcSAndroid Build Coastguard Worker if (val) {
369*436bf2bcSAndroid Build Coastguard Worker op->value = strdup(val);
370*436bf2bcSAndroid Build Coastguard Worker if (!op->value) {
371*436bf2bcSAndroid Build Coastguard Worker free(op);
372*436bf2bcSAndroid Build Coastguard Worker goto out_free;
373*436bf2bcSAndroid Build Coastguard Worker }
374*436bf2bcSAndroid Build Coastguard Worker }
375*436bf2bcSAndroid Build Coastguard Worker op->next = trace_plugin_options;
376*436bf2bcSAndroid Build Coastguard Worker trace_plugin_options = op;
377*436bf2bcSAndroid Build Coastguard Worker }
378*436bf2bcSAndroid Build Coastguard Worker
379*436bf2bcSAndroid Build Coastguard Worker return process_option(plugin, option_str, val);
380*436bf2bcSAndroid Build Coastguard Worker
381*436bf2bcSAndroid Build Coastguard Worker out_free:
382*436bf2bcSAndroid Build Coastguard Worker free(plugin);
383*436bf2bcSAndroid Build Coastguard Worker free(option_str);
384*436bf2bcSAndroid Build Coastguard Worker return -ENOMEM;
385*436bf2bcSAndroid Build Coastguard Worker }
386*436bf2bcSAndroid Build Coastguard Worker
print_op_data(struct trace_seq * s,const char * name,const char * op)387*436bf2bcSAndroid Build Coastguard Worker static void print_op_data(struct trace_seq *s, const char *name,
388*436bf2bcSAndroid Build Coastguard Worker const char *op)
389*436bf2bcSAndroid Build Coastguard Worker {
390*436bf2bcSAndroid Build Coastguard Worker if (op)
391*436bf2bcSAndroid Build Coastguard Worker trace_seq_printf(s, "%8s:\t%s\n", name, op);
392*436bf2bcSAndroid Build Coastguard Worker }
393*436bf2bcSAndroid Build Coastguard Worker
394*436bf2bcSAndroid Build Coastguard Worker /**
395*436bf2bcSAndroid Build Coastguard Worker * tep_plugin_print_options - print out the registered plugin options
396*436bf2bcSAndroid Build Coastguard Worker * @s: The trace_seq descriptor to write the plugin options into
397*436bf2bcSAndroid Build Coastguard Worker *
398*436bf2bcSAndroid Build Coastguard Worker * Writes a list of options into trace_seq @s.
399*436bf2bcSAndroid Build Coastguard Worker */
tep_plugin_print_options(struct trace_seq * s)400*436bf2bcSAndroid Build Coastguard Worker void tep_plugin_print_options(struct trace_seq *s)
401*436bf2bcSAndroid Build Coastguard Worker {
402*436bf2bcSAndroid Build Coastguard Worker struct registered_plugin_options *reg;
403*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *op;
404*436bf2bcSAndroid Build Coastguard Worker
405*436bf2bcSAndroid Build Coastguard Worker for (reg = registered_options; reg; reg = reg->next) {
406*436bf2bcSAndroid Build Coastguard Worker if (reg != registered_options)
407*436bf2bcSAndroid Build Coastguard Worker trace_seq_printf(s, "============\n");
408*436bf2bcSAndroid Build Coastguard Worker for (op = reg->options; op->name; op++) {
409*436bf2bcSAndroid Build Coastguard Worker if (op != reg->options)
410*436bf2bcSAndroid Build Coastguard Worker trace_seq_printf(s, "------------\n");
411*436bf2bcSAndroid Build Coastguard Worker print_op_data(s, "file", op->file);
412*436bf2bcSAndroid Build Coastguard Worker print_op_data(s, "plugin", op->plugin_alias);
413*436bf2bcSAndroid Build Coastguard Worker print_op_data(s, "option", op->name);
414*436bf2bcSAndroid Build Coastguard Worker print_op_data(s, "desc", op->description);
415*436bf2bcSAndroid Build Coastguard Worker print_op_data(s, "value", op->value);
416*436bf2bcSAndroid Build Coastguard Worker trace_seq_printf(s, "%8s:\t%d\n", "set", op->set);
417*436bf2bcSAndroid Build Coastguard Worker }
418*436bf2bcSAndroid Build Coastguard Worker }
419*436bf2bcSAndroid Build Coastguard Worker }
420*436bf2bcSAndroid Build Coastguard Worker
421*436bf2bcSAndroid Build Coastguard Worker /**
422*436bf2bcSAndroid Build Coastguard Worker * tep_print_plugins - print out the list of plugins loaded
423*436bf2bcSAndroid Build Coastguard Worker * @s: the trace_seq descripter to write to
424*436bf2bcSAndroid Build Coastguard Worker * @prefix: The prefix string to add before listing the option name
425*436bf2bcSAndroid Build Coastguard Worker * @suffix: The suffix string ot append after the option name
426*436bf2bcSAndroid Build Coastguard Worker * @list: The list of plugins (usually returned by tep_load_plugins()
427*436bf2bcSAndroid Build Coastguard Worker *
428*436bf2bcSAndroid Build Coastguard Worker * Writes to the trace_seq @s the list of plugins (files) that is
429*436bf2bcSAndroid Build Coastguard Worker * returned by tep_load_plugins(). Use @prefix and @suffix for formating:
430*436bf2bcSAndroid Build Coastguard Worker * @prefix = " ", @suffix = "\n".
431*436bf2bcSAndroid Build Coastguard Worker */
tep_print_plugins(struct trace_seq * s,const char * prefix,const char * suffix,const struct tep_plugin_list * list)432*436bf2bcSAndroid Build Coastguard Worker void tep_print_plugins(struct trace_seq *s,
433*436bf2bcSAndroid Build Coastguard Worker const char *prefix, const char *suffix,
434*436bf2bcSAndroid Build Coastguard Worker const struct tep_plugin_list *list)
435*436bf2bcSAndroid Build Coastguard Worker {
436*436bf2bcSAndroid Build Coastguard Worker while (list) {
437*436bf2bcSAndroid Build Coastguard Worker trace_seq_printf(s, "%s%s%s", prefix, list->name, suffix);
438*436bf2bcSAndroid Build Coastguard Worker list = list->next;
439*436bf2bcSAndroid Build Coastguard Worker }
440*436bf2bcSAndroid Build Coastguard Worker }
441*436bf2bcSAndroid Build Coastguard Worker
442*436bf2bcSAndroid Build Coastguard Worker static void
load_plugin(struct tep_handle * tep,const char * path,const char * file,void * data)443*436bf2bcSAndroid Build Coastguard Worker load_plugin(struct tep_handle *tep, const char *path,
444*436bf2bcSAndroid Build Coastguard Worker const char *file, void *data)
445*436bf2bcSAndroid Build Coastguard Worker {
446*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list **plugin_list = data;
447*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_option *options;
448*436bf2bcSAndroid Build Coastguard Worker tep_plugin_load_func func;
449*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list *list;
450*436bf2bcSAndroid Build Coastguard Worker const char *alias;
451*436bf2bcSAndroid Build Coastguard Worker char *plugin;
452*436bf2bcSAndroid Build Coastguard Worker void *handle;
453*436bf2bcSAndroid Build Coastguard Worker int ret;
454*436bf2bcSAndroid Build Coastguard Worker
455*436bf2bcSAndroid Build Coastguard Worker ret = asprintf(&plugin, "%s/%s", path, file);
456*436bf2bcSAndroid Build Coastguard Worker if (ret < 0) {
457*436bf2bcSAndroid Build Coastguard Worker tep_warning("could not allocate plugin memory\n");
458*436bf2bcSAndroid Build Coastguard Worker return;
459*436bf2bcSAndroid Build Coastguard Worker }
460*436bf2bcSAndroid Build Coastguard Worker
461*436bf2bcSAndroid Build Coastguard Worker handle = dlopen(plugin, RTLD_NOW | RTLD_GLOBAL);
462*436bf2bcSAndroid Build Coastguard Worker if (!handle) {
463*436bf2bcSAndroid Build Coastguard Worker tep_warning("could not load plugin '%s'\n%s\n",
464*436bf2bcSAndroid Build Coastguard Worker plugin, dlerror());
465*436bf2bcSAndroid Build Coastguard Worker goto out_free;
466*436bf2bcSAndroid Build Coastguard Worker }
467*436bf2bcSAndroid Build Coastguard Worker
468*436bf2bcSAndroid Build Coastguard Worker alias = dlsym(handle, TEP_PLUGIN_ALIAS_NAME);
469*436bf2bcSAndroid Build Coastguard Worker if (!alias)
470*436bf2bcSAndroid Build Coastguard Worker alias = file;
471*436bf2bcSAndroid Build Coastguard Worker
472*436bf2bcSAndroid Build Coastguard Worker options = dlsym(handle, TEP_PLUGIN_OPTIONS_NAME);
473*436bf2bcSAndroid Build Coastguard Worker if (options) {
474*436bf2bcSAndroid Build Coastguard Worker while (options->name) {
475*436bf2bcSAndroid Build Coastguard Worker ret = update_option(alias, options);
476*436bf2bcSAndroid Build Coastguard Worker if (ret < 0)
477*436bf2bcSAndroid Build Coastguard Worker goto out_close;
478*436bf2bcSAndroid Build Coastguard Worker options++;
479*436bf2bcSAndroid Build Coastguard Worker }
480*436bf2bcSAndroid Build Coastguard Worker }
481*436bf2bcSAndroid Build Coastguard Worker
482*436bf2bcSAndroid Build Coastguard Worker func = dlsym(handle, TEP_PLUGIN_LOADER_NAME);
483*436bf2bcSAndroid Build Coastguard Worker if (!func) {
484*436bf2bcSAndroid Build Coastguard Worker tep_warning("could not find func '%s' in plugin '%s'\n%s\n",
485*436bf2bcSAndroid Build Coastguard Worker TEP_PLUGIN_LOADER_NAME, plugin, dlerror());
486*436bf2bcSAndroid Build Coastguard Worker goto out_close;
487*436bf2bcSAndroid Build Coastguard Worker }
488*436bf2bcSAndroid Build Coastguard Worker
489*436bf2bcSAndroid Build Coastguard Worker list = malloc(sizeof(*list));
490*436bf2bcSAndroid Build Coastguard Worker if (!list) {
491*436bf2bcSAndroid Build Coastguard Worker tep_warning("could not allocate plugin memory\n");
492*436bf2bcSAndroid Build Coastguard Worker goto out_close;
493*436bf2bcSAndroid Build Coastguard Worker }
494*436bf2bcSAndroid Build Coastguard Worker
495*436bf2bcSAndroid Build Coastguard Worker list->next = *plugin_list;
496*436bf2bcSAndroid Build Coastguard Worker list->handle = handle;
497*436bf2bcSAndroid Build Coastguard Worker list->name = plugin;
498*436bf2bcSAndroid Build Coastguard Worker *plugin_list = list;
499*436bf2bcSAndroid Build Coastguard Worker
500*436bf2bcSAndroid Build Coastguard Worker tep_info("registering plugin: %s", plugin);
501*436bf2bcSAndroid Build Coastguard Worker func(tep);
502*436bf2bcSAndroid Build Coastguard Worker return;
503*436bf2bcSAndroid Build Coastguard Worker
504*436bf2bcSAndroid Build Coastguard Worker out_close:
505*436bf2bcSAndroid Build Coastguard Worker dlclose(handle);
506*436bf2bcSAndroid Build Coastguard Worker out_free:
507*436bf2bcSAndroid Build Coastguard Worker free(plugin);
508*436bf2bcSAndroid Build Coastguard Worker }
509*436bf2bcSAndroid Build Coastguard Worker
510*436bf2bcSAndroid Build Coastguard Worker static void
load_plugins_dir(struct tep_handle * tep,const char * suffix,const char * path,void (* load_plugin)(struct tep_handle * tep,const char * path,const char * name,void * data),void * data)511*436bf2bcSAndroid Build Coastguard Worker load_plugins_dir(struct tep_handle *tep, const char *suffix,
512*436bf2bcSAndroid Build Coastguard Worker const char *path,
513*436bf2bcSAndroid Build Coastguard Worker void (*load_plugin)(struct tep_handle *tep,
514*436bf2bcSAndroid Build Coastguard Worker const char *path,
515*436bf2bcSAndroid Build Coastguard Worker const char *name,
516*436bf2bcSAndroid Build Coastguard Worker void *data),
517*436bf2bcSAndroid Build Coastguard Worker void *data)
518*436bf2bcSAndroid Build Coastguard Worker {
519*436bf2bcSAndroid Build Coastguard Worker struct dirent *dent;
520*436bf2bcSAndroid Build Coastguard Worker struct stat st;
521*436bf2bcSAndroid Build Coastguard Worker DIR *dir;
522*436bf2bcSAndroid Build Coastguard Worker int ret;
523*436bf2bcSAndroid Build Coastguard Worker
524*436bf2bcSAndroid Build Coastguard Worker ret = stat(path, &st);
525*436bf2bcSAndroid Build Coastguard Worker if (ret < 0)
526*436bf2bcSAndroid Build Coastguard Worker return;
527*436bf2bcSAndroid Build Coastguard Worker
528*436bf2bcSAndroid Build Coastguard Worker if (!S_ISDIR(st.st_mode))
529*436bf2bcSAndroid Build Coastguard Worker return;
530*436bf2bcSAndroid Build Coastguard Worker
531*436bf2bcSAndroid Build Coastguard Worker dir = opendir(path);
532*436bf2bcSAndroid Build Coastguard Worker if (!dir)
533*436bf2bcSAndroid Build Coastguard Worker return;
534*436bf2bcSAndroid Build Coastguard Worker
535*436bf2bcSAndroid Build Coastguard Worker while ((dent = readdir(dir))) {
536*436bf2bcSAndroid Build Coastguard Worker const char *name = dent->d_name;
537*436bf2bcSAndroid Build Coastguard Worker
538*436bf2bcSAndroid Build Coastguard Worker if (strcmp(name, ".") == 0 ||
539*436bf2bcSAndroid Build Coastguard Worker strcmp(name, "..") == 0)
540*436bf2bcSAndroid Build Coastguard Worker continue;
541*436bf2bcSAndroid Build Coastguard Worker
542*436bf2bcSAndroid Build Coastguard Worker /* Only load plugins that end in suffix */
543*436bf2bcSAndroid Build Coastguard Worker if (strcmp(name + (strlen(name) - strlen(suffix)), suffix) != 0)
544*436bf2bcSAndroid Build Coastguard Worker continue;
545*436bf2bcSAndroid Build Coastguard Worker
546*436bf2bcSAndroid Build Coastguard Worker load_plugin(tep, path, name, data);
547*436bf2bcSAndroid Build Coastguard Worker }
548*436bf2bcSAndroid Build Coastguard Worker
549*436bf2bcSAndroid Build Coastguard Worker closedir(dir);
550*436bf2bcSAndroid Build Coastguard Worker }
551*436bf2bcSAndroid Build Coastguard Worker
552*436bf2bcSAndroid Build Coastguard Worker /**
553*436bf2bcSAndroid Build Coastguard Worker * tep_load_plugins_hook - call a user specified callback to load a plugin
554*436bf2bcSAndroid Build Coastguard Worker * @tep: handler to traceevent context
555*436bf2bcSAndroid Build Coastguard Worker * @suffix: filter only plugin files with given suffix
556*436bf2bcSAndroid Build Coastguard Worker * @load_plugin: user specified callback, called for each plugin file
557*436bf2bcSAndroid Build Coastguard Worker * @data: custom context, passed to @load_plugin
558*436bf2bcSAndroid Build Coastguard Worker *
559*436bf2bcSAndroid Build Coastguard Worker * Searches for traceevent plugin files and calls @load_plugin for each
560*436bf2bcSAndroid Build Coastguard Worker * The order of plugins search is:
561*436bf2bcSAndroid Build Coastguard Worker * - Directories, specified in @tep->plugins_dir and priority TEP_PLUGIN_FIRST
562*436bf2bcSAndroid Build Coastguard Worker * - Directory, specified at compile time with PLUGIN_TRACEEVENT_DIR
563*436bf2bcSAndroid Build Coastguard Worker * - Directory, specified by environment variable TRACEEVENT_PLUGIN_DIR
564*436bf2bcSAndroid Build Coastguard Worker * - In user's home: ~/.local/lib/traceevent/plugins/
565*436bf2bcSAndroid Build Coastguard Worker * - Directories, specified in @tep->plugins_dir and priority TEP_PLUGIN_LAST
566*436bf2bcSAndroid Build Coastguard Worker *
567*436bf2bcSAndroid Build Coastguard Worker */
tep_load_plugins_hook(struct tep_handle * tep,const char * suffix,void (* load_plugin)(struct tep_handle * tep,const char * path,const char * name,void * data),void * data)568*436bf2bcSAndroid Build Coastguard Worker void tep_load_plugins_hook(struct tep_handle *tep, const char *suffix,
569*436bf2bcSAndroid Build Coastguard Worker void (*load_plugin)(struct tep_handle *tep,
570*436bf2bcSAndroid Build Coastguard Worker const char *path,
571*436bf2bcSAndroid Build Coastguard Worker const char *name,
572*436bf2bcSAndroid Build Coastguard Worker void *data),
573*436bf2bcSAndroid Build Coastguard Worker void *data)
574*436bf2bcSAndroid Build Coastguard Worker {
575*436bf2bcSAndroid Build Coastguard Worker struct tep_plugins_dir *dir = NULL;
576*436bf2bcSAndroid Build Coastguard Worker char *home;
577*436bf2bcSAndroid Build Coastguard Worker char *path;
578*436bf2bcSAndroid Build Coastguard Worker char *envdir;
579*436bf2bcSAndroid Build Coastguard Worker int ret;
580*436bf2bcSAndroid Build Coastguard Worker
581*436bf2bcSAndroid Build Coastguard Worker if (tep && tep->flags & TEP_DISABLE_PLUGINS)
582*436bf2bcSAndroid Build Coastguard Worker return;
583*436bf2bcSAndroid Build Coastguard Worker
584*436bf2bcSAndroid Build Coastguard Worker if (tep)
585*436bf2bcSAndroid Build Coastguard Worker dir = tep->plugins_dir;
586*436bf2bcSAndroid Build Coastguard Worker while (dir) {
587*436bf2bcSAndroid Build Coastguard Worker if (dir->prio == TEP_PLUGIN_FIRST)
588*436bf2bcSAndroid Build Coastguard Worker load_plugins_dir(tep, suffix, dir->path,
589*436bf2bcSAndroid Build Coastguard Worker load_plugin, data);
590*436bf2bcSAndroid Build Coastguard Worker dir = dir->next;
591*436bf2bcSAndroid Build Coastguard Worker }
592*436bf2bcSAndroid Build Coastguard Worker
593*436bf2bcSAndroid Build Coastguard Worker /*
594*436bf2bcSAndroid Build Coastguard Worker * If a system plugin directory was defined,
595*436bf2bcSAndroid Build Coastguard Worker * check that first.
596*436bf2bcSAndroid Build Coastguard Worker */
597*436bf2bcSAndroid Build Coastguard Worker #ifdef PLUGIN_DIR
598*436bf2bcSAndroid Build Coastguard Worker if (!tep || !(tep->flags & TEP_DISABLE_SYS_PLUGINS))
599*436bf2bcSAndroid Build Coastguard Worker load_plugins_dir(tep, suffix, PLUGIN_DIR,
600*436bf2bcSAndroid Build Coastguard Worker load_plugin, data);
601*436bf2bcSAndroid Build Coastguard Worker #endif
602*436bf2bcSAndroid Build Coastguard Worker
603*436bf2bcSAndroid Build Coastguard Worker /*
604*436bf2bcSAndroid Build Coastguard Worker * Next let the environment-set plugin directory
605*436bf2bcSAndroid Build Coastguard Worker * override the system defaults.
606*436bf2bcSAndroid Build Coastguard Worker */
607*436bf2bcSAndroid Build Coastguard Worker envdir = getenv("TRACEEVENT_PLUGIN_DIR");
608*436bf2bcSAndroid Build Coastguard Worker if (envdir)
609*436bf2bcSAndroid Build Coastguard Worker load_plugins_dir(tep, suffix, envdir, load_plugin, data);
610*436bf2bcSAndroid Build Coastguard Worker
611*436bf2bcSAndroid Build Coastguard Worker /*
612*436bf2bcSAndroid Build Coastguard Worker * Now let the home directory override the environment
613*436bf2bcSAndroid Build Coastguard Worker * or system defaults.
614*436bf2bcSAndroid Build Coastguard Worker */
615*436bf2bcSAndroid Build Coastguard Worker home = getenv("HOME");
616*436bf2bcSAndroid Build Coastguard Worker if (!home)
617*436bf2bcSAndroid Build Coastguard Worker return;
618*436bf2bcSAndroid Build Coastguard Worker
619*436bf2bcSAndroid Build Coastguard Worker ret = asprintf(&path, "%s/%s", home, LOCAL_PLUGIN_DIR);
620*436bf2bcSAndroid Build Coastguard Worker if (ret < 0) {
621*436bf2bcSAndroid Build Coastguard Worker tep_warning("could not allocate plugin memory\n");
622*436bf2bcSAndroid Build Coastguard Worker return;
623*436bf2bcSAndroid Build Coastguard Worker }
624*436bf2bcSAndroid Build Coastguard Worker
625*436bf2bcSAndroid Build Coastguard Worker load_plugins_dir(tep, suffix, path, load_plugin, data);
626*436bf2bcSAndroid Build Coastguard Worker
627*436bf2bcSAndroid Build Coastguard Worker if (tep)
628*436bf2bcSAndroid Build Coastguard Worker dir = tep->plugins_dir;
629*436bf2bcSAndroid Build Coastguard Worker while (dir) {
630*436bf2bcSAndroid Build Coastguard Worker if (dir->prio == TEP_PLUGIN_LAST)
631*436bf2bcSAndroid Build Coastguard Worker load_plugins_dir(tep, suffix, dir->path,
632*436bf2bcSAndroid Build Coastguard Worker load_plugin, data);
633*436bf2bcSAndroid Build Coastguard Worker dir = dir->next;
634*436bf2bcSAndroid Build Coastguard Worker }
635*436bf2bcSAndroid Build Coastguard Worker
636*436bf2bcSAndroid Build Coastguard Worker free(path);
637*436bf2bcSAndroid Build Coastguard Worker }
638*436bf2bcSAndroid Build Coastguard Worker
639*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list*
tep_load_plugins(struct tep_handle * tep)640*436bf2bcSAndroid Build Coastguard Worker tep_load_plugins(struct tep_handle *tep)
641*436bf2bcSAndroid Build Coastguard Worker {
642*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list *list = NULL;
643*436bf2bcSAndroid Build Coastguard Worker
644*436bf2bcSAndroid Build Coastguard Worker tep_load_plugins_hook(tep, ".so", load_plugin, &list);
645*436bf2bcSAndroid Build Coastguard Worker return list;
646*436bf2bcSAndroid Build Coastguard Worker }
647*436bf2bcSAndroid Build Coastguard Worker
648*436bf2bcSAndroid Build Coastguard Worker /**
649*436bf2bcSAndroid Build Coastguard Worker * tep_add_plugin_path - Add a new plugin directory.
650*436bf2bcSAndroid Build Coastguard Worker * @tep: Trace event handler.
651*436bf2bcSAndroid Build Coastguard Worker * @path: Path to a directory. All plugin files in that
652*436bf2bcSAndroid Build Coastguard Worker * directory will be loaded.
653*436bf2bcSAndroid Build Coastguard Worker *@prio: Load priority of the plugins in that directory.
654*436bf2bcSAndroid Build Coastguard Worker *
655*436bf2bcSAndroid Build Coastguard Worker * Returns -1 in case of an error, 0 otherwise.
656*436bf2bcSAndroid Build Coastguard Worker */
tep_add_plugin_path(struct tep_handle * tep,char * path,enum tep_plugin_load_priority prio)657*436bf2bcSAndroid Build Coastguard Worker int tep_add_plugin_path(struct tep_handle *tep, char *path,
658*436bf2bcSAndroid Build Coastguard Worker enum tep_plugin_load_priority prio)
659*436bf2bcSAndroid Build Coastguard Worker {
660*436bf2bcSAndroid Build Coastguard Worker struct tep_plugins_dir *dir;
661*436bf2bcSAndroid Build Coastguard Worker
662*436bf2bcSAndroid Build Coastguard Worker if (!tep || !path)
663*436bf2bcSAndroid Build Coastguard Worker return -1;
664*436bf2bcSAndroid Build Coastguard Worker
665*436bf2bcSAndroid Build Coastguard Worker dir = calloc(1, sizeof(*dir));
666*436bf2bcSAndroid Build Coastguard Worker if (!dir)
667*436bf2bcSAndroid Build Coastguard Worker return -1;
668*436bf2bcSAndroid Build Coastguard Worker
669*436bf2bcSAndroid Build Coastguard Worker dir->path = strdup(path);
670*436bf2bcSAndroid Build Coastguard Worker if (!dir->path) {
671*436bf2bcSAndroid Build Coastguard Worker free(dir);
672*436bf2bcSAndroid Build Coastguard Worker return -1;
673*436bf2bcSAndroid Build Coastguard Worker }
674*436bf2bcSAndroid Build Coastguard Worker dir->prio = prio;
675*436bf2bcSAndroid Build Coastguard Worker dir->next = tep->plugins_dir;
676*436bf2bcSAndroid Build Coastguard Worker tep->plugins_dir = dir;
677*436bf2bcSAndroid Build Coastguard Worker
678*436bf2bcSAndroid Build Coastguard Worker return 0;
679*436bf2bcSAndroid Build Coastguard Worker }
680*436bf2bcSAndroid Build Coastguard Worker
free_tep_plugin_paths(struct tep_handle * tep)681*436bf2bcSAndroid Build Coastguard Worker __hidden void free_tep_plugin_paths(struct tep_handle *tep)
682*436bf2bcSAndroid Build Coastguard Worker {
683*436bf2bcSAndroid Build Coastguard Worker struct tep_plugins_dir *dir;
684*436bf2bcSAndroid Build Coastguard Worker
685*436bf2bcSAndroid Build Coastguard Worker if (!tep)
686*436bf2bcSAndroid Build Coastguard Worker return;
687*436bf2bcSAndroid Build Coastguard Worker
688*436bf2bcSAndroid Build Coastguard Worker dir = tep->plugins_dir;
689*436bf2bcSAndroid Build Coastguard Worker while (dir) {
690*436bf2bcSAndroid Build Coastguard Worker tep->plugins_dir = tep->plugins_dir->next;
691*436bf2bcSAndroid Build Coastguard Worker free(dir->path);
692*436bf2bcSAndroid Build Coastguard Worker free(dir);
693*436bf2bcSAndroid Build Coastguard Worker dir = tep->plugins_dir;
694*436bf2bcSAndroid Build Coastguard Worker }
695*436bf2bcSAndroid Build Coastguard Worker }
696*436bf2bcSAndroid Build Coastguard Worker
697*436bf2bcSAndroid Build Coastguard Worker void
tep_unload_plugins(struct tep_plugin_list * plugin_list,struct tep_handle * tep)698*436bf2bcSAndroid Build Coastguard Worker tep_unload_plugins(struct tep_plugin_list *plugin_list, struct tep_handle *tep)
699*436bf2bcSAndroid Build Coastguard Worker {
700*436bf2bcSAndroid Build Coastguard Worker tep_plugin_unload_func func;
701*436bf2bcSAndroid Build Coastguard Worker struct tep_plugin_list *list;
702*436bf2bcSAndroid Build Coastguard Worker
703*436bf2bcSAndroid Build Coastguard Worker while (plugin_list) {
704*436bf2bcSAndroid Build Coastguard Worker list = plugin_list;
705*436bf2bcSAndroid Build Coastguard Worker plugin_list = list->next;
706*436bf2bcSAndroid Build Coastguard Worker func = dlsym(list->handle, TEP_PLUGIN_UNLOADER_NAME);
707*436bf2bcSAndroid Build Coastguard Worker if (func)
708*436bf2bcSAndroid Build Coastguard Worker func(tep);
709*436bf2bcSAndroid Build Coastguard Worker dlclose(list->handle);
710*436bf2bcSAndroid Build Coastguard Worker free(list->name);
711*436bf2bcSAndroid Build Coastguard Worker free(list);
712*436bf2bcSAndroid Build Coastguard Worker }
713*436bf2bcSAndroid Build Coastguard Worker }
714