Browse Source

[433] Check to make sure msqg isnt already running.

Check to ensure there is no existing daemon running before removing
the socket endpoint. Fail to start if one is. Added a new test to
check this behaviour.
Kean Johnston 11 years ago
parent
commit
9cb427b494
3 changed files with 33 additions and 2 deletions
  1. 21 2
      src/bin/msgq/msgq.py.in
  2. 4 0
      src/bin/msgq/msgq_messages.mes
  3. 8 0
      src/bin/msgq/tests/msgq_run_test.py

+ 21 - 2
src/bin/msgq/msgq.py.in

@@ -74,6 +74,8 @@ SPECFILE_LOCATION = SPECFILE_PATH + "/msgq.spec"
 
 
 class MsgQReceiveError(Exception): pass
 class MsgQReceiveError(Exception): pass
 
 
+class MsgQRunningError(Exception): pass
+
 class MsgQCloseOnReceive(Exception):
 class MsgQCloseOnReceive(Exception):
     """Exception raised when reading data from a socket results in 'shutdown'.
     """Exception raised when reading data from a socket results in 'shutdown'.
 
 
@@ -268,11 +270,28 @@ class MsgQ:
         """Set up the listener socket.  Internal function."""
         """Set up the listener socket.  Internal function."""
         logger.debug(TRACE_BASIC, MSGQ_LISTENER_SETUP, self.socket_file)
         logger.debug(TRACE_BASIC, MSGQ_LISTENER_SETUP, self.socket_file)
 
 
-        self.listen_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-
         if os.path.exists(self.socket_file):
         if os.path.exists(self.socket_file):
+            # Rather than just blindly removing the socket file, attempt to
+            # connect to the existing socket to see if there is an existing
+            # msgq running. Only if that fails do we remove the file and
+            # attempt to create a new socket.
+            self._existing = True
+            try:
+                self._session = isc.cc.Session(self.socket_file)
+            except isc.cc.session.SessionError:
+                self._existing = False
+
+            self._session.close()
+            self._session = None
+
+            if self._existing:
+                logger.fatal(MSGQ_ALREADY_RUNNING)
+                raise MsgQRunningError("Message Queue daemon already running")
+
             os.remove(self.socket_file)
             os.remove(self.socket_file)
+
         try:
         try:
+            self.listen_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.listen_socket.bind(self.socket_file)
             self.listen_socket.bind(self.socket_file)
             self.listen_socket.listen(1024)
             self.listen_socket.listen(1024)
         except Exception as e:
         except Exception as e:

+ 4 - 0
src/bin/msgq/msgq_messages.mes

@@ -19,6 +19,10 @@
 # <topsrcdir>/tools/reorder_message_file.py to make sure the
 # <topsrcdir>/tools/reorder_message_file.py to make sure the
 # messages are in the correct order.
 # messages are in the correct order.
 
 
+% MSGQ_ALREADY_RUNNING Another copy of the message queue daemon is already running.
+Only a single instance of the message queue daemon should ever be run at one
+time. This instance will now terminate.
+
 % MSGQ_CFGMGR_SUBSCRIBED The config manager subscribed to message queue
 % MSGQ_CFGMGR_SUBSCRIBED The config manager subscribed to message queue
 This is a debug message. The message queue has little bit of special handling
 This is a debug message. The message queue has little bit of special handling
 for the configuration manager. This special handling is happening now.
 for the configuration manager. This special handling is happening now.

+ 8 - 0
src/bin/msgq/tests/msgq_run_test.py

@@ -328,6 +328,14 @@ class MsgqRunTest(unittest.TestCase):
             'group': 'notifications/cc_members'
             'group': 'notifications/cc_members'
         }]}, msg)
         }]}, msg)
 
 
+    def test_multiple_invocations(self):
+        """
+        Check to make sure that an attempt to start a second copy of the MsgQ
+        daemon fails.
+        """
+        self.__retcode = subprocess.call([MSGQ_PATH, '-s', SOCKET_PATH])
+        self.assertNotEqual(self.__retcode, 0)
+
 if __name__ == '__main__':
 if __name__ == '__main__':
     isc.log.init("msgq-tests")
     isc.log.init("msgq-tests")
     isc.log.resetUnitTestRootLogger()
     isc.log.resetUnitTestRootLogger()