Browse files

Merge "Fixes Hyper-V SCSI slot selection"

  • Loading branch information...
2 parents 301f690 + a73e310 commit 7d85aafab7a814a7f5f1a9541e39b847f09bfb72 Jenkins committed with openstack-gerrit Jul 19, 2014
View
21 nova/tests/virt/hyperv/test_hypervapi.py
@@ -164,7 +164,7 @@ def fake_vmutils__init__(self, host='.'):
self._mox.StubOutWithMock(vmutils.VMUtils, 'set_nic_connection')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_scsi_controller')
self._mox.StubOutWithMock(vmutils.VMUtils, 'get_vm_ide_controller')
- self._mox.StubOutWithMock(vmutils.VMUtils, 'get_attached_disks_count')
+ self._mox.StubOutWithMock(vmutils.VMUtils, 'get_attached_disks')
self._mox.StubOutWithMock(vmutils.VMUtils,
'attach_volume_to_controller')
self._mox.StubOutWithMock(vmutils.VMUtils,
@@ -1121,6 +1121,8 @@ def _mock_attach_volume(self, instance_name, target_iqn, target_lun,
fake_mounted_disk = "fake_mounted_disk"
fake_device_number = 0
fake_controller_path = 'fake_scsi_controller_path'
+ self._mox.StubOutWithMock(self._conn._volumeops,
+ '_get_free_controller_slot')
self._mock_login_storage_target(target_iqn, target_lun,
target_portal,
@@ -1140,7 +1142,8 @@ def _mock_attach_volume(self, instance_name, target_iqn, target_lun,
m.AndReturn(fake_controller_path)
fake_free_slot = 1
- m = vmutils.VMUtils.get_attached_disks_count(fake_controller_path)
+ m = self._conn._volumeops._get_free_controller_slot(
+ fake_controller_path)
m.AndReturn(fake_free_slot)
m = vmutils.VMUtils.attach_volume_to_controller(instance_name,
@@ -1732,3 +1735,17 @@ def test_get_mounted_disk_from_lun_failure(self):
self.assertRaises(exception.NotFound,
self.volumeops._get_mounted_disk_from_lun,
target_iqn, target_lun)
+
+ def test_get_free_controller_slot_exception(self):
+ fake_drive = mock.MagicMock()
+ type(fake_drive).AddressOnParent = mock.PropertyMock(
+ side_effect=xrange(constants.SCSI_CONTROLLER_SLOTS_NUMBER))
+ fake_scsi_controller_path = 'fake_scsi_controller_path'
+
+ with mock.patch.object(self.volumeops._vmutils,
+ 'get_attached_disks') as fake_get_attached_disks:
+ fake_get_attached_disks.return_value = (
+ [fake_drive] * constants.SCSI_CONTROLLER_SLOTS_NUMBER)
+ self.assertRaises(vmutils.HyperVException,
+ self.volumeops._get_free_controller_slot,
+ fake_scsi_controller_path)
View
2 nova/virt/hyperv/constants.py
@@ -73,3 +73,5 @@
VHD_TYPE_FIXED = 2
VHD_TYPE_DYNAMIC = 3
+
+SCSI_CONTROLLER_SLOTS_NUMBER = 64
View
4 nova/virt/hyperv/vmutils.py
@@ -266,7 +266,7 @@ def get_vm_ide_controller(self, vm_name, ctrller_addr):
vm = self._lookup_vm_check(vm_name)
return self._get_vm_ide_controller(vm, ctrller_addr)
- def get_attached_disks_count(self, scsi_controller_path):
+ def get_attached_disks(self, scsi_controller_path):
volumes = self._conn.query("SELECT * FROM %(class_name)s "
"WHERE ResourceSubType = "
"'%(res_sub_type)s' AND "
@@ -277,7 +277,7 @@ def get_attached_disks_count(self, scsi_controller_path):
self._PHYS_DISK_RES_SUB_TYPE,
'parent':
scsi_controller_path.replace("'", "''")})
- return len(volumes)
+ return volumes
def _get_new_setting_data(self, class_name):
return self._conn.query("SELECT * FROM %s WHERE InstanceID "
View
11 nova/virt/hyperv/volumeops.py
@@ -26,7 +26,9 @@
from nova.openstack.common import excutils
from nova.openstack.common import log as logging
from nova.virt import driver
+from nova.virt.hyperv import constants
from nova.virt.hyperv import utilsfactory
+from nova.virt.hyperv import vmutils
LOG = logging.getLogger(__name__)
@@ -149,8 +151,13 @@ def attach_volume(self, connection_info, instance_name, ebs_root=False):
self._volutils.logout_storage_target(target_iqn)
def _get_free_controller_slot(self, scsi_controller_path):
- #Slots starts from 0, so the length of the disks gives us the free slot
- return self._vmutils.get_attached_disks_count(scsi_controller_path)
+ attached_disks = self._vmutils.get_attached_disks(scsi_controller_path)
+ used_slots = [int(disk.AddressOnParent) for disk in attached_disks]
+
+ for slot in xrange(constants.SCSI_CONTROLLER_SLOTS_NUMBER):
+ if slot not in used_slots:
+ return slot
+ raise vmutils.HyperVException("Exceeded the maximum number of slots")
def detach_volumes(self, block_device_info, instance_name):
mapping = driver.block_device_info_get_mapping(block_device_info)

0 comments on commit 7d85aaf

Please sign in to comment.