1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
10 import sys, os, time, atexit
12 from signal import SIGTERM
14 LOG = logging.getLogger(__name__)
19 A generic daemon class.
21 Usage: subclass the Daemon class and override the run() method
24 def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
25 super(Daemon, self).__init__()
29 self.pidfile = pidfile
33 do the UNIX double-fork magic, see Stevens' "Advanced
34 Programming in the UNIX Environment" for details (ISBN 0201563177)
35 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
42 LOG.error("fork #1 failed: %(errno)s, %(strerror)s",
43 {'errno': e.errno, 'strerror': e.strerror})
46 # decouple from parent environment
55 # exit from second parent
58 LOG.error("fork #1 failed: %(errno)s, %(strerror)s",
59 {'errno': e.errno, 'strerror': e.strerror})
62 # redirect standard file descriptors
65 si = file(self.stdin, 'r')
66 so = file(self.stdout, 'a+')
67 se = file(self.stderr, 'a+', 0)
68 os.dup2(si.fileno(), sys.stdin.fileno())
69 os.dup2(so.fileno(), sys.stdout.fileno())
70 os.dup2(se.fileno(), sys.stderr.fileno())
73 atexit.register(self.delpid)
74 pid = str(os.getpid())
75 file(self.pidfile, 'w+').write("%s\n" % pid)
78 os.remove(self.pidfile)
85 # Check for a pidfile to see if the daemon already runs
87 pf = file(self.pidfile, 'r')
88 pid = int(pf.read().strip())
94 message = "pidfile %s already exist. Daemon already running?\n"
95 sys.stderr.write(message % self.pidfile)
97 LOG.info("daemon start to run daemonize")
106 # Get the pid from the pidfile
108 pf = file(self.pidfile, 'r')
109 pid = int(pf.read().strip())
115 message = "pidfile %s does not exist. Daemon not running?\n"
116 sys.stderr.write(message % self.pidfile)
117 return # not an error in a restart
119 # Try killing the daemon process
122 os.kill(pid, SIGTERM)
126 if err.find("No such process") > 0:
127 if os.path.exists(self.pidfile):
128 os.remove(self.pidfile)
142 You should override this method when you subclass Daemon.
143 It will be called after the process has been
144 daemonized by start() or restart().
149 def daemon_die(self):
150 """You should override this method when you shutdown daemon
151 this func will be call by stop() before kill the process