BIND 10 trac642, updated. db92eedf80baf664de114dd04980cea7b8c3f85c Insure that we don't exit due to writing when we are shutting down.
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Apr 20 11:27:55 UTC 2011
The branch, trac642 has been updated
via db92eedf80baf664de114dd04980cea7b8c3f85c (commit)
from 49deb2642865c1db3e65e6066949b6fa8dbcbe26 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit db92eedf80baf664de114dd04980cea7b8c3f85c
Author: Shane Kerr <shane at isc.org>
Date: Wed Apr 20 13:21:44 2011 +0200
Insure that we don't exit due to writing when we are shutting down.
-----------------------------------------------------------------------
Summary of changes:
src/bin/bind10/bind10.py.in | 78 +++++++++++++++++++++++--------
src/bin/bind10/tests/bind10_test.py.in | 28 +++++++++++-
2 files changed, 84 insertions(+), 22 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/bind10/bind10.py.in b/src/bin/bind10/bind10.py.in
index f72f314..59e764b 100755
--- a/src/bin/bind10/bind10.py.in
+++ b/src/bin/bind10/bind10.py.in
@@ -667,10 +667,15 @@ class BoB:
def shutdown(self):
"""Stop the BoB instance."""
+ # Note that we try harder than usual to continue in the face of
+ # errors.
if self.verbose:
- sys.stdout.write("[bind10] Stopping the server.\n")
- # first try using the BIND 10 request to stop
+ try:
+ sys.stdout.write("[bind10] Stopping the server.\n")
+ except:
+ pass
try:
+ # first try using the BIND 10 request to stop
self.stop_all_processes()
except:
pass
@@ -683,10 +688,14 @@ class BoB:
processes_to_stop = list(self.processes.values())
for proc_info in processes_to_stop:
if self.verbose:
- sys.stdout.write("[bind10] Sending SIGTERM to %s (PID %d).\n" %
- (proc_info.name, proc_info.pid))
+ try:
+ sys.stdout.write("[bind10] Sending SIGTERM to %s (PID %d).\n" %
+ (proc_info.name, proc_info.pid))
+ except:
+ pass
try:
- proc_info.process.terminate()
+ if proc_info.process:
+ proc_info.process.terminate()
except OSError:
# ignore these (usually ESRCH because the child
# finally exited)
@@ -699,16 +708,26 @@ class BoB:
processes_to_stop = list(self.processes.values())
for proc_info in processes_to_stop:
if self.verbose:
- sys.stdout.write("[bind10] Sending SIGKILL to %s (PID %d).\n" %
- (proc_info.name, proc_info.pid))
+ try:
+ sys.stdout.write("[bind10] Sending SIGKILL to %s (PID %d).\n" %
+ (proc_info.name, proc_info.pid))
+ except:
+ pass
try:
- proc_info.process.kill()
+ if proc_info.process:
+ proc_info.process.kill()
except OSError:
# ignore these (usually ESRCH because the child
# finally exited)
pass
if self.verbose:
- sys.stdout.write("[bind10] All processes ended, server done.\n")
+ try:
+ sys.stdout.write("[bind10] All processes ended, server done.\n")
+ except:
+ pass
+
+ def wait_on_child(self):
+ return os.waitpid(-1, os.WNOHANG)
def reap_children(self):
"""Check to see if any of our child processes have exited,
@@ -716,7 +735,7 @@ class BoB:
"""
while True:
try:
- (pid, exit_status) = os.waitpid(-1, os.WNOHANG)
+ (pid, exit_status) = self.wait_on_child()
except OSError as o:
if o.errno == errno.ECHILD: break
# XXX: should be impossible to get any other error here
@@ -734,21 +753,36 @@ class BoB:
# elsewhere.
if self.runnable:
if exit_status is None:
- sys.stdout.write(
- "[bind10] Process %s (PID %d) died: exit status not available" %
- (proc_info.name, proc_info.pid))
+ try:
+ sys.stdout.write(
+ "[bind10] Process %s (PID %d) died: exit status not available" %
+ (proc_info.name, proc_info.pid))
+ except:
+ # Error writing - shutdown
+ self.runnable = False
else:
- sys.stdout.write(
- "[bind10] Process %s (PID %d) terminated, exit status = %d\n" %
- (proc_info.name, proc_info.pid, exit_status))
+ try:
+ sys.stdout.write(
+ "[bind10] Process %s (PID %d) terminated, exit status = %d\n" %
+ (proc_info.name, proc_info.pid, exit_status))
+ except:
+ # Error writing - shutdown
+ self.runnable = False
# Was it a special process?
if proc_info.name == "b10-msgq":
- sys.stdout.write(
- "[bind10] The b10-msgq process died, shutting down.\n")
+ try:
+ sys.stdout.write(
+ "[bind10] The b10-msgq process died, shutting down.\n")
+ except:
+ pass
self.runnable = False
else:
- sys.stdout.write("[bind10] Unknown child pid %d exited.\n" % pid)
+ try:
+ sys.stdout.write("[bind10] Unknown child pid %d exited.\n" % pid)
+ except:
+ # Error writing - shutdown
+ self.runnable = False
def restart_processes(self):
"""
@@ -1054,7 +1088,11 @@ def main():
sys.stdout.write("[bind10] BIND 10 started\n")
report_boot_time()
main_loop(wakeup_pipe)
- sys.stdout.write("[bind10] BIND 10 exiting\n");
+ try:
+ sys.stdout.write("[bind10] BIND 10 exiting\n");
+ except:
+ # do not let failure to write cause problems here!
+ pass
shutdown()
if __name__ == "__main__":
diff --git a/src/bin/bind10/tests/bind10_test.py.in b/src/bin/bind10/tests/bind10_test.py.in
index 2178724..63d3f4f 100644
--- a/src/bin/bind10/tests/bind10_test.py.in
+++ b/src/bin/bind10/tests/bind10_test.py.in
@@ -28,6 +28,7 @@ import sys
import os
import signal
import socket
+import errno
from isc.net.addr import IPAddr
from isc.testutils.parse_args import TestOptParser, OptsError
@@ -263,6 +264,13 @@ class MockBob(BoB):
del self.processes[11]
self.cmdctl = False
+ def wait_on_child(self):
+ if self.processes:
+ pid = list(self.processes.keys())[0]
+ return (pid, 0)
+ else:
+ raise OSError(errno.ECHILD, 'No child processes')
+
class TestStartStopProcessesBob(unittest.TestCase):
"""
Check that the start_all_processes method starts the right combination
@@ -669,6 +677,7 @@ class TestTTYDisconnect(unittest.TestCase):
# Here we check what happens if the TTY we are outputting go goes
# away.
def test_tty_disconnect(self):
+ # some setup for the test, putting our test harness in place
self.save_bob_class = bind10.BoB
self.save_stdout = sys.stdout
self.save_stderr = sys.stderr
@@ -676,19 +685,34 @@ class TestTTYDisconnect(unittest.TestCase):
bind10.BoB = MockBob
sys.stdout = open("/dev/null", "w")
self.wakeup_pipe = os.pipe()
+
+ # now set up
bind10.setup(self.wakeup_pipe)
+ # close the output and see what happens
sys.stdout.close()
sys.stderr = open("/dev/null", "w")
bind10.main_loop(self.wakeup_pipe)
+ # restore our file descriptors so we can see if we caused problems
sys.stderr = self.save_stderr
sys.stdout = self.save_stdout
- os.close(self.wakeup_pipe[0])
- os.close(self.wakeup_pipe[1])
+ # make sure we are supposed to stop now
self.assertFalse(bind10.boss_of_bind.runnable)
+ # try our shutdown (turn on verbose to insure failure)
+ sys.stdout = open("/dev/null", "w")
+ sys.stdout.close()
+ bind10.boss_of_bind.verbose = True
+ bind10.shutdown()
+
+ # cleanup
+ sys.stderr = self.save_stderr
+ sys.stdout = self.save_stdout
+ os.close(self.wakeup_pipe[0])
+ os.close(self.wakeup_pipe[1])
+
bind10.BoB = self.save_bob_class
More information about the bind10-changes
mailing list