summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/features/marker/utils/syncdaemon/configinterface.py31
-rw-r--r--xlators/features/marker/utils/syncdaemon/syncdutils.py31
2 files changed, 49 insertions, 13 deletions
diff --git a/xlators/features/marker/utils/syncdaemon/configinterface.py b/xlators/features/marker/utils/syncdaemon/configinterface.py
index cda7da7ebf3..a1079d80394 100644
--- a/xlators/features/marker/utils/syncdaemon/configinterface.py
+++ b/xlators/features/marker/utils/syncdaemon/configinterface.py
@@ -109,19 +109,19 @@ class GConffile(object):
continue
print("%s: %s" % (k, v))
- def write(self):
- if not self.config.has_section(SECT_META):
- self.config.add_section(SECT_META)
- self.config.set(SECT_META, 'version', config_version)
- f = None
- try:
- f = open(self.path, 'wb')
+ def write(self, trfn, *a, **kw):
+ def mergeconf(f):
+ self.config = ConfigParser.RawConfigParser()
+ self.config.readfp(f)
+ def updateconf(f):
+ if not self.config.has_section(SECT_META):
+ self.config.add_section(SECT_META)
+ self.config.set(SECT_META, 'version', config_version)
+ trfn(*a, **kw)
self.config.write(f)
- finally:
- if f:
- f.close()
+ syncdutils.update_file(self.path, updateconf, mergeconf)
- def set(self, opt, val, rx=False):
+ def _set(self, opt, val, rx=False):
sect = self.section(rx)
if not self.config.has_section(sect):
self.config.add_section(sect)
@@ -130,11 +130,16 @@ class GConffile(object):
self.config.add_section(SECT_ORD)
self.config.set(SECT_ORD, sect, len(self.config._sections[SECT_ORD]))
self.config.set(sect, opt, val)
- self.write()
- def delete(self, opt, rx=False):
+ def set(self, *a, **kw):
+ self.write(self._set, *a, **kw)
+
+ def _delete(self, opt, rx=False):
sect = self.section(rx)
if not self.config.has_section(sect):
return
if self.config.remove_option(sect, opt):
self.write()
+
+ def delete(self, *a, **kw):
+ self.write(self._delete, *a, **kw)
diff --git a/xlators/features/marker/utils/syncdaemon/syncdutils.py b/xlators/features/marker/utils/syncdaemon/syncdutils.py
index 52dad8c5ff3..723ab8fb5fc 100644
--- a/xlators/features/marker/utils/syncdaemon/syncdutils.py
+++ b/xlators/features/marker/utils/syncdaemon/syncdutils.py
@@ -1,3 +1,5 @@
+import os
+import fcntl
try:
# py 3
from urllib import parse as urllib
@@ -9,3 +11,32 @@ def escape(s):
def unescape(s):
return urllib.unquote_plus(s)
+
+def update_file(path, updater, merger = lambda f: True):
+ """update a file in a transaction-like manner"""
+
+ fr = fw = None
+ try:
+ fd = os.open(path, os.O_CREAT|os.O_RDWR)
+ try:
+ fr = os.fdopen(fd, 'r+b')
+ except:
+ os.close(fd)
+ raise
+ fcntl.lockf(fr, fcntl.LOCK_EX)
+ merger(fr)
+
+ tmpp = path + '.tmp.' + str(os.getpid())
+ fd = os.open(tmpp, os.O_CREAT|os.O_EXCL|os.O_WRONLY)
+ try:
+ fw = os.fdopen(fd, 'wb', 0)
+ except:
+ os.close(fd)
+ raise
+ updater(fw)
+ os.fsync(fd)
+ os.rename(tmpp, path)
+ finally:
+ for fx in (fr, fw):
+ if fx:
+ fx.close()