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
23 def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
24 super(Daemon, self).__init__()
28 self.pidfile = pidfile
32 do the UNIX double-fork magic, see Stevens' "Advanced
33 Programming in the UNIX Environment" for details (ISBN 0201563177)
34 http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16
41 LOG.error("fork #1 failed: %(errno)s, %(strerror)s",
42 {'errno':e.errno, 'strerror': e.strerror})
45 # decouple from parent environment
54 # exit from second parent
57 LOG.error("fork #1 failed: %(errno)s, %(strerror)s",
58 {'errno':e.errno, 'strerror': e.strerror})
61 # redirect standard file descriptors
64 si = file(self.stdin, 'r')
65 so = file(self.stdout, 'a+')
66 se = file(self.stderr, 'a+', 0)
67 os.dup2(si.fileno(), sys.stdin.fileno())
68 os.dup2(so.fileno(), sys.stdout.fileno())
69 os.dup2(se.fileno(), sys.stderr.fileno())
72 atexit.register(self.delpid)
73 pid = str(os.getpid())
74 file(self.pidfile,'w+').write("%s\n" % pid)
77 os.remove(self.pidfile)
84 # Check for a pidfile to see if the daemon already runs
86 pf = file(self.pidfile,'r')
87 pid = int(pf.read().strip())
93 message = "pidfile %s already exist. Daemon already running?\n"
94 sys.stderr.write(message % self.pidfile)
96 LOG.info("daemon start to run daemonize")
105 # Get the pid from the pidfile
107 pf = file(self.pidfile,'r')
108 pid = int(pf.read().strip())
114 message = "pidfile %s does not exist. Daemon not running?\n"
115 sys.stderr.write(message % self.pidfile)
116 return # not an error in a restart
118 # Try killing the daemon process
121 os.kill(pid, SIGTERM)
125 if err.find("No such process") > 0:
126 if os.path.exists(self.pidfile):
127 os.remove(self.pidfile)
141 You should override this method when you subclass Daemon.
142 It will be called after the process has been
143 daemonized by start() or restart().
148 def daemon_die(self):
149 """You should this method when you shutdown daemon
150 this func will be call by stop() before kill the process