HPSSA: Add support for nested RAID levels
This commit adds support for nested RAID levels and changes functional test case for testing them as well. RAID 2 support is removed as it is useless and is now obsolete (as per Wikipedia). Implements: blueprint hpssa-support Change-Id: I61e31825812b4e80f4fd09a2dbc7ea8ac3d061f9
This commit is contained in:
parent
e923d7c750
commit
5e228cbac5
@ -18,6 +18,7 @@ import stat
|
||||
from oslo.concurrency import processutils
|
||||
import testtools
|
||||
|
||||
from proliantutils.hpssa import constants
|
||||
from proliantutils.hpssa import manager
|
||||
from proliantutils.hpssa import objects
|
||||
|
||||
@ -31,8 +32,6 @@ class HPSSATestCase(testtools.TestCase):
|
||||
def _get_server(self):
|
||||
|
||||
server = objects.Server()
|
||||
if not server.controllers:
|
||||
self.fail("No controllers detected on the server.")
|
||||
return server
|
||||
|
||||
def _get_physical_drives(self, server, no_of_physical_drives_required,
|
||||
@ -50,7 +49,7 @@ class HPSSATestCase(testtools.TestCase):
|
||||
|
||||
return physical_drives[:no_of_physical_drives_required]
|
||||
|
||||
def test_create_configuration_single_logical_drive(self):
|
||||
def _test_create_configuration_single_logical_drive(self, raid_level):
|
||||
|
||||
server = self._get_server()
|
||||
size_gb = 100
|
||||
@ -58,14 +57,11 @@ class HPSSATestCase(testtools.TestCase):
|
||||
manager.delete_configuration()
|
||||
devices_before_create = set(glob.glob('/dev/sd[a-z]'))
|
||||
|
||||
for raid_level in ['0', '1', '5', '6']:
|
||||
self._get_physical_drives(server, 2, size_gb)
|
||||
minimum_disks_required = constants.RAID_LEVEL_MIN_DISKS[raid_level]
|
||||
self._get_physical_drives(server, minimum_disks_required, size_gb)
|
||||
|
||||
raid_config = {
|
||||
'logical_disks':
|
||||
[{'size_gb': size_gb,
|
||||
'raid_level': raid_level}]
|
||||
}
|
||||
'logical_disks': [{'size_gb': size_gb, 'raid_level': raid_level}]}
|
||||
|
||||
current_config = manager.create_configuration(raid_config)
|
||||
|
||||
@ -111,3 +107,24 @@ class HPSSATestCase(testtools.TestCase):
|
||||
self.assertEqual(logical_disk['root_device_hint']['wwn'], wwn)
|
||||
|
||||
manager.delete_configuration()
|
||||
|
||||
def test_raid_0_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('0')
|
||||
|
||||
def test_raid_1_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('1')
|
||||
|
||||
def test_raid_5_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('5')
|
||||
|
||||
def test_raid_6_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('6')
|
||||
|
||||
def test_raid_10_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('1+0')
|
||||
|
||||
def test_raid_50_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('5+0')
|
||||
|
||||
def test_raid_60_single_drive(self):
|
||||
self._test_create_configuration_single_logical_drive('6+0')
|
||||
|
@ -30,6 +30,9 @@ RAID_60 = '6+0'
|
||||
RAID_1_ADM = '1ADM'
|
||||
RAID_10_ADM = '10ADM'
|
||||
|
||||
RAID_LEVEL_INPUT_TO_HPSSA_MAPPING = {RAID_50: '50', RAID_60: '60'}
|
||||
RAID_LEVEL_HPSSA_TO_INPUT_MAPPING = {
|
||||
v: k for k, v in RAID_LEVEL_INPUT_TO_HPSSA_MAPPING.iteritems()}
|
||||
|
||||
INTERFACE_TYPE_MAP = {'SCSI': INTERFACE_TYPE_SCSI,
|
||||
'SAS': INTERFACE_TYPE_SAS,
|
||||
@ -49,7 +52,8 @@ RAID_LEVEL_MIN_DISKS = {RAID_0: 2,
|
||||
RAID_5: 3,
|
||||
RAID_6: 4,
|
||||
RAID_10: 4,
|
||||
RAID_50: 6}
|
||||
RAID_50: 6,
|
||||
RAID_60: 8}
|
||||
|
||||
|
||||
def get_interface_type(ssa_interface):
|
||||
|
@ -326,6 +326,11 @@ class Controller(object):
|
||||
phy_drive_ids = ','.join(physical_drive_ids)
|
||||
size_mb = logical_drive_info['size_gb'] * 1024
|
||||
raid_level = logical_drive_info['raid_level']
|
||||
|
||||
# For RAID levels (like 5+0 and 6+0), HPSSA names them differently.
|
||||
# Check if we have mapping stored, otherwise use the same.
|
||||
raid_level = constants.RAID_LEVEL_INPUT_TO_HPSSA_MAPPING.get(
|
||||
raid_level, raid_level)
|
||||
self.execute_cmd("create", "type=logicaldrive",
|
||||
"drives=%s" % phy_drive_ids,
|
||||
"raid=%s" % raid_level,
|
||||
@ -382,7 +387,14 @@ class LogicalDrive(object):
|
||||
|
||||
# TODO(rameshg87): Check if size is always reported in GB
|
||||
self.size_gb = int(float(self.properties['Size'].rstrip(' GB')))
|
||||
|
||||
self.raid_level = self.properties.get('Fault Tolerance')
|
||||
# For RAID levels (like 5+0 and 6+0), HPSSA names them differently.
|
||||
# Check if we have mapping stored, otherwise use the same.
|
||||
raid_level_mapping = constants.RAID_LEVEL_HPSSA_TO_INPUT_MAPPING
|
||||
self.raid_level = raid_level_mapping.get(self.raid_level,
|
||||
self.raid_level)
|
||||
|
||||
self.volume_name = self.properties.get('Logical Drive Label')
|
||||
|
||||
# Trim down the WWN to 16 digits (8 bytes) so that it matches
|
||||
|
@ -9,7 +9,7 @@
|
||||
"properties": {
|
||||
"raid_level": {
|
||||
"type": "string",
|
||||
"enum": [ "0", "1", "2", "5", "6", "1+0" ],
|
||||
"enum": [ "0", "1", "5", "6", "1+0", "5+0", "6+0" ],
|
||||
"description": "RAID level for the logical disk. Required."
|
||||
},
|
||||
"size_gb": {
|
||||
|
@ -437,6 +437,248 @@ Smart Array P822 in Slot 2
|
||||
Model: SRCv24x6G
|
||||
'''
|
||||
|
||||
|
||||
HPSSA_ONE_DRIVE_RAID_50 = '''
|
||||
|
||||
Smart Array P822 in Slot 2
|
||||
Bus Interface: PCI
|
||||
Slot: 2
|
||||
Serial Number: PDVTF0BRH5T0MO
|
||||
Cache Serial Number: PBKUD0BRH5T3I6
|
||||
RAID 6 (ADG) Status: Enabled
|
||||
Controller Status: OK
|
||||
Hardware Revision: B
|
||||
Firmware Version: 4.68
|
||||
Rebuild Priority: Medium
|
||||
Expand Priority: Medium
|
||||
Surface Scan Delay: 3 secs
|
||||
Surface Scan Mode: Idle
|
||||
Queue Depth: Automatic
|
||||
Monitor and Performance Delay: 60 min
|
||||
Elevator Sort: Enabled
|
||||
Degraded Performance Optimization: Disabled
|
||||
Inconsistency Repair Policy: Disabled
|
||||
Wait for Cache Room: Disabled
|
||||
Surface Analysis Inconsistency Notification: Disabled
|
||||
Post Prompt Timeout: 15 secs
|
||||
Cache Board Present: True
|
||||
Cache Status: OK
|
||||
Cache Ratio: 10% Read / 90% Write
|
||||
Drive Write Cache: Disabled
|
||||
Total Cache Size: 2.0 GB
|
||||
Total Cache Memory Available: 1.8 GB
|
||||
No-Battery Write Cache: Disabled
|
||||
Cache Backup Power Source: Capacitors
|
||||
Battery/Capacitor Count: 1
|
||||
Battery/Capacitor Status: OK
|
||||
SATA NCQ Supported: True
|
||||
Spare Activation Mode: Activate on physical drive failure (default)
|
||||
Controller Temperature (C): 88
|
||||
Cache Module Temperature (C): 38
|
||||
Capacitor Temperature (C): 23
|
||||
Number of Ports: 6 (2 Internal / 4 External )
|
||||
Driver Name: hpsa
|
||||
Driver Version: 3.4.4
|
||||
Driver Supports HP SSD Smart Path: True
|
||||
|
||||
Array: A
|
||||
Interface Type: SAS
|
||||
Unused Space: 3280165 MB
|
||||
Status: OK
|
||||
MultiDomain Status: OK
|
||||
Array Type: Data
|
||||
HP SSD Smart Path: disable
|
||||
|
||||
|
||||
|
||||
Logical Drive: 1
|
||||
Size: 100.0 GB
|
||||
Fault Tolerance: 50
|
||||
Number of Parity Groups: 2
|
||||
Heads: 255
|
||||
Sectors Per Track: 32
|
||||
Cylinders: 25700
|
||||
Strip Size: 256 KB
|
||||
Full Stripe Size: 512 KB
|
||||
Status: OK
|
||||
MultiDomain Status: OK
|
||||
Caching: Enabled
|
||||
Parity Initialization Status: Queued
|
||||
Unique Identifier: 600508B1001C0FC2145AA6F3A0AF2A57
|
||||
Disk Name: /dev/sda
|
||||
Mount Points: None
|
||||
Logical Drive Label: 02795E8FPDVTF0BRH5T0MOF6B8
|
||||
Parity Group 0:
|
||||
physicaldrive 5I:1:1 (port 5I:box 1:bay 1, SAS, 600 GB, OK)
|
||||
physicaldrive 5I:1:3 (port 5I:box 1:bay 3, SAS, 600 GB, OK)
|
||||
physicaldrive 6I:1:5 (port 6I:box 1:bay 5, SAS, 600 GB, OK)
|
||||
Parity Group 1:
|
||||
physicaldrive 5I:1:2 (port 5I:box 1:bay 2, SAS, 600 GB, OK)
|
||||
physicaldrive 5I:1:4 (port 5I:box 1:bay 4, SAS, 600 GB, OK)
|
||||
physicaldrive 6I:1:6 (port 6I:box 1:bay 6, SAS, 600 GB, OK)
|
||||
Drive Type: Data
|
||||
LD Acceleration Method: Controller Cache
|
||||
|
||||
physicaldrive 5I:1:1
|
||||
Port: 5I
|
||||
Box: 1
|
||||
Bay: 1
|
||||
Status: OK
|
||||
Drive Type: Data Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7G55D0000N4173JLT
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 36
|
||||
Maximum Temperature (C): 43
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
physicaldrive 5I:1:2
|
||||
Port: 5I
|
||||
Box: 1
|
||||
Bay: 2
|
||||
Status: OK
|
||||
Drive Type: Data Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7H2DM0000B41800Y0
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 37
|
||||
Maximum Temperature (C): 44
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
physicaldrive 5I:1:3
|
||||
Port: 5I
|
||||
Box: 1
|
||||
Bay: 3
|
||||
Status: OK
|
||||
Drive Type: Data Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7G4ZN0000B41707PD
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 35
|
||||
Maximum Temperature (C): 42
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
physicaldrive 5I:1:4
|
||||
Port: 5I
|
||||
Box: 1
|
||||
Bay: 4
|
||||
Status: OK
|
||||
Drive Type: Data Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7H27F0000B41800S0
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 38
|
||||
Maximum Temperature (C): 45
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
physicaldrive 6I:1:5
|
||||
Port: 6I
|
||||
Box: 1
|
||||
Bay: 5
|
||||
Status: OK
|
||||
Drive Type: Data Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7H2BR0000B41800V8
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 33
|
||||
Maximum Temperature (C): 41
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
physicaldrive 6I:1:6
|
||||
Port: 6I
|
||||
Box: 1
|
||||
Bay: 6
|
||||
Status: OK
|
||||
Drive Type: Data Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7G4WD0000N4180GEJ
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 36
|
||||
Maximum Temperature (C): 44
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
|
||||
unassigned
|
||||
|
||||
physicaldrive 6I:1:7
|
||||
Port: 6I
|
||||
Box: 1
|
||||
Bay: 7
|
||||
Status: OK
|
||||
Drive Type: Unassigned Drive
|
||||
Interface Type: SAS
|
||||
Size: 600 GB
|
||||
Native Block Size: 512
|
||||
Rotational Speed: 15000
|
||||
Firmware Revision: HPD6
|
||||
Serial Number: 6SL7G54Q0000N4180W34
|
||||
Model: HP EF0600FARNA
|
||||
Current Temperature (C): 33
|
||||
Maximum Temperature (C): 39
|
||||
PHY Count: 2
|
||||
PHY Transfer Rate: 6.0Gbps, Unknown
|
||||
Drive Authentication Status: OK
|
||||
Carrier Application Version: 11
|
||||
Carrier Bootloader Version: 6
|
||||
|
||||
|
||||
SEP (Vendor ID PMCSIERA, Model SRCv24x6G) 380
|
||||
Device Number: 380
|
||||
Firmware Version: RevB
|
||||
WWID: 5001438028842E1F
|
||||
Vendor ID: PMCSIERA
|
||||
Model: SRCv24x6G
|
||||
|
||||
'''
|
||||
|
||||
HPSSA_ONE_DRIVE_100GB_RAID_5 = '''
|
||||
|
||||
Smart Array P822 in Slot 2
|
||||
|
@ -97,6 +97,16 @@ class ServerTest(testtools.TestCase):
|
||||
self.assertEqual(controller, physical_drive.parent)
|
||||
self.assertEqual(400, physical_drive.size_gb)
|
||||
|
||||
def test_server_object_one_logical_drive_raid_level_mappping(
|
||||
self, get_all_details_mock):
|
||||
stdout = raid_constants.HPSSA_ONE_DRIVE_RAID_50
|
||||
get_all_details_mock.return_value = stdout
|
||||
|
||||
server = objects.Server()
|
||||
|
||||
logical_drive = server.controllers[0].raid_arrays[0].logical_drives[0]
|
||||
self.assertEqual(constants.RAID_50, logical_drive.raid_level)
|
||||
|
||||
def test_get_controller_by_id(self, get_all_details_mock):
|
||||
|
||||
get_all_details_mock.return_value = raid_constants.HPSSA_ONE_DRIVE
|
||||
@ -212,6 +222,35 @@ class ControllerTest(testtools.TestCase):
|
||||
"raid=1",
|
||||
"size=51200")
|
||||
|
||||
@mock.patch.object(objects.Controller, 'execute_cmd')
|
||||
def test_create_logical_drive_raid_level_mapping(self, execute_mock,
|
||||
get_all_details_mock):
|
||||
|
||||
get_all_details_mock.return_value = raid_constants.HPSSA_NO_DRIVES
|
||||
|
||||
server = objects.Server()
|
||||
controller = server.controllers[0]
|
||||
|
||||
logical_drive_info = {'size_gb': 50,
|
||||
'raid_level': '5+0',
|
||||
'volume_name': 'boot_volume',
|
||||
'is_boot_volume': 'true',
|
||||
'controller': 'Smart Array P822 in Slot 2',
|
||||
'physical_disks': ['5I:1:1',
|
||||
'5I:1:2',
|
||||
'5I:1:3',
|
||||
'5I:1:4',
|
||||
'5I:1:5',
|
||||
'6I:1:6']}
|
||||
|
||||
controller.create_logical_drive(logical_drive_info,
|
||||
['5I:1:1', '5I:1:2', '5I:1:3',
|
||||
'5I:1:4', '5I:1:5', '6I:1:6'])
|
||||
execute_mock.assert_called_once_with(
|
||||
"create", "type=logicaldrive",
|
||||
"drives=5I:1:1,5I:1:2,5I:1:3,5I:1:4,5I:1:5,6I:1:6",
|
||||
"raid=50", "size=51200")
|
||||
|
||||
@mock.patch.object(objects.Controller, 'execute_cmd')
|
||||
def test_delete_all_logical_drives(self, execute_mock,
|
||||
get_all_details_mock):
|
||||
|
Loading…
Reference in New Issue
Block a user