Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reaps on SIGTERM (docker stop), not reaping on CTRL^C (SIGINT) #1

Closed
dreamcat4 opened this issue Mar 2, 2015 · 9 comments
Closed

Comments

@dreamcat4
Copy link

Hi. Sorry for the long output. Basically I type CTRL^C on the keyboard (interactive tty). And that sends an interrupt signal (SIGINT) which does not reap the orphans. Wheras docker stop command sends a TERM, which does in fact works.

It would be nice to respong for CTRL^C (SIGINT) too. Other possible signals to listen for are QUIT and HUP.

Anyway, here is all the long testing outputs:

@dreamcat4
Copy link
Author

My test commands (in terminal window):

# check to see if any instances of 'tail -f' are running
ps -aux | grep -v grep | grep 'tail -f'

# check for running instances of 's6test' container
docker ps --no-trunc | grep s6test

# build
docker build --rm --tag=dreamcat4/s6test .
docker rm --force s6test

# run
docker run --tty --name s6test dreamcat4/s6test

# Test 1: send ta TERM (from another window)
docker stop s6test
# Test result: Yes, it reaps :))

# Test 2: Break interactively with CTRL^C - sends a SIGINT (INT = 'interrupt')
^C
# Test result: No, it does not reap.

# check again to see if 'tail -f' (the orphan) was reaped ?
ps -aux | grep -v grep | grep 'tail -f'

# check to see if 's6test' container is still listed as running ?
docker ps --no-trunc | grep s6test

# to clean up (kill) any non-reaped 'tail' program
sudo killall -9 tail

Dockerfile:

FROM busybox

ADD https://github.com/glerchundi/container-s6-overlay-builder/releases/download/v0.1.0/s6-overlay-0.1.0-linux-amd64.tar.gz /s6-overlay.tar.gz
RUN gunzip -c /s6-overlay.tar.gz | tar -xvf - -C / && rm /s6-overlay.tar.gz

# COPY s6 /
COPY myprogram.sh /myprogram.sh

ENTRYPOINT ["/init","/myprogram.sh"]
CMD ["arg1","arg2","arg3"]

myprogram.sh:

#!/bin/sh

_term ()
{
    echo ; echo "trap: received SIGTERM ('TERM')" ; echo "exiting..." ; exit 0
}

_int ()
{
    echo ; echo "trap: received SIGINT ('INT')"   ; echo "exiting..." ; exit 0
}

_quit ()
{
    echo ; echo "trap: received SIGQUIT ('QUIT')" ; echo "exiting..." ; exit 0
}

_hup ()
{
    echo ; echo "trap: received SIGHUP ('HUP')"   ; echo "exiting..." ; exit 0
}

trap _term TERM
trap _int  INT
trap _quit QUIT
trap _hup  HUP

echo "==="
echo " have started: $0"
echo "    with args: $@"
echo "==="
echo " running: tail -f /dev/null | while read line ..."
echo " the 'tail -f /dev/null' created above ^^ is an orphaned process"
echo ""

tail -f /dev/null | while read line; do
    sleep 0
done

Output for the successul Test 1: receives TERM signal (docker stop):

# check to see if any instances of 'tail' are running
$ ps -aux -eww | grep -v grep | grep 's6test - orphaned process'

$ # check for running instances of 's6test' container
$ docker ps --no-trunc | grep s6test

$ # build
$ docker build --rm --tag=dreamcat4/s6test .
Sending build context to Docker daemon 10.33 MB
Sending build context to Docker daemon 
Step 0 : FROM busybox
 ---> 4986bf8c1536
Step 1 : ADD https://github.com/glerchundi/container-s6-overlay-builder/releases/download/v0.1.0/s6-overlay-0.1.0-linux-amd64.tar.gz /s6-overlay.tar.gz
Downloading [==================================================>] 2.458 MB/2.458 MB
 ---> Using cache
 ---> b432cd6299d0
Step 2 : RUN gunzip -c /s6-overlay.tar.gz | tar -xvf - -C / && rm /s6-overlay.tar.gz
 ---> Using cache
 ---> 2107900c12c3
Step 3 : COPY myprogram.sh /myprogram.sh
 ---> Using cache
 ---> 0644fcd7704f
Step 4 : ENTRYPOINT /init /myprogram.sh
 ---> Using cache
 ---> a7495548761d
Step 5 : CMD arg1 arg2 arg3
 ---> Using cache
 ---> 9b93f0bdb1d9
Successfully built 9b93f0bdb1d9
$ docker rm --force s6test
s6test

$ # run
$ docker run --tty --name s6test dreamcat4/s6test
[fix-attrs] fixing file attributes (ownership & permission)...
[fix-attrs] /etc/fix-attrs.d/00-base: applying...
[fix-attrs] /etc/fix-attrs.d/00-base: done.
[fix-attrs] done.
===
 have started: /myprogram.sh
    with args: arg1 arg2 arg3
===
 running: tail -f /dev/null | while read line ...
 the 'tail -f /dev/null' created above ^^ is an orphaned process

# in window2
$ docker stop s6test
s6test
$ # check again to see if 'tail -f' (the orphan) was reaped ?
$ ps -aux -eww | grep -v grep | grep 's6test - orphaned process'
$ # check to see if 's6test' container is still listed as running ?
$ docker ps --no-trunc | grep s6test

# back in window1
[s6-finish] syncing disks.
[s6-finish] sending all processes the TERM signal.
Hangup
Hangup

trap: received SIGHUP ('HUP')
exiting...
[s6-finish] sending all processes the KILL signal.
[s6-finish] syncing disks.

Output for the failed Test 2: receives INT signal (CTRL^C):

# check to see if any instances of 'tail -f' are running
$ ps -aux | grep -v grep | grep 'tail -f'

$ # check for running instances of 's6test' container
$ docker ps --no-trunc | grep s6test

$ # build
$ docker build --rm --tag=dreamcat4/s6test .
Sending build context to Docker daemon 10.33 MB
Sending build context to Docker daemon 
Step 0 : FROM busybox
 ---> 4986bf8c1536
Step 1 : ADD https://github.com/glerchundi/container-s6-overlay-builder/releases/download/v0.1.0/s6-overlay-0.1.0-linux-amd64.tar.gz /s6-overlay.tar.gz
Downloading [==================================================>] 2.458 MB/2.458 MB
 ---> Using cache
 ---> b432cd6299d0
Step 2 : RUN gunzip -c /s6-overlay.tar.gz | tar -xvf - -C / && rm /s6-overlay.tar.gz
 ---> Using cache
 ---> 2107900c12c3
Step 3 : COPY myprogram.sh /myprogram.sh
 ---> Using cache
 ---> 0644fcd7704f
Step 4 : ENTRYPOINT /init /myprogram.sh
 ---> Using cache
 ---> a7495548761d
Step 5 : CMD arg1 arg2 arg3
 ---> Using cache
 ---> 9b93f0bdb1d9
Successfully built 9b93f0bdb1d9
$ docker rm --force s6test
s6test

$ # run
$ docker run --tty --name s6test dreamcat4/s6test
[fix-attrs] fixing file attributes (ownership & permission)...
[fix-attrs] /etc/fix-attrs.d/00-base: applying...
[fix-attrs] /etc/fix-attrs.d/00-base: done.
[fix-attrs] done.
===
 have started: /myprogram.sh
    with args: arg1 arg2 arg3
===
 running: tail -f /dev/null | while read line ...
 the 'tail -f /dev/null' created above ^^ is an orphaned process

^C$ # break with CTRL^C
$ # check again to see if 'tail -f' (the orphan) was reaped ?
$ ps -aux | grep -v grep | grep 'tail -f'
root     10340  0.0  0.0   3164   188 pts/3    S+   12:32   0:00 tail -f /dev/null

$ # check to see if 's6test' container is still listed as running ?
$ docker ps --no-trunc | grep s6test
40deb59b790e9a0f3628248b5f04981954866982194c25491319840f12211e8b   dreamcat4/s6test:latest     "/init /myprogram.sh arg1 arg2 arg3"                                                                                 26 seconds ago      Up 26 seconds                           s6test              

$ # clean up (kill) all 'tail' program
$ sudo killall -9 tail

@glerchundi
Copy link
Member

i need to take my time to do this, i'll do it when Laurent finishes his job with init-stage{1,2,3}

@dreamcat4
Copy link
Author

Great. Perhaps Laurent will see and fix it already as a matter of course when he goes though everything in the stages1,2,3. OK.

I just take a shot to try and explain why it might be doing that in the initial 0.1.0* release code. Here is my guess:

The argv of init are passed in to stage 2, and are launched as foreground { $@ } s6….. So perhaps the { $@ } that come before s6 launched, that process is not being monitored by s6-scan. No scan directory of it or stop script / etc. So when the first foreground program stop of it's own volition (it exits by itself). Then that foreground task just exit. And no s6 stop or anything like that is triggered to the overall stop script.

Wheras if the persistent pid 1 process (s6-whatever) receives a TERM. Then that does get to shut down the whole s6 process supervisor, and in turn finish by calling the reaping stop script. Which is when the myprogram.sh (launched from init's argv) and it's orphan(s) tail -f get terminated. All of them / everything.

@jprjr
Copy link
Member

jprjr commented Mar 2, 2015

If it helps, I made up a quick script for testing all this out.

https://jrjrtech.com/s6-test-auto.tar.gz

It builds a basic image and tries out different cases, like sending a SIGINT, using docker stop etc

@glerchundi
Copy link
Member

@jprjr @dreamcat4 can u test the new overlay (i published v1.7.0) if this solves the issue? it should because it includes the new init process/script which is far better than mine :-)

@glerchundi
Copy link
Member

@dreamcat4 although there is an issue with busybox:ubuntu-14.04 (#15) can u test this against busybox:latest and see if it is solved already?

@dreamcat4
Copy link
Author

@glerchundi Yeah sorry I haven't got around to re-test this before seeing those other things. But don't worry - I consider this an important issue too and will be testing it as soon as I can (e,g, later today).

@dreamcat4
Copy link
Author

To re-test this probelm, I had to switch over to using FROM ubuntu-debootstrap:14.04 instead of busybox. This issue seems to be resolved with v1.7.1. It cleans up after itself from CTRL^C sigint. And likely all other voluntary program exit.

$ docker run -it --name s6test dreamcat4/s6test
===
 have started: /myprogram.sh
    with args: arg1 arg2 arg3
===
 running: tail -f /dev/null | while read line ...
 the 'tail -f /dev/null' created above ^^ is an orphaned process

^C
trap: received SIGINT ('INT')
exiting...
/myprogram.sh exited 0. Stopping the supervision tree.
$  ps -aux | grep -v grep | grep 'tail -f'
$ docker ps
CONTAINER ID        IMAGE                                 COMMAND                CREATED             STATUS              PORTS               NAMES
$ 

... guess you can close this issue too now.

@glerchundi
Copy link
Member

great!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants