From 00ac56a100ac7329a01b5f1fa336b99e64778eaf Mon Sep 17 00:00:00 2001 From: ftersin Date: Mon, 26 May 2014 20:07:55 +0400 Subject: [PATCH] Run instance root device determination fix. Legacy bdm in incoming parameters contains a number of devices specified by their names (e.g. "vdb" or "/dev/vdc"). Current code considers "vda" as root device and doesn't work on "/dev/vda", for example. This fix extracts the last significant character (digits are skipped in "..sda1") from the name like "a", "b", "c" and selects the root device by checking for "a". Change-Id: Iebaa117bb747d30ac9ceabd8805740dec9d1355c Closes-Bug: #1322180 --- nova/block_device.py | 10 ++++++++++ nova/compute/api.py | 4 +++- nova/compute/utils.py | 6 +----- nova/tests/test_block_device.py | 9 +++++++++ 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/nova/block_device.py b/nova/block_device.py index 360316631f24..fbc87099dbe2 100644 --- a/nova/block_device.py +++ b/nova/block_device.py @@ -453,6 +453,16 @@ def strip_prefix(device_name): return _pref.sub('', device_name) +_nums = re.compile('\d+') + + +def get_device_letter(device_name): + letter = strip_prefix(device_name) + # NOTE(vish): delete numbers in case we have something like + # /dev/sda1 + return _nums.sub('', letter) + + def instance_block_mapping(instance, bdms): root_device_name = instance['root_device_name'] # NOTE(clayg): remove this when xenapi is setting default_root_device diff --git a/nova/compute/api.py b/nova/compute/api.py index 47ec3af7e691..c025616711fc 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -861,7 +861,9 @@ class API(base.Base): return {} for bdm in block_device_mapping: - if legacy_bdm and bdm.get('device_name') != 'vda': + if (legacy_bdm and + block_device.get_device_letter( + bdm.get('device_name', '')) != 'a'): continue elif not legacy_bdm and bdm.get('boot_index') != 0: continue diff --git a/nova/compute/utils.py b/nova/compute/utils.py index 1eea08449b24..3b47dce3d0ea 100644 --- a/nova/compute/utils.py +++ b/nova/compute/utils.py @@ -15,7 +15,6 @@ """Compute-related Utilities and helpers.""" import itertools -import re import string import traceback @@ -164,10 +163,7 @@ def get_next_device_name(instance, device_name_list, used_letters = set() for device_path in device_name_list: - letter = block_device.strip_prefix(device_path) - # NOTE(vish): delete numbers in case we have something like - # /dev/sda1 - letter = re.sub("\d+", "", letter) + letter = block_device.get_device_letter(device_path) used_letters.add(letter) # NOTE(vish): remove this when xenapi is properly setting diff --git a/nova/tests/test_block_device.py b/nova/tests/test_block_device.py index c1b5f1192696..2f0792a20203 100644 --- a/nova/tests/test_block_device.py +++ b/nova/tests/test_block_device.py @@ -94,6 +94,15 @@ class BlockDeviceTestCase(test.NoDBTestCase): self.assertEqual(block_device.strip_prefix('xvda'), 'a') self.assertEqual(block_device.strip_prefix('vda'), 'a') + def test_get_device_letter(self): + self.assertEqual(block_device.get_device_letter(''), '') + self.assertEqual(block_device.get_device_letter('/dev/sda1'), 'a') + self.assertEqual(block_device.get_device_letter('/dev/xvdb'), 'b') + self.assertEqual(block_device.get_device_letter('/dev/d'), 'd') + 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') + def test_volume_in_mapping(self): swap = {'device_name': '/dev/sdb', 'swap_size': 1}