libvirt: fix failure when attaching volume to iso instance

Attaching volume to iso instance results in failure like
this 'libvirtError: Requested operation is not valid: target
hda already exists'. The root device of iso instance is hda,
nova-compute should not assign hda to cinder volume again.

Note: this patch only address the issue of duplicate device
name 'hda', disk bus 'ide' cannot be hotplugged, so we should
stop iso instance first when attaching volume.

Closes-Bug: #1379212
(cherry picked from commit 2f0f67d17c)

Conflicts:
	nova/tests/unit/compute/test_compute.py
	nova/tests/unit/test_block_device.py

Change-Id: If9f848dc3a3788862d25692250746387c6b35286
This commit is contained in:
kiwik-chenrui 2014-10-09 16:21:34 +08:00 committed by Zhang Hua
parent 3dd5bb32bb
commit 4b439b9558
3 changed files with 30 additions and 2 deletions

View File

@ -459,11 +459,11 @@ def prepend_dev(device_name):
return device_name and '/dev/' + strip_dev(device_name)
_pref = re.compile('^((x?v|s)d)')
_pref = re.compile('^((x?v|s|h)d)')
def strip_prefix(device_name):
"""remove both leading /dev/ and xvd or sd or vd."""
"""remove both leading /dev/ and xvd or sd or vd or hd."""
device_name = strip_dev(device_name)
return _pref.sub('', device_name)

View File

@ -7240,6 +7240,32 @@ class ComputeTestCase(BaseTestCase):
self.assertEqual(vol_bdm.disk_bus, 'virtio')
self.assertEqual(vol_bdm.device_type, 'disk')
def test_reserve_block_device_name_with_iso_instance(self):
instance = self._create_fake_instance_obj(
params={'root_device_name': '/dev/hda'})
bdm = objects.BlockDeviceMapping(
**{'source_type': 'image', 'destination_type': 'local',
'image_id': 'fake-image-id', 'device_name': '/dev/hda',
'instance_uuid': instance.uuid})
bdm.create(self.context)
self.compute.reserve_block_device_name(self.context, instance,
'/dev/vdb', 'fake-volume-id',
'ide', 'disk')
bdms = objects.BlockDeviceMappingList.get_by_instance_uuid(
self.context, instance.uuid)
bdms = list(bdms)
self.assertEqual(2, len(bdms))
bdms.sort(key=operator.attrgetter('device_name'))
vol_bdm = bdms[1]
self.assertEqual('volume', vol_bdm.source_type)
self.assertEqual('volume', vol_bdm.destination_type)
self.assertEqual('/dev/hdb', vol_bdm.device_name)
self.assertEqual('fake-volume-id', vol_bdm.volume_id)
self.assertEqual('ide', vol_bdm.disk_bus)
self.assertEqual('disk', vol_bdm.device_type)
class ComputeAPITestCase(BaseTestCase):
def setUp(self):

View File

@ -133,6 +133,7 @@ class BlockDeviceTestCase(test.NoDBTestCase):
self.assertEqual(block_device.strip_prefix('a'), 'a')
self.assertEqual(block_device.strip_prefix('xvda'), 'a')
self.assertEqual(block_device.strip_prefix('vda'), 'a')
self.assertEqual(block_device.strip_prefix('hda'), 'a')
def test_get_device_letter(self):
self.assertEqual(block_device.get_device_letter(''), '')
@ -142,6 +143,7 @@ class BlockDeviceTestCase(test.NoDBTestCase):
self.assertEqual(block_device.get_device_letter('a'), 'a')
self.assertEqual(block_device.get_device_letter('sdb2'), 'b')
self.assertEqual(block_device.get_device_letter('vdc'), 'c')
self.assertEqual(block_device.get_device_letter('hdc'), 'c')
def test_volume_in_mapping(self):
swap = {'device_name': '/dev/sdb',