Skip to content

Commit

Permalink
Fix resizing bug
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ftersin committed Jun 20, 2016
1 parent 4559de4 commit 37dfb3c
Show file tree
Hide file tree
Showing 19 changed files with 381 additions and 221 deletions.
30 changes: 20 additions & 10 deletions 12.0.0-mos43.diff
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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
+#
Expand Down Expand Up @@ -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
+
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
+
Expand Down
30 changes: 20 additions & 10 deletions 12.0.1.diff
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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
+#
Expand Down Expand Up @@ -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
+
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
+
Expand Down
30 changes: 20 additions & 10 deletions 12.0.2-mos21.diff
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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
+#
Expand Down Expand Up @@ -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
+
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
+
Expand Down
30 changes: 20 additions & 10 deletions 12.0.2.diff
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)


Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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
+#
Expand Down Expand Up @@ -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
+
Expand All @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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)
+
Expand Down
Loading

0 comments on commit 37dfb3c

Please sign in to comment.