Antoni Segura Puimedon has uploaded a new change for review.
Change subject: Added utility to ensure that files written to the file system happen atomically. ......................................................................
Added utility to ensure that files written to the file system happen atomically.
The only way in python to make a file be written in an atomic way is to take advantage of the fact that in POSIX filesystems the rename operation is atomic. Thus, we write the context to a temporary file on the same filesystem, sync on the file descriptor and finally do the atomic file rename to the original file we wanted to write.
For more info: http://stackoverflow.com/questions/2333872/atomic-writing-to-file-with-pytho... http://stackoverflow.com/questions/7433057/is-rename-without-fsync-safe
Change-Id: Ibecd61d6746231a5a8cb17bad9a3302b01454f27 Signed-off-by: Antoni S. Puimedon asegurap@redhat.com --- M vdsm/configNetwork.py M vdsm/utils.py 2 files changed, 17 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/56/7656/1
diff --git a/vdsm/configNetwork.py b/vdsm/configNetwork.py index 58117f8..b943574 100755 --- a/vdsm/configNetwork.py +++ b/vdsm/configNetwork.py @@ -369,7 +369,8 @@ '''Backs up the previous contents of the file referenced by fileName writes the new configuration and sets the specified access mode.''' self._backup(fileName) - open(fileName, 'w').write(configuration) + with utils.atomicWrite(fileName) as f: + f.write(configuration) os.chmod(fileName, 0664) try: selinux.restorecon(fileName) diff --git a/vdsm/utils.py b/vdsm/utils.py index 5e2d4e5..bb8a842 100644 --- a/vdsm/utils.py +++ b/vdsm/utils.py @@ -36,6 +36,7 @@ import fcntl import functools import stat +from contextlib import contextmanager
import ethtool
@@ -829,3 +830,17 @@
def __unicode__(self): return unicode(self.cmd) + +@contextmanager +def atomicWrite(file): + '''Context manager that makes the write happen to a temporary file and if + and only it is successful, overwrites the original file. It creates the + temporary file in the same directory of the destination file, as rename is + only atomic within the same filesystem.''' + tempFile = file+'vdsm_temp' + f = open(tempFile, 'w') + yield f + f.flush() + os.fsync(f.fileno()) + f.close() + os.rename(tempFile, file)
-- To view, visit http://gerrit.ovirt.org/7656 To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange Gerrit-Change-Id: Ibecd61d6746231a5a8cb17bad9a3302b01454f27 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Antoni Segura Puimedon asegurap@redhat.com