diff options
author | Andy Pan <panjf2000@gmail.com> | 2021-01-20 04:57:30 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-19 22:57:30 +0200 |
commit | fb66e2e24943018961321d13e46ee2ab66de882a (patch) | |
tree | 04075a8d909bc1eba249ecb1aaf1b4705fc84823 /tests | |
parent | aaf71b380ed5ef8d5d63f8a60733c35202c5b838 (diff) | |
download | redis-fb66e2e24943018961321d13e46ee2ab66de882a.tar.gz |
Use FD_CLOEXEC in Sentinel, so that FDs don't leak to the scripts it runs (#8242)
Sentinel uses execve to run scripts, so it needs to use FD_CLOEXEC
on all file descriptors, so that they're not accessible by the script it runs.
This commit includes a change to the sentinel tests, which verifies no
FDs are left opened when the script is executed.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/instances.tcl | 14 | ||||
-rw-r--r-- | tests/sentinel/run.tcl | 2 | ||||
-rw-r--r-- | tests/sentinel/tests/includes/init-tests.tcl | 2 | ||||
-rwxr-xr-x | tests/sentinel/tests/includes/notify.sh | 20 |
4 files changed, 36 insertions, 2 deletions
diff --git a/tests/instances.tcl b/tests/instances.tcl index 18eb1a402..5b25bcc97 100644 --- a/tests/instances.tcl +++ b/tests/instances.tcl @@ -400,6 +400,11 @@ proc check_leaks instance_types { # Execute all the units inside the 'tests' directory. proc run_tests {} { + set sentinel_fd_leaks_file "sentinel_fd_leaks" + if { [file exists $sentinel_fd_leaks_file] } { + file delete $sentinel_fd_leaks_file + } + set tests [lsort [glob ../tests/*]] foreach test $tests { if {$::run_matching ne {} && [string match $::run_matching $test] == 0} { @@ -414,7 +419,14 @@ proc run_tests {} { # Print a message and exists with 0 / 1 according to zero or more failures. proc end_tests {} { - if {$::failed == 0} { + set sentinel_fd_leaks_file "sentinel_fd_leaks" + if { [file exists $sentinel_fd_leaks_file] } { + puts [colorstr red "WARNING: sentinel test(s) failed, there are leaked fds in sentinel:"] + exec cat $sentinel_fd_leaks_file + exit 1 + } + + if {$::failed == 0 } { puts "GOOD! No errors." exit 0 } else { diff --git a/tests/sentinel/run.tcl b/tests/sentinel/run.tcl index 996af906a..99362c193 100644 --- a/tests/sentinel/run.tcl +++ b/tests/sentinel/run.tcl @@ -10,7 +10,7 @@ set ::tlsdir "../../tls" proc main {} { parse_options - spawn_instance sentinel $::sentinel_base_port $::instances_count + spawn_instance sentinel $::sentinel_base_port $::instances_count [list "sentinel deny-scripts-reconfig no"] spawn_instance redis $::redis_base_port $::instances_count run_tests cleanup diff --git a/tests/sentinel/tests/includes/init-tests.tcl b/tests/sentinel/tests/includes/init-tests.tcl index 234f9c589..d6796fda6 100644 --- a/tests/sentinel/tests/includes/init-tests.tcl +++ b/tests/sentinel/tests/includes/init-tests.tcl @@ -37,6 +37,8 @@ test "(init) Sentinels can start monitoring a master" { S $id SENTINEL SET mymaster down-after-milliseconds 2000 S $id SENTINEL SET mymaster failover-timeout 20000 S $id SENTINEL SET mymaster parallel-syncs 10 + S $id SENTINEL SET mymaster notification-script ../../tests/includes/notify.sh + S $id SENTINEL SET mymaster client-reconfig-script ../../tests/includes/notify.sh } } diff --git a/tests/sentinel/tests/includes/notify.sh b/tests/sentinel/tests/includes/notify.sh new file mode 100755 index 000000000..09a8addca --- /dev/null +++ b/tests/sentinel/tests/includes/notify.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +OS=`uname -s` +if [ ${OS} == "Linux" ] +then + exit 0 +fi + +# fd 3 is meant to catch the actual access to /proc/pid/fd, +# in case there's an fd leak by the sentinel, +# it can take 3, but then the access to /proc will take another fd, and we'll catch that. +leaked_fd_count=`ls /proc/self/fd | grep -vE '^[0|1|2|3]$' | wc -l` +if [ $leaked_fd_count -gt 0 ] +then + sentinel_fd_leaks_file="../sentinel_fd_leaks" + if [ ! -f $sentinel_fd_leaks_file ] + then + ls -l /proc/self/fd | cat >> $sentinel_fd_leaks_file + fi +fi |