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.
This commit is contained in:
Maxim Dounin 2016-02-04 20:25:29 +03:00
parent 0805ba14e7
commit 97f59dda09
21 changed files with 1136 additions and 34 deletions

View File

@ -5,12 +5,17 @@
LINK="\$(CC)" LINK="\$(CC)"
MAIN_LINK=
MODULE_LINK="-shared"
ngx_include_opt="-I " ngx_include_opt="-I "
ngx_compile_opt="-c" ngx_compile_opt="-c"
ngx_pic_opt="-fPIC"
ngx_objout="-o " ngx_objout="-o "
ngx_binout="-o " ngx_binout="-o "
ngx_objext="o" ngx_objext="o"
ngx_binext= ngx_binext=
ngx_modext=".so"
ngx_long_start= ngx_long_start=
ngx_long_end= ngx_long_end=
@ -45,6 +50,9 @@ if test -n "$CFLAGS"; then
sunc) sunc)
MAIN_LINK=
MODULE_LINK="-G"
case "$NGX_MACHINE" in case "$NGX_MACHINE" in
i86pc) i86pc)
@ -156,6 +164,20 @@ if [ "$NGX_PLATFORM" != win32 ]; then
fi fi
ngx_feature="-Wl,-E switch"
ngx_feature_name=
ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs=-Wl,-E
ngx_feature_test=
. auto/feature
if [ $ngx_found = yes ]; then
MAIN_LINK="-Wl,-E"
fi
ngx_feature="gcc builtin atomic operations" ngx_feature="gcc builtin atomic operations"
ngx_feature_name=NGX_HAVE_GCC_ATOMIC ngx_feature_name=NGX_HAVE_GCC_ATOMIC
ngx_feature_run=yes ngx_feature_run=yes

View File

@ -118,6 +118,12 @@ NGX_RCC="rc -fo$NGX_RES \$(CORE_INCS) $NGX_WIN32_RC"
CORE_LINK="$NGX_RES $CORE_LINK" CORE_LINK="$NGX_RES $CORE_LINK"
# dynamic modules
#MAIN_LINK="-link -def:$NGX_OBJS/nginx.def"
#MODULE_LINK="-LD $NGX_OBJS/nginx.lib"
ngx_pic_opt=
ngx_objout="-Fo" ngx_objout="-Fo"
ngx_binout="-Fe" ngx_binout="-Fe"
ngx_objext="obj" ngx_objext="obj"

View File

@ -57,6 +57,9 @@ case "$NGX_MACHINE" in
esac esac
MAIN_LINK=
MODULE_LINK="-G"
# optimizations # optimizations

View File

@ -5,6 +5,7 @@
NGX_MAKEFILE=$NGX_OBJS/Makefile NGX_MAKEFILE=$NGX_OBJS/Makefile
NGX_MODULES_C=$NGX_OBJS/ngx_modules.c NGX_MODULES_C=$NGX_OBJS/ngx_modules.c
NGX_MODULES=
NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h NGX_AUTO_HEADERS_H=$NGX_OBJS/ngx_auto_headers.h
NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h NGX_AUTO_CONFIG_H=$NGX_OBJS/ngx_auto_config.h

View File

@ -26,6 +26,18 @@ case ".$NGX_SBIN_PATH" in
esac esac
case ".$NGX_MODULES_PATH" in
./*)
;;
*)
NGX_MODULES_PATH=$NGX_PREFIX/$NGX_MODULES_PATH
;;
esac
NGX_MODULES_PATH=`dirname $NGX_MODULES_PATH/.`
case ".$NGX_CONF_PATH" in case ".$NGX_CONF_PATH" in
./*) ./*)
;; ;;
@ -158,12 +170,24 @@ END
fi fi
if test -n "$NGX_MODULES"; then
cat << END >> $NGX_MAKEFILE
test -d '\$(DESTDIR)$NGX_MODULES_PATH' \
|| mkdir -p '\$(DESTDIR)$NGX_MODULES_PATH'
cp $NGX_MODULES '\$(DESTDIR)$NGX_MODULES_PATH'
END
fi
# create Makefile # create Makefile
cat << END >> Makefile cat << END >> Makefile
build: build:
\$(MAKE) -f $NGX_MAKEFILE \$(MAKE) -f $NGX_MAKEFILE
\$(MAKE) -f $NGX_MAKEFILE modules
\$(MAKE) -f $NGX_MAKEFILE manpage \$(MAKE) -f $NGX_MAKEFILE manpage
install: install:

View File

@ -58,11 +58,11 @@ if [ $USE_ZLIB = YES ]; then
. auto/lib/zlib/conf . auto/lib/zlib/conf
fi fi
if [ $USE_LIBXSLT = YES ]; then if [ $USE_LIBXSLT != NO ]; then
. auto/lib/libxslt/conf . auto/lib/libxslt/conf
fi fi
if [ $USE_LIBGD = YES ]; then if [ $USE_LIBGD != NO ]; then
. auto/lib/libgd/conf . auto/lib/libgd/conf
fi fi
@ -70,7 +70,7 @@ if [ $USE_PERL = YES ]; then
. auto/lib/perl/conf . auto/lib/perl/conf
fi fi
if [ $HTTP_GEOIP = YES ]; then if [ $USE_GEOIP != NO ]; then
. auto/lib/geoip/conf . auto/lib/geoip/conf
fi fi

View File

@ -67,7 +67,12 @@ fi
if [ $ngx_found = yes ]; then if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path" CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
if [ $USE_GEOIP = YES ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
fi
NGX_LIB_GEOIP=$ngx_feature_libs
if [ $NGX_IPV6 = YES ]; then if [ $NGX_IPV6 = YES ]; then
ngx_feature="GeoIP IPv6 support" ngx_feature="GeoIP IPv6 support"

View File

@ -67,7 +67,12 @@ fi
if [ $ngx_found = yes ]; then if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path" CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
if [ $USE_LIBGD = YES ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
fi
NGX_LIB_LIBGD=$ngx_feature_libs
else else

View File

@ -76,7 +76,12 @@ fi
if [ $ngx_found = yes ]; then if [ $ngx_found = yes ]; then
CORE_INCS="$CORE_INCS $ngx_feature_path" CORE_INCS="$CORE_INCS $ngx_feature_path"
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
if [ $USE_LIBXSLT = YES ]; then
CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
fi
NGX_LIB_LIBXSLT=$ngx_feature_libs
else else
@ -152,5 +157,9 @@ fi
if [ $ngx_found = yes ]; then if [ $ngx_found = yes ]; then
CORE_LIBS="$CORE_LIBS -lexslt" if [ $USE_LIBXSLT = YES ]; then
CORE_LIBS="$CORE_LIBS -lexslt"
fi
NGX_LIB_LIBXSLT="$NGX_LIB_LIBXSLT -lexslt"
fi fi

203
auto/make
View File

@ -98,9 +98,11 @@ fi
# the mail dependencies and include paths # the mail dependencies and include paths
if [ $MAIL = YES ]; then if [ $MAIL != NO ]; then
ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS" if [ $MAIL = YES ]; then
ngx_all_srcs="$ngx_all_srcs $MAIL_SRCS"
fi
ngx_deps=`echo $MAIL_DEPS \ ngx_deps=`echo $MAIL_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
@ -124,9 +126,11 @@ fi
# the stream dependencies and include paths # the stream dependencies and include paths
if [ $STREAM = YES ]; then if [ $STREAM != NO ]; then
ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS" if [ $STREAM = YES ]; then
ngx_all_srcs="$ngx_all_srcs $STREAM_SRCS"
fi
ngx_deps=`echo $STREAM_DEPS \ ngx_deps=`echo $STREAM_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
@ -204,6 +208,7 @@ ngx_objs=`echo $ngx_all_objs $ngx_modules_obj \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \ | sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"` -e "s/\//$ngx_regex_dirsep/g"`
ngx_libs=
if test -n "$NGX_LD_OPT$CORE_LIBS"; then if test -n "$NGX_LD_OPT$CORE_LIBS"; then
ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \ ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"` | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
@ -212,13 +217,18 @@ fi
ngx_link=${CORE_LINK:+`echo $CORE_LINK \ ngx_link=${CORE_LINK:+`echo $CORE_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`} | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
ngx_main_link=${MAIN_LINK:+`echo $MAIN_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
cat << END >> $NGX_MAKEFILE cat << END >> $NGX_MAKEFILE
$NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}: $ngx_deps$ngx_spacer
\$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link \$(LINK) ${ngx_long_start}${ngx_binout}$NGX_OBJS${ngx_dirsep}nginx$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_main_link
$ngx_rcc $ngx_rcc
${ngx_long_end} ${ngx_long_end}
modules:
END END
@ -472,3 +482,186 @@ $ngx_pch
END END
fi fi
# dynamic modules
if test -n "$NGX_PCH"; then
ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)"
else
ngx_cc="\$(CC) $ngx_compile_opt $ngx_pic_opt \$(CFLAGS) \$(ALL_INCS)"
fi
ngx_obj_deps="\$(CORE_DEPS)"
if [ $HTTP != NO ]; then
ngx_obj_deps="$ngx_obj_deps \$(HTTP_DEPS)"
fi
if [ $MAIL != NO ]; then
ngx_obj_deps="$ngx_obj_deps \$(MAIL_DEPS)"
fi
if [ $STREAM != NO ]; then
ngx_obj_deps="$ngx_obj_deps \$(STREAM_DEPS)"
fi
for ngx_module in $DYNAMIC_MODULES
do
eval ngx_module_srcs="\$${ngx_module}_SRCS"
eval eval ngx_module_libs="\\\"\$${ngx_module}_LIBS\\\""
eval ngx_module_modules="\$${ngx_module}_MODULES"
eval ngx_module_order="\$${ngx_module}_ORDER"
ngx_modules_c=$NGX_OBJS/${ngx_module}_modules.c
cat << END > $ngx_modules_c
#include <ngx_config.h>
#include <ngx_core.h>
END
for mod in $ngx_module_modules
do
echo "extern ngx_module_t $mod;" >> $ngx_modules_c
done
echo >> $ngx_modules_c
echo 'ngx_module_t *ngx_modules[] = {' >> $ngx_modules_c
for mod in $ngx_module_modules
do
echo " &$mod," >> $ngx_modules_c
done
cat << END >> $ngx_modules_c
NULL
};
END
echo 'char *ngx_module_names[] = {' >> $ngx_modules_c
for mod in $ngx_module_modules
do
echo " \"$mod\"," >> $ngx_modules_c
done
cat << END >> $ngx_modules_c
NULL
};
END
echo 'char *ngx_module_order[] = {' >> $ngx_modules_c
for mod in $ngx_module_order
do
echo " \"$mod\"," >> $ngx_modules_c
done
cat << END >> $ngx_modules_c
NULL
};
END
ngx_modules_c=`echo $ngx_modules_c | sed -e "s/\//$ngx_regex_dirsep/g"`
ngx_modules_obj=`echo $ngx_modules_c \
| sed -e "s/\(.*\.\)c/\1$ngx_objext/"`
ngx_module_objs=
for ngx_src in $ngx_module_srcs
do
case "$ngx_src" in
src/*)
ngx_obj=$ngx_src
;;
*)
ngx_obj="addon/`basename \`dirname $ngx_src\``"
mkdir -p $NGX_OBJS/$ngx_obj
ngx_obj="$ngx_obj/`basename $ngx_src`"
;;
esac
ngx_module_objs="$ngx_module_objs $ngx_obj"
done
ngx_module_objs=`echo $ngx_module_objs \
| sed -e "s#\([^ ]*\.\)cpp#$NGX_OBJS\/\1$ngx_objext#g" \
-e "s#\([^ ]*\.\)cc#$NGX_OBJS\/\1$ngx_objext#g" \
-e "s#\([^ ]*\.\)c#$NGX_OBJS\/\1$ngx_objext#g" \
-e "s#\([^ ]*\.\)S#$NGX_OBJS\/\1$ngx_objext#g"`
ngx_deps=`echo $ngx_module_objs $ngx_modules_obj $LINK_DEPS \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_objs=`echo $ngx_module_objs $ngx_modules_obj \
| sed -e "s/ *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
-e "s/\//$ngx_regex_dirsep/g"`
ngx_obj=$NGX_OBJS${ngx_dirsep}${ngx_module}${ngx_modext}
NGX_MODULES="$NGX_MODULES $ngx_obj"
if [ "$NGX_PLATFORM" = win32 ]; then
ngx_module_libs="$CORE_LIBS $ngx_module_libs"
fi
ngx_libs=
if test -n "$NGX_LD_OPT$ngx_module_libs"; then
ngx_libs=`echo $NGX_LD_OPT $ngx_module_libs \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
fi
ngx_link=${CORE_LINK:+`echo $CORE_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
ngx_module_link=${MODULE_LINK:+`echo $MODULE_LINK \
| sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`}
cat << END >> $NGX_MAKEFILE
modules: $ngx_obj
$ngx_obj: $ngx_deps$ngx_spacer
\$(LINK) $ngx_long_start$ngx_binout$ngx_obj$ngx_long_cont$ngx_objs$ngx_libs$ngx_link$ngx_module_link
$ngx_long_end
$ngx_modules_obj: \$(CORE_DEPS)$ngx_cont$ngx_modules_c
$ngx_cc$ngx_tab$ngx_objout$ngx_modules_obj$ngx_tab$ngx_modules_c$NGX_AUX
END
for ngx_src in $ngx_module_srcs
do
case "$ngx_src" in
src/*)
ngx_obj=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
*)
ngx_obj="addon/`basename \`dirname $ngx_src\``"
ngx_obj=`echo $ngx_obj/\`basename $ngx_src\` \
| sed -e "s/\//$ngx_regex_dirsep/g"`
;;
esac
ngx_obj=`echo $ngx_obj \
| sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \
-e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"`
ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"`
cat << END >> $NGX_MAKEFILE
$ngx_obj: $ngx_obj_deps$ngx_cont$ngx_src
$ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX
END
done
done

View File

@ -9,7 +9,58 @@ case $ngx_module_type in
esac esac
if [ "$ngx_module_link" = YES ]; then if [ "$ngx_module_link" = DYNAMIC ]; then
for ngx_module in $ngx_module_name; do
# extract the first name
break
done
DYNAMIC_MODULES="$DYNAMIC_MODULES $ngx_module"
eval ${ngx_module}_SRCS=\"$ngx_module_srcs\"
eval ${ngx_module}_MODULES=\"$ngx_module_name\"
if [ -z "$ngx_module_order" -a \
\( "$ngx_module_type" = "HTTP_FILTER" \
-o "$ngx_module_type" = "HTTP_AUX_FILTER" \) ]
then
eval ${ngx_module}_ORDER=\"$ngx_module_name \
ngx_http_copy_filter_module\"
else
eval ${ngx_module}_ORDER=\"$ngx_module_order\"
fi
if test -n "$ngx_module_incs"; then
CORE_INCS="$CORE_INCS $ngx_module_incs"
fi
libs=
for lib in $ngx_module_libs
do
case $lib in
LIBXSLT | LIBGD | GEOIP)
libs="$libs \$NGX_LIB_$lib"
if eval [ "\$USE_${lib}" = NO ] ; then
eval USE_${lib}=DYNAMIC
fi
;;
PCRE | OPENSSL | MD5 | SHA1 | ZLIB | PERL)
eval USE_${lib}=YES
;;
*)
libs="$libs $lib"
;;
esac
done
eval ${ngx_module}_LIBS=\'$libs\'
elif [ "$ngx_module_link" = YES ]; then
eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \ eval ${ngx_module_type}_MODULES=\"\$${ngx_module_type}_MODULES \
$ngx_module_name\" $ngx_module_name\"

View File

@ -159,6 +159,35 @@ fi
ngx_module_type=HTTP_FILTER ngx_module_type=HTTP_FILTER
HTTP_FILTER_MODULES= HTTP_FILTER_MODULES=
ngx_module_order="ngx_http_static_module \
ngx_http_gzip_static_module \
ngx_http_dav_module \
ngx_http_autoindex_module \
ngx_http_index_module \
ngx_http_random_index_module \
ngx_http_access_module \
ngx_http_realip_module \
ngx_http_write_filter_module \
ngx_http_header_filter_module \
ngx_http_chunked_filter_module \
ngx_http_v2_filter_module \
ngx_http_range_header_filter_module \
ngx_http_gzip_filter_module \
ngx_http_postpone_filter_module \
ngx_http_ssi_filter_module \
ngx_http_charset_filter_module \
ngx_http_xslt_filter_module \
ngx_http_image_filter_module \
ngx_http_sub_filter_module \
ngx_http_addition_filter_module \
ngx_http_gunzip_filter_module \
ngx_http_userid_filter_module \
ngx_http_headers_filter_module \
ngx_http_copy_filter_module \
ngx_http_range_body_filter_module \
ngx_http_not_modified_filter_module \
ngx_http_slice_filter_module"
if :; then if :; then
ngx_module_name=ngx_http_write_filter_module ngx_module_name=ngx_http_write_filter_module
ngx_module_incs= ngx_module_incs=
@ -263,7 +292,7 @@ if [ $HTTP_CHARSET = YES ]; then
. auto/module . auto/module
fi fi
if [ $HTTP_XSLT = YES ]; then if [ $HTTP_XSLT != NO ]; then
ngx_module_name=ngx_http_xslt_filter_module ngx_module_name=ngx_http_xslt_filter_module
ngx_module_incs= ngx_module_incs=
ngx_module_deps= ngx_module_deps=
@ -274,7 +303,7 @@ if [ $HTTP_XSLT = YES ]; then
. auto/module . auto/module
fi fi
if [ $HTTP_IMAGE_FILTER = YES ]; then if [ $HTTP_IMAGE_FILTER != NO ]; then
ngx_module_name=ngx_http_image_filter_module ngx_module_name=ngx_http_image_filter_module
ngx_module_incs= ngx_module_incs=
ngx_module_deps= ngx_module_deps=
@ -579,14 +608,14 @@ if [ $HTTP_GEO = YES ]; then
. auto/module . auto/module
fi fi
if [ $HTTP_GEOIP = YES ]; then if [ $HTTP_GEOIP != NO ]; then
have=NGX_HTTP_X_FORWARDED_FOR . auto/have have=NGX_HTTP_X_FORWARDED_FOR . auto/have
ngx_module_name=ngx_http_geoip_module ngx_module_name=ngx_http_geoip_module
ngx_module_incs= ngx_module_incs=
ngx_module_deps= ngx_module_deps=
ngx_module_srcs=src/http/modules/ngx_http_geoip_module.c ngx_module_srcs=src/http/modules/ngx_http_geoip_module.c
ngx_module_libs= ngx_module_libs=GEOIP
ngx_module_link=$HTTP_GEOIP ngx_module_link=$HTTP_GEOIP
. auto/module . auto/module
@ -864,7 +893,7 @@ if [ $HTTP_STUB_STATUS = YES ]; then
fi fi
if [ $MAIL == YES ]; then if [ $MAIL != NO ]; then
MAIL_MODULES= MAIL_MODULES=
MAIL_DEPS= MAIL_DEPS=
MAIL_INCS= MAIL_INCS=
@ -873,6 +902,8 @@ if [ $MAIL == YES ]; then
ngx_module_libs= ngx_module_libs=
ngx_module_link=YES ngx_module_link=YES
ngx_module_order=
ngx_module_name="ngx_mail_module ngx_mail_core_module" ngx_module_name="ngx_mail_module ngx_mail_core_module"
ngx_module_incs="src/mail" ngx_module_incs="src/mail"
ngx_module_deps="src/mail/ngx_mail.h" ngx_module_deps="src/mail/ngx_mail.h"
@ -937,7 +968,7 @@ if [ $MAIL == YES ]; then
fi fi
if [ $STREAM = YES ]; then if [ $STREAM != NO ]; then
STREAM_MODULES= STREAM_MODULES=
STREAM_DEPS= STREAM_DEPS=
STREAM_INCS= STREAM_INCS=
@ -948,6 +979,8 @@ if [ $STREAM = YES ]; then
ngx_module_libs= ngx_module_libs=
ngx_module_link=YES ngx_module_link=YES
ngx_module_order=
ngx_module_name="ngx_stream_module \ ngx_module_name="ngx_stream_module \
ngx_stream_core_module \ ngx_stream_core_module \
ngx_stream_proxy_module \ ngx_stream_proxy_module \
@ -1041,6 +1074,7 @@ if test -n "$NGX_ADDONS"; then
ngx_module_deps= ngx_module_deps=
ngx_module_srcs= ngx_module_srcs=
ngx_module_libs= ngx_module_libs=
ngx_module_order=
ngx_module_link=ADDON ngx_module_link=ADDON
if test -f $ngx_addon_dir/config; then if test -f $ngx_addon_dir/config; then
@ -1056,6 +1090,36 @@ if test -n "$NGX_ADDONS"; then
fi fi
if test -n "$DYNAMIC_ADDONS"; then
echo configuring additional dynamic modules
for ngx_addon_dir in $DYNAMIC_ADDONS
do
echo "adding module in $ngx_addon_dir"
ngx_module_type=
ngx_module_name=
ngx_module_incs=
ngx_module_deps=
ngx_module_srcs=
ngx_module_libs=
ngx_module_order=
ngx_module_link=DYNAMIC
if test -f $ngx_addon_dir/config; then
. $ngx_addon_dir/config
echo " + $ngx_addon_name was configured"
else
echo "$0: error: no $ngx_addon_dir/config was found"
exit 1
fi
done
fi
if [ $USE_OPENSSL = YES ]; then if [ $USE_OPENSSL = YES ]; then
ngx_module_type=CORE ngx_module_type=CORE
ngx_module_name=ngx_openssl_module ngx_module_name=ngx_openssl_module
@ -1065,6 +1129,7 @@ if [ $USE_OPENSSL = YES ]; then
src/event/ngx_event_openssl_stapling.c" src/event/ngx_event_openssl_stapling.c"
ngx_module_libs= ngx_module_libs=
ngx_module_link=YES ngx_module_link=YES
ngx_module_order=
. auto/module . auto/module
fi fi
@ -1078,6 +1143,7 @@ if [ $USE_PCRE = YES ]; then
ngx_module_srcs=src/core/ngx_regex.c ngx_module_srcs=src/core/ngx_regex.c
ngx_module_libs= ngx_module_libs=
ngx_module_link=YES ngx_module_link=YES
ngx_module_order=
. auto/module . auto/module
fi fi
@ -1100,14 +1166,42 @@ if [ $HTTP = YES ]; then
fi fi
if [ $MAIL = YES ]; then if [ $MAIL != NO ]; then
modules="$modules $MAIL_MODULES"
if [ $MAIL = YES ]; then
modules="$modules $MAIL_MODULES"
elif [ $MAIL = DYNAMIC ]; then
ngx_module_name=$MAIL_MODULES
ngx_module_incs=
ngx_module_deps=$MAIL_DEPS
ngx_module_srcs=$MAIL_SRCS
ngx_module_libs=
ngx_module_link=DYNAMIC
. auto/module
fi
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)" NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(MAIL_DEPS)"
fi fi
if [ $STREAM = YES ]; then if [ $STREAM != NO ]; then
modules="$modules $STREAM_MODULES"
if [ $STREAM = YES ]; then
modules="$modules $STREAM_MODULES"
elif [ $STREAM = DYNAMIC ]; then
ngx_module_name=$STREAM_MODULES
ngx_module_incs=
ngx_module_deps=$STREAM_DEPS
ngx_module_srcs=$STREAM_SRCS
ngx_module_libs=
ngx_module_link=DYNAMIC
. auto/module
fi
NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(STREAM_DEPS)" NGX_ADDON_DEPS="$NGX_ADDON_DEPS \$(STREAM_DEPS)"
fi fi
@ -1167,3 +1261,16 @@ cat << END >> $NGX_MODULES_C
}; };
END END
echo 'char *ngx_module_names[] = {' >> $NGX_MODULES_C
for mod in $modules
do
echo " \"$mod\"," >> $NGX_MODULES_C
done
cat << END >> $NGX_MODULES_C
NULL
};
END

View File

@ -7,6 +7,7 @@ help=no
NGX_PREFIX= NGX_PREFIX=
NGX_SBIN_PATH= NGX_SBIN_PATH=
NGX_MODULES_PATH=
NGX_CONF_PREFIX= NGX_CONF_PREFIX=
NGX_CONF_PATH= NGX_CONF_PATH=
NGX_ERROR_LOG_PATH= NGX_ERROR_LOG_PATH=
@ -120,7 +121,11 @@ STREAM_UPSTREAM_HASH=YES
STREAM_UPSTREAM_LEAST_CONN=YES STREAM_UPSTREAM_LEAST_CONN=YES
STREAM_UPSTREAM_ZONE=YES STREAM_UPSTREAM_ZONE=YES
DYNAMIC_MODULES=
NGX_ADDONS= NGX_ADDONS=
NGX_ADDON_DEPS=
DYNAMIC_ADDONS=
USE_PCRE=NO USE_PCRE=NO
PCRE=NONE PCRE=NONE
@ -151,6 +156,7 @@ NGX_PERL=perl
USE_LIBXSLT=NO USE_LIBXSLT=NO
USE_LIBGD=NO USE_LIBGD=NO
USE_GEOIP=NO
NGX_GOOGLE_PERFTOOLS=NO NGX_GOOGLE_PERFTOOLS=NO
NGX_CPP_TEST=NO NGX_CPP_TEST=NO
@ -178,6 +184,7 @@ do
--prefix=) NGX_PREFIX="!" ;; --prefix=) NGX_PREFIX="!" ;;
--prefix=*) NGX_PREFIX="$value" ;; --prefix=*) NGX_PREFIX="$value" ;;
--sbin-path=*) NGX_SBIN_PATH="$value" ;; --sbin-path=*) NGX_SBIN_PATH="$value" ;;
--modules-path=*) NGX_MODULES_PATH="$value" ;;
--conf-path=*) NGX_CONF_PATH="$value" ;; --conf-path=*) NGX_CONF_PATH="$value" ;;
--error-log-path=*) NGX_ERROR_LOG_PATH="$value";; --error-log-path=*) NGX_ERROR_LOG_PATH="$value";;
--pid-path=*) NGX_PID_PATH="$value" ;; --pid-path=*) NGX_PID_PATH="$value" ;;
@ -215,8 +222,13 @@ do
--with-http_realip_module) HTTP_REALIP=YES ;; --with-http_realip_module) HTTP_REALIP=YES ;;
--with-http_addition_module) HTTP_ADDITION=YES ;; --with-http_addition_module) HTTP_ADDITION=YES ;;
--with-http_xslt_module) HTTP_XSLT=YES ;; --with-http_xslt_module) HTTP_XSLT=YES ;;
--with-http_xslt_module=dynamic) HTTP_XSLT=DYNAMIC ;;
--with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;; --with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;;
--with-http_image_filter_module=dynamic)
HTTP_IMAGE_FILTER=DYNAMIC ;;
--with-http_geoip_module) HTTP_GEOIP=YES ;; --with-http_geoip_module) HTTP_GEOIP=YES ;;
--with-http_geoip_module=dynamic)
HTTP_GEOIP=DYNAMIC ;;
--with-http_sub_module) HTTP_SUB=YES ;; --with-http_sub_module) HTTP_SUB=YES ;;
--with-http_dav_module) HTTP_DAV=YES ;; --with-http_dav_module) HTTP_DAV=YES ;;
--with-http_flv_module) HTTP_FLV=YES ;; --with-http_flv_module) HTTP_FLV=YES ;;
@ -266,6 +278,7 @@ do
--with-http_stub_status_module) HTTP_STUB_STATUS=YES ;; --with-http_stub_status_module) HTTP_STUB_STATUS=YES ;;
--with-mail) MAIL=YES ;; --with-mail) MAIL=YES ;;
--with-mail=dynamic) MAIL=DYNAMIC ;;
--with-mail_ssl_module) MAIL_SSL=YES ;; --with-mail_ssl_module) MAIL_SSL=YES ;;
# STUB # STUB
--with-imap) --with-imap)
@ -285,6 +298,7 @@ use the \"--with-mail_ssl_module\" option instead"
--without-mail_smtp_module) MAIL_SMTP=NO ;; --without-mail_smtp_module) MAIL_SMTP=NO ;;
--with-stream) STREAM=YES ;; --with-stream) STREAM=YES ;;
--with-stream=dynamic) STREAM=DYNAMIC ;;
--with-stream_ssl_module) STREAM_SSL=YES ;; --with-stream_ssl_module) STREAM_SSL=YES ;;
--without-stream_limit_conn_module) --without-stream_limit_conn_module)
STREAM_LIMIT_CONN=NO ;; STREAM_LIMIT_CONN=NO ;;
@ -300,6 +314,7 @@ use the \"--with-mail_ssl_module\" option instead"
--with-cpp_test_module) NGX_CPP_TEST=YES ;; --with-cpp_test_module) NGX_CPP_TEST=YES ;;
--add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;; --add-module=*) NGX_ADDONS="$NGX_ADDONS $value" ;;
--add-dynamic-module=*) DYNAMIC_ADDONS="$DYNAMIC_ADDONS $value" ;;
--with-cc=*) CC="$value" ;; --with-cc=*) CC="$value" ;;
--with-cpp=*) CPP="$value" ;; --with-cpp=*) CPP="$value" ;;
@ -356,6 +371,7 @@ cat << END
--prefix=PATH set installation prefix --prefix=PATH set installation prefix
--sbin-path=PATH set nginx binary pathname --sbin-path=PATH set nginx binary pathname
--modules-path=PATH set modules path
--conf-path=PATH set nginx.conf pathname --conf-path=PATH set nginx.conf pathname
--error-log-path=PATH set error log pathname --error-log-path=PATH set error log pathname
--pid-path=PATH set nginx.pid pathname --pid-path=PATH set nginx.pid pathname
@ -384,8 +400,12 @@ cat << END
--with-http_realip_module enable ngx_http_realip_module --with-http_realip_module enable ngx_http_realip_module
--with-http_addition_module enable ngx_http_addition_module --with-http_addition_module enable ngx_http_addition_module
--with-http_xslt_module enable ngx_http_xslt_module --with-http_xslt_module enable ngx_http_xslt_module
--with-http_xslt_module=dynamic enable dynamic ngx_http_xslt_module
--with-http_image_filter_module enable ngx_http_image_filter_module --with-http_image_filter_module enable ngx_http_image_filter_module
--with-http_image_filter_module=dynamic
enable dynamic ngx_http_image_filter_module
--with-http_geoip_module enable ngx_http_geoip_module --with-http_geoip_module enable ngx_http_geoip_module
--with-http_geoip_module=dynamic enable dynamic ngx_http_geoip_module
--with-http_sub_module enable ngx_http_sub_module --with-http_sub_module enable ngx_http_sub_module
--with-http_dav_module enable ngx_http_dav_module --with-http_dav_module enable ngx_http_dav_module
--with-http_flv_module enable ngx_http_flv_module --with-http_flv_module enable ngx_http_flv_module
@ -451,12 +471,14 @@ cat << END
--without-http-cache disable HTTP cache --without-http-cache disable HTTP cache
--with-mail enable POP3/IMAP4/SMTP proxy module --with-mail enable POP3/IMAP4/SMTP proxy module
--with-mail=dynamic enable dynamic POP3/IMAP4/SMTP proxy module
--with-mail_ssl_module enable ngx_mail_ssl_module --with-mail_ssl_module enable ngx_mail_ssl_module
--without-mail_pop3_module disable ngx_mail_pop3_module --without-mail_pop3_module disable ngx_mail_pop3_module
--without-mail_imap_module disable ngx_mail_imap_module --without-mail_imap_module disable ngx_mail_imap_module
--without-mail_smtp_module disable ngx_mail_smtp_module --without-mail_smtp_module disable ngx_mail_smtp_module
--with-stream enable TCP proxy module --with-stream enable TCP proxy module
--with-stream=dynamic enable dynamic TCP proxy module
--with-stream_ssl_module enable ngx_stream_ssl_module --with-stream_ssl_module enable ngx_stream_ssl_module
--without-stream_limit_conn_module disable ngx_stream_limit_conn_module --without-stream_limit_conn_module disable ngx_stream_limit_conn_module
--without-stream_access_module disable ngx_stream_access_module --without-stream_access_module disable ngx_stream_access_module
@ -470,7 +492,8 @@ cat << END
--with-google_perftools_module enable ngx_google_perftools_module --with-google_perftools_module enable ngx_google_perftools_module
--with-cpp_test_module enable ngx_cpp_test_module --with-cpp_test_module enable ngx_cpp_test_module
--add-module=PATH enable an external module --add-module=PATH enable external module
--add-dynamic-module=PATH enable dynamic external module
--with-cc=PATH set C compiler pathname --with-cc=PATH set C compiler pathname
--with-cpp=PATH set C preprocessor pathname --with-cpp=PATH set C preprocessor pathname
@ -533,6 +556,7 @@ fi
NGX_SBIN_PATH=${NGX_SBIN_PATH:-sbin/nginx} NGX_SBIN_PATH=${NGX_SBIN_PATH:-sbin/nginx}
NGX_MODULES_PATH=${NGX_MODULES_PATH:-modules}
NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf} NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}
NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH` NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid} NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}

View File

@ -14,6 +14,9 @@ CORE_SRCS="$UNIX_SRCS $DARWIN_SRCS"
ngx_spacer=' ngx_spacer='
' '
MAIN_LINK=
MODULE_LINK="-shared -Wl,-undefined,dynamic_lookup"
# kqueue # kqueue
echo " + kqueue found" echo " + kqueue found"

View File

@ -12,10 +12,15 @@ OS_CONFIG="$WIN32_CONFIG"
NGX_ICONS="$NGX_WIN32_ICONS" NGX_ICONS="$NGX_WIN32_ICONS"
SELECT_SRCS=$WIN32_SELECT_SRCS SELECT_SRCS=$WIN32_SELECT_SRCS
ngx_pic_opt=
case "$NGX_CC_NAME" in case "$NGX_CC_NAME" in
gcc) gcc)
CORE_LIBS="$CORE_LIBS -ladvapi32 -lws2_32" CORE_LIBS="$CORE_LIBS -ladvapi32 -lws2_32"
MAIN_LINK="$MAIN_LINK -Wl,--export-all-symbols"
MAIN_LINK="$MAIN_LINK -Wl,--out-implib=$NGX_OBJS/libnginx.a"
MODULE_LINK="-shared -L $NGX_OBJS -lnginx"
;; ;;
*) *)

View File

@ -60,6 +60,7 @@ echo
cat << END cat << END
nginx path prefix: "$NGX_PREFIX" nginx path prefix: "$NGX_PREFIX"
nginx binary file: "$NGX_SBIN_PATH" nginx binary file: "$NGX_SBIN_PATH"
nginx modules path: "$NGX_MODULES_PATH"
nginx configuration prefix: "$NGX_CONF_PREFIX" nginx configuration prefix: "$NGX_CONF_PREFIX"
nginx configuration file: "$NGX_CONF_PATH" nginx configuration file: "$NGX_CONF_PATH"
nginx pid file: "$NGX_PID_PATH" nginx pid file: "$NGX_PID_PATH"

View File

@ -24,6 +24,10 @@ static char *ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf); void *conf);
static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, static char *ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf); void *conf);
static char *ngx_load_module(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
#if (NGX_HAVE_DLOPEN)
static void ngx_unload_module(void *data);
#endif
static ngx_conf_enum_t ngx_debug_points[] = { static ngx_conf_enum_t ngx_debug_points[] = {
@ -133,6 +137,13 @@ static ngx_command_t ngx_core_commands[] = {
0, 0,
NULL }, NULL },
{ ngx_string("load_module"),
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
ngx_load_module,
0,
0,
NULL },
ngx_null_command ngx_null_command
}; };
@ -1403,3 +1414,101 @@ ngx_set_worker_processes(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK; return NGX_CONF_OK;
} }
static char *
ngx_load_module(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
#if (NGX_HAVE_DLOPEN)
void *handle;
char **names, **order;
ngx_str_t *value, file;
ngx_uint_t i;
ngx_module_t *module, **modules;
ngx_pool_cleanup_t *cln;
if (cf->cycle->modules_used) {
return "is specified too late";
}
value = cf->args->elts;
file = value[1];
if (ngx_conf_full_name(cf->cycle, &file, 0) != NGX_OK) {
return NGX_CONF_ERROR;
}
cln = ngx_pool_cleanup_add(cf->cycle->pool, 0);
if (cln == NULL) {
return NGX_CONF_ERROR;
}
handle = ngx_dlopen(file.data);
if (handle == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ngx_dlopen_n " \"%s\" failed (%s)",
file.data, ngx_dlerror());
return NGX_CONF_ERROR;
}
cln->handler = ngx_unload_module;
cln->data = handle;
modules = ngx_dlsym(handle, "ngx_modules");
if (modules == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ngx_dlsym_n " \"%V\", \"%s\" failed (%s)",
&value[1], "ngx_modules", ngx_dlerror());
return NGX_CONF_ERROR;
}
names = ngx_dlsym(handle, "ngx_module_names");
if (names == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
ngx_dlsym_n " \"%V\", \"%s\" failed (%s)",
&value[1], "ngx_module_names", ngx_dlerror());
return NGX_CONF_ERROR;
}
order = ngx_dlsym(handle, "ngx_module_order");
for (i = 0; modules[i]; i++) {
module = modules[i];
module->name = names[i];
if (ngx_add_module(cf, &file, module, order) != NGX_OK) {
return NGX_CONF_ERROR;
}
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0, "module: %s i:%i",
module->name, module->index);
}
return NGX_CONF_OK;
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"load_module\" is not supported "
"on this platform");
return NGX_CONF_ERROR;
#endif
}
#if (NGX_HAVE_DLOPEN)
static void
ngx_unload_module(void *data)
{
void *handle = data;
if (ngx_dlclose(handle) != 0) {
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
ngx_dlclose_n " failed (%s)", ngx_dlerror());
}
}
#endif

View File

@ -212,7 +212,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len); ngx_strlow(cycle->hostname.data, (u_char *) hostname, cycle->hostname.len);
cycle->modules = ngx_modules; if (ngx_cycle_modules(cycle) != NGX_OK) {
ngx_destroy_pool(pool);
return NULL;
}
for (i = 0; cycle->modules[i]; i++) { for (i = 0; cycle->modules[i]; i++) {

View File

@ -49,6 +49,8 @@ struct ngx_cycle_s {
ngx_uint_t free_connection_n; ngx_uint_t free_connection_n;
ngx_module_t **modules; ngx_module_t **modules;
ngx_uint_t modules_n;
ngx_uint_t modules_used; /* unsigned modules_used:1; */
ngx_queue_t reusable_connections_queue; ngx_queue_t reusable_connections_queue;

View File

@ -10,7 +10,16 @@
#include <ngx_core.h> #include <ngx_core.h>
ngx_uint_t ngx_max_module; #define NGX_MAX_DYNAMIC_MODULES 128
static ngx_uint_t ngx_module_index(ngx_cycle_t *cycle);
static ngx_uint_t ngx_module_ctx_index(ngx_cycle_t *cycle, ngx_uint_t type,
ngx_uint_t index);
ngx_uint_t ngx_max_module;
static ngx_uint_t ngx_modules_n;
ngx_int_t ngx_int_t
@ -20,9 +29,36 @@ ngx_preinit_modules()
ngx_max_module = 0; ngx_max_module = 0;
for (i = 0; ngx_modules[i]; i++) { for (i = 0; ngx_modules[i]; i++) {
ngx_modules[i]->index = ngx_max_module++; ngx_modules[i]->index = i;
ngx_modules[i]->name = ngx_module_names[i];
} }
ngx_modules_n = i;
ngx_max_module = ngx_modules_n + NGX_MAX_DYNAMIC_MODULES;
return NGX_OK;
}
ngx_int_t
ngx_cycle_modules(ngx_cycle_t *cycle)
{
/*
* create a list of modules to be used for this cycle,
* copy static modules to it
*/
cycle->modules = ngx_pcalloc(cycle->pool, (ngx_max_module + 1)
* sizeof(ngx_module_t *));
if (cycle->modules == NULL) {
return NGX_ERROR;
}
ngx_memcpy(cycle->modules, ngx_modules,
ngx_modules_n * sizeof(ngx_module_t *));
cycle->modules_n = ngx_modules_n;
return NGX_OK; return NGX_OK;
} }
@ -47,19 +83,279 @@ ngx_init_modules(ngx_cycle_t *cycle)
ngx_int_t ngx_int_t
ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type) ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type)
{ {
ngx_uint_t i, max; ngx_uint_t i, next, max;
ngx_module_t *module;
next = 0;
max = 0; max = 0;
/* count appropriate modules, set up their indices */ /* count appropriate modules, set up their indices */
for (i = 0; cycle->modules[i]; i++) { for (i = 0; cycle->modules[i]; i++) {
if (cycle->modules[i]->type != type) { module = cycle->modules[i];
if (module->type != type) {
continue; continue;
} }
cycle->modules[i]->ctx_index = max++; if (module->ctx_index != NGX_MODULE_UNSET_INDEX) {
/* if ctx_index was assigned, preserve it */
if (module->ctx_index > max) {
max = module->ctx_index;
}
if (module->ctx_index == next) {
next++;
}
continue;
}
/* search for some free index */
module->ctx_index = ngx_module_ctx_index(cycle, type, next);
if (module->ctx_index > max) {
max = module->ctx_index;
}
next = module->ctx_index + 1;
} }
return max; /*
* make sure the number returned is big enough for previous
* cycle as well, else there will be problems if the number
* will be stored in a global variable (as it's used to be)
* and we'll have to roll back to the previous cycle
*/
if (cycle->old_cycle && cycle->old_cycle->modules) {
for (i = 0; cycle->old_cycle->modules[i]; i++) {
module = cycle->old_cycle->modules[i];
if (module->type != type) {
continue;
}
if (module->ctx_index > max) {
max = module->ctx_index;
}
}
}
/* prevent loading of additional modules */
cycle->modules_used = 1;
return max + 1;
}
ngx_int_t
ngx_add_module(ngx_conf_t *cf, ngx_str_t *file, ngx_module_t *module,
char **order)
{
void *rv;
ngx_uint_t i, m, before;
ngx_core_module_t *core_module;
if (cf->cycle->modules_n >= ngx_max_module) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"too many modules loaded");
return NGX_ERROR;
}
if (module->version != nginx_version) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"module \"%V\" version %ui instead of %ui",
file, module->version, nginx_version);
return NGX_ERROR;
}
if (ngx_strcmp(module->signature, NGX_MODULE_SIGNATURE) != 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"module \"%V\" is not binary compatible",
file);
return NGX_ERROR;
}
for (m = 0; cf->cycle->modules[m]; m++) {
if (ngx_strcmp(cf->cycle->modules[m]->name, module->name) == 0) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"module \"%s\" is already loaded",
module->name);
return NGX_ERROR;
}
}
/*
* if the module wasn't previously loaded, assign an index
*/
if (module->index == NGX_MODULE_UNSET_INDEX) {
module->index = ngx_module_index(cf->cycle);
if (module->index >= ngx_max_module) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"too many modules loaded");
return NGX_ERROR;
}
}
/*
* put the module into the cycle->modules array
*/
before = cf->cycle->modules_n;
if (order) {
for (i = 0; order[i]; i++) {
if (ngx_strcmp(order[i], module->name) == 0) {
i++;
break;
}
}
for ( /* void */ ; order[i]; i++) {
#if 0
ngx_log_debug2(NGX_LOG_DEBUG_CORE, cf->log, 0,
"module: %s before %s",
module->name, order[i]);
#endif
for (m = 0; m < before; m++) {
if (ngx_strcmp(cf->cycle->modules[m]->name, order[i]) == 0) {
ngx_log_debug3(NGX_LOG_DEBUG_CORE, cf->log, 0,
"module: %s before %s:%i",
module->name, order[i], m);
before = m;
break;
}
}
}
}
/* put the module before modules[before] */
if (before != cf->cycle->modules_n) {
ngx_memmove(&cf->cycle->modules[before + 1],
&cf->cycle->modules[before],
(cf->cycle->modules_n - before) * sizeof(ngx_module_t *));
}
cf->cycle->modules[before] = module;
cf->cycle->modules_n++;
if (module->type == NGX_CORE_MODULE) {
/*
* we are smart enough to initialize core modules;
* other modules are expected to be loaded before
* initialization - e.g., http modules must be loaded
* before http{} block
*/
core_module = module->ctx;
if (core_module->create_conf) {
rv = core_module->create_conf(cf->cycle);
if (rv == NULL) {
return NGX_ERROR;
}
cf->cycle->conf_ctx[module->index] = rv;
}
}
return NGX_OK;
}
static ngx_uint_t
ngx_module_index(ngx_cycle_t *cycle)
{
ngx_uint_t i, index;
ngx_module_t *module;
index = 0;
again:
/* find an unused index */
for (i = 0; cycle->modules[i]; i++) {
module = cycle->modules[i];
if (module->index == index) {
index++;
goto again;
}
}
/* check previous cycle */
if (cycle->old_cycle && cycle->old_cycle->modules) {
for (i = 0; cycle->old_cycle->modules[i]; i++) {
module = cycle->old_cycle->modules[i];
if (module->index == index) {
index++;
goto again;
}
}
}
return index;
}
static ngx_uint_t
ngx_module_ctx_index(ngx_cycle_t *cycle, ngx_uint_t type, ngx_uint_t index)
{
ngx_uint_t i;
ngx_module_t *module;
again:
/* find an unused ctx_index */
for (i = 0; cycle->modules[i]; i++) {
module = cycle->modules[i];
if (module->type != type) {
continue;
}
if (module->ctx_index == index) {
index++;
goto again;
}
}
/* check previous cycle */
if (cycle->old_cycle && cycle->old_cycle->modules) {
for (i = 0; cycle->old_cycle->modules[i]; i++) {
module = cycle->old_cycle->modules[i];
if (module->type != type) {
continue;
}
if (module->ctx_index == index) {
index++;
goto again;
}
}
}
return index;
} }

View File

@ -12,9 +12,234 @@
#include <ngx_config.h> #include <ngx_config.h>
#include <ngx_core.h> #include <ngx_core.h>
#include <nginx.h>
#define NGX_MODULE_V1 0, 0, 0, 0, 0, 0, 1 #define NGX_MODULE_UNSET_INDEX (ngx_uint_t) -1
#define NGX_MODULE_SIGNATURE_0 \
ngx_value(NGX_PTR_SIZE) "," \
ngx_value(NGX_SIG_ATOMIC_T_SIZE) "," \
ngx_value(NGX_TIME_T_SIZE) ","
#if (NGX_HAVE_KQUEUE)
#define NGX_MODULE_SIGNATURE_1 "1"
#else
#define NGX_MODULE_SIGNATURE_1 "0"
#endif
#if (NGX_HAVE_IOCP)
#define NGX_MODULE_SIGNATURE_2 "1"
#else
#define NGX_MODULE_SIGNATURE_2 "0"
#endif
#if (NGX_HAVE_FILE_AIO)
#define NGX_MODULE_SIGNATURE_3 "1"
#else
#define NGX_MODULE_SIGNATURE_3 "0"
#endif
#if (NGX_HAVE_AIO_SENDFILE)
#define NGX_MODULE_SIGNATURE_4 "1"
#else
#define NGX_MODULE_SIGNATURE_4 "0"
#endif
#if (NGX_HAVE_EVENTFD)
#define NGX_MODULE_SIGNATURE_5 "1"
#else
#define NGX_MODULE_SIGNATURE_5 "0"
#endif
#if (NGX_HAVE_EPOLL)
#define NGX_MODULE_SIGNATURE_6 "1"
#else
#define NGX_MODULE_SIGNATURE_6 "0"
#endif
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
#define NGX_MODULE_SIGNATURE_7 "1"
#else
#define NGX_MODULE_SIGNATURE_7 "0"
#endif
#if (NGX_HAVE_INET6)
#define NGX_MODULE_SIGNATURE_8 "1"
#else
#define NGX_MODULE_SIGNATURE_8 "0"
#endif
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
#define NGX_MODULE_SIGNATURE_9 "1"
#else
#define NGX_MODULE_SIGNATURE_9 "0"
#endif
#if (NGX_HAVE_REUSEPORT)
#define NGX_MODULE_SIGNATURE_10 "1"
#else
#define NGX_MODULE_SIGNATURE_10 "0"
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER)
#define NGX_MODULE_SIGNATURE_11 "1"
#else
#define NGX_MODULE_SIGNATURE_11 "0"
#endif
#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT)
#define NGX_MODULE_SIGNATURE_12 "1"
#else
#define NGX_MODULE_SIGNATURE_12 "0"
#endif
#if (NGX_HAVE_SETFIB)
#define NGX_MODULE_SIGNATURE_13 "1"
#else
#define NGX_MODULE_SIGNATURE_13 "0"
#endif
#if (NGX_HAVE_TCP_FASTOPEN)
#define NGX_MODULE_SIGNATURE_14 "1"
#else
#define NGX_MODULE_SIGNATURE_14 "0"
#endif
#if (NGX_HAVE_UNIX_DOMAIN)
#define NGX_MODULE_SIGNATURE_15 "1"
#else
#define NGX_MODULE_SIGNATURE_15 "0"
#endif
#if (NGX_HAVE_VARIADIC_MACROS)
#define NGX_MODULE_SIGNATURE_16 "1"
#else
#define NGX_MODULE_SIGNATURE_16 "0"
#endif
#if (NGX_HAVE_MD5)
#define NGX_MODULE_SIGNATURE_17 "1"
#else
#define NGX_MODULE_SIGNATURE_17 "0"
#endif
#if (NGX_HAVE_SHA1)
#define NGX_MODULE_SIGNATURE_18 "1"
#else
#define NGX_MODULE_SIGNATURE_18 "0"
#endif
#if (NGX_HAVE_OPENAT)
#define NGX_MODULE_SIGNATURE_19 "1"
#else
#define NGX_MODULE_SIGNATURE_19 "0"
#endif
#if (NGX_HAVE_ATOMIC_OPS)
#define NGX_MODULE_SIGNATURE_20 "1"
#else
#define NGX_MODULE_SIGNATURE_20 "0"
#endif
#if (NGX_HAVE_POSIX_SEM)
#define NGX_MODULE_SIGNATURE_21 "1"
#else
#define NGX_MODULE_SIGNATURE_21 "0"
#endif
#if (NGX_THREADS)
#define NGX_MODULE_SIGNATURE_22 "1"
#else
#define NGX_MODULE_SIGNATURE_22 "0"
#endif
#if (NGX_PCRE)
#define NGX_MODULE_SIGNATURE_23 "1"
#else
#define NGX_MODULE_SIGNATURE_23 "0"
#endif
#if (NGX_HTTP_SSL)
#define NGX_MODULE_SIGNATURE_24 "1"
#else
#define NGX_MODULE_SIGNATURE_24 "0"
#endif
#if (NGX_HTTP_V2)
#define NGX_MODULE_SIGNATURE_25 "1"
#else
#define NGX_MODULE_SIGNATURE_25 "0"
#endif
#if (NGX_HTTP_GZIP)
#define NGX_MODULE_SIGNATURE_26 "1"
#else
#define NGX_MODULE_SIGNATURE_26 "0"
#endif
#if (NGX_HTTP_DEGRADATION)
#define NGX_MODULE_SIGNATURE_27 "1"
#else
#define NGX_MODULE_SIGNATURE_27 "0"
#endif
#if (NGX_HTTP_X_FORWARDED_FOR)
#define NGX_MODULE_SIGNATURE_28 "1"
#else
#define NGX_MODULE_SIGNATURE_28 "0"
#endif
#if (NGX_HTTP_REALIP)
#define NGX_MODULE_SIGNATURE_29 "1"
#else
#define NGX_MODULE_SIGNATURE_29 "0"
#endif
#if (NGX_HTTP_HEADERS)
#define NGX_MODULE_SIGNATURE_30 "1"
#else
#define NGX_MODULE_SIGNATURE_30 "0"
#endif
#if (NGX_HTTP_DAV)
#define NGX_MODULE_SIGNATURE_31 "1"
#else
#define NGX_MODULE_SIGNATURE_31 "0"
#endif
#if (NGX_HTTP_CACHE)
#define NGX_MODULE_SIGNATURE_32 "1"
#else
#define NGX_MODULE_SIGNATURE_32 "0"
#endif
#if (NGX_HTTP_UPSTREAM_ZONE)
#define NGX_MODULE_SIGNATURE_33 "1"
#else
#define NGX_MODULE_SIGNATURE_33 "0"
#endif
#define NGX_MODULE_SIGNATURE \
NGX_MODULE_SIGNATURE_0 NGX_MODULE_SIGNATURE_1 NGX_MODULE_SIGNATURE_2 \
NGX_MODULE_SIGNATURE_3 NGX_MODULE_SIGNATURE_4 NGX_MODULE_SIGNATURE_5 \
NGX_MODULE_SIGNATURE_6 NGX_MODULE_SIGNATURE_7 NGX_MODULE_SIGNATURE_8 \
NGX_MODULE_SIGNATURE_9 NGX_MODULE_SIGNATURE_10 NGX_MODULE_SIGNATURE_11 \
NGX_MODULE_SIGNATURE_12 NGX_MODULE_SIGNATURE_13 NGX_MODULE_SIGNATURE_14 \
NGX_MODULE_SIGNATURE_15 NGX_MODULE_SIGNATURE_16 NGX_MODULE_SIGNATURE_17 \
NGX_MODULE_SIGNATURE_18 NGX_MODULE_SIGNATURE_19 NGX_MODULE_SIGNATURE_20 \
NGX_MODULE_SIGNATURE_21 NGX_MODULE_SIGNATURE_22 NGX_MODULE_SIGNATURE_23 \
NGX_MODULE_SIGNATURE_24 NGX_MODULE_SIGNATURE_25 NGX_MODULE_SIGNATURE_26 \
NGX_MODULE_SIGNATURE_27 NGX_MODULE_SIGNATURE_28 NGX_MODULE_SIGNATURE_29 \
NGX_MODULE_SIGNATURE_30 NGX_MODULE_SIGNATURE_31 NGX_MODULE_SIGNATURE_32 \
NGX_MODULE_SIGNATURE_33
#define NGX_MODULE_V1 \
NGX_MODULE_UNSET_INDEX, NGX_MODULE_UNSET_INDEX, \
NULL, 0, 0, nginx_version, NGX_MODULE_SIGNATURE
#define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0 #define NGX_MODULE_V1_PADDING 0, 0, 0, 0, 0, 0, 0, 0
@ -22,12 +247,13 @@ struct ngx_module_s {
ngx_uint_t ctx_index; ngx_uint_t ctx_index;
ngx_uint_t index; ngx_uint_t index;
char *name;
ngx_uint_t spare0; ngx_uint_t spare0;
ngx_uint_t spare1; ngx_uint_t spare1;
ngx_uint_t spare2;
ngx_uint_t spare3;
ngx_uint_t version; ngx_uint_t version;
char *signature;
void *ctx; void *ctx;
ngx_command_t *commands; ngx_command_t *commands;
@ -63,12 +289,19 @@ typedef struct {
ngx_int_t ngx_preinit_modules(); ngx_int_t ngx_preinit_modules();
ngx_int_t ngx_cycle_modules(ngx_cycle_t *cycle);
ngx_int_t ngx_init_modules(ngx_cycle_t *cycle); ngx_int_t ngx_init_modules(ngx_cycle_t *cycle);
ngx_int_t ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type); ngx_int_t ngx_count_modules(ngx_cycle_t *cycle, ngx_uint_t type);
ngx_int_t ngx_add_module(ngx_conf_t *cf, ngx_str_t *file,
ngx_module_t *module, char **order);
extern ngx_module_t *ngx_modules[]; extern ngx_module_t *ngx_modules[];
extern ngx_uint_t ngx_max_module; extern ngx_uint_t ngx_max_module;
extern char *ngx_module_names[];
#endif /* _NGX_MODULE_H_INCLUDED_ */ #endif /* _NGX_MODULE_H_INCLUDED_ */