Module: check_mk
Branch: master
Commit: fcc50323ced6708a9b388e5c09b6f57923c4390f
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=fcc50323ced670…
Author: Lars Michelsen <lm(a)mathias-kettner.de>
Date: Thu Jun 2 10:58:37 2016 +0200
3586 FIX Fixed file locking issues (rare and random errors that settings file could not be
loaded)
---
.werks/3586 | 10 ++++++++++
ChangeLog | 1 +
web/htdocs/config.py | 28 +++++++++++++++-------------
web/htdocs/lib.py | 17 +++++++++++++++--
4 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/.werks/3586 b/.werks/3586
new file mode 100644
index 0000000..0df176d
--- /dev/null
+++ b/.werks/3586
@@ -0,0 +1,10 @@
+Title: Fixed file locking issues (rare and random errors that settings file could not be
loaded)
+Level: 1
+Component: multisite
+Class: fix
+Compatible: compat
+State: unknown
+Version: 1.2.9i1
+Date: 1464857879
+
+
diff --git a/ChangeLog b/ChangeLog
index bb495a6..968ceb0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -331,6 +331,7 @@
* 3537 FIX: PNP/Graph Templates: fixed incorrect scaling of check-mk-ping,
check_mk-active-icmp and check-mk-host-ping...
* 3576 FIX: LDAP: Fixed "Internal error" when using the "Filter
Group" option in an LDAP connection...
* 3627 FIX: fixed double graphs of database size
+ * 3586 FIX: Fixed file locking issues (rare and random errors that settings file
could not be loaded)
WATO:
* 3244 WATO BI Module: swap order of aggregation function and child node
selection...
diff --git a/web/htdocs/config.py b/web/htdocs/config.py
index 205c664..eb1c666 100644
--- a/web/htdocs/config.py
+++ b/web/htdocs/config.py
@@ -453,12 +453,14 @@ def load_user_file(name, deflt, lock = False):
return deflt # No user known at this point of time
path = user_confdir + "/" + name + ".mk"
- try:
- if lock:
- aquire_lock(path)
+ if lock:
+ aquire_lock(path)
+
+ try:
return eval(file(path).read())
except:
+ # TODO: Really "throw user data away" and start over?
return deflt
def save_user_file(name, content, unlock=False, user=None):
@@ -467,19 +469,19 @@ def save_user_file(name, content, unlock=False, user=None):
dirname = config_dir + "/" + user
make_nagios_directory(dirname)
path = dirname + "/" + name + ".mk"
- try:
- write_settings_file(path + ".new", content)
- os.rename(path + ".new", path)
+ try:
+ try:
+ write_settings_file(path + ".new", content)
+ os.rename(path + ".new", path)
+ except Exception, e:
+ if debug:
+ raise
+ raise MKConfigError(_("Cannot save %s options for user
<b>%s</b> into <b>%s</b>: %s") % \
+ (name, user, path, e))
+ finally:
if unlock:
release_lock(path)
- except Exception, e:
- # Error while writing file -> release lock
- release_lock(path)
- if debug:
- raise
- raise MKConfigError(_("Cannot save %s options for user <b>%s</b>
into <b>%s</b>: %s") % \
- (name, user, path, e))
#.
# .--Sites---------------------------------------------------------------.
diff --git a/web/htdocs/lib.py b/web/htdocs/lib.py
index dbb9447..9d1b847 100644
--- a/web/htdocs/lib.py
+++ b/web/htdocs/lib.py
@@ -389,8 +389,21 @@ g_locked_paths = []
def aquire_lock(path):
if path in g_locked_paths:
return # No recursive locking
- fd = os.open(path, os.O_RDONLY)
- fcntl.flock(fd, fcntl.LOCK_EX)
+
+ # Create file for locking if not existant yet
+ fd = os.open(path, os.O_RDONLY | os.O_CREAT)
+
+ # Handle the case where the file has been renamed in the meantime
+ while True:
+ fcntl.flock(fd, fcntl.LOCK_EX)
+ fd_new = os.open(path, os.O_RDONLY | os.O_CREAT)
+ if os.path.sameopenfile(fd, fd_new):
+ os.close(fd_new)
+ break
+ else:
+ os.close(fd)
+ fd = fd_new
+
g_aquired_locks.append((path, fd))
g_locked_paths.append(path)