class MCollective::UnixDaemon

Public Class Methods

daemonize() { || ... } click to toggle source

Daemonize the current process

   # File lib/mcollective/unix_daemon.rb
 4 def self.daemonize
 5   fork do
 6     Process.setsid
 7     exit if fork
 8     Dir.chdir('/tmp')
 9     STDIN.reopen('/dev/null')
10     STDOUT.reopen('/dev/null', 'a')
11     STDERR.reopen('/dev/null', 'a')
12 
13     yield
14   end
15 end
daemonize_runner(pid=nil) click to toggle source
   # File lib/mcollective/unix_daemon.rb
17 def self.daemonize_runner(pid=nil)
18   raise "The Unix Daemonizer can not be used on the Windows Platform" if Util.windows?
19 
20   UnixDaemon.daemonize do
21     if pid
22       # Clean up stale pidfile if needed
23       if File.exist?(pid)
24         lock_pid = File.read(pid)
25         begin
26           lock_pid = Integer(lock_pid)
27         rescue ArgumentError, TypeError
28           lock_pid = nil
29         end
30 
31         # If there's no pid in the pidfile, remove it
32         if lock_pid.nil?
33           File.unlink(pid)
34         else
35           begin
36             # This will raise an error if the process doesn't
37             # exist, and do nothing otherwise
38             Process.kill(0, lock_pid)
39             # If we reach this point then the process is running.
40             # We should raise an error rather than continuing on
41             # trying to create the PID
42             raise "Process is already running with PID #{lock_pid}"
43           rescue Errno::ESRCH
44             # Errno::ESRCH = no such process
45             # PID in pidfile doesn't exist, remove pidfile
46             File.unlink(pid)
47           end
48         end
49 
50       end
51 
52       # Use exclusive create on the PID to avoid race condition
53       # when two mcollectived processes start at the same time
54       opt =  File::CREAT | File::EXCL | File::WRONLY
55       File.open(pid, opt) {|f| f.print(Process.pid) }
56     end
57 
58     begin
59       runner = Runner.new(nil)
60       runner.main_loop
61     rescue => e
62       Log.warn(e.backtrace)
63       Log.warn(e)
64     ensure
65       File.unlink(pid) if pid && File.exist?(pid)
66     end
67   end
68 end