Daemonising fixes
- change forking exit order as systemd expects (wait until child is ready, then exit parent, then grandparent) - fix signal handler if prctl not installed - revert recent PID file changes
This commit is contained in:
parent
baba0ae206
commit
d9a4263083
|
@ -342,13 +342,21 @@ class Main:
|
|||
sleep(1)
|
||||
|
||||
def daemonize(self):
|
||||
grandfatherPid = os.getpid()
|
||||
parentPid = None
|
||||
try:
|
||||
if os.fork():
|
||||
# unlock
|
||||
shared.thisapp.cleanup()
|
||||
# wait until grandchild ready
|
||||
while True:
|
||||
sleep(1)
|
||||
os._exit(0)
|
||||
except AttributeError:
|
||||
# fork not implemented
|
||||
pass
|
||||
else:
|
||||
parentPid = os.getpid()
|
||||
shared.thisapp.lock() # relock
|
||||
os.umask(0)
|
||||
try:
|
||||
|
@ -358,12 +366,17 @@ class Main:
|
|||
pass
|
||||
try:
|
||||
if os.fork():
|
||||
# unlock
|
||||
shared.thisapp.cleanup()
|
||||
# wait until child ready
|
||||
while True:
|
||||
sleep(1)
|
||||
os._exit(0)
|
||||
except AttributeError:
|
||||
# fork not implemented
|
||||
pass
|
||||
else:
|
||||
shared.thisapp.lock(True) # relock and write pid
|
||||
shared.thisapp.lock() # relock
|
||||
shared.thisapp.lockPid = None # indicate we're the final child
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
|
@ -374,6 +387,10 @@ class Main:
|
|||
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||
if parentPid:
|
||||
# signal ready
|
||||
os.kill(parentPid, signal.SIGTERM)
|
||||
os.kill(grandfatherPid, signal.SIGTERM)
|
||||
|
||||
def setSignalHandler(self):
|
||||
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
||||
|
|
|
@ -51,7 +51,7 @@ def signal_handler(signal, frame):
|
|||
raise SystemExit
|
||||
if "PoolWorker" in current_process().name:
|
||||
raise SystemExit
|
||||
if current_thread().name != "PyBitmessage":
|
||||
if current_thread().name not in ("PyBitmessage", "MainThread"):
|
||||
return
|
||||
logger.error("Got signal %i", signal)
|
||||
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon'):
|
||||
|
|
|
@ -36,7 +36,7 @@ class singleinstance:
|
|||
self.initialized = True
|
||||
atexit.register(self.cleanup)
|
||||
|
||||
def lock(self, writePid = False):
|
||||
def lock(self):
|
||||
if self.lockPid is None:
|
||||
self.lockPid = os.getpid()
|
||||
if sys.platform == 'win32':
|
||||
|
@ -68,16 +68,24 @@ class singleinstance:
|
|||
sys.exit(-1)
|
||||
else:
|
||||
pidLine = "%i\n" % self.lockPid
|
||||
if writePid:
|
||||
self.fp.truncate(0)
|
||||
self.fp.write(pidLine)
|
||||
self.fp.flush()
|
||||
self.fp.truncate(0)
|
||||
self.fp.write(pidLine)
|
||||
self.fp.flush()
|
||||
|
||||
def cleanup(self):
|
||||
if not self.initialized:
|
||||
return
|
||||
if self.daemon and self.lockPid == os.getpid():
|
||||
# these are the two initial forks while daemonizing
|
||||
try:
|
||||
if sys.platform == 'win32':
|
||||
if hasattr(self, 'fd'):
|
||||
os.close(self.fd)
|
||||
else:
|
||||
fcntl.lockf(self.fp, fcntl.LOCK_UN)
|
||||
except Exception, e:
|
||||
pass
|
||||
|
||||
return
|
||||
print "Cleaning up lockfile"
|
||||
try:
|
||||
|
|
Reference in New Issue
Block a user