summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/compute/manager.py15
-rw-r--r--nova/compute/utils.py38
-rw-r--r--nova/tests/compute/test_compute_utils.py11
3 files changed, 38 insertions, 26 deletions
diff --git a/nova/compute/manager.py b/nova/compute/manager.py
index 0ad5c1dc8..39e68e9f8 100644
--- a/nova/compute/manager.py
+++ b/nova/compute/manager.py
@@ -2438,16 +2438,19 @@ class ComputeManager(manager.SchedulerDependentManager):
def do_reserve():
bdms = self.conductor_api.block_device_mapping_get_all_by_instance(
context, instance)
- result = compute_utils.get_device_name_for_instance(context,
- instance,
- bdms,
- device)
+
+ device_name = compute_utils.get_device_name_for_instance(
+ context, instance, bdms, device)
+
# NOTE(vish): create bdm here to avoid race condition
values = {'instance_uuid': instance['uuid'],
'volume_id': volume_id or 'reserved',
- 'device_name': result}
+ 'device_name': device_name}
+
self.conductor_api.block_device_mapping_create(context, values)
- return result
+
+ return device_name
+
return do_reserve()
@exception.wrap_exception(notifier=notifier, publisher_id=publisher_id())
diff --git a/nova/compute/utils.py b/nova/compute/utils.py
index 8d363fa1c..bdec9acec 100644
--- a/nova/compute/utils.py
+++ b/nova/compute/utils.py
@@ -75,49 +75,59 @@ def get_device_name_for_instance(context, instance, bdms, device):
appropriate format.
"""
req_prefix = None
- req_letters = None
+ req_letter = None
+
if device:
try:
- req_prefix, req_letters = block_device.match_device(device)
+ req_prefix, req_letter = block_device.match_device(device)
except (TypeError, AttributeError, ValueError):
raise exception.InvalidDevicePath(path=device)
+
mappings = block_device.instance_block_mapping(instance, bdms)
+
try:
prefix = block_device.match_device(mappings['root'])[0]
except (TypeError, AttributeError, ValueError):
raise exception.InvalidDevicePath(path=mappings['root'])
+
# NOTE(vish): remove this when xenapi is setting default_root_device
if driver.compute_driver_matches('xenapi.XenAPIDriver'):
prefix = '/dev/xvd'
+
if req_prefix != prefix:
LOG.debug(_("Using %(prefix)s instead of %(req_prefix)s") % locals())
- letters_list = []
- for _name, device in mappings.iteritems():
- letter = block_device.strip_prefix(device)
+
+ used_letters = set()
+ for device_path in mappings.itervalues():
+ letter = block_device.strip_prefix(device_path)
# NOTE(vish): delete numbers in case we have something like
# /dev/sda1
letter = re.sub("\d+", "", letter)
- letters_list.append(letter)
- used_letters = set(letters_list)
+ used_letters.add(letter)
# NOTE(vish): remove this when xenapi is properly setting
# default_ephemeral_device and default_swap_device
if driver.compute_driver_matches('xenapi.XenAPIDriver'):
instance_type_id = instance['instance_type_id']
instance_type = instance_types.get_instance_type(instance_type_id)
+
if instance_type['ephemeral_gb']:
- used_letters.update('b')
+ used_letters.add('b')
+
if instance_type['swap']:
- used_letters.update('c')
+ used_letters.add('c')
- if not req_letters:
- req_letters = _get_unused_letters(used_letters)
- if req_letters in used_letters:
+ if not req_letter:
+ req_letter = _get_unused_letter(used_letters)
+
+ if req_letter in used_letters:
raise exception.DevicePathInUse(path=device)
- return prefix + req_letters
+
+ device_name = prefix + req_letter
+ return device_name
-def _get_unused_letters(used_letters):
+def _get_unused_letter(used_letters):
doubles = [first + second for second in string.ascii_lowercase
for first in string.ascii_lowercase]
all_letters = set(list(string.ascii_lowercase) + doubles)
diff --git a/nova/tests/compute/test_compute_utils.py b/nova/tests/compute/test_compute_utils.py
index 4372039e0..e7763a1c3 100644
--- a/nova/tests/compute/test_compute_utils.py
+++ b/nova/tests/compute/test_compute_utils.py
@@ -71,10 +71,8 @@ class ComputeValidateDeviceTestCase(test.TestCase):
def _validate_device(self, device=None):
bdms = db.block_device_mapping_get_all_by_instance(
self.context, self.instance['uuid'])
- return compute_utils.get_device_name_for_instance(self.context,
- self.instance,
- bdms,
- device)
+ return compute_utils.get_device_name_for_instance(
+ self.context, self.instance, bdms, device)
@staticmethod
def _fake_bdm(device):
@@ -148,8 +146,9 @@ class ComputeValidateDeviceTestCase(test.TestCase):
self._validate_device, '/baddata/vdc')
def test_device_in_use(self):
- self.assertRaises(exception.DevicePathInUse,
- self._validate_device, '/dev/vdb')
+ exc = self.assertRaises(exception.DevicePathInUse,
+ self._validate_device, '/dev/vda')
+ self.assertIn('/dev/vda', str(exc))
def test_swap(self):
self.instance['default_swap_device'] = "/dev/vdc"