summaryrefslogtreecommitdiff
path: root/python/ovs/daemon.py
diff options
context:
space:
mode:
authorBen Pfaff <blp@nicira.com>2010-09-23 09:39:47 -0700
committerBen Pfaff <blp@nicira.com>2010-09-23 11:45:34 -0700
commite4bd5e2a6c4223fd9cfb2dd1ad82a4eeb1b1fbe6 (patch)
treea65109dc63a3d51db42f5a1cd8be4ef7275106c4 /python/ovs/daemon.py
parentcbbdf81cf8bfcc87e141f66b93bf3bcf1220bff8 (diff)
downloadopenvswitch-e4bd5e2a6c4223fd9cfb2dd1ad82a4eeb1b1fbe6.tar.gz
daemon: Fix behavior of read_pidfile() for our own pidfile.
Opening a file descriptor and then closing it always discards any locks held on the underlying file, even if the file is still open as another file descriptor. This meant that calling read_pidfile() on the process's own pidfile would discard the lock and make other OVS processes think that the process had died. This commit fixes the problem.
Diffstat (limited to 'python/ovs/daemon.py')
-rw-r--r--python/ovs/daemon.py23
1 files changed, 22 insertions, 1 deletions
diff --git a/python/ovs/daemon.py b/python/ovs/daemon.py
index a8373cfd0..eaaaa519b 100644
--- a/python/ovs/daemon.py
+++ b/python/ovs/daemon.py
@@ -35,6 +35,10 @@ _detach = False
# --pidfile: Name of pidfile (null if none).
_pidfile = None
+# Our pidfile's inode and device, if we have created one.
+_pidfile_dev = None
+_pidfile_ino = None
+
# --overwrite-pidfile: Create pidfile even if one already exists and is locked?
_overwrite_pidfile = False
@@ -163,7 +167,7 @@ def _make_pidfile():
logging.error("%s: create failed: %s"
% (tmpfile, os.strerror(e.errno)))
return
-
+
try:
fcntl.lockf(file, fcntl.LOCK_EX | fcntl.LOCK_NB)
except IOError, e:
@@ -191,6 +195,10 @@ def _make_pidfile():
file.close()
return
+ s = os.fstat(file.fileno())
+ _pidfile_dev = s.st_dev
+ _pidfile_ino = s.st_ino
+
def daemonize():
"""If configured with set_pidfile() or set_detach(), creates the pid file
and detaches from the foreground session."""
@@ -368,6 +376,19 @@ Daemon options:
def read_pidfile(pidfile):
"""Opens and reads a PID from 'pidfile'. Returns the nonnegative PID if
successful, otherwise a negative errno value."""
+ if _pidfile_dev is not None:
+ try:
+ s = os.stat(pidfile)
+ if s.st_ino == _pidfile_ino and s.st_dev == _pidfile_dev:
+ # It's our own pidfile. We can't afford to open it,
+ # because closing *any* fd for a file that a process
+ # has locked also releases all the locks on that file.
+ #
+ # Fortunately, we know the associated pid anyhow.
+ return os.getpid()
+ except OSError:
+ pass
+
try:
file = open(pidfile, "r")
except IOError, e: