diff options
-rw-r--r-- | xlators/features/marker/utils/syncdaemon/configinterface.py | 31 | ||||
-rw-r--r-- | xlators/features/marker/utils/syncdaemon/syncdutils.py | 31 |
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() |