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: Michael Hanselmann <[email protected]> --- lib/utils.py | 11 ++++++++++- test/ganeti.utils_unittest.py | 11 +++++++++++ 2 files changed, 21 insertions(+), 1 deletions(-) diff --git a/lib/utils.py b/lib/utils.py index 65ef2c3..8fb3dd5 100644 --- a/lib/utils.py +++ b/lib/utils.py @@ -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 EEXISTS. 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 diff --git a/test/ganeti.utils_unittest.py b/test/ganeti.utils_unittest.py index 62f4805..fe7464d 100755 --- a/test/ganeti.utils_unittest.py +++ b/test/ganeti.utils_unittest.py @@ -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): -- 1.6.4.3
