From 6db5b0b77d0dd8b0f5010a71c769a821881797c5 Mon Sep 17 00:00:00 2001 From: Brian Haley Date: Tue, 7 May 2013 11:06:29 -0400 Subject: [PATCH] Change Daemon class to better match process command lines. 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 | 12 ++++++++---- quantum/agent/metadata/namespace_proxy.py | 3 ++- quantum/tests/unit/test_linux_daemon.py | 24 +++++++++++++++++++++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/quantum/agent/linux/daemon.py b/quantum/agent/linux/daemon.py index cf45fd6f4..07fd0c433 100644 --- a/quantum/agent/linux/daemon.py +++ b/quantum/agent/linux/daemon.py @@ -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: diff --git a/quantum/agent/metadata/namespace_proxy.py b/quantum/agent/metadata/namespace_proxy.py index f6282e8b4..4ab19f1c9 100644 --- a/quantum/agent/metadata/namespace_proxy.py +++ b/quantum/agent/metadata/namespace_proxy.py @@ -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 diff --git a/quantum/tests/unit/test_linux_daemon.py b/quantum/tests/unit/test_linux_daemon.py index d2c7be16f..8df48bc5b 100644 --- a/quantum/tests/unit/test_linux_daemon.py +++ b/quantum/tests/unit/test_linux_daemon.py @@ -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): -- 2.45.2