Class: MCollective::UnixDaemon

Inherits:
Object
  • Object
show all
Defined in:
lib/mcollective/unix_daemon.rb

Class Method Summary collapse

Class Method Details

.daemonizeObject

Daemonize the current process



4
5
6
7
8
9
10
11
12
13
14
15
# File 'lib/mcollective/unix_daemon.rb', line 4

def self.daemonize
  fork do
    Process.setsid
    exit if fork
    Dir.chdir('/tmp')
    STDIN.reopen('/dev/null')
    STDOUT.reopen('/dev/null', 'a')
    STDERR.reopen('/dev/null', 'a')

    yield
  end
end

.daemonize_runner(pid = nil) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/mcollective/unix_daemon.rb', line 17

def self.daemonize_runner(pid=nil)
  raise "The Unix Daemonizer can not be used on the Windows Platform" if Util.windows?

  UnixDaemon.daemonize do
    if pid
      # Clean up stale pidfile if needed
      if File.exist?(pid)
        lock_pid = File.read(pid)
        begin
          lock_pid = Integer(lock_pid)
        rescue ArgumentError, TypeError
          lock_pid = nil
        end

        # If there's no pid in the pidfile, remove it
        if lock_pid.nil?
          File.unlink(pid)
        else
          begin
            # This will raise an error if the process doesn't
            # exist, and do nothing otherwise
            Process.kill(0, lock_pid)
            # If we reach this point then the process is running.
            # We should raise an error rather than continuing on
            # trying to create the PID
            raise "Process is already running with PID #{lock_pid}"
          rescue Errno::ESRCH
            # Errno::ESRCH = no such process
            # PID in pidfile doesn't exist, remove pidfile
            File.unlink(pid)
          end
        end

      end

      # Use exclusive create on the PID to avoid race condition
      # when two mcollectived processes start at the same time
      opt =  File::CREAT | File::EXCL | File::WRONLY
      File.open(pid, opt) {|f| f.print(Process.pid) }
    end

    begin
      runner = Runner.new(nil)
      runner.main_loop
    rescue => e
      Log.warn(e.backtrace)
      Log.warn(e)
    ensure
      File.unlink(pid) if pid && File.exist?(pid)
    end
  end
end