Mercurial > hg > nginx
comparison src/core/nginx.c @ 6383:85dea406e18f
Dynamic modules.
The auto/module script is extended to understand ngx_module_link=DYNAMIC.
When set, it links the module as a shared object rather than statically
into nginx binary. The module can later be loaded using the "load_module"
directive.
New auto/module parameter ngx_module_order allows to define module loading
order in complex cases. By default the order is set based on ngx_module_type.
3rd party modules can be compiled dynamically using the --add-dynamic-module
configure option, which will preset ngx_module_link to "DYNAMIC" before
calling the module config script.
Win32 support is rudimentary, and only works when using MinGW gcc (which
is able to handle exports/imports automatically).
In collaboration with Ruslan Ermilov.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 04 Feb 2016 20:25:29 +0300 |
parents | 0f203a2af17c |
children | 50fb3fd79f76 |
comparison
equal
deleted
inserted
replaced
6382:392959224560 | 6383:85dea406e18f |
---|---|
22 static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 22 static char *ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
23 static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, | 23 static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, |
24 void *conf); | 24 void *conf); |
25 static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, | 25 static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, |
26 void *conf); | 26 void *conf); |
27 static char *ngx_load_module(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
28 #if (NGX_HAVE_DLOPEN) | |
29 static void ngx_unload_module(void *data); | |
30 #endif | |
27 | 31 |
28 | 32 |
29 static ngx_conf_enum_t ngx_debug_points[] = { | 33 static ngx_conf_enum_t ngx_debug_points[] = { |
30 { ngx_string("stop"), NGX_DEBUG_POINTS_STOP }, | 34 { ngx_string("stop"), NGX_DEBUG_POINTS_STOP }, |
31 { ngx_string("abort"), NGX_DEBUG_POINTS_ABORT }, | 35 { ngx_string("abort"), NGX_DEBUG_POINTS_ABORT }, |
127 NULL }, | 131 NULL }, |
128 | 132 |
129 { ngx_string("env"), | 133 { ngx_string("env"), |
130 NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, | 134 NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, |
131 ngx_set_env, | 135 ngx_set_env, |
136 0, | |
137 0, | |
138 NULL }, | |
139 | |
140 { ngx_string("load_module"), | |
141 NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1, | |
142 ngx_load_module, | |
132 0, | 143 0, |
133 0, | 144 0, |
134 NULL }, | 145 NULL }, |
135 | 146 |
136 ngx_null_command | 147 ngx_null_command |
1401 return "invalid value"; | 1412 return "invalid value"; |
1402 } | 1413 } |
1403 | 1414 |
1404 return NGX_CONF_OK; | 1415 return NGX_CONF_OK; |
1405 } | 1416 } |
1417 | |
1418 | |
1419 static char * | |
1420 ngx_load_module(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1421 { | |
1422 #if (NGX_HAVE_DLOPEN) | |
1423 void *handle; | |
1424 char **names, **order; | |
1425 ngx_str_t *value, file; | |
1426 ngx_uint_t i; | |
1427 ngx_module_t *module, **modules; | |
1428 ngx_pool_cleanup_t *cln; | |
1429 | |
1430 if (cf->cycle->modules_used) { | |
1431 return "is specified too late"; | |
1432 } | |
1433 | |
1434 value = cf->args->elts; | |
1435 | |
1436 file = value[1]; | |
1437 | |
1438 if (ngx_conf_full_name(cf->cycle, &file, 0) != NGX_OK) { | |
1439 return NGX_CONF_ERROR; | |
1440 } | |
1441 | |
1442 cln = ngx_pool_cleanup_add(cf->cycle->pool, 0); | |
1443 if (cln == NULL) { | |
1444 return NGX_CONF_ERROR; | |
1445 } | |
1446 | |
1447 handle = ngx_dlopen(file.data); | |
1448 if (handle == NULL) { | |
1449 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1450 ngx_dlopen_n " \"%s\" failed (%s)", | |
1451 file.data, ngx_dlerror()); | |
1452 return NGX_CONF_ERROR; | |
1453 } | |
1454 | |
1455 cln->handler = ngx_unload_module; | |
1456 cln->data = handle; | |
1457 | |
1458 modules = ngx_dlsym(handle, "ngx_modules"); | |
1459 if (modules == NULL) { | |
1460 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1461 ngx_dlsym_n " \"%V\", \"%s\" failed (%s)", | |
1462 &value[1], "ngx_modules", ngx_dlerror()); | |
1463 return NGX_CONF_ERROR; | |
1464 } | |
1465 | |
1466 names = ngx_dlsym(handle, "ngx_module_names"); | |
1467 if (names == NULL) { | |
1468 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1469 ngx_dlsym_n " \"%V\", \"%s\" failed (%s)", | |
1470 &value[1], "ngx_module_names", ngx_dlerror()); | |
1471 return NGX_CONF_ERROR; | |
1472 } | |
1473 | |
1474 order = ngx_dlsym(handle, "ngx_module_order"); | |
1475 | |
1476 for (i = 0; modules[i]; i++) { | |
1477 module = modules[i]; | |
1478 module->name = names[i]; | |
1479 | |
1480 if (ngx_add_module(cf, &file, module, order) != NGX_OK) { | |
1481 return NGX_CONF_ERROR; | |
1482 } | |
1483 | |
1484 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0, "module: %s i:%i", | |
1485 module->name, module->index); | |
1486 } | |
1487 | |
1488 return NGX_CONF_OK; | |
1489 | |
1490 #else | |
1491 | |
1492 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1493 "\"load_module\" is not supported " | |
1494 "on this platform"); | |
1495 return NGX_CONF_ERROR; | |
1496 | |
1497 #endif | |
1498 } | |
1499 | |
1500 | |
1501 #if (NGX_HAVE_DLOPEN) | |
1502 | |
1503 static void | |
1504 ngx_unload_module(void *data) | |
1505 { | |
1506 void *handle = data; | |
1507 | |
1508 if (ngx_dlclose(handle) != 0) { | |
1509 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, | |
1510 ngx_dlclose_n " failed (%s)", ngx_dlerror()); | |
1511 } | |
1512 } | |
1513 | |
1514 #endif |