From 4b70e68144a4948e184c8bf4652bb2ba0382a2af Mon Sep 17 00:00:00 2001 From: Ryan Moe Date: Fri, 2 May 2014 13:08:45 -0700 Subject: [PATCH] Make pid file locking non-blocking fcntl.flock will block indefinitely if another process holds an exclusive lock. A non-blocking flock operation will raise an error when a lock already exists so we can fail immediately. Closes-bug: 1315507 Change-Id: Icf97b1f8643157719b3d28ac2c0c1576a5069697 --- neutron/agent/linux/daemon.py | 13 ++++++------- neutron/tests/unit/test_linux_daemon.py | 5 +++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/neutron/agent/linux/daemon.py b/neutron/agent/linux/daemon.py index 38c1bb5db9..59bcd8eb0c 100644 --- a/neutron/agent/linux/daemon.py +++ b/neutron/agent/linux/daemon.py @@ -29,16 +29,15 @@ LOG = logging.getLogger(__name__) class Pidfile(object): def __init__(self, pidfile, procname, uuid=None): - try: - self.fd = os.open(pidfile, os.O_CREAT | os.O_RDWR) - except IOError: - LOG.exception(_("Failed to open pidfile: %s"), pidfile) - sys.exit(1) self.pidfile = pidfile self.procname = procname self.uuid = uuid - if not not fcntl.flock(self.fd, fcntl.LOCK_EX): - raise IOError(_('Unable to lock pid file')) + try: + self.fd = os.open(pidfile, os.O_CREAT | os.O_RDWR) + fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) + except IOError: + LOG.exception(_("Error while handling pidfile: %s"), pidfile) + sys.exit(1) def __str__(self): return self.pidfile diff --git a/neutron/tests/unit/test_linux_daemon.py b/neutron/tests/unit/test_linux_daemon.py index 12e7d9f351..ab65a2bb29 100644 --- a/neutron/tests/unit/test_linux_daemon.py +++ b/neutron/tests/unit/test_linux_daemon.py @@ -44,7 +44,8 @@ class TestPidfile(base.BaseTestCase): daemon.Pidfile('thefile', 'python') self.os.open.assert_called_once_with('thefile', os.O_CREAT | os.O_RDWR) - self.fcntl.flock.assert_called_once_with(FAKE_FD, self.fcntl.LOCK_EX) + self.fcntl.flock.assert_called_once_with(FAKE_FD, self.fcntl.LOCK_EX | + self.fcntl.LOCK_NB) def test_init_open_fail(self): self.os.open.side_effect = IOError @@ -61,7 +62,7 @@ class TestPidfile(base.BaseTestCase): p = daemon.Pidfile('thefile', 'python') p.unlock() self.fcntl.flock.assert_has_calls([ - mock.call(FAKE_FD, self.fcntl.LOCK_EX), + mock.call(FAKE_FD, self.fcntl.LOCK_EX | self.fcntl.LOCK_NB), mock.call(FAKE_FD, self.fcntl.LOCK_UN)] )