Skip to content

Commit

Permalink
xenapi: remove auto_disk_config check during resize
Browse files Browse the repository at this point in the history
This check was introduced by the following change:
7c5c8a7

This is an alternative fix to ensure resize down
is not processed if the disk cannot be resized.

Note the failure now registers an instance action
and does not leave the VM in an error state.

In addition, this keeps the behavior that a failure
to resize up and instance during spawn will not
cause the operation to fail and put the VM into error.

fixes bug 1188135
fixes bug 1187934
fixes bug 1081225

Change-Id: I5b3dfdc7fcda26c55702dde6cdf191beee0c818c
  • Loading branch information
John Garbutt authored and openstack-gerrit committed Jun 12, 2013
1 parent 4461f20 commit 1cf78d3
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 14 deletions.
4 changes: 4 additions & 0 deletions nova/exception.py
Expand Up @@ -964,6 +964,10 @@ class ResizeError(NovaException):
message = _("Resize error: %(reason)s")


class CannotResizeDisk(NovaException):
message = _("Server disk was unable to be resized because: %(reason)s")


class InstanceTypeMemoryTooSmall(NovaException):
message = _("Instance type's memory is too small for requested image.")

Expand Down
33 changes: 29 additions & 4 deletions nova/tests/virt/xenapi/test_xenapi.py
Expand Up @@ -1297,6 +1297,7 @@ def setUp(self):
stubs.stubout_session(self.stubs, stubs.FakeSessionForVMTests)
db_fakes.stub_out_db_instance_api(self.stubs)
xenapi_fake.create_network('fake', CONF.flat_network_bridge)
xenapi_fake.create_local_srs()
self.user_id = 'fake'
self.project_id = 'fake'
self.context = context.RequestContext(self.user_id, self.project_id)
Expand Down Expand Up @@ -1517,16 +1518,40 @@ def fake_vdi_resize(*args, **kwargs):
dict(base_copy='hurr', cow='durr'),
network_info, image_meta, resize_instance=False)

def test_migrate_no_auto_disk_config_no_resize_down(self):
# Resize down should fail when auto_disk_config not set.
@stub_vm_utils_with_vdi_attached_here
def test_migrate_too_many_partitions_no_resize_down(self):
instance_values = self.instance_values
instance_values['root_gb'] = 40
instance_values['auto_disk_config'] = False
instance = db.instance_create(self.context, instance_values)
xenapi_fake.create_vm(instance['name'], 'Running')
instance_type = db.instance_type_get_by_name(self.context, 'm1.small')
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)
self.assertRaises(exception.ResizeError,

def fake_get_partitions(partition):
return [(1, 2, 3, 4), (1, 2, 3, 4)]

self.stubs.Set(vm_utils, '_get_partitions', fake_get_partitions)

self.assertRaises(exception.InstanceFaultRollback,
conn.migrate_disk_and_power_off,
self.context, instance,
'127.0.0.1', instance_type, None)

@stub_vm_utils_with_vdi_attached_here
def test_migrate_bad_fs_type_no_resize_down(self):
instance_values = self.instance_values
instance_values['root_gb'] = 40
instance = db.instance_create(self.context, instance_values)
xenapi_fake.create_vm(instance['name'], 'Running')
instance_type = db.instance_type_get_by_name(self.context, 'm1.small')
conn = xenapi_conn.XenAPIDriver(fake.FakeVirtAPI(), False)

def fake_get_partitions(partition):
return [(1, 2, 3, "ext2")]

self.stubs.Set(vm_utils, '_get_partitions', fake_get_partitions)

self.assertRaises(exception.InstanceFaultRollback,
conn.migrate_disk_and_power_off,
self.context, instance,
'127.0.0.1', instance_type, None)
Expand Down
19 changes: 16 additions & 3 deletions nova/virt/xenapi/vm_utils.py
Expand Up @@ -758,7 +758,7 @@ def resize_disk(session, instance, vdi_ref, instance_type):

try:
# Resize partition and filesystem down
auto_configure_disk(session, copy_ref, instance_type['root_gb'])
_auto_configure_disk(session, copy_ref, instance_type['root_gb'])

# Create new VDI
vdi_size = instance_type['root_gb'] * 1024 * 1024 * 1024
Expand All @@ -778,7 +778,7 @@ def resize_disk(session, instance, vdi_ref, instance_type):
destroy_vdi(session, copy_ref)


def auto_configure_disk(session, vdi_ref, new_gb):
def _auto_configure_disk(session, vdi_ref, new_gb):
"""Partition and resize FS to match the size specified by
flavors.root_gb.
Expand All @@ -798,12 +798,25 @@ def auto_configure_disk(session, vdi_ref, new_gb):
partitions = _get_partitions(dev)

if len(partitions) != 1:
return
reason = _('Disk must have only one partition.')
raise exception.CannotResizeDisk(reason=reason)

_num, start, old_sectors, ptype = partitions[0]
if ptype in ('ext3', 'ext4'):
new_sectors = new_gb * 1024 * 1024 * 1024 / SECTOR_SIZE
_resize_part_and_fs(dev, start, old_sectors, new_sectors)
else:
reason = _('Disk contains a filesystem '
'we are unable to resize: %s')
raise exception.CannotResizeDisk(reason=(reason % ptype))


def try_auto_configure_disk(session, vdi_ref, new_gb):
try:
_auto_configure_disk(session, vdi_ref, new_gb)
except exception.CannotResizeDisk as e:
msg = _('Attempted auto_configure_disk failed because: %s')
LOG.warn(msg % e)


def _generate_disk(session, instance, vm_ref, userdevice, name_label,
Expand Down
10 changes: 3 additions & 7 deletions nova/virt/xenapi/vmops.py
Expand Up @@ -592,9 +592,9 @@ def _attach_disks(self, instance, vm_ref, name_label, vdis,
if instance['auto_disk_config']:
LOG.debug(_("Auto configuring disk, attempting to "
"resize partition..."), instance=instance)
vm_utils.auto_configure_disk(self._session,
root_vdi['ref'],
instance_type['root_gb'])
vm_utils.try_auto_configure_disk(self._session,
root_vdi['ref'],
instance_type['root_gb'])

vm_utils.create_vbd(self._session, vm_ref, root_vdi['ref'],
DEVICE_ROOT, bootable=True,
Expand Down Expand Up @@ -820,10 +820,6 @@ def _resize_ensure_vm_is_shutdown(self, instance, vm_ref):

def _migrate_disk_resizing_down(self, context, instance, dest,
instance_type, vm_ref, sr_path):
if not instance['auto_disk_config']:
reason = _('Resize down not allowed without auto_disk_config')
raise exception.ResizeError(reason=reason)

step = make_step_decorator(context, instance,
self._virtapi.instance_update)

Expand Down

0 comments on commit 1cf78d3

Please sign in to comment.