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
This commit is contained in:
parent
17336b9cb6
commit
6db5b0b77d
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user