]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Change Daemon class to better match process command lines.
authorBrian Haley <brian.haley@hp.com>
Tue, 7 May 2013 15:06:29 +0000 (11:06 -0400)
committerBrian Haley <brian.haley@hp.com>
Tue, 7 May 2013 21:04:20 +0000 (17:04 -0400)
Add additional uuid argument Daemon class to help it better
match output from /proc/$id/cmdline to the correct daemon.
If there is a stale pid in the pidfile, and that process has
the same name, then it could match accidentally and not
start the daemon up properly.

Fixes bug 1177416

Change-Id: I1109ca73c539c5e96cbe3dbb55ce68c92013ee10

quantum/agent/linux/daemon.py
quantum/agent/metadata/namespace_proxy.py
quantum/tests/unit/test_linux_daemon.py

index cf45fd6f4c7562667ab98b3541e0ed2b2253b15d..07fd0c4335f71d2cd866b8778b8921633e2c7284 100644 (file)
@@ -28,7 +28,7 @@ LOG = logging.getLogger(__name__)
 
 
 class Pidfile(object):
-    def __init__(self, pidfile, procname, root_helper='sudo'):
+    def __init__(self, pidfile, procname, uuid=None, root_helper='sudo'):
         try:
             self.fd = os.open(pidfile, os.O_CREAT | os.O_RDWR)
         except IOError:
@@ -36,6 +36,7 @@ class Pidfile(object):
             sys.exit(1)
         self.pidfile = pidfile
         self.procname = procname
+        self.uuid = uuid
         self.root_helper = root_helper
         if not not fcntl.flock(self.fd, fcntl.LOCK_EX):
             raise IOError(_('Unable to lock pid file'))
@@ -67,7 +68,9 @@ class Pidfile(object):
 
         cmd = ['cat', '/proc/%s/cmdline' % pid]
         try:
-            return self.procname in utils.execute(cmd, self.root_helper)
+            exec_out = utils.execute(cmd, self.root_helper)
+            return self.procname in exec_out and (not self.uuid or
+                                                  self.uuid in exec_out)
         except RuntimeError:
             return False
 
@@ -78,12 +81,13 @@ class Daemon(object):
     Usage: subclass the Daemon class and override the run() method
     """
     def __init__(self, pidfile, stdin='/dev/null', stdout='/dev/null',
-                 stderr='/dev/null', procname='python', root_helper='sudo'):
+                 stderr='/dev/null', procname='python', uuid=None,
+                 root_helper='sudo'):
         self.stdin = stdin
         self.stdout = stdout
         self.stderr = stderr
         self.procname = procname
-        self.pidfile = Pidfile(pidfile, procname, root_helper)
+        self.pidfile = Pidfile(pidfile, procname, uuid, root_helper)
 
     def _fork(self):
         try:
index f6282e8b4284a207effa2c471a15eff75ab077df..4ab19f1c992a814a2cc369733d95198b6f43eb32 100644 (file)
@@ -131,7 +131,8 @@ class NetworkMetadataProxyHandler(object):
 
 class ProxyDaemon(daemon.Daemon):
     def __init__(self, pidfile, port, network_id=None, router_id=None):
-        super(ProxyDaemon, self).__init__(pidfile)
+        uuid = network_id or router_id
+        super(ProxyDaemon, self).__init__(pidfile, uuid=uuid)
         self.network_id = network_id
         self.router_id = router_id
         self.port = port
index d2c7be16f8da138ef218a177757b75fbe3398604..8df48bc5b1d440d535a401274abda2552d430a7e 100644 (file)
@@ -95,6 +95,30 @@ class TestPidfile(base.BaseTestCase):
             execute.assert_called_once_with(
                 ['cat', '/proc/34/cmdline'], 'sudo')
 
+    def test_is_running_uuid_true(self):
+        with mock.patch('quantum.agent.linux.utils.execute') as execute:
+            execute.return_value = 'python 1234'
+            p = daemon.Pidfile('thefile', 'python', uuid='1234')
+
+            with mock.patch.object(p, 'read') as read:
+                read.return_value = 34
+                self.assertTrue(p.is_running())
+
+            execute.assert_called_once_with(
+                ['cat', '/proc/34/cmdline'], 'sudo')
+
+    def test_is_running_uuid_false(self):
+        with mock.patch('quantum.agent.linux.utils.execute') as execute:
+            execute.return_value = 'python 1234'
+            p = daemon.Pidfile('thefile', 'python', uuid='6789')
+
+            with mock.patch.object(p, 'read') as read:
+                read.return_value = 34
+                self.assertFalse(p.is_running())
+
+            execute.assert_called_once_with(
+                ['cat', '/proc/34/cmdline'], 'sudo')
+
 
 class TestDaemon(base.BaseTestCase):
     def setUp(self):