plugin autoloading (finally)

This commit is contained in:
roberto@mrspurr
2011-05-07 09:21:07 +02:00
parent 26135018a3
commit 3d3d0304bc
4 changed files with 77 additions and 13 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ ini = true
yaml = true
json = auto
sqlite3 = auto
zeromq = auto
zeromq = false
snmp = true
sctp = false
spooler = true
+38 -11
View File
@@ -2,7 +2,7 @@
extern struct uwsgi_server uwsgi;
int uwsgi_load_plugin(int modifier, char *plugin, char *pargs, int absolute) {
void *uwsgi_load_plugin(int modifier, char *plugin, char *has_option, int absolute) {
void *plugin_handle;
@@ -23,7 +23,7 @@ check:
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 0;
return NULL;
}
}
if (uwsgi.p[i]->alias) {
@@ -31,7 +31,7 @@ check:
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 0;
return NULL;
}
}
}
@@ -43,7 +43,7 @@ check:
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 0;
return NULL;
}
}
if (uwsgi.gp[i]->alias) {
@@ -51,7 +51,7 @@ check:
#ifdef UWSGI_DEBUG
uwsgi_log("%s plugin already available\n", plugin);
#endif
return 0;
return NULL;
}
}
}
@@ -63,12 +63,18 @@ check:
goto check;
}
if (absolute) {
plugin_name = malloc(strlen(plugin) + 1);
memcpy(plugin_name, plugin, strlen(plugin) + 1);
if (absolute == 1) {
plugin_name = uwsgi_concat2(plugin, "");
// need to fix this... postpone until needed
plugin_entry_symbol = uwsgi_concat2n(plugin, strlen(plugin)-3 ,"", 0);
}
else if (absolute == 2) {
plugin_name = uwsgi_concat3(UWSGI_PLUGIN_DIR, "/", plugin);
plugin_entry_symbol = uwsgi_concat2n(plugin, strlen(plugin)-3 ,"", 0);
}
else {
plugin_name = uwsgi_concat4(UWSGI_PLUGIN_DIR, "/", plugin, "_plugin.so");
plugin_entry_symbol = uwsgi_concat2(plugin, "_plugin");
}
plugin_handle = dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL);
free(plugin_name);
@@ -77,19 +83,40 @@ check:
uwsgi_log( "%s\n", dlerror());
}
else {
plugin_entry_symbol = uwsgi_concat2(plugin, "_plugin");
up = dlsym(plugin_handle, plugin_entry_symbol);
if (up) {
if (has_option) {
struct option *lopt = up->options, *aopt;
int found = 0;
while ((aopt = lopt)) {
if (!aopt->name)
break;
if (!strcmp(has_option, aopt->name)) {
found = 1;
break;
}
lopt++;
}
if (!found) {
if (dlclose(plugin_handle)) {
uwsgi_error("dlclose()");
}
free(plugin_entry_symbol);
return NULL;
}
}
if (modifier != -1) {
fill_plugin_table(modifier, up);
}
else {
fill_plugin_table(up->modifier1, up);
}
return 1;
free(plugin_entry_symbol);
return plugin_handle;
}
uwsgi_log( "%s\n", dlerror());
}
return 0;
return NULL;
}
+34
View File
@@ -198,6 +198,7 @@ UWSGI_DECLARE_EMBEDDED_PLUGINS static struct option long_base_options[] = {
{"worker-exec", required_argument, 0, LONG_ARGS_WORKER_EXEC},
{"attach-daemon", required_argument, 0, LONG_ARGS_ATTACH_DAEMON},
{"plugins", required_argument, 0, LONG_ARGS_PLUGINS},
{"autoload", no_argument, &uwsgi.autoload, 1},
{"allowed-modifiers", required_argument, 0, LONG_ARGS_ALLOWED_MODIFIERS},
{"remap-modifier", required_argument, 0, LONG_ARGS_REMAP_MODIFIER},
{"dump-options", no_argument, &uwsgi.dump_options, 1},
@@ -213,17 +214,24 @@ void uwsgi_configure(void) {
struct option *aopt;
char *val;
int i;
int is_retry;
int found;
for (i = 0; i < uwsgi.exported_opts_cnt; i++) {
if (uwsgi.exported_opts[i]->configured)
continue;
is_retry = 0;
retry:
found = 0;
lopt = uwsgi.long_options;;
while ((aopt = lopt)) {
if (!aopt->name)
break;
if (!strcmp(aopt->name, uwsgi.exported_opts[i]->key)) {
found = 1;
val = uwsgi.exported_opts[i]->value;
if (aopt->flag)
@@ -245,6 +253,32 @@ void uwsgi_configure(void) {
}
lopt++;
}
if (!found && uwsgi.autoload && !is_retry) {
DIR *pdir;
struct dirent *dp;
pdir = opendir(UWSGI_PLUGIN_DIR);
if (!pdir) {
uwsgi_fatal_error("opendir()");
}
while ((dp = readdir(pdir)) != NULL) {
if (!strncmp("_plugin.so", dp->d_name+(strlen(dp->d_name)-10), 19)) {
if (uwsgi_load_plugin(-1, dp->d_name, uwsgi.exported_opts[i]->key, 2)) {
uwsgi_log("option \"%s\" found in plugin %s\n", uwsgi.exported_opts[i]->key, dp->d_name);
found = 1;
break;
}
}
}
if (found) {
build_options();
closedir(pdir);
// avoid deadly loops...
is_retry = 1;
goto retry;
}
closedir(pdir);
}
}
}
+4 -1
View File
@@ -7,6 +7,7 @@
#define UMAX16 65536
#define uwsgi_error(x) uwsgi_log("%s: %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_fatal_error(x) uwsgi_error(x); exit(1);
#define uwsgi_error_open(x) uwsgi_log("open(\"%s\"): %s [%s line %d]\n", x, strerror(errno), __FILE__, __LINE__);
#define uwsgi_debug(x, ...) uwsgi_log("[uWSGI DEBUG] " x, __VA_ARGS__);
#define uwsgi_rawlog(x) if (write(2, x, strlen(x)) != strlen(x)) uwsgi_error("write()")
@@ -842,6 +843,8 @@ struct uwsgi_server {
int apps_cnt;
int default_app;
int autoload;
unsigned int reloads;
int master_as_root;
@@ -1509,7 +1512,7 @@ void uwsgi_log(const char *,...);
void uwsgi_log_verbose(const char *,...);
int uwsgi_load_plugin(int, char *, char *, int);
void *uwsgi_load_plugin(int, char *, char *, int);
int unconfigured_hook(struct wsgi_request *);