2 * Copyright (C) 2009, 2010 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
4 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation;
8 * version 2.1 of the License (not later!)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, see <http://www.gnu.org/licenses>
18 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24 #include <sys/types.h>
28 #include "event-parse.h"
29 #include "event-utils.h"
31 #define LOCAL_PLUGIN_DIR ".traceevent/plugins"
34 struct plugin_list
*next
;
40 load_plugin(struct pevent
*pevent
, const char *path
,
41 const char *file
, void *data
)
43 struct plugin_list
**plugin_list
= data
;
44 pevent_plugin_load_func func
;
45 struct plugin_list
*list
;
50 plugin
= malloc(strlen(path
) + strlen(file
) + 2);
52 warning("could not allocate plugin memory\n");
60 handle
= dlopen(plugin
, RTLD_NOW
| RTLD_GLOBAL
);
62 warning("could not load plugin '%s'\n%s\n",
67 alias
= dlsym(handle
, PEVENT_PLUGIN_ALIAS_NAME
);
71 func
= dlsym(handle
, PEVENT_PLUGIN_LOADER_NAME
);
73 warning("could not find func '%s' in plugin '%s'\n%s\n",
74 PEVENT_PLUGIN_LOADER_NAME
, plugin
, dlerror());
78 list
= malloc(sizeof(*list
));
80 warning("could not allocate plugin memory\n");
84 list
->next
= *plugin_list
;
85 list
->handle
= handle
;
89 pr_stat("registering plugin: %s", plugin
);
98 load_plugins_dir(struct pevent
*pevent
, const char *suffix
,
100 void (*load_plugin
)(struct pevent
*pevent
,
111 ret
= stat(path
, &st
);
115 if (!S_ISDIR(st
.st_mode
))
122 while ((dent
= readdir(dir
))) {
123 const char *name
= dent
->d_name
;
125 if (strcmp(name
, ".") == 0 ||
126 strcmp(name
, "..") == 0)
129 /* Only load plugins that end in suffix */
130 if (strcmp(name
+ (strlen(name
) - strlen(suffix
)), suffix
) != 0)
133 load_plugin(pevent
, path
, name
, data
);
140 load_plugins(struct pevent
*pevent
, const char *suffix
,
141 void (*load_plugin
)(struct pevent
*pevent
,
152 * If a system plugin directory was defined,
156 load_plugins_dir(pevent
, suffix
, PLUGIN_DIR
, load_plugin
, data
);
160 * Next let the environment-set plugin directory
161 * override the system defaults.
163 envdir
= getenv("TRACEEVENT_PLUGIN_DIR");
165 load_plugins_dir(pevent
, suffix
, envdir
, load_plugin
, data
);
168 * Now let the home directory override the environment
169 * or system defaults.
171 home
= getenv("HOME");
175 path
= malloc(strlen(home
) + strlen(LOCAL_PLUGIN_DIR
) + 2);
177 warning("could not allocate plugin memory\n");
183 strcat(path
, LOCAL_PLUGIN_DIR
);
185 load_plugins_dir(pevent
, suffix
, path
, load_plugin
, data
);
191 traceevent_load_plugins(struct pevent
*pevent
)
193 struct plugin_list
*list
= NULL
;
195 load_plugins(pevent
, ".so", load_plugin
, &list
);
200 traceevent_unload_plugins(struct plugin_list
*plugin_list
, struct pevent
*pevent
)
202 pevent_plugin_unload_func func
;
203 struct plugin_list
*list
;
205 while (plugin_list
) {
207 plugin_list
= list
->next
;
208 func
= dlsym(list
->handle
, PEVENT_PLUGIN_UNLOADER_NAME
);
211 dlclose(list
->handle
);