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 ##############################################################################
15 from signal import SIGTERM
17 LOG = logging.getLogger(__name__)
22 A generic daemon class.
24 Usage: subclass the Daemon class and override the run() method
33 super(Daemon, self).__init__()
37 self.pidfile = pidfile
41 do the UNIX double-fork magic, see Stevens' "Advanced
42 Programming in the UNIX Environment" for details (ISBN 0201563177)
43 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
50 LOG.error("fork #1 failed: %(errno)s, %(strerror)s",
51 {'errno': e.errno, 'strerror': e.strerror})
54 # decouple from parent environment
63 # exit from second parent
66 LOG.error("fork #1 failed: %(errno)s, %(strerror)s",
67 {'errno': e.errno, 'strerror': e.strerror})
70 # redirect standard file descriptors
73 si = file(self.stdin, 'r')
74 so = file(self.stdout, 'a+')
75 se = file(self.stderr, 'a+', 0)
76 os.dup2(si.fileno(), sys.stdin.fileno())
77 os.dup2(so.fileno(), sys.stdout.fileno())
78 os.dup2(se.fileno(), sys.stderr.fileno())
81 atexit.register(self.delpid)
82 pid = str(os.getpid())
83 file(self.pidfile, 'w+').write("%s\n" % pid)
86 os.remove(self.pidfile)
93 # Check for a pidfile to see if the daemon already runs
95 pf = file(self.pidfile, 'r')
96 pid = int(pf.read().strip())
102 message = "pidfile %s already exist. Daemon already running?\n"
103 sys.stderr.write(message % self.pidfile)
105 LOG.info("daemon start to run daemonize")
114 # Get the pid from the pidfile
116 pf = file(self.pidfile, 'r')
117 pid = int(pf.read().strip())
123 message = "pidfile %s does not exist. Daemon not running?\n"
124 sys.stderr.write(message % self.pidfile)
125 return # not an error in a restart
127 # Try killing the daemon process
130 os.kill(pid, SIGTERM)
132 except OSError as err:
134 if err.find("No such process") > 0:
135 if os.path.exists(self.pidfile):
136 os.remove(self.pidfile)
150 You should override this method when you subclass Daemon.
151 It will be called after the process has been
152 daemonized by start() or restart().
157 def daemon_die(self):
158 """You should override this method when you shutdown daemon
159 this func will be call by stop() before kill the process