diff --git a/nova/tests/unit/virt/hyperv/test_imagecache.py b/nova/tests/unit/virt/hyperv/test_imagecache.py index a9a4439a61f7..6b1a2ff0f20a 100644 --- a/nova/tests/unit/virt/hyperv/test_imagecache.py +++ b/nova/tests/unit/virt/hyperv/test_imagecache.py @@ -242,6 +242,13 @@ class ImageCacheTestCase(test_base.HyperVBaseTestCase): self.imagecache._pathutils.get_age_of_file.assert_has_calls(calls) mock_get_backing_files.assert_called_once_with(mock.sentinel.image) + def test_remove_old_image(self): + fake_img_path = os.path.join(self.FAKE_BASE_DIR, + self.FAKE_IMAGE_REF) + self.imagecache._remove_old_image(fake_img_path) + self.imagecache._pathutils.remove.assert_called_once_with( + fake_img_path) + @mock.patch.object(imagecache.ImageCache, '_age_and_verify_cached_images') @mock.patch.object(imagecache.ImageCache, '_list_base_images') @mock.patch.object(imagecache.ImageCache, '_list_running_instances') diff --git a/nova/virt/hyperv/imagecache.py b/nova/virt/hyperv/imagecache.py index b4cdbebefcd2..34f0c75b7831 100644 --- a/nova/virt/hyperv/imagecache.py +++ b/nova/virt/hyperv/imagecache.py @@ -37,17 +37,6 @@ LOG = logging.getLogger(__name__) CONF = nova.conf.CONF -def synchronize_with_path(f): - def wrapper(self, image_path): - - @utils.synchronized(image_path) - def inner(): - return f(self, image_path) - return inner() - - return wrapper - - class ImageCache(imagecache.ImageCacheManager): def __init__(self): super(ImageCache, self).__init__() @@ -79,7 +68,11 @@ class ImageCache(imagecache.ImageCacheManager): root_vhd_size_gb, path_parts[1]) - @utils.synchronized(resized_vhd_path) + lock_path = os.path.dirname(resized_vhd_path) + lock_name = "%s-cache.lock" % os.path.basename(resized_vhd_path) + + @utils.synchronized(name=lock_name, external=True, + lock_path=lock_path) def copy_and_resize_vhd(): if not self._pathutils.exists(resized_vhd_path): try: @@ -109,7 +102,10 @@ class ImageCache(imagecache.ImageCacheManager): base_vhd_dir = self._pathutils.get_base_vhd_dir() base_vhd_path = os.path.join(base_vhd_dir, image_id) - @utils.synchronized(base_vhd_path) + lock_name = "%s-cache.lock" % image_id + + @utils.synchronized(name=lock_name, external=True, + lock_path=base_vhd_dir) def fetch_image_if_not_existing(): vhd_path = None for format_ext in ['vhd', 'vhdx']: @@ -206,11 +202,18 @@ class ImageCache(imagecache.ImageCacheManager): age_seconds = self._pathutils.get_age_of_file(img) if age_seconds > max_age_seconds: LOG.info(_LI("Removing old, unused image: %s"), img) - self.remove_old_image(img) + self._remove_old_image(img) - @synchronize_with_path - def remove_old_image(self, img): - self._pathutils.remove(img) + def _remove_old_image(self, image_path): + lock_path = os.path.dirname(image_path) + lock_name = "%s-cache.lock" % os.path.basename(image_path) + + @utils.synchronized(name=lock_name, external=True, + lock_path=lock_path) + def _image_synchronized_remove(): + self._pathutils.remove(image_path) + + _image_synchronized_remove() def update(self, context, all_instances): base_vhd_dir = self._pathutils.get_base_vhd_dir()