Add method to generate device names universally

When attaching block devices, we find the next device name to use by
looking at the used device letters in the block device mappings and
selecting the next available letter, as long as the letter is within
'a' - 'z' or 'aa' - 'zz'. This allows us to represent 702 devices (and
would interestingly hit an IndexError if all 'a' - 'z' and 'aa' - 'zz'
letters were in use already.

This adds a method for generating device names universally, not limited
to any particular maximum, based on a device index. For example:

  vda(index=0), sdb(index=1), vdaa(index=26), sdabc(index=730), ...

This method and its helper method will be used in a subsequent patch.

Part of blueprint conf-max-attach-volumes

Change-Id: I2699f600a98222a4dc58903ec97ca70e57701c93
This commit is contained in:
Tsuyoshi Nagata 2018-06-07 10:56:27 +09:00 committed by melanie witt
parent 89c2d1056b
commit 36f310f469
2 changed files with 40 additions and 0 deletions

View File

@ -509,6 +509,32 @@ def get_device_letter(device_name):
return _nums.sub('', letter) if device_name else device_name
def generate_device_letter(index):
"""Returns device letter by index (starts by zero)
i.e.
index = 0, 1,..., 18277
results = a, b,..., zzz
"""
base = ord('z') - ord('a') + 1
unit_dev_name = ""
while index >= 0:
letter = chr(ord('a') + (index % base))
unit_dev_name = letter + unit_dev_name
index = int(index / base) - 1
return unit_dev_name
def generate_device_name(prefix, index):
"""Returns device unit name by index (starts by zero)
i.e.
prefix = vd
index = 0, 1,..., 18277
results = vda, vdb,..., vdzzz
"""
return prefix + generate_device_letter(index)
def instance_block_mapping(instance, bdms):
root_device_name = instance['root_device_name']
# NOTE(clayg): remove this when xenapi is setting default_root_device

View File

@ -149,6 +149,20 @@ class BlockDeviceTestCase(test.NoDBTestCase):
self.assertEqual('c', block_device.get_device_letter('hdc'))
self.assertIsNone(block_device.get_device_letter(None))
def test_generate_device_name(self):
expected = (
('vda', ("vd", 0)),
('vdaa', ("vd", 26)),
('vdabc', ("vd", 730)),
('vdidpok', ("vd", 4194304)),
('sdc', ("sd", 2)),
('sdaa', ("sd", 26)),
('sdiw', ("sd", 256)),
('hdzz', ("hd", 701))
)
for res, args in expected:
self.assertEqual(res, block_device.generate_device_name(*args))
def test_volume_in_mapping(self):
swap = {'device_name': '/dev/sdb',
'swap_size': 1}