summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnthony Young <sleepsonthefloor@gmail.com>2012-03-13 14:44:31 -0700
committerAnthony Young <sleepsonthefloor@gmail.com>2012-03-13 14:44:31 -0700
commitaa204ea41b88e6896f5505df2d35cdb275cf6187 (patch)
treeb67273a911ce9d446cbf5da262775ba5fc8624da
parentdec0e49db2b031e09f7a73ce645a6000bc6ab932 (diff)
downloadnova-aa204ea41b88e6896f5505df2d35cdb275cf6187.tar.gz
nova-aa204ea41b88e6896f5505df2d35cdb275cf6187.tar.xz
nova-aa204ea41b88e6896f5505df2d35cdb275cf6187.zip
Fix backing file cp/resize race condition.
* Fixes bug 953831 Change-Id: I39950b16c9b76159b16203f7b8b504cae5475516
-rw-r--r--nova/virt/libvirt/connection.py37
1 files changed, 21 insertions, 16 deletions
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index 8fd00457c..5603b1e26 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -46,6 +46,7 @@ import multiprocessing
import os
import shutil
import sys
+import time
import uuid
from eventlet import greenthread
@@ -1012,22 +1013,26 @@ class LibvirtConnection(driver.ComputeDriver):
# For raw it's quicker to just generate outside the cache
call_if_not_exists(target, fn, *args, **kwargs)
- if cow:
- cow_base = base
- if size:
- size_gb = size / (1024 * 1024 * 1024)
- cow_base += "_%d" % size_gb
- if not os.path.exists(cow_base):
- libvirt_utils.copy_image(base, cow_base)
- disk.extend(cow_base, size)
- libvirt_utils.create_cow_image(cow_base, target)
- elif not generating:
- libvirt_utils.copy_image(base, target)
- # Resize after the copy, as it's usually much faster
- # to make sparse updates, rather than potentially
- # naively copying the whole image file.
- if size:
- disk.extend(target, size)
+ @utils.synchronized(base)
+ def copy_and_extend(cow, generating, base, target, size):
+ if cow:
+ cow_base = base
+ if size:
+ size_gb = size / (1024 * 1024 * 1024)
+ cow_base += "_%d" % size_gb
+ if not os.path.exists(cow_base):
+ libvirt_utils.copy_image(base, cow_base)
+ disk.extend(cow_base, size)
+ libvirt_utils.create_cow_image(cow_base, target)
+ elif not generating:
+ libvirt_utils.copy_image(base, target)
+ # Resize after the copy, as it's usually much faster
+ # to make sparse updates, rather than potentially
+ # naively copying the whole image file.
+ if size:
+ disk.extend(target, size)
+
+ copy_and_extend(cow, generating, base, target, size)
@staticmethod
def _create_local(target, local_size, unit='G',