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)
|
sleep(1)
|
||||||
|
|
||||||
def daemonize(self):
|
def daemonize(self):
|
||||||
|
grandfatherPid = os.getpid()
|
||||||
|
parentPid = None
|
||||||
try:
|
try:
|
||||||
if os.fork():
|
if os.fork():
|
||||||
|
# unlock
|
||||||
|
shared.thisapp.cleanup()
|
||||||
|
# wait until grandchild ready
|
||||||
|
while True:
|
||||||
|
sleep(1)
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# fork not implemented
|
# fork not implemented
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
parentPid = os.getpid()
|
||||||
shared.thisapp.lock() # relock
|
shared.thisapp.lock() # relock
|
||||||
os.umask(0)
|
os.umask(0)
|
||||||
try:
|
try:
|
||||||
|
@ -358,12 +366,17 @@ class Main:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
if os.fork():
|
if os.fork():
|
||||||
|
# unlock
|
||||||
|
shared.thisapp.cleanup()
|
||||||
|
# wait until child ready
|
||||||
|
while True:
|
||||||
|
sleep(1)
|
||||||
os._exit(0)
|
os._exit(0)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# fork not implemented
|
# fork not implemented
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
shared.thisapp.lock(True) # relock and write pid
|
shared.thisapp.lock() # relock
|
||||||
shared.thisapp.lockPid = None # indicate we're the final child
|
shared.thisapp.lockPid = None # indicate we're the final child
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
@ -374,6 +387,10 @@ class Main:
|
||||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||||
os.dup2(se.fileno(), sys.stderr.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):
|
def setSignalHandler(self):
|
||||||
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
signal.signal(signal.SIGINT, helper_generic.signal_handler)
|
||||||
|
|
|
@ -51,7 +51,7 @@ def signal_handler(signal, frame):
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
if "PoolWorker" in current_process().name:
|
if "PoolWorker" in current_process().name:
|
||||||
raise SystemExit
|
raise SystemExit
|
||||||
if current_thread().name != "PyBitmessage":
|
if current_thread().name not in ("PyBitmessage", "MainThread"):
|
||||||
return
|
return
|
||||||
logger.error("Got signal %i", signal)
|
logger.error("Got signal %i", signal)
|
||||||
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon'):
|
if BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon'):
|
||||||
|
|
|
@ -36,7 +36,7 @@ class singleinstance:
|
||||||
self.initialized = True
|
self.initialized = True
|
||||||
atexit.register(self.cleanup)
|
atexit.register(self.cleanup)
|
||||||
|
|
||||||
def lock(self, writePid = False):
|
def lock(self):
|
||||||
if self.lockPid is None:
|
if self.lockPid is None:
|
||||||
self.lockPid = os.getpid()
|
self.lockPid = os.getpid()
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
@ -68,16 +68,24 @@ class singleinstance:
|
||||||
sys.exit(-1)
|
sys.exit(-1)
|
||||||
else:
|
else:
|
||||||
pidLine = "%i\n" % self.lockPid
|
pidLine = "%i\n" % self.lockPid
|
||||||
if writePid:
|
self.fp.truncate(0)
|
||||||
self.fp.truncate(0)
|
self.fp.write(pidLine)
|
||||||
self.fp.write(pidLine)
|
self.fp.flush()
|
||||||
self.fp.flush()
|
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
if not self.initialized:
|
if not self.initialized:
|
||||||
return
|
return
|
||||||
if self.daemon and self.lockPid == os.getpid():
|
if self.daemon and self.lockPid == os.getpid():
|
||||||
# these are the two initial forks while daemonizing
|
# 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
|
return
|
||||||
print "Cleaning up lockfile"
|
print "Cleaning up lockfile"
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user