[svn] commit: r2091 - in /trunk: ChangeLog src/bin/xfrout/tests/xfrout_test.py src/bin/xfrout/xfrout.py.in

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Jun 8 11:41:54 UTC 2010


Author: zhanglikun
Date: Tue Jun  8 11:41:54 2010
New Revision: 2091

Log:
When xfrout is launched, check whether the socket file is being used by one running xfrout process, if it is, exit from python. If the file isn't a socket file or nobody is listening, it will be removed. If it can't be removed, exit from python.

Modified:
    trunk/ChangeLog
    trunk/src/bin/xfrout/tests/xfrout_test.py
    trunk/src/bin/xfrout/xfrout.py.in

Modified: trunk/ChangeLog
==============================================================================
--- trunk/ChangeLog (original)
+++ trunk/ChangeLog Tue Jun  8 11:41:54 2010
@@ -1,3 +1,11 @@
+  52.   [func]      zhanglikun
+	bin/xfrout: When xfrout is launched, check whether the
+	socket file is being used by one running xfrout process, 
+	if it is, exit from python.	If the file isn't a socket file 
+	or nobody is listening, it will be removed. If it can't 
+	be removed, exit from python.
+	(Trac #151, svn r2084)
+
 bind10-devel-20100602 released on June 2, 2010
 
   51.   [build]         jelte

Modified: trunk/src/bin/xfrout/tests/xfrout_test.py
==============================================================================
--- trunk/src/bin/xfrout/tests/xfrout_test.py (original)
+++ trunk/src/bin/xfrout/tests/xfrout_test.py Tue Jun  8 11:41:54 2010
@@ -278,6 +278,70 @@
         self.unix.decrease_transfers_counter()
         self.assertEqual(count - 1, self.unix._transfers_counter)
 
+    def _remove_file(self, sock_file):
+        try:
+            os.remove(sock_file)
+        except OSError:
+            pass
+ 
+    def test_sock_file_in_use_file_exist(self):
+        sock_file = 'temp.sock.file'
+        self._remove_file(sock_file)
+        self.assertFalse(self.unix._sock_file_in_use(sock_file))
+        self.assertFalse(os.path.exists(sock_file))
+
+    def test_sock_file_in_use_file_not_exist(self):
+        self.assertFalse(self.unix._sock_file_in_use('temp.sock.file'))
+
+    def _start_unix_sock_server(self, sock_file):
+        serv = ThreadingUnixStreamServer(sock_file, BaseRequestHandler)
+        serv_thread = threading.Thread(target=serv.serve_forever)
+        serv_thread.setDaemon(True)
+        serv_thread.start()
+
+    def test_sock_file_in_use(self):
+        sock_file = 'temp.sock.file'
+        self._remove_file(sock_file)
+        self.assertFalse(self.unix._sock_file_in_use(sock_file))
+        self._start_unix_sock_server(sock_file)
+
+        old_stdout = sys.stdout
+        sys.stdout = open(os.devnull, 'w')
+        self.assertTrue(self.unix._sock_file_in_use(sock_file))
+        sys.stdout = old_stdout
+
+    def test_remove_unused_sock_file_in_use(self):
+        sock_file = 'temp.sock.file'
+        self._remove_file(sock_file)
+        self.assertFalse(self.unix._sock_file_in_use(sock_file))
+        self._start_unix_sock_server(sock_file)
+        old_stdout = sys.stdout
+        sys.stdout = open(os.devnull, 'w')
+        try:
+            self.unix._remove_unused_sock_file(sock_file)
+        except SystemExit:
+            pass
+        else:
+            # This should never happen
+            self.assertTrue(False)
+
+        sys.stdout = old_stdout
+
+    def test_remove_unused_sock_file_dir(self):
+        import tempfile
+        dir_name = tempfile.mkdtemp()
+        old_stdout = sys.stdout
+        sys.stdout = open(os.devnull, 'w')
+        try:
+            self.unix._remove_unused_sock_file(dir_name)
+        except SystemExit:
+            pass
+        else:
+            # This should never happen
+            self.assertTrue(False)
+
+        sys.stdout = old_stdout
+        os.rmdir(dir_name)
 
 if __name__== "__main__":
     unittest.main()

Modified: trunk/src/bin/xfrout/xfrout.py.in
==============================================================================
--- trunk/src/bin/xfrout/xfrout.py.in (original)
+++ trunk/src/bin/xfrout/xfrout.py.in Tue Jun  8 11:41:54 2010
@@ -28,6 +28,7 @@
 from isc.config.ccsession import *
 from isc.cc import SessionError
 import socket
+import errno
 from optparse import OptionParser, OptionValueError
 try:
     from bind10_xfr import *
@@ -57,7 +58,13 @@
     def handle(self):
         fd = recv_fd(self.request.fileno())
         if fd < 0:
-            raise XfroutException("failed to receive the FD for XFR connection")
+            # This may happen when one xfrout process try to connect to
+            # xfrout unix socket server, to check whether there is another
+            # xfrout running. 
+            print("[b10-xfrout] Failed to receive the FD for XFR connection, "
+                  "maybe because another xfrout process was started.")
+            return
+
         data_len = self.request.recv(2)
         msg_len = struct.unpack('!H', data_len)[0]
         msgdata = self.request.recv(msg_len)
@@ -277,18 +284,44 @@
     '''The unix domain socket server which accept xfr query sent from auth server.'''
 
     def __init__(self, sock_file, handle_class, shutdown_event, config_data):
-        try:
-            os.unlink(sock_file)
-        except:
-            pass
- 
+        self._remove_unused_sock_file(sock_file)
         self._sock_file = sock_file
         ThreadingUnixStreamServer.__init__(self, sock_file, handle_class)
         self._lock = threading.Lock()
         self._transfers_counter = 0
         self._shutdown_event = shutdown_event
         self.update_config_data(config_data)
-    
+
+    def _remove_unused_sock_file(self, sock_file):
+        '''Try to remove the socket file. If the file is being used 
+        by one running xfrout process, exit from python. 
+        If it's not a socket file or nobody is listening
+        , it will be removed. If it can't be removed, exit from python. '''
+        if self._sock_file_in_use(sock_file):
+            print("[b10-xfrout] Fail to start xfrout process, unix socket" 
+                  " file '%s' is being used by another xfrout process" % sock_file)
+            sys.exit(0)
+        else:
+            if not os.path.exists(sock_file):
+                return
+
+            try:
+                os.unlink(sock_file)
+            except OSError as err:
+                print('[b10-xfrout] Fail to remove file ' + sock_file, err)
+                sys.exit(0)
+   
+    def _sock_file_in_use(self, sock_file):
+        '''Check whether the socket file 'sock_file' exists and 
+        is being used by one running xfrout process. If it is, 
+        return True, or else return False. '''
+        try:
+            sock = socket.socket(socket.AF_UNIX)
+            sock.connect(sock_file)
+        except socket.error as err:
+            return False
+        else:
+            return True 
 
     def shutdown(self):
         ThreadingUnixStreamServer.shutdown(self)




More information about the bind10-changes mailing list