Ansible async and SIGHUP with shell module

Hi all,

I’m trying to understand what happens when a shell command exits in ansible in sync vs. async modes. It seems that in the former case there is a SIGHUP sent and in the latter there isn’t. To test this I created a startup script for a background process that runs forever:

start_run_forever.sh:


#!/usr/bin/bash

strace -o ~/debug-start sh /home/asb_service/run_forever.sh &

echo “Done”


run_forever.sh:


#!/usr/bin/bash

while true

do

echo “here”

sleep 5

done


When I run an ad-hoc command synchronously, the run_forever.sh script starts and then receives a SIGHUP when the terminal exits, as I’d expect.

ansible -vvv {myhost} -i environments/dev -m shell -a “~/start_run_forever.sh” -u {myuser}

strace output:

...
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 
rt_sigaction(SIGINT, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f60b1587400}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f60b158740 0}, 8) = 0 
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f60b1587400}, {sa_handler=0x43e910, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7f60b158740 0}, 8) = 0 
wait4(-1, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGHUP}], 0, NULL) = 22102 
--- SIGHUP {si_signo=SIGHUP, si_code=SI_KERNEL} --- 
+++ killed by SIGHUP +++

but when I run in async mode it never receives the SIGHUP and keeps running, which I would not expect to happen.

ansible -B 10 -P 5 -vvv {myhost} -i environments/dev -m shell -a “~/start_run_forever.sh” -u {myuser}

strace output:

...
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 22395
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=22395, si_uid=2153, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, 0x7ffcd93f6010, WNOHANG, NULL) = -1 ECHILD (No child processes)
rt_sigreturn({mask=[]})                 = 0
rt_sigaction(SIGINT, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fb5e2e1d400}, {sa_handler=SIG_IGN, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fb5e2e1d40\
0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
write(1, "here\n", 5)                   = -1 EPIPE (Broken pipe)
...

I’ve tried this with 2.5.0 and 2.6.4 and the behavior is the same. I know the right way to start a background process is to use “nohup” but developers on our project were relying on this behavior of async to start background processes in production code. At this point I am just curious whether it’s a feature or a bug in ansible because I can’t find any documentation about this.

Thanks,
Sarah