mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-03 23:45:27 +00:00
Refactor the child reaping code to sit in the boss class, so we don't
have to kill processes that respect the shutdown command. git-svn-id: svn://bind10.isc.org/svn/bind10/branches/parkinglot@532 e5f2f494-b856-4b98-b285-d166d9295462
This commit is contained in:
@@ -189,6 +189,7 @@ class BoB:
|
|||||||
pass
|
pass
|
||||||
# XXX: some delay probably useful... how much is uncertain
|
# XXX: some delay probably useful... how much is uncertain
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
self.reap_children()
|
||||||
# next try sending a SIGTERM
|
# next try sending a SIGTERM
|
||||||
processes_to_stop = list(self.processes.values())
|
processes_to_stop = list(self.processes.values())
|
||||||
unstopped_processes = []
|
unstopped_processes = []
|
||||||
@@ -204,10 +205,7 @@ class BoB:
|
|||||||
pass
|
pass
|
||||||
# XXX: some delay probably useful... how much is uncertain
|
# XXX: some delay probably useful... how much is uncertain
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
for proc_info in processes_to_stop:
|
self.reap_children()
|
||||||
(pid, exit_status) = os.waitpid(proc_info.pid, os.WNOHANG)
|
|
||||||
if pid == 0:
|
|
||||||
unstopped_processes.append(proc_info)
|
|
||||||
# finally, send a SIGKILL (unmaskable termination)
|
# finally, send a SIGKILL (unmaskable termination)
|
||||||
processes_to_stop = unstopped_processes
|
processes_to_stop = unstopped_processes
|
||||||
for proc_info in processes_to_stop:
|
for proc_info in processes_to_stop:
|
||||||
@@ -223,17 +221,19 @@ class BoB:
|
|||||||
if self.verbose:
|
if self.verbose:
|
||||||
sys.stdout.write("All processes ended, server done.\n")
|
sys.stdout.write("All processes ended, server done.\n")
|
||||||
|
|
||||||
def reap(self, pid, exit_status):
|
def reap_children(self):
|
||||||
"""The process specified by pid has exited with the value
|
"""Check to see if any of our child processes have exited,
|
||||||
exit_status, so perform any action necessary (cleanup,
|
and note this for later handling.
|
||||||
restart, and so on).
|
|
||||||
|
|
||||||
Returns True if everything is okay, or False if a fatal error
|
|
||||||
has been detected and the program should exit.
|
|
||||||
"""
|
"""
|
||||||
if not pid in self.processes:
|
while True:
|
||||||
sys.stdout.write("Unknown child pid %d exited.\n" % pid)
|
try:
|
||||||
return
|
(pid, exit_status) = os.waitpid(-1, os.WNOHANG)
|
||||||
|
except OSError as o:
|
||||||
|
if o.errno == errno.ECHILD: break
|
||||||
|
# XXX: should be impossible to get any other error here
|
||||||
|
raise
|
||||||
|
if pid == 0: break
|
||||||
|
if pid in self.processes:
|
||||||
proc_info = self.processes.pop(pid)
|
proc_info = self.processes.pop(pid)
|
||||||
self.dead_processes[proc_info.pid] = proc_info
|
self.dead_processes[proc_info.pid] = proc_info
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
@@ -241,8 +241,11 @@ class BoB:
|
|||||||
(proc_info.name, proc_info.pid))
|
(proc_info.name, proc_info.pid))
|
||||||
if proc_info.name == "msgq":
|
if proc_info.name == "msgq":
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
sys.stdout.write("The msgq process died, shutting down.\n")
|
sys.stdout.write(
|
||||||
|
"The msgq process died, shutting down.\n")
|
||||||
self.runnable = False
|
self.runnable = False
|
||||||
|
else:
|
||||||
|
sys.stdout.write("Unknown child pid %d exited.\n" % pid)
|
||||||
|
|
||||||
def recv_and_process_cc_msg(self):
|
def recv_and_process_cc_msg(self):
|
||||||
"""Receive and process the next message on the c-channel,
|
"""Receive and process the next message on the c-channel,
|
||||||
@@ -268,20 +271,14 @@ class BoB:
|
|||||||
if self.verbose:
|
if self.verbose:
|
||||||
sys.stdout.write("Non-list command\n")
|
sys.stdout.write("Non-list command\n")
|
||||||
return
|
return
|
||||||
if len(cmd) < 2:
|
|
||||||
if self.verbose:
|
|
||||||
sys.stdout.write("Command too short\n")
|
|
||||||
return
|
|
||||||
if cmd[0] != "boss":
|
|
||||||
return
|
|
||||||
|
|
||||||
# done checking and extracting... time to execute the command
|
# done checking and extracting... time to execute the command
|
||||||
if cmd[1] == "shutdown":
|
if cmd[0] == "shutdown":
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
sys.stdout.write("shutdown command received\n")
|
sys.stdout.write("shutdown command received\n")
|
||||||
self.runnable = False
|
self.runnable = False
|
||||||
# XXX: reply here?
|
# XXX: reply here?
|
||||||
elif cmd[1] == "getProcessList":
|
elif cmd[0] == "getProcessList":
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
sys.stdout.write("getProcessList command received\n")
|
sys.stdout.write("getProcessList command received\n")
|
||||||
live_processes = [ ]
|
live_processes = [ ]
|
||||||
@@ -420,16 +417,7 @@ def main():
|
|||||||
os.read(wakeup_fd, 32)
|
os.read(wakeup_fd, 32)
|
||||||
|
|
||||||
# clean up any processes that exited
|
# clean up any processes that exited
|
||||||
while True:
|
boss_of_bind.reap_children()
|
||||||
try:
|
|
||||||
(pid, exit_status) = os.waitpid(-1, os.WNOHANG)
|
|
||||||
except OSError as o:
|
|
||||||
if o.errno == errno.ECHILD: break
|
|
||||||
# XXX: should be impossible to get any other error here
|
|
||||||
raise
|
|
||||||
if pid == 0: break
|
|
||||||
boss_of_bind.reap(pid, exit_status)
|
|
||||||
|
|
||||||
boss_of_bind.restart_processes()
|
boss_of_bind.restart_processes()
|
||||||
|
|
||||||
# shutdown
|
# shutdown
|
||||||
|
Reference in New Issue
Block a user