Commit a426508d authored by Michael Hanselmann's avatar Michael Hanselmann

Handle EEXIST in utils.RenameFile

This should fix an issue I've seen exactly once during testing. It might have
been caused by parallel RPC calls to archive jobs.

[…] ganeti-noded:112 ERROR Error in RPC call […]
 File "/usr/lib/python2.4/site-packages/ganeti/backend.py", line 2365, in JobQueueRename
   utils.RenameFile(old, new, mkdir=True)
 File "/usr/lib/python2.4/site-packages/ganeti/utils.py", line 322, in RenameFile
   os.makedirs(os.path.dirname(new), mkdir_mode)
 File "/usr/lib/python2.4/os.py", line 159, in makedirs
   mkdir(name, mode)
OSError: [Errno 17] File exists: '/var/lib/ganeti/queue/archive/0'
Signed-off-by: default avatarMichael Hanselmann <hansmi@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent b6c07b79
......@@ -319,8 +319,17 @@ def RenameFile(old, new, mkdir=False, mkdir_mode=0750):
# as efficient.
if mkdir and err.errno == errno.ENOENT:
# Create directory and try again
os.makedirs(os.path.dirname(new), mkdir_mode)
dirname = os.path.dirname(new)
try:
os.makedirs(dirname, mode=mkdir_mode)
except OSError, err:
# Ignore EEXIST. This is only handled in os.makedirs as included in
# Python 2.5 and above.
if err.errno != errno.EEXIST or not os.path.exists(dirname):
raise
return os.rename(old, new)
raise
......
......@@ -295,16 +295,27 @@ class TestRename(unittest.TestCase):
def testSimpleRename1(self):
"""Simple rename 1"""
utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"))
self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
def testSimpleRename2(self):
"""Simple rename 2"""
utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "xyz"),
mkdir=True)
self.assert_(os.path.isfile(os.path.join(self.tmpdir, "xyz")))
def testRenameMkdir(self):
"""Rename with mkdir"""
utils.RenameFile(self.tmpfile, os.path.join(self.tmpdir, "test/xyz"),
mkdir=True)
self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/xyz")))
utils.RenameFile(os.path.join(self.tmpdir, "test/xyz"),
os.path.join(self.tmpdir, "test/foo/bar/baz"),
mkdir=True)
self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test")))
self.assert_(os.path.isdir(os.path.join(self.tmpdir, "test/foo/bar")))
self.assert_(os.path.isfile(os.path.join(self.tmpdir, "test/foo/bar/baz")))
class TestMatchNameComponent(unittest.TestCase):
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment