Properly daemonize the mail_room process

The old invocation only worked by accident because we have a '&'
somewhere in the init script for expediency. When ran from a terminal,
the mail_room daemon process ended up in the session of the terminal.
This commit adds a small wrapper that tries to do the textbook
daemonization steps (double fork, setsid etc.) while also taking
care that the pidfile is written before the 'start' process exits.
This commit is contained in:
Jacob Vosmaer 2015-08-27 16:35:00 +02:00
parent abb5b9f6e5
commit 1081a322f1
2 changed files with 34 additions and 3 deletions

33
bin/daemon_with_pidfile Executable file
View File

@ -0,0 +1,33 @@
#!/usr/bin/env ruby
# daemon_with_pidfile
#
# Daemonize, write a pidfile, and exec the remainder of the command line.
def main(pidfile, cmd)
if middle_pid = Process.fork
# outer process
# Do not exit the outer process before the middle process finishes
Process.waitpid(middle_pid)
exit $?.exitstatus
end
if final_pid = Process.fork
# middle process
open(pidfile, 'w') { |f| f.puts final_pid }
exit
end
# Standard daemon things: become session leader, ignore SIGHUP, close stdin.
Signal.trap("HUP", "IGNORE")
Process.setsid
IO.new(0).close
exec(*cmd)
end
if ARGV.count < 2
abort "Usage: #$0 pidfile command [args...]"
end
pidfile = ARGV.shift
main(pidfile, ARGV)

View File

@ -19,9 +19,7 @@ get_mail_room_pid()
start()
{
bundle exec mail_room -q -c $mail_room_config >> $mail_room_logfile 2>&1 &
PID=$!
echo $PID > $mail_room_pidfile
bin/daemon_with_pidfile $mail_room_pidfile bundle exec mail_room -q -c $mail_room_config >> $mail_room_logfile 2>&1
}
stop()