diff options
| author | Anthony Young <sleepsonthefloor@gmail.com> | 2012-03-13 14:44:31 -0700 |
|---|---|---|
| committer | Anthony Young <sleepsonthefloor@gmail.com> | 2012-03-13 14:44:31 -0700 |
| commit | aa204ea41b88e6896f5505df2d35cdb275cf6187 (patch) | |
| tree | b67273a911ce9d446cbf5da262775ba5fc8624da | |
| parent | dec0e49db2b031e09f7a73ce645a6000bc6ab932 (diff) | |
| download | nova-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.py | 37 |
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', |
