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