From 37dfb3cb056615a85a9569530838f7d826574cef Mon Sep 17 00:00:00 2001 From: Feodor Tersin Date: Mon, 20 Jun 2016 20:18:23 +0300 Subject: [PATCH] Fix resizing bug If an instance is being moved to another host during resizing, instance root disk is not mapped to the new host, but is mapped to the old host. In this case the disk must not be directly unmapped from the new host, but must be deleted with ignore_mappings flag. Also since 12.0.4 driver.py checks the disks for existence before removing its snapshot. Because that this check is stubbed with False to enable create_image call from cache method, the snapshot is not removed. To workaround this create_snapshot now creates the snapshot even the snapshot is already exists. It does not avoid SIO from unused snapshot, but allows the second resize at least. Also extend operation is now called even if size is not changed. This allows to resize an instance to a flavor with the same size, but different storage pool/protection domain settings. --- 12.0.0-mos43.diff | 30 ++++++++++++++++++--------- 12.0.1.diff | 30 ++++++++++++++++++--------- 12.0.2-mos21.diff | 30 ++++++++++++++++++--------- 12.0.2.diff | 30 ++++++++++++++++++--------- 12.0.3.diff | 30 ++++++++++++++++++--------- 12.0.4.diff | 30 ++++++++++++++++++--------- 2014.2.2-mos30.diff | 34 ++++++++++++++++++------------- 2014.2.2-mos31.diff | 30 ++++++++++++++++++--------- 2014.2.2-mos46.diff | 34 ++++++++++++++++++------------- 2014.2.2-mos48.diff | 30 ++++++++++++++++++--------- 2014.2.2.diff | 34 ++++++++++++++++++------------- 2014.2.4.diff | 34 ++++++++++++++++++------------- 2015.1.1-mos19662.diff | 30 ++++++++++++++++++--------- 2015.1.1-mos19676.diff | 30 ++++++++++++++++++--------- 2015.1.1-mos19695.diff | 30 ++++++++++++++++++--------- 2015.1.1.diff | 46 +++++++++++++++++++----------------------- 2015.1.2.diff | 30 ++++++++++++++++++--------- 2015.1.3.diff | 30 ++++++++++++++++++--------- 2015.1.4.diff | 30 ++++++++++++++++++--------- 19 files changed, 381 insertions(+), 221 deletions(-) diff --git a/12.0.0-mos43.diff b/12.0.0-mos43.diff index a40c044..2e0eae9 100644 --- a/12.0.0-mos43.diff +++ b/12.0.0-mos43.diff @@ -211,7 +211,7 @@ index 920a283..cdc8857 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 151ebc4..9d876e3 100644 +index 151ebc4..1ddeae1 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -29,6 +29,7 @@ from oslo_utils import strutils @@ -288,7 +288,7 @@ index 151ebc4..9d876e3 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -902,6 +948,113 @@ class Ploop(Image): +@@ -902,6 +948,115 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -343,7 +343,9 @@ index 151ebc4..9d876e3 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -402,7 +404,7 @@ index 151ebc4..9d876e3 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -910,7 +1063,8 @@ class Backend(object): +@@ -910,7 +1065,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -414,10 +416,10 @@ index 151ebc4..9d876e3 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/storage/sio_utils.py b/nova/virt/libvirt/storage/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/storage/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -703,7 +705,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -717,6 +719,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -745,8 +750,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -764,9 +768,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/12.0.1.diff b/12.0.1.diff index 588b401..c300034 100644 --- a/12.0.1.diff +++ b/12.0.1.diff @@ -211,7 +211,7 @@ index 3e719e9..3da1fc7 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 151ebc4..9d876e3 100644 +index 151ebc4..1ddeae1 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -29,6 +29,7 @@ from oslo_utils import strutils @@ -288,7 +288,7 @@ index 151ebc4..9d876e3 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -902,6 +948,113 @@ class Ploop(Image): +@@ -902,6 +948,115 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -343,7 +343,9 @@ index 151ebc4..9d876e3 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -402,7 +404,7 @@ index 151ebc4..9d876e3 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -910,7 +1063,8 @@ class Backend(object): +@@ -910,7 +1065,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -414,10 +416,10 @@ index 151ebc4..9d876e3 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/storage/sio_utils.py b/nova/virt/libvirt/storage/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/storage/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -703,7 +705,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -717,6 +719,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -745,8 +750,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -764,9 +768,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/12.0.2-mos21.diff b/12.0.2-mos21.diff index 06ad3aa..39e16b5 100644 --- a/12.0.2-mos21.diff +++ b/12.0.2-mos21.diff @@ -161,7 +161,7 @@ index 7b772c1..c6612fc 100644 connection_info = vol['connection_info'] disk_dev = vol['mount_device'].rpartition("/")[2] diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 558fe82..d327391 100644 +index 558fe82..52af225 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -29,6 +29,7 @@ from oslo_utils import strutils @@ -213,7 +213,7 @@ index 558fe82..d327391 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -936,6 +957,113 @@ class Ploop(Image): +@@ -936,6 +957,115 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -268,7 +268,9 @@ index 558fe82..d327391 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -327,7 +329,7 @@ index 558fe82..d327391 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -944,7 +1072,8 @@ class Backend(object): +@@ -944,7 +1074,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -339,10 +341,10 @@ index 558fe82..d327391 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/storage/sio_utils.py b/nova/virt/libvirt/storage/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/storage/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -628,7 +630,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -642,6 +644,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -670,8 +675,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -689,9 +693,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/12.0.2.diff b/12.0.2.diff index 3fcbf88..01b130b 100644 --- a/12.0.2.diff +++ b/12.0.2.diff @@ -161,7 +161,7 @@ index 6328d05..2739d30 100644 connection_info = vol['connection_info'] disk_dev = vol['mount_device'].rpartition("/")[2] diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 558fe82..d327391 100644 +index 558fe82..52af225 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -29,6 +29,7 @@ from oslo_utils import strutils @@ -213,7 +213,7 @@ index 558fe82..d327391 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -936,6 +957,113 @@ class Ploop(Image): +@@ -936,6 +957,115 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -268,7 +268,9 @@ index 558fe82..d327391 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -327,7 +329,7 @@ index 558fe82..d327391 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -944,7 +1072,8 @@ class Backend(object): +@@ -944,7 +1074,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -339,10 +341,10 @@ index 558fe82..d327391 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/storage/sio_utils.py b/nova/virt/libvirt/storage/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/storage/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -628,7 +630,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -642,6 +644,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -670,8 +675,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -689,9 +693,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/12.0.3.diff b/12.0.3.diff index e960142..f005d81 100644 --- a/12.0.3.diff +++ b/12.0.3.diff @@ -161,7 +161,7 @@ index 9d8f8df..bbcb82c 100644 connection_info = vol['connection_info'] disk_dev = vol['mount_device'].rpartition("/")[2] diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 558fe82..d327391 100644 +index 558fe82..52af225 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -29,6 +29,7 @@ from oslo_utils import strutils @@ -213,7 +213,7 @@ index 558fe82..d327391 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -936,6 +957,113 @@ class Ploop(Image): +@@ -936,6 +957,115 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -268,7 +268,9 @@ index 558fe82..d327391 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -327,7 +329,7 @@ index 558fe82..d327391 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -944,7 +1072,8 @@ class Backend(object): +@@ -944,7 +1074,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -339,10 +341,10 @@ index 558fe82..d327391 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/storage/sio_utils.py b/nova/virt/libvirt/storage/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/storage/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -628,7 +630,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -642,6 +644,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -670,8 +675,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -689,9 +693,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/12.0.4.diff b/12.0.4.diff index bfa7b7a..d612faa 100644 --- a/12.0.4.diff +++ b/12.0.4.diff @@ -161,7 +161,7 @@ index 7e99ba7..70233e6 100644 connection_info = vol['connection_info'] disk_dev = vol['mount_device'].rpartition("/")[2] diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 558fe82..d327391 100644 +index 558fe82..52af225 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -29,6 +29,7 @@ from oslo_utils import strutils @@ -213,7 +213,7 @@ index 558fe82..d327391 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -936,6 +957,113 @@ class Ploop(Image): +@@ -936,6 +957,115 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -268,7 +268,9 @@ index 558fe82..d327391 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -327,7 +329,7 @@ index 558fe82..d327391 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -944,7 +1072,8 @@ class Backend(object): +@@ -944,7 +1074,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -339,10 +341,10 @@ index 558fe82..d327391 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/storage/sio_utils.py b/nova/virt/libvirt/storage/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/storage/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -628,7 +630,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -642,6 +644,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -670,8 +675,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -689,9 +693,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2014.2.2-mos30.diff b/2014.2.2-mos30.diff index bdb09ce..02ac519 100644 --- a/2014.2.2-mos30.diff +++ b/2014.2.2-mos30.diff @@ -169,7 +169,7 @@ index a2c04d6..2f5c6ae 100644 instance, block_device_info) diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index c7549fa..035e14a 100644 +index c7549fa..91127bc 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -20,11 +20,15 @@ import os @@ -246,7 +246,7 @@ index c7549fa..035e14a 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -737,6 +785,115 @@ class Rbd(Image): +@@ -737,6 +785,117 @@ class Rbd(Image): reason=reason) @@ -306,7 +306,9 @@ index c7549fa..035e14a 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume(self.volume_name, size, + self.extra_specs, + self.orig_extra_specs) @@ -362,7 +364,7 @@ index c7549fa..035e14a 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -744,6 +901,7 @@ class Backend(object): +@@ -744,6 +903,7 @@ class Backend(object): 'qcow2': Qcow2, 'lvm': Lvm, 'rbd': Rbd, @@ -372,10 +374,10 @@ index c7549fa..035e14a 100644 diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..310076b +index 0000000..a2e63eb --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,395 @@ +@@ -0,0 +1,403 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -659,7 +661,7 @@ index 0000000..310076b + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -673,6 +675,9 @@ index 0000000..310076b + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -702,8 +707,7 @@ index 0000000..310076b + 'iflag=direct', + 'conv=fsync', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -721,9 +725,15 @@ index 0000000..310076b + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + @@ -793,7 +803,3 @@ index c05de93..5e3c55e 100644 if path.startswith('/dev'): return 'lvm' elif path.startswith('rbd:'): -rn 'sio' - if path.startswith('/dev'): - return 'lvm' - elif path.startswith('rbd:'): diff --git a/2014.2.2-mos31.diff b/2014.2.2-mos31.diff index f1f931a..d5985ae 100644 --- a/2014.2.2-mos31.diff +++ b/2014.2.2-mos31.diff @@ -169,7 +169,7 @@ index 0e04e4b..fe44c1f 100644 instance, block_device_info) diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index c7549fa..035e14a 100644 +index c7549fa..91127bc 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -20,11 +20,15 @@ import os @@ -246,7 +246,7 @@ index c7549fa..035e14a 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -737,6 +785,115 @@ class Rbd(Image): +@@ -737,6 +785,117 @@ class Rbd(Image): reason=reason) @@ -306,7 +306,9 @@ index c7549fa..035e14a 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume(self.volume_name, size, + self.extra_specs, + self.orig_extra_specs) @@ -362,7 +364,7 @@ index c7549fa..035e14a 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -744,6 +901,7 @@ class Backend(object): +@@ -744,6 +903,7 @@ class Backend(object): 'qcow2': Qcow2, 'lvm': Lvm, 'rbd': Rbd, @@ -372,10 +374,10 @@ index c7549fa..035e14a 100644 diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..310076b +index 0000000..a2e63eb --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,395 @@ +@@ -0,0 +1,403 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -659,7 +661,7 @@ index 0000000..310076b + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -673,6 +675,9 @@ index 0000000..310076b + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -702,8 +707,7 @@ index 0000000..310076b + 'iflag=direct', + 'conv=fsync', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -721,9 +725,15 @@ index 0000000..310076b + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2014.2.2-mos46.diff b/2014.2.2-mos46.diff index 245c5a7..0efec0e 100644 --- a/2014.2.2-mos46.diff +++ b/2014.2.2-mos46.diff @@ -169,7 +169,7 @@ index eba1ff3..08fb5d1 100644 instance, block_device_info) diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 934bbca..896c1e9 100644 +index 934bbca..6644f16 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -20,11 +20,15 @@ import os @@ -246,7 +246,7 @@ index 934bbca..896c1e9 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -753,6 +801,115 @@ class Rbd(Image): +@@ -753,6 +801,117 @@ class Rbd(Image): reason=reason) @@ -306,7 +306,9 @@ index 934bbca..896c1e9 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume(self.volume_name, size, + self.extra_specs, + self.orig_extra_specs) @@ -362,7 +364,7 @@ index 934bbca..896c1e9 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -760,6 +917,7 @@ class Backend(object): +@@ -760,6 +919,7 @@ class Backend(object): 'qcow2': Qcow2, 'lvm': Lvm, 'rbd': Rbd, @@ -372,10 +374,10 @@ index 934bbca..896c1e9 100644 diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..85deed9 +index 0000000..9388bd9 --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,397 @@ +@@ -0,0 +1,405 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -661,7 +663,7 @@ index 0000000..85deed9 + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -675,6 +677,9 @@ index 0000000..85deed9 + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -704,8 +709,7 @@ index 0000000..85deed9 + 'iflag=direct', + 'conv=fsync', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -723,9 +727,15 @@ index 0000000..85deed9 + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + @@ -795,7 +805,3 @@ index c7cda44..cdb9cdf 100644 if path.startswith('/dev'): return 'lvm' elif path.startswith('rbd:'): -rn 'sio' - if path.startswith('/dev'): - return 'lvm' - elif path.startswith('rbd:'): diff --git a/2014.2.2-mos48.diff b/2014.2.2-mos48.diff index a64c48d..c2578b6 100644 --- a/2014.2.2-mos48.diff +++ b/2014.2.2-mos48.diff @@ -169,7 +169,7 @@ index 4860e7b..951f197 100644 instance, block_device_info) diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 934bbca..896c1e9 100644 +index 934bbca..6644f16 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -20,11 +20,15 @@ import os @@ -246,7 +246,7 @@ index 934bbca..896c1e9 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -753,6 +801,115 @@ class Rbd(Image): +@@ -753,6 +801,117 @@ class Rbd(Image): reason=reason) @@ -306,7 +306,9 @@ index 934bbca..896c1e9 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume(self.volume_name, size, + self.extra_specs, + self.orig_extra_specs) @@ -362,7 +364,7 @@ index 934bbca..896c1e9 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -760,6 +917,7 @@ class Backend(object): +@@ -760,6 +919,7 @@ class Backend(object): 'qcow2': Qcow2, 'lvm': Lvm, 'rbd': Rbd, @@ -372,10 +374,10 @@ index 934bbca..896c1e9 100644 diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..85deed9 +index 0000000..9388bd9 --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,397 @@ +@@ -0,0 +1,405 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -661,7 +663,7 @@ index 0000000..85deed9 + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -675,6 +677,9 @@ index 0000000..85deed9 + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -704,8 +709,7 @@ index 0000000..85deed9 + 'iflag=direct', + 'conv=fsync', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -723,9 +727,15 @@ index 0000000..85deed9 + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2014.2.2.diff b/2014.2.2.diff index 058db21..014cc01 100644 --- a/2014.2.2.diff +++ b/2014.2.2.diff @@ -161,7 +161,7 @@ index cec2013..dd72109 100644 instance, block_device_info) diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index a539335..c58cb20 100644 +index a539335..8d978f7 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -20,11 +20,15 @@ import os @@ -238,7 +238,7 @@ index a539335..c58cb20 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -739,6 +787,115 @@ class Rbd(Image): +@@ -739,6 +787,117 @@ class Rbd(Image): reason=reason) @@ -298,7 +298,9 @@ index a539335..c58cb20 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume(self.volume_name, size, + self.extra_specs, + self.orig_extra_specs) @@ -354,7 +356,7 @@ index a539335..c58cb20 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -746,6 +903,7 @@ class Backend(object): +@@ -746,6 +905,7 @@ class Backend(object): 'qcow2': Qcow2, 'lvm': Lvm, 'rbd': Rbd, @@ -364,10 +366,10 @@ index a539335..c58cb20 100644 diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..310076b +index 0000000..a2e63eb --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,395 @@ +@@ -0,0 +1,403 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -651,7 +653,7 @@ index 0000000..310076b + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -665,6 +667,9 @@ index 0000000..310076b + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -694,8 +699,7 @@ index 0000000..310076b + 'iflag=direct', + 'conv=fsync', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -713,9 +717,15 @@ index 0000000..310076b + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + @@ -785,7 +795,3 @@ index c05de93..5e3c55e 100644 if path.startswith('/dev'): return 'lvm' elif path.startswith('rbd:'): -rn 'sio' - if path.startswith('/dev'): - return 'lvm' - elif path.startswith('rbd:'): diff --git a/2014.2.4.diff b/2014.2.4.diff index 9c87125..00f8cbf 100644 --- a/2014.2.4.diff +++ b/2014.2.4.diff @@ -169,7 +169,7 @@ index beb5332..ea23aeb 100644 instance, block_device_info) diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index c7549fa..035e14a 100644 +index c7549fa..91127bc 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -20,11 +20,15 @@ import os @@ -246,7 +246,7 @@ index c7549fa..035e14a 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -737,6 +785,115 @@ class Rbd(Image): +@@ -737,6 +785,117 @@ class Rbd(Image): reason=reason) @@ -306,7 +306,9 @@ index c7549fa..035e14a 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume(self.volume_name, size, + self.extra_specs, + self.orig_extra_specs) @@ -362,7 +364,7 @@ index c7549fa..035e14a 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -744,6 +901,7 @@ class Backend(object): +@@ -744,6 +903,7 @@ class Backend(object): 'qcow2': Qcow2, 'lvm': Lvm, 'rbd': Rbd, @@ -372,10 +374,10 @@ index c7549fa..035e14a 100644 diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..310076b +index 0000000..a2e63eb --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,395 @@ +@@ -0,0 +1,403 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -659,7 +661,7 @@ index 0000000..310076b + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -673,6 +675,9 @@ index 0000000..310076b + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -702,8 +707,7 @@ index 0000000..310076b + 'iflag=direct', + 'conv=fsync', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -721,9 +725,15 @@ index 0000000..310076b + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + @@ -793,7 +803,3 @@ index 6f66107..1ae4eec 100644 if path.startswith('/dev'): return 'lvm' elif path.startswith('rbd:'): -rn 'sio' - if path.startswith('/dev'): - return 'lvm' - elif path.startswith('rbd:'): diff --git a/2015.1.1-mos19662.diff b/2015.1.1-mos19662.diff index 3f4e387..c479e49 100644 --- a/2015.1.1-mos19662.diff +++ b/2015.1.1-mos19662.diff @@ -201,7 +201,7 @@ index 2a520d0..8b7f1d0 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 8655b48..458cdaa 100644 +index 8655b48..af6eb81 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index 8655b48..458cdaa 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -826,6 +871,110 @@ class Ploop(Image): +@@ -826,6 +871,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index 8655b48..458cdaa 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index 8655b48..458cdaa 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -834,7 +983,8 @@ class Backend(object): +@@ -834,7 +985,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index 8655b48..458cdaa 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..c2128f9 +index 0000000..5a07dcf --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,394 @@ +@@ -0,0 +1,402 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -680,7 +682,7 @@ index 0000000..c2128f9 + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -694,6 +696,9 @@ index 0000000..c2128f9 + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -722,8 +727,7 @@ index 0000000..c2128f9 + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -741,9 +745,15 @@ index 0000000..c2128f9 + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2015.1.1-mos19676.diff b/2015.1.1-mos19676.diff index 4ca9577..9562429 100644 --- a/2015.1.1-mos19676.diff +++ b/2015.1.1-mos19676.diff @@ -201,7 +201,7 @@ index 5dbc8ac..bcebaaf 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index f5e464e..7e411a3 100644 +index f5e464e..c5f1f5d 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index f5e464e..7e411a3 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -835,6 +880,110 @@ class Ploop(Image): +@@ -835,6 +880,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index f5e464e..7e411a3 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index f5e464e..7e411a3 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -843,7 +992,8 @@ class Backend(object): +@@ -843,7 +994,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index f5e464e..7e411a3 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -682,7 +684,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -696,6 +698,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -724,8 +729,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -743,9 +747,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2015.1.1-mos19695.diff b/2015.1.1-mos19695.diff index c0dd6fd..595428e 100644 --- a/2015.1.1-mos19695.diff +++ b/2015.1.1-mos19695.diff @@ -201,7 +201,7 @@ index 3d9dd50..516ff85 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 931ce17..ab92b13 100644 +index 931ce17..7270a81 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index 931ce17..ab92b13 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -842,6 +887,110 @@ class Ploop(Image): +@@ -842,6 +887,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index 931ce17..ab92b13 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index 931ce17..ab92b13 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -850,7 +999,8 @@ class Backend(object): +@@ -850,7 +1001,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index 931ce17..ab92b13 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -682,7 +684,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -696,6 +698,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -724,8 +729,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -743,9 +747,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2015.1.1.diff b/2015.1.1.diff index 1434992..7176096 100644 --- a/2015.1.1.diff +++ b/2015.1.1.diff @@ -201,7 +201,7 @@ index 40ee080..b21f42a 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 8655b48..458cdaa 100644 +index 8655b48..af6eb81 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index 8655b48..458cdaa 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -826,6 +871,110 @@ class Ploop(Image): +@@ -826,6 +871,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index 8655b48..458cdaa 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index 8655b48..458cdaa 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -834,7 +983,8 @@ class Backend(object): +@@ -834,7 +985,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index 8655b48..458cdaa 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..c2128f9 +index 0000000..5a07dcf --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,394 @@ +@@ -0,0 +1,402 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -680,7 +682,7 @@ index 0000000..c2128f9 + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -694,6 +696,9 @@ index 0000000..c2128f9 + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -722,8 +727,7 @@ index 0000000..c2128f9 + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -741,9 +745,15 @@ index 0000000..c2128f9 + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + @@ -813,21 +823,7 @@ index 7b80464..ff25e58 100644 if path.startswith('/dev'): return 'lvm' elif path.startswith('rbd:'): - self.remove_volume(volume, ignore_mappings=True) -diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py -index 7b80464..ff25e58 100644 ---- a/nova/virt/libvirt/utils.py -+++ b/nova/virt/libvirt/utils.py -@@ -50,6 +50,8 @@ CONF.register_opts(libvirt_opts, 'libvirt') - CONF.import_opt('instances_path', 'nova.compute.manager') - LOG = logging.getLogger(__name__) - -+RESIZE_SNAPSHOT_NAME = 'nova-resize' -+ - - def execute(*args, **kwargs): - return utils.execute(*args, **kwargs) -@@ -468,6 +470,8 @@ def find_disk(virt_dom): +nd_disk(virt_dom): def get_disk_type(path): """Retrieve disk type (raw, qcow2, lvm) for given file.""" diff --git a/2015.1.2.diff b/2015.1.2.diff index 0783285..9fab3c2 100644 --- a/2015.1.2.diff +++ b/2015.1.2.diff @@ -201,7 +201,7 @@ index 1cf6c89..e4ab3c0 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index 8655b48..458cdaa 100644 +index 8655b48..af6eb81 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index 8655b48..458cdaa 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -826,6 +871,110 @@ class Ploop(Image): +@@ -826,6 +871,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index 8655b48..458cdaa 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index 8655b48..458cdaa 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -834,7 +983,8 @@ class Backend(object): +@@ -834,7 +985,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index 8655b48..458cdaa 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..c2128f9 +index 0000000..5a07dcf --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,394 @@ +@@ -0,0 +1,402 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -680,7 +682,7 @@ index 0000000..c2128f9 + images.convert_image(source, dest, out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -694,6 +696,9 @@ index 0000000..c2128f9 + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -722,8 +727,7 @@ index 0000000..c2128f9 + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -741,9 +745,15 @@ index 0000000..c2128f9 + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2015.1.3.diff b/2015.1.3.diff index ded961c..ae13cbb 100644 --- a/2015.1.3.diff +++ b/2015.1.3.diff @@ -201,7 +201,7 @@ index 1b5c4b9..a9c3641 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index f5e464e..7e411a3 100644 +index f5e464e..c5f1f5d 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index f5e464e..7e411a3 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -835,6 +880,110 @@ class Ploop(Image): +@@ -835,6 +880,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index f5e464e..7e411a3 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index f5e464e..7e411a3 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -843,7 +992,8 @@ class Backend(object): +@@ -843,7 +994,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index f5e464e..7e411a3 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -682,7 +684,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -696,6 +698,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -724,8 +729,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -743,9 +747,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) + diff --git a/2015.1.4.diff b/2015.1.4.diff index 90959a4..d0c034e 100644 --- a/2015.1.4.diff +++ b/2015.1.4.diff @@ -201,7 +201,7 @@ index 37c06ed..56235d1 100644 instance, image_meta, diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py -index f5e464e..7e411a3 100644 +index f5e464e..c5f1f5d 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -27,6 +27,7 @@ from oslo_utils import strutils @@ -270,7 +270,7 @@ index f5e464e..7e411a3 100644 class Raw(Image): def __init__(self, instance=None, disk_name=None, path=None): -@@ -835,6 +880,110 @@ class Ploop(Image): +@@ -835,6 +880,112 @@ class Ploop(Image): create_ploop_image(base, self.path, size) @@ -325,7 +325,9 @@ index f5e464e..7e411a3 100644 + if size < vol_size: + LOG.debug('Cannot resize volume %s to a smaller size.', + self.volume_name) -+ elif size > vol_size: ++ else: ++ # give a chance for extend_volume to migrate the volume to ++ # another pd/sp if required + self.driver.extend_volume( + self.volume_name, size, + self.extra_specs, self.orig_extra_specs) @@ -381,7 +383,7 @@ index f5e464e..7e411a3 100644 class Backend(object): def __init__(self, use_cow): self.BACKEND = { -@@ -843,7 +992,8 @@ class Backend(object): +@@ -843,7 +994,8 @@ class Backend(object): 'lvm': Lvm, 'rbd': Rbd, 'ploop': Ploop, @@ -393,10 +395,10 @@ index f5e464e..7e411a3 100644 def backend(self, image_type=None): diff --git a/nova/virt/libvirt/sio_utils.py b/nova/virt/libvirt/sio_utils.py new file mode 100644 -index 0000000..9503ffe +index 0000000..aeef0a8 --- /dev/null +++ b/nova/virt/libvirt/sio_utils.py -@@ -0,0 +1,396 @@ +@@ -0,0 +1,404 @@ +# Copyright (c) 2015 EMC Corporation +# All Rights Reserved +# @@ -682,7 +684,7 @@ index 0000000..9503ffe + images.convert_image(source, dest, 'raw', out_format, run_as_root=True) + + def extend_volume(self, name, new_size, extra_specs, orig_extra_specs): -+ """Extend the size of a volume. ++ """Extend the size of a volume, honoring extra specs. + + This method is used primarily with openstack resize operation + @@ -696,6 +698,9 @@ index 0000000..9503ffe + orig_extra_specs.get(PROTECTION_DOMAIN_KEY) and + extra_specs.get(STORAGE_POOL_KEY) == + orig_extra_specs.get(STORAGE_POOL_KEY)): ++ if self.get_volume_size(name) == new_size: ++ # extending is not required ++ return + vol_id = self.get_volume_id(name) + self.ioctx.extend_volume(vol_id, new_size / units.Gi) + # NOTE(ft): siolib does not raise an exception if it cannot extend @@ -724,8 +729,7 @@ index 0000000..9503ffe + 'bs=1M', + 'iflag=direct', + run_as_root=True) -+ self.unmap_volume(name) -+ self.remove_volume(name) ++ self.remove_volume(name, ignore_mappings=True) + if not mapped: + self.unmap_volume(tmp_name) + new_id = self.get_volume_id(tmp_name) @@ -743,9 +747,15 @@ index 0000000..9503ffe + """ + vol_id = self.get_volume_id(name) + snap_gid, _vol_list = self.ioctx.snapshot_volume(snapshot_name, vol_id) -+ # NOTE(ft): siolib does not rais an exception if it cannot create ++ # NOTE(ft): siolib does not raise an exception if it cannot create + # the snapshot + if not snap_gid: ++ if self.check_volume_exists(snapshot_name): ++ self.remove_volume(snapshot_name, ignore_mappings=True) ++ (snap_gid, ++ _vol_list) = self.ioctx.snapshot_volume(snapshot_name, vol_id) ++ if snap_gid: ++ return + raise RuntimeError(_('Failed to create snapshot of disk volume %s') + % name) +