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