Fix rebuild with volumes attached
This patch assumes that the correct behavior for instance rebuild is to maintain attached volumes across a rebuild operation. Two important changes are: 1) Detaching all volumes during a rebuild so that they won't be 'in-use' when prep_block_devices is called to reattach them. 2) xenapi: Allowing additional volumes, not just root volumes, to be attached before boot. To handle this, we cycle through all block-device-mappings, not just the root-device, create the VDI, and later, create the VBD. Small changes include: * Using `connection_data` instead of `dev_params` (to match other parts of the code base) * Renaming `get_vdis_for_boot_from_vol` to `get_vdi_uuid_for_volume` to reflect its more general and simpler semantics. Fixes bug 1071547 Change-Id: Ie54a16be4bae2a718ed7d506f32777d0847b9089
This commit is contained in:
@@ -149,23 +149,20 @@ def match_device(device):
|
|||||||
return match.groups()
|
return match.groups()
|
||||||
|
|
||||||
|
|
||||||
def volume_in_mapping(mount_device, block_device_info, strip=strip_dev):
|
def volume_in_mapping(mount_device, block_device_info):
|
||||||
# FIXME(sirp): xen uses strip_prefix to be mountpoint agnostic. There is
|
block_device_list = [strip_dev(vol['mount_device'])
|
||||||
# probably a better way to handle this so that strip_dev can be used
|
|
||||||
# exclusively.
|
|
||||||
block_device_list = [strip(vol['mount_device'])
|
|
||||||
for vol in
|
for vol in
|
||||||
driver.block_device_info_get_mapping(
|
driver.block_device_info_get_mapping(
|
||||||
block_device_info)]
|
block_device_info)]
|
||||||
|
|
||||||
swap = driver.block_device_info_get_swap(block_device_info)
|
swap = driver.block_device_info_get_swap(block_device_info)
|
||||||
if driver.swap_is_usable(swap):
|
if driver.swap_is_usable(swap):
|
||||||
block_device_list.append(strip(swap['device_name']))
|
block_device_list.append(strip_dev(swap['device_name']))
|
||||||
|
|
||||||
block_device_list += [strip(ephemeral['device_name'])
|
block_device_list += [strip_dev(ephemeral['device_name'])
|
||||||
for ephemeral in
|
for ephemeral in
|
||||||
driver.block_device_info_get_ephemerals(
|
driver.block_device_info_get_ephemerals(
|
||||||
block_device_info)]
|
block_device_info)]
|
||||||
|
|
||||||
LOG.debug(_("block_device_list %s"), block_device_list)
|
LOG.debug(_("block_device_list %s"), block_device_list)
|
||||||
return strip(mount_device) in block_device_list
|
return strip_dev(mount_device) in block_device_list
|
||||||
|
@@ -14,7 +14,7 @@ XENSM_TYPE = 'xensm'
|
|||||||
ISCSI_TYPE = 'iscsi'
|
ISCSI_TYPE = 'iscsi'
|
||||||
|
|
||||||
|
|
||||||
def get_fake_dev_params(sr_type):
|
def get_fake_connection_data(sr_type):
|
||||||
fakes = {XENSM_TYPE: {'sr_uuid': 'falseSR',
|
fakes = {XENSM_TYPE: {'sr_uuid': 'falseSR',
|
||||||
'name_label': 'fake_storage',
|
'name_label': 'fake_storage',
|
||||||
'name_description': 'test purposes',
|
'name_description': 'test purposes',
|
||||||
@@ -73,16 +73,16 @@ class GetInstanceForVdisForSrTestCase(stubs.XenAPITestBase):
|
|||||||
|
|
||||||
self.assertEquals([], result)
|
self.assertEquals([], result)
|
||||||
|
|
||||||
def test_get_vdis_for_boot_from_vol_with_sr_uuid(self):
|
def test_get_vdi_uuid_for_volume_with_sr_uuid(self):
|
||||||
dev_params = get_fake_dev_params(XENSM_TYPE)
|
connection_data = get_fake_connection_data(XENSM_TYPE)
|
||||||
stubs.stubout_session(self.stubs, fake.SessionBase)
|
stubs.stubout_session(self.stubs, fake.SessionBase)
|
||||||
driver = xenapi_conn.XenAPIDriver(False)
|
driver = xenapi_conn.XenAPIDriver(False)
|
||||||
|
|
||||||
result = vm_utils.get_vdis_for_boot_from_vol(driver._session,
|
vdi_uuid = vm_utils.get_vdi_uuid_for_volume(
|
||||||
dev_params)
|
driver._session, connection_data)
|
||||||
self.assertEquals(result['root']['uuid'], 'falseVDI')
|
self.assertEquals(vdi_uuid, 'falseVDI')
|
||||||
|
|
||||||
def test_get_vdis_for_boot_from_vol_failure(self):
|
def test_get_vdi_uuid_for_volume_failure(self):
|
||||||
stubs.stubout_session(self.stubs, fake.SessionBase)
|
stubs.stubout_session(self.stubs, fake.SessionBase)
|
||||||
driver = xenapi_conn.XenAPIDriver(False)
|
driver = xenapi_conn.XenAPIDriver(False)
|
||||||
|
|
||||||
@@ -90,19 +90,19 @@ class GetInstanceForVdisForSrTestCase(stubs.XenAPITestBase):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
self.stubs.Set(volume_utils, 'introduce_sr', bad_introduce_sr)
|
self.stubs.Set(volume_utils, 'introduce_sr', bad_introduce_sr)
|
||||||
dev_params = get_fake_dev_params(XENSM_TYPE)
|
connection_data = get_fake_connection_data(XENSM_TYPE)
|
||||||
self.assertRaises(exception.NovaException,
|
self.assertRaises(exception.NovaException,
|
||||||
vm_utils.get_vdis_for_boot_from_vol,
|
vm_utils.get_vdi_uuid_for_volume,
|
||||||
driver._session, dev_params)
|
driver._session, connection_data)
|
||||||
|
|
||||||
def test_get_vdis_for_boot_from_iscsi_vol_missing_sr_uuid(self):
|
def test_get_vdi_uuid_for_volume_from_iscsi_vol_missing_sr_uuid(self):
|
||||||
dev_params = get_fake_dev_params(ISCSI_TYPE)
|
connection_data = get_fake_connection_data(ISCSI_TYPE)
|
||||||
stubs.stubout_session(self.stubs, fake.SessionBase)
|
stubs.stubout_session(self.stubs, fake.SessionBase)
|
||||||
driver = xenapi_conn.XenAPIDriver(False)
|
driver = xenapi_conn.XenAPIDriver(False)
|
||||||
|
|
||||||
result = vm_utils.get_vdis_for_boot_from_vol(driver._session,
|
vdi_uuid = vm_utils.get_vdi_uuid_for_volume(
|
||||||
dev_params)
|
driver._session, connection_data)
|
||||||
self.assertNotEquals(result['root']['uuid'], None)
|
self.assertNotEquals(vdi_uuid, None)
|
||||||
|
|
||||||
|
|
||||||
class VMRefOrRaiseVMFoundTestCase(test.TestCase):
|
class VMRefOrRaiseVMFoundTestCase(test.TestCase):
|
||||||
|
Reference in New Issue
Block a user