diff options
author | Csaba Henk <csaba@gluster.com> | 2011-04-02 19:40:48 +0000 |
---|---|---|
committer | Vijay Bellur <vijay@dev.gluster.com> | 2011-04-04 08:02:22 -0700 |
commit | e77c35248e8ce796bc5b108c10013089a0c65bde (patch) | |
tree | 10e7eda370a3bb9c35ed3f965e84c2063ca47195 /xlators/features/marker/utils/syncdaemon/syncdutils.py | |
parent | cfb9c834f96dc57c47dac8d27da4266d0dab1f3f (diff) |
syncdaemon: provide transactional semantics to config file writing
So updating the config file from multiple contexts won't mess it up.
This prepares the next commit where we'll set options internaly (which lacks
the serial nature of user actions).
Signed-off-by: Csaba Henk <csaba@gluster.com>
Signed-off-by: Vijay Bellur <vijay@dev.gluster.com>
BUG: 2537 (gsync autorestart)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=2537
Diffstat (limited to 'xlators/features/marker/utils/syncdaemon/syncdutils.py')
-rw-r--r-- | xlators/features/marker/utils/syncdaemon/syncdutils.py | 31 |
1 files changed, 31 insertions, 0 deletions
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() |