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
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:
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'))
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
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:
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
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):