summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTodd Gamblin <tgamblin@llnl.gov>2017-07-02 17:49:08 -0700
committerTodd Gamblin <tgamblin@llnl.gov>2017-07-04 11:41:37 -0700
commitbd7a591df17c38d6ce9f51e092364a98ed4c1d7b (patch)
tree86cee8ccb827185a827d146ad1f6947814fb8d80 /lib
parent326e2f7f667f81c296de95a39bf72e1cadbe997a (diff)
downloadspack-bd7a591df17c38d6ce9f51e092364a98ed4c1d7b.tar.gz
spack-bd7a591df17c38d6ce9f51e092364a98ed4c1d7b.tar.bz2
spack-bd7a591df17c38d6ce9f51e092364a98ed4c1d7b.tar.xz
spack-bd7a591df17c38d6ce9f51e092364a98ed4c1d7b.zip
Make filesytem more resilient to concurrent updates.
- Uses O_CREAT for touch (for guaranteed atomic open on NFS, multi-node) - Ignore concurrent create errors in mkdirp
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/llnl/util/filesystem.py14
1 files changed, 12 insertions, 2 deletions
diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index 88e000b6d3..7a9fb7b8ac 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -251,7 +251,11 @@ def mkdirp(*paths):
"""Creates a directory, as well as parent directories if needed."""
for path in paths:
if not os.path.exists(path):
- os.makedirs(path)
+ try:
+ os.makedirs(path)
+ except OSError as e:
+ if e.errno != errno.EEXIST or not os.path.isdir(path):
+ raise e
elif not os.path.isdir(path):
raise OSError(errno.EEXIST, "File already exists", path)
@@ -291,8 +295,14 @@ def hide_files(*file_list):
def touch(path):
"""Creates an empty file at the specified path."""
- with open(path, 'a'):
+ perms = (os.O_WRONLY | os.O_CREAT | os.O_NONBLOCK | os.O_NOCTTY)
+ fd = None
+ try:
+ fd = os.open(path, perms)
os.utime(path, None)
+ finally:
+ if fd is not None:
+ os.close(fd)
def touchp(path):