From cdeefd9b5fa8f36ff43959d7e4f16a95d067f94c Mon Sep 17 00:00:00 2001
From: Guido Trotter <ultrotter@google.com>
Date: Mon, 22 Mar 2010 15:41:33 +0000
Subject: [PATCH] Remove race condition in FileStorage.Create

Rather than checking that the file doesn't exist, and then creating it,
we create it with O_CREAT | O_EXCL, making sure the checking/creation is
atomic.

Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/bdev.py | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/lib/bdev.py b/lib/bdev.py
index 721f3a6ec..da7745cee 100644
--- a/lib/bdev.py
+++ b/lib/bdev.py
@@ -1915,13 +1915,14 @@ class FileStorage(BlockDev):
     if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 2:
       raise ValueError("Invalid configuration data %s" % str(unique_id))
     dev_path = unique_id[1]
-    if os.path.exists(dev_path):
-      _ThrowError("File already existing: %s", dev_path)
     try:
-      f = open(dev_path, 'w')
+      fd = os.open(dev_path, os.O_RDWR | os.O_CREAT | os.O_EXCL)
+      f = os.fdopen(fd, "w")
       f.truncate(size * 1024 * 1024)
       f.close()
-    except IOError, err:
+    except EnvironmentError, err:
+      if err.errno == errno.EEXIST:
+        _ThrowError("File already existing: %s", dev_path)
       _ThrowError("Error in file creation: %", str(err))
 
     return FileStorage(unique_id, children, size)
-- 
GitLab