Skip to content

Commit f9e4a21

Browse files
committed
feature: implemented a new 'lua_sa_restart' directive, which sets the SA_RESTART flag on nginx workers signal dispositions.
1 parent af9d4d3 commit f9e4a21

File tree

8 files changed

+210
-0
lines changed

8 files changed

+210
-0
lines changed

‎README.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ documentation of `ngx_http_lua_module` for more details about their usage and be
147147
* [lua_check_client_abort](https://github.com/openresty/lua-nginx-module#lua_check_client_abort)
148148
* [lua_max_pending_timers](https://github.com/openresty/lua-nginx-module#lua_max_pending_timers)
149149
* [lua_max_running_timers](https://github.com/openresty/lua-nginx-module#lua_max_running_timers)
150+
* [lua_sa_restart](https://github.com/openresty/lua-nginx-module#lua_sa_restart)
150151
* [lua_add_variable](#lua_add_variable)
151152
* [lua_capture_error_log](https://github.com/openresty/lua-nginx-module#lua_capture_error_log)
152153
* [preread_by_lua_no_postpone](#preread_by_lua_no_postpone)

‎config‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,5 +439,16 @@ ngx_feature_test='setsockopt(1, SOL_SOCKET, SO_PASSCRED, NULL, 0);'
439439

440440
. auto/feature
441441

442+
ngx_feature="SA_RESTART"
443+
ngx_feature_libs=
444+
ngx_feature_name="NGX_STREAM_LUA_HAVE_SA_RESTART"
445+
ngx_feature_run=no
446+
ngx_feature_incs="#include <signal.h>"
447+
ngx_feature_path=
448+
ngx_feature_test='struct sigaction act;
449+
act.sa_flags |= SA_RESTART;'
450+
451+
. auto/feature
452+
442453
#CFLAGS=$"$CFLAGS -DLUA_DEFAULT_PATH='\"/usr/local/openresty/lualib/?.lua\"'"
443454
#CFLAGS=$"$CFLAGS -DLUA_DEFAULT_CPATH='\"/usr/local/openresty/lualib/?.so\"'"

‎src/ngx_stream_lua_common.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ struct ngx_stream_lua_main_conf_s {
221221
ngx_uint_t malloc_trim_req_count;
222222

223223

224+
ngx_flag_t set_sa_restart;
225+
224226
unsigned requires_preread:1;
225227

226228
unsigned requires_log:1;

‎src/ngx_stream_lua_initworkerby.c‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ ngx_stream_lua_init_worker(ngx_cycle_t *cycle)
7979
}
8080
#endif /* NGX_WIN32 */
8181

82+
#if NGX_STREAM_LUA_HAVE_SA_RESTART
83+
if (lmcf->set_sa_restart) {
84+
ngx_stream_lua_set_sa_restart(ngx_cycle->log);
85+
}
86+
#endif
87+
8288
if (lmcf->init_worker_handler == NULL) {
8389
return NGX_OK;
8490
}

‎src/ngx_stream_lua_module.c‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,13 @@ static ngx_command_t ngx_stream_lua_cmds[] = {
108108
0,
109109
NULL },
110110

111+
{ ngx_string("lua_sa_restart"),
112+
NGX_STREAM_MAIN_CONF|NGX_CONF_FLAG,
113+
ngx_conf_set_flag_slot,
114+
NGX_STREAM_MAIN_CONF_OFFSET,
115+
offsetof(ngx_stream_lua_main_conf_t, set_sa_restart),
116+
NULL },
117+
111118
#if (NGX_PCRE)
112119
{ ngx_string("lua_regex_cache_max_entries"),
113120
NGX_STREAM_MAIN_CONF|NGX_CONF_TAKE1,
@@ -638,6 +645,8 @@ ngx_stream_lua_create_main_conf(ngx_conf_t *cf)
638645

639646
lmcf->postponed_to_preread_phase_end = NGX_CONF_UNSET;
640647

648+
lmcf->set_sa_restart = NGX_CONF_UNSET;
649+
641650
#if (NGX_STREAM_LUA_HAVE_MALLOC_TRIM)
642651
lmcf->malloc_trim_cycle = NGX_CONF_UNSET_UINT;
643652
#endif
@@ -676,6 +685,12 @@ ngx_stream_lua_init_main_conf(ngx_conf_t *cf, void *conf)
676685
lmcf->max_running_timers = 256;
677686
}
678687

688+
#if (NGX_STREAM_LUA_HAVE_SA_RESTART)
689+
if (lmcf->set_sa_restart == NGX_CONF_UNSET) {
690+
lmcf->set_sa_restart = 1;
691+
}
692+
#endif
693+
679694
#if (NGX_STREAM_LUA_HAVE_MALLOC_TRIM)
680695
if (lmcf->malloc_trim_cycle == NGX_CONF_UNSET_UINT) {
681696
lmcf->malloc_trim_cycle = 1000; /* number of reqs */

‎src/ngx_stream_lua_util.c‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,25 @@
6767
#endif
6868

6969

70+
#if (NGX_STREAM_LUA_HAVE_SA_RESTART)
71+
#define NGX_STREAM_LUA_SA_RESTART_SIGS { \
72+
ngx_signal_value(NGX_RECONFIGURE_SIGNAL), \
73+
ngx_signal_value(NGX_REOPEN_SIGNAL), \
74+
ngx_signal_value(NGX_NOACCEPT_SIGNAL), \
75+
ngx_signal_value(NGX_TERMINATE_SIGNAL), \
76+
ngx_signal_value(NGX_SHUTDOWN_SIGNAL), \
77+
ngx_signal_value(NGX_CHANGEBIN_SIGNAL), \
78+
SIGALRM, \
79+
SIGINT, \
80+
SIGIO, \
81+
SIGCHLD, \
82+
SIGSYS, \
83+
SIGPIPE, \
84+
0 \
85+
};
86+
#endif
87+
88+
7089
char ngx_stream_lua_code_cache_key;
7190
char ngx_stream_lua_regex_cache_key;
7291
char ngx_stream_lua_socket_pool_key;
@@ -3582,4 +3601,32 @@ ngx_stream_lua_cleanup_free(ngx_stream_lua_request_t *r,
35823601
}
35833602

35843603

3604+
#if (NGX_STREAM_LUA_HAVE_SA_RESTART)
3605+
void
3606+
ngx_stream_lua_set_sa_restart(ngx_log_t *log)
3607+
{
3608+
int *signo;
3609+
int sigs[] = NGX_STREAM_LUA_SA_RESTART_SIGS;
3610+
struct sigaction act;
3611+
3612+
for (signo = sigs; *signo != 0; signo++) {
3613+
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, log, 0,
3614+
"setting SA_RESTART for signal %d", *signo);
3615+
3616+
if (sigaction(*signo, NULL, &act) != 0) {
3617+
ngx_log_error(NGX_LOG_WARN, log, ngx_errno, "failed to get "
3618+
"sigaction for signal %d", *signo);
3619+
}
3620+
3621+
act.sa_flags |= SA_RESTART;
3622+
3623+
if (sigaction(*signo, &act, NULL) != 0) {
3624+
ngx_log_error(NGX_LOG_WARN, log, ngx_errno, "failed to set "
3625+
"sigaction for signal %d", *signo);
3626+
}
3627+
}
3628+
}
3629+
#endif
3630+
3631+
35853632
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

‎src/ngx_stream_lua_util.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ int ngx_stream_lua_do_call(ngx_log_t *log, lua_State *L);
250250
void ngx_stream_lua_cleanup_free(ngx_stream_lua_request_t *r,
251251
ngx_stream_lua_cleanup_pt *cleanup);
252252

253+
#if (NGX_STREAM_LUA_HAVE_SA_RESTART)
254+
void ngx_stream_lua_set_sa_restart(ngx_log_t *log);
255+
#endif
253256

254257
#define ngx_stream_lua_check_if_abortable(L, ctx) \
255258
if ((ctx)->no_abort) { \

‎t/159-sa-restart.t‎

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
3+
use Test::Nginx::Socket::Lua::Stream;
4+
5+
add_block_preprocessor(sub {
6+
my $block = shift;
7+
8+
my $stream_config = $block->stream_config || '';
9+
10+
$stream_config .= <<_EOC_;
11+
init_by_lua_block {
12+
function test_sa_restart()
13+
local signals = {
14+
"HUP",
15+
--"INFO",
16+
--"XCPU",
17+
--"USR1",
18+
--"USR2",
19+
"ALRM",
20+
--"INT",
21+
"IO",
22+
"CHLD",
23+
"WINCH",
24+
}
25+
26+
for _, signame in ipairs(signals) do
27+
local cmd = string.format("kill -s %s %d && sleep 0.01",
28+
signame, ngx.worker.pid())
29+
local err = select(2, io.popen(cmd):read("*a"))
30+
if err then
31+
error("SIG" .. signame .. " caused: " .. err)
32+
end
33+
end
34+
end
35+
}
36+
_EOC_
37+
38+
$block->set_value("stream_config", $stream_config);
39+
40+
if (!defined $block->stream_server_config) {
41+
my $stream_config = <<_EOC_;
42+
content_by_lua_block {
43+
ngx.say("ok")
44+
}
45+
_EOC_
46+
47+
$block->set_value("stream_server_config", $stream_config);
48+
}
49+
50+
if (!defined $block->no_error_log) {
51+
$block->set_value("no_error_log", "[error]");
52+
}
53+
});
54+
55+
plan tests => repeat_each() * (blocks() * 2 + 1);
56+
57+
no_long_string();
58+
run_tests();
59+
60+
__DATA__
61+
62+
=== TEST 1: lua_sa_restart default - sets SA_RESTART in init_worker_by_lua*
63+
--- stream_config
64+
init_worker_by_lua_block {
65+
test_sa_restart()
66+
}
67+
68+
69+
70+
=== TEST 2: lua_sa_restart off - does not set SA_RESTART
71+
We must specify the lua_sa_restart directive in the http block as well, since
72+
otherwise, ngx_lua's own default of lua_sa_restart is 'on', and ngx_lua
73+
re-enables the SA_RESTART flag.
74+
--- http_config
75+
lua_sa_restart off;
76+
--- stream_config
77+
lua_sa_restart off;
78+
79+
init_worker_by_lua_block {
80+
test_sa_restart()
81+
}
82+
--- no_error_log
83+
[crit]
84+
--- error_log
85+
Interrupted system call
86+
87+
88+
89+
=== TEST 3: lua_sa_restart on (default) - sets SA_RESTART if no init_worker_by_lua* phase is defined
90+
--- stream_server_config
91+
content_by_lua_block {
92+
test_sa_restart()
93+
}
94+
95+
96+
97+
=== TEST 4: lua_sa_restart on (default) - SA_RESTART is effective in content_by_lua*
98+
--- stream_server_config
99+
content_by_lua_block {
100+
test_sa_restart()
101+
}
102+
103+
104+
105+
=== TEST 5: lua_sa_restart on (default) - SA_RESTART is effective in log_by_lua*
106+
--- stream_server_config
107+
content_by_lua_block {
108+
ngx.say("ok")
109+
}
110+
111+
log_by_lua_block {
112+
test_sa_restart()
113+
}
114+
115+
116+
117+
=== TEST 6: lua_sa_restart on (default) - SA_RESTART is effective in timer phase
118+
--- stream_server_config
119+
content_by_lua_block {
120+
ngx.say("ok")
121+
}
122+
123+
log_by_lua_block {
124+
ngx.timer.at(0, test_sa_restart)
125+
}

0 commit comments

Comments
 (0)