Add manage/unmanage methods for Hitachi Block Storage Driver

This patch adds manage_existing, manage_existing_get_size, and
 unmanage methods for Hitachi Block Storage Driver.

Implements: blueprint hitachi-driver-manage-api

Change-Id: I8dc9086452f4db2e2635bf9c933e1fd9d4328367
Signed-off-by: Seiji Aguchi <seiji.aguchi.tr@hitachi.com>
This commit is contained in:
Seiji Aguchi 2015-01-23 14:24:41 +09:00
parent 56551e66d6
commit 83e15a1653
10 changed files with 951 additions and 5 deletions

View File

@ -903,6 +903,10 @@ class HBSDNotFound(NotFound):
message = _("Storage resource could not be found.")
class HBSDVolumeIsBusy(VolumeIsBusy):
message = _("Volume %(volume_name)s is busy.")
# Datera driver
class DateraAPIException(VolumeBackendAPIException):
message = _("Bad response from Datera API")

View File

@ -33,6 +33,38 @@ def _exec_raidcom(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_vals.get(args)
def _exec_raidcom_get_ldev_no_stdout(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_no_stdout.get(args)
def _exec_raidcom_get_ldev_no_nml(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_no_nml.get(args)
def _exec_raidcom_get_ldev_no_open_v(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_no_open_v.get(args)
def _exec_raidcom_get_ldev_no_hdp(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_no_hdp.get(args)
def _exec_raidcom_get_ldev_pair(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_pair.get(args)
def _exec_raidcom_get_ldev_permit(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_permit.get(args)
def _exec_raidcom_get_ldev_invalid_size(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_invalid_size.get(args)
def _exec_raidcom_get_ldev_num_port(*args, **kargs):
return HBSDHORCMFCDriverTest.horcm_get_ldev_num_port.get(args)
class HBSDHORCMFCDriverTest(test.TestCase):
"""Test HBSDHORCMFCDriver."""
@ -52,7 +84,11 @@ VOL_TYPE : NOT DEFINED"
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS"
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : CVS : HDP\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 0\n\
STS : NML"
raidcom_get_result3 = "Serial# : 210944\n\
LDEV : 0\n\
@ -298,6 +334,108 @@ HBSD-127.0.0.1None1A30P HBSD-127.0.0.1None1A30S -mirror_id 0'):
('raidcom', u'delete lun -port CL1-A-1 -ldev_id 1'):
[1, "", ""]}
horcm_get_ldev_no_stdout = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "", ""]}
raidcom_get_ldev_no_nml = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : CVS : HDP\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 0\n\
STS :"
horcm_get_ldev_no_nml = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_no_nml, ""]}
raidcom_get_ldev_no_open_v = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : CVS\n\
VOL_ATTR : CVS : HDP\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 0\n\
STS : NML"
horcm_get_ldev_no_open_v = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_no_open_v, ""]}
raidcom_get_ldev_no_hdp = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : CVS :\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 0\n\
STS : NML"
horcm_get_ldev_no_hdp = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_no_hdp, ""]}
raidcom_get_ldev_pair = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : HORC : HDP\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 0\n\
STS : NML"
horcm_get_ldev_pair = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_pair, ""]}
raidcom_get_ldev_permit = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : XXX : HDP\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 0\n\
STS : NML"
horcm_get_ldev_permit = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_permit, ""]}
raidcom_get_ldev_invalid_size = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : CVS : HDP\n\
VOL_Capacity(BLK) : 2097151\n\
NUM_PORT : 0\n\
STS : NML"
horcm_get_ldev_invalid_size = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_invalid_size, ""]}
raidcom_get_ldev_num_port = "DUMMY\n\
LDEV : 1\n\
DUMMY\n\
DUMMY\n\
VOL_TYPE : OPEN-V-CVS\n\
VOL_ATTR : CVS : HDP\n\
VOL_Capacity(BLK) : 2097152\n\
NUM_PORT : 1\n\
STS : NML"
horcm_get_ldev_num_port = {
('raidcom', 'get ldev -ldev_id 1'):
[0, "%s" % raidcom_get_ldev_num_port, ""]}
# The following information is passed on to tests, when creating a volume
_VOLUME = {'size': 128, 'volume_type': None, 'source_volid': '0',
@ -347,6 +485,17 @@ HBSD-127.0.0.1None1A30P HBSD-127.0.0.1None1A30S -mirror_id 0'):
'volume': _VOLUME,
'provider_location': '1', 'status': 'available'}
SERIAL_NUM = '210944'
test_existing_ref = {'ldev': '1', 'serial_number': SERIAL_NUM}
test_existing_none_ldev_ref = {'ldev': None,
'serial_number': SERIAL_NUM}
test_existing_invalid_ldev_ref = {'ldev': 'AAA',
'serial_number': SERIAL_NUM}
test_existing_no_ldev_ref = {'serial_number': SERIAL_NUM}
test_existing_none_serial_ref = {'ldev': '1', 'serial_number': None}
test_existing_invalid_serial_ref = {'ldev': '1', 'serial_number': '999999'}
test_existing_no_serial_ref = {'ldev': '1'}
def __init__(self, *args, **kwargs):
super(HBSDHORCMFCDriverTest, self).__init__(*args, **kwargs)
@ -364,6 +513,7 @@ HBSD-127.0.0.1None1A30P HBSD-127.0.0.1None1A30S -mirror_id 0'):
self._setup_driver()
self.driver.check_param()
self.driver.common.pair_flock = hbsd_basiclib.NopLock()
self.driver.common.command = hbsd_horcm.HBSDHORCM(self.configuration)
self.driver.common.command.horcmgr_flock = hbsd_basiclib.NopLock()
self.driver.common.create_lock_file()
self.driver.common.command.connect_storage()
@ -668,3 +818,184 @@ HBSD-127.0.0.1None1A30P HBSD-127.0.0.1None1A30S -mirror_id 0'):
self.driver.terminate_connection,
self._VOLUME, connector)
return
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
def test_manage_existing(self, arg1, arg2):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
rc = self.driver.manage_existing(self._VOLUME, self.test_existing_ref)
self.assertEqual(1, rc['provider_location'])
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
size = self.driver.manage_existing_get_size(self._VOLUME,
self.test_existing_ref)
self.assertEqual(1, size)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_none_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_none_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_invalid_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_invalid_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_no_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_no_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_none_serial_ref(self, arg1, arg2,
arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_none_serial_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_invalid_serial_ref(self, arg1, arg2,
arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_invalid_serial_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_no_serial_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_no_serial_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'start_horcm',
return_value=[0, "", ""])
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'check_horcm',
return_value=[0, "", ""])
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
def test_unmanage(self, arg1, arg2, arg3, arg4):
self.driver.unmanage(self._VOLUME)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom)
def test_unmanage_busy(self, arg1, arg2):
self.assertRaises(exception.HBSDVolumeIsBusy,
self.driver.unmanage, self.test_volume_error3)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_no_stdout)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_no_stdout(self, arg1, arg2,
arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_no_nml)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_no_nml(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_no_open_v)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_no_open_v(self, arg1, arg2,
arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_no_hdp)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_no_hdp(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_pair)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_pair(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_permit)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_permit(self, arg1, arg2, arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_invalid_size)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_invalid_size(self, arg1, arg2,
arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_horcm.HBSDHORCM, 'exec_raidcom',
side_effect=_exec_raidcom_get_ldev_num_port)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_get_ldev_num_port(self, arg1, arg2,
arg3):
self.configuration.hitachi_serial_number = self.SERIAL_NUM
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)

View File

@ -32,6 +32,26 @@ def _exec_hsnm(*args, **kargs):
return HBSDSNM2FCDriverTest.hsnm_vals.get(args)
def _exec_hsnm_get_lu_ret_err(*args, **kargs):
return HBSDSNM2FCDriverTest.hsnm_get_lu_ret_err.get(args)
def _exec_hsnm_get_lu_vol_type_err(*args, **kargs):
return HBSDSNM2FCDriverTest.hsnm_get_lu_vol_type_err.get(args)
def _exec_hsnm_get_lu_dppool_err(*args, **kargs):
return HBSDSNM2FCDriverTest.hsnm_get_lu_dppool_err.get(args)
def _exec_hsnm_get_lu_size_err(*args, **kargs):
return HBSDSNM2FCDriverTest.hsnm_get_lu_size_err.get(args)
def _exec_hsnm_get_lu_num_port_err(*args, **kargs):
return HBSDSNM2FCDriverTest.hsnm_get_lu_num_port_err.get(args)
class HBSDSNM2FCDriverTest(test.TestCase):
"""Test HBSDSNM2FCDriver."""
@ -63,7 +83,13 @@ LUN Status Copy Type Group \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 0 Enable 5( 3D+1P) SAS"
0 2097152 blocks 256KB 0 0 Enable 0 Normal"
auluref_result1 = " Stripe RAID DP Tier \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 0 Enable 0 DUMMY"
auhgwwn_result = "Port 00 Host Group Security ON\n Detected WWN\n \
Name Port Name Host Group\n\
@ -103,11 +129,63 @@ Host Group\n abcdefg 10000000C97BCE7A \
('auluadd', '-unit None -lu 1 -dppoolno 30 -size 128g'): [0, 0, ""],
('auluadd', '-unit None -lu 1 -dppoolno 30 -size 256g'): [1, "", ""],
('auluref', '-unit None'): [0, "%s" % auluref_result, ""],
('auluref', '-unit None -lu 0'): [0, "%s" % auluref_result, ""],
('auhgmap', '-unit None -add 0 0 1 1 1'): [0, 0, ""],
('auhgwwn', '-unit None -refer'): [0, "%s" % auhgwwn_result, ""],
('aufibre1', '-unit None -refer'): [0, "%s" % aufibre1_result, ""],
('auhgmap', '-unit None -refer'): [0, "%s" % auhgmap_result, ""]}
auluref_ret_err = "Stripe RAID DP Tier \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 0 Enable 0 Normal"
hsnm_get_lu_ret_err = {
('auluref', '-unit None -lu 0'): [1, "%s" % auluref_ret_err, ""],
}
auluref_vol_type_err = "Stripe RAID DP Tier \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 0 Enable 0 DUMMY"
hsnm_get_lu_vol_type_err = {
('auluref', '-unit None -lu 0'):
[0, "%s" % auluref_vol_type_err, ""],
}
auluref_dppool_err = "Stripe RAID DP Tier \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 N/A Enable 0 Normal"
hsnm_get_lu_dppool_err = {
('auluref', '-unit None -lu 0'):
[0, "%s" % auluref_dppool_err, ""],
}
auluref_size_err = "Stripe RAID DP Tier \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097151 blocks 256KB N/A 0 Enable 0 Normal"
hsnm_get_lu_size_err = {
('auluref', '-unit None -lu 0'): [0, "%s" % auluref_size_err, ""],
}
auluref_num_port_err = "Stripe RAID DP Tier \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 0 Enable 1 Normal"
hsnm_get_lu_num_port_err = {
('auluref', '-unit None -lu 0'): [0, "%s" % auluref_num_port_err, ""],
}
# The following information is passed on to tests, when creating a volume
_VOLUME = {'size': 128, 'volume_type': None, 'source_volid': '0',
@ -151,6 +229,15 @@ Host Group\n abcdefg 10000000C97BCE7A \
'volume': test_volume_error,
'provider_location': None, 'status': 'available'}
UNIT_NAME = 'HUS110_91122819'
test_existing_ref = {'ldev': '0', 'unit_name': UNIT_NAME}
test_existing_none_ldev_ref = {'ldev': None, 'unit_name': UNIT_NAME}
test_existing_invalid_ldev_ref = {'ldev': 'AAA', 'unit_name': UNIT_NAME}
test_existing_no_ldev_ref = {'unit_name': UNIT_NAME}
test_existing_none_unit_ref = {'ldev': '0', 'unit_name': None}
test_existing_invalid_unit_ref = {'ldev': '0', 'unit_name': 'Dummy'}
test_existing_no_unit_ref = {'ldev': '0'}
def __init__(self, *args, **kwargs):
super(HBSDSNM2FCDriverTest, self).__init__(*args, **kwargs)
@ -184,6 +271,8 @@ Host Group\n abcdefg 10000000C97BCE7A \
self.driver.common.command = hbsd_snm2.HBSDSNM2(self.configuration)
self.driver.common.pair_flock = \
self.driver.common.command.set_pair_flock()
self.driver.common.horcmgr_flock = \
self.driver.common.command.set_horcmgr_flock()
self.driver.do_setup_status.set()
# API test cases
@ -377,3 +466,133 @@ Host Group\n abcdefg 10000000C97BCE7A \
self.driver.terminate_connection,
self._VOLUME, connector)
return
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
def test_manage_existing(self, arg1, arg2):
rc = self.driver.manage_existing(self._VOLUME, self.test_existing_ref)
self.assertEqual(0, rc['provider_location'])
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
size = self.driver.manage_existing_get_size(self._VOLUME,
self.test_existing_ref)
self.assertEqual(1, size)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_none_ldev(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_none_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_invalid_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_invalid_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_no_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_no_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_none_unit_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_none_unit_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_invalid_unit_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_invalid_unit_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_no_unit_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_no_unit_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm',
side_effect=_exec_hsnm_get_lu_ret_err)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_ret_err(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm',
side_effect=_exec_hsnm_get_lu_vol_type_err)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_lu_vol_type_err(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm',
side_effect=_exec_hsnm_get_lu_dppool_err)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_lu_dppool_err(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm',
side_effect=_exec_hsnm_get_lu_size_err)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_lu_size_err(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm',
side_effect=_exec_hsnm_get_lu_num_port_err)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_lu_num_port_err(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
def test_unmanage(self, arg1, arg2):
self.driver.unmanage(self._VOLUME)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
def test_unmanage_busy(self, arg1, arg2):
self.assertRaises(exception.HBSDVolumeIsBusy,
self.driver.unmanage, self.test_volume_error3)

View File

@ -68,7 +68,7 @@ LUN Status Copy Type Group \
RAID Rotational Number\n\
LU Capacity Size Group Pool Mode Level Type\
Speed of Paths Status\n\
0 2097152 blocks 256KB 0 0 Enable 5( 3D+1P) SAS"
0 2097152 blocks 256KB 0 0 Enable 0 Normal"
auhgwwn_result = "Port 00 Host Group Security ON\n Detected WWN\n \
Name Port Name Host Group\n\
@ -144,6 +144,7 @@ Authentication\n\
('auluadd', '-unit None -lu 1 -dppoolno 30 -size 128g'): [0, "", ""],
('auluadd', '-unit None -lu 1 -dppoolno 30 -size 256g'): [1, "", ""],
('auluref', '-unit None'): [0, "%s" % auluref_result, ""],
('auluref', '-unit None -lu 0'): [0, "%s" % auluref_result, ""],
('autargetmap', '-unit None -add 0 0 1 1 1'): [0, "", ""],
('autargetmap', '-unit None -add 0 0 0 0 1'): [0, "", ""],
('autargetini', '-unit None -refer'):
@ -244,6 +245,15 @@ Authentication\n\
'volume': test_volume_error,
'provider_location': None, 'status': 'available'}
UNIT_NAME = 'HUS110_91122819'
test_existing_ref = {'ldev': '0', 'unit_name': UNIT_NAME}
test_existing_none_ldev_ref = {'ldev': None, 'unit_name': UNIT_NAME}
test_existing_invalid_ldev_ref = {'ldev': 'AAA', 'unit_name': UNIT_NAME}
test_existing_no_ldev_ref = {'unit_name': UNIT_NAME}
test_existing_none_unit_ref = {'ldev': '0', 'unit_name': None}
test_existing_invalid_unit_ref = {'ldev': '0', 'unit_name': 'Dummy'}
test_existing_no_unit_ref = {'ldev': '0'}
def __init__(self, *args, **kwargs):
super(HBSDSNM2ISCSIDriverTest, self).__init__(*args, **kwargs)
@ -296,6 +306,9 @@ Authentication\n\
db = None
self.driver.common = hbsd_common.HBSDCommon(
self.configuration, self.driver, context, db)
self.driver.common.command = hbsd_snm2.HBSDSNM2(self.configuration)
self.driver.common.horcmgr_flock = \
self.driver.common.command.set_horcmgr_flock()
# API test cases
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@ -492,3 +505,83 @@ Authentication\n\
self.driver.terminate_connection,
self._VOLUME, connector)
return
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
def test_manage_existing(self, arg1, arg2):
rc = self.driver.manage_existing(self._VOLUME, self.test_existing_ref)
self.assertEqual(0, rc['provider_location'])
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
size = self.driver.manage_existing_get_size(self._VOLUME,
self.test_existing_ref)
self.assertEqual(1, size)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_none_ldev(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_none_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_invalid_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_invalid_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_no_ldev_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_no_ldev_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_none_unit_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_none_unit_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_invalid_unit_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_invalid_unit_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
@mock.patch.object(hbsd_common.HBSDCommon, '_update_volume_metadata')
def test_manage_existing_get_size_no_unit_ref(self, arg1, arg2, arg3):
self.configuration.hitachi_unit_name = self.UNIT_NAME
self.assertRaises(exception.ManageExistingInvalidReference,
self.driver.manage_existing_get_size, self._VOLUME,
self.test_existing_no_unit_ref)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
def test_unmanage(self, arg1, arg2):
self.driver.unmanage(self._VOLUME)
@mock.patch.object(hbsd_basiclib, 'get_process_lock')
@mock.patch.object(hbsd_snm2.HBSDSNM2, 'exec_hsnm', side_effect=_exec_hsnm)
def test_unmanage_busy(self, arg1, arg2):
self.assertRaises(exception.HBSDVolumeIsBusy,
self.driver.unmanage, self.test_volume_error3)

View File

@ -48,6 +48,8 @@ DEFAULT_GROUP_RANGE = [0, 65535]
NAME_PREFIX = 'HBSD-'
NORMAL_VOLUME_TYPE = 'Normal'
LOCK_DIR = '/var/lock/hbsd/'
LOG = logging.getLogger(__name__)
@ -56,6 +58,9 @@ HBSD_INFO_MSG = {
1: _('The parameter of the storage backend. '
'(config_group: %(config_group)s)'),
3: _('The storage backend can be used. (config_group: %(config_group)s)'),
4: _('The volume %(volume_id)s is managed successfully. (LDEV: %(ldev)s)'),
5: _('The volume %(volume_id)s is unmanaged successfully. '
'(LDEV: %(ldev)s)'),
}
HBSD_WARN_MSG = {
@ -131,6 +136,20 @@ HBSD_ERR_MSG = {
655: _('A snapshot status is invalid. (status: %(status)s)'),
659: _('A host group is invalid. (host group: %(gid)s)'),
660: _('The specified %(desc)s is busy.'),
700: _('There is no designation of the %(param)s. '
'The specified storage is essential to manage the volume.'),
701: _('There is no designation of the ldev. '
'The specified ldev is essential to manage the volume.'),
702: _('The specified ldev %(ldev)s could not be managed. '
'The volume type must be DP-VOL.'),
703: _('The specified ldev %(ldev)s could not be managed. '
'The ldev size must be in multiples of gigabyte.'),
704: _('The specified ldev %(ldev)s could not be managed. '
'The ldev must not be mapping.'),
705: _('The specified ldev %(ldev)s could not be managed. '
'The ldev must not be paired.'),
706: _('The volume %(volume_id)s could not be unmanaged. '
'The volume type must be %(volume_type)s.'),
}
@ -249,6 +268,9 @@ class HBSDBasicLib(object):
def set_pair_flock(self):
return NopLock()
def set_horcmgr_flock(self):
return NopLock()
def discard_zero_page(self, ldev):
pass

View File

@ -35,8 +35,12 @@ from cinder.volume.drivers.hitachi import hbsd_horcm as horcm
from cinder.volume.drivers.hitachi import hbsd_snm2 as snm2
from cinder.volume import utils as volume_utils
VERSION = '1.0.0'
"""
Version history:
1.0.0 - Initial driver
1.1.0 - Add manage_existing/manage_existing_get_size/unmanage methods
"""
VERSION = '1.1.0'
PARAM_RANGE = {
'hitachi_copy_check_interval': {'min': 1, 'max': 600},
@ -152,6 +156,10 @@ class HBSDCommon(object):
def get_snapshot_metadata(self, snapshot_id):
return self.db.snapshot_metadata_get(self.context, snapshot_id)
def _update_volume_metadata(self, volume_id, volume_metadata):
self.db.volume_metadata_update(self.context, volume_id,
volume_metadata, False)
def get_ldev(self, obj):
if not obj:
return None
@ -195,6 +203,21 @@ class HBSDCommon(object):
method = self.configuration.hitachi_default_copy_method
return method
def _string2int(self, num):
if not num:
return None
if num.isdigit():
return int(num, 10)
if not re.match(r'\w\w:\w\w:\w\w', num):
return None
try:
num = int(num.replace(':', ''), 16)
except ValueError:
return None
return num
def _range2list(self, conf, param):
str = getattr(conf, param)
lists = str.split('-')
@ -305,6 +328,7 @@ class HBSDCommon(object):
self.command = horcm.HBSDHORCM(conf)
self.command.check_param()
self.pair_flock = self.command.set_pair_flock()
self.horcmgr_flock = self.command.set_horcmgr_flock()
def create_lock_file(self):
basic_lib.create_empty_file(self.system_lock_file)
@ -734,3 +758,85 @@ class HBSDCommon(object):
def init_volinfo(self, vol_info, ldev):
vol_info[ldev] = {'in_use': TryLock(), 'lock': threading.Lock()}
def manage_existing(self, volume, existing_ref):
"""Manage an existing Hitachi storage volume.
existing_ref is a dictionary of the form:
For HUS 100 Family,
{'ldev': <logical device number on storage>,
'unit_name': <storage device name>}
For VSP G1000/VSP/HUS VM,
{'ldev': <logical device number on storage>,
'serial_number': <product number of storage system>}
"""
ldev = self._string2int(existing_ref.get('ldev'))
msg = basic_lib.set_msg(4, volume_id=volume['id'], ldev=ldev)
LOG.info(msg)
return {'provider_location': ldev}
def _manage_existing_get_size(self, volume, existing_ref):
"""Return size of volume for manage_existing."""
ldev = self._string2int(existing_ref.get('ldev'))
if ldev is None:
msg = basic_lib.output_err(701)
raise exception.HBSDError(data=msg)
size = self.command.get_ldev_size_in_gigabyte(ldev, existing_ref)
metadata = {'type': basic_lib.NORMAL_VOLUME_TYPE, 'ldev': ldev}
self._update_volume_metadata(volume['id'], metadata)
return size
def manage_existing_get_size(self, volume, existing_ref):
try:
return self._manage_existing_get_size(volume, existing_ref)
except exception.HBSDError as ex:
raise exception.ManageExistingInvalidReference(
existing_ref=existing_ref,
reason=six.text_type(ex))
def _unmanage(self, volume, ldev):
with self.horcmgr_flock:
self.delete_pair(ldev)
with self.volinfo_lock:
if ldev in self.volume_info:
self.volume_info.pop(ldev)
def unmanage(self, volume):
"""Remove the specified volume from Cinder management."""
ldev = self.get_ldev(volume)
if ldev is None:
return
self.add_volinfo(ldev, volume['id'])
if not self.volume_info[ldev]['in_use'].lock.acquire(False):
desc = self.volume_info[ldev]['in_use'].desc
basic_lib.output_err(660, desc=desc)
raise exception.HBSDVolumeIsBusy(volume_name=volume['name'])
is_vvol = self.get_volume_is_vvol(volume)
if is_vvol:
basic_lib.output_err(706, volume_id=volume['id'],
volume_type=basic_lib.NORMAL_VOLUME_TYPE)
raise exception.HBSDVolumeIsBusy(volume_name=volume['name'])
try:
self._unmanage(volume, ldev)
except exception.HBSDBusy:
raise exception.HBSDVolumeIsBusy(volume_name=volume['name'])
else:
msg = basic_lib.set_msg(5, volume_id=volume['id'], ldev=ldev)
LOG.info(msg)
finally:
if ldev in self.volume_info:
self.volume_info[ldev]['in_use'].lock.release()

View File

@ -519,3 +519,14 @@ class HBSDFCDriver(cinder.volume.driver.FibreChannelDriver):
super(HBSDFCDriver, self).restore_backup(context, backup,
volume, backup_service)
self.discard_zero_page(volume)
def manage_existing(self, volume, existing_ref):
return self.common.manage_existing(volume, existing_ref)
def manage_existing_get_size(self, volume, existing_ref):
self.do_setup_status.wait()
return self.common.manage_existing_get_size(volume, existing_ref)
def unmanage(self, volume):
self.do_setup_status.wait()
self.common.unmanage(volume)

View File

@ -23,6 +23,7 @@ import time
from oslo_concurrency import processutils as putils
from oslo_config import cfg
from oslo_utils import excutils
from oslo_utils import units
import six
from cinder import exception
@ -46,6 +47,8 @@ LUN_DELETE_INTERVAL = 3
EXEC_MAX_WAITTIME = 30
EXEC_RETRY_INTERVAL = 5
HORCM_WAITTIME = 1
PAIR_TYPE = ('HORC', 'MRCF', 'QS')
PERMITTED_TYPE = ('CVS', 'HDP', 'HDT')
RAIDCOM_LOCK_FILE = basic_lib.LOCK_DIR + 'raidcom_'
HORCMGR_LOCK_FILE = basic_lib.LOCK_DIR + 'horcmgr_'
@ -1507,3 +1510,78 @@ HORCM_CMD
self.add_used_hlun(port, gid, list)
return list
def get_ldev_size_in_gigabyte(self, ldev, existing_ref):
param = 'serial_number'
if param not in existing_ref:
msg = basic_lib.output_err(700, param=param)
raise exception.HBSDError(data=msg)
storage = existing_ref.get(param)
if storage != self.conf.hitachi_serial_number:
msg = basic_lib.output_err(648, resource=param)
raise exception.HBSDError(data=msg)
stdout = self.comm_get_ldev(ldev)
if not stdout:
msg = basic_lib.output_err(648, resource='LDEV')
raise exception.HBSDError(data=msg)
sts_line = vol_type = ""
vol_attrs = []
size = num_port = 1
lines = stdout.splitlines()
for line in lines:
if line.startswith("STS :"):
sts_line = line
elif line.startswith("VOL_TYPE :"):
vol_type = shlex.split(line)[2]
elif line.startswith("VOL_ATTR :"):
vol_attrs = shlex.split(line)[2:]
elif line.startswith("VOL_Capacity(BLK) :"):
size = int(shlex.split(line)[2])
elif line.startswith("NUM_PORT :"):
num_port = int(shlex.split(line)[2])
if 'NML' not in sts_line:
msg = basic_lib.output_err(648, resource='LDEV')
raise exception.HBSDError(data=msg)
if 'OPEN-V' not in vol_type:
msg = basic_lib.output_err(702, ldev=ldev)
raise exception.HBSDError(data=msg)
if 'HDP' not in vol_attrs:
msg = basic_lib.output_err(702, ldev=ldev)
raise exception.HBSDError(data=msg)
for vol_attr in vol_attrs:
if vol_attr == ':':
continue
if vol_attr in PAIR_TYPE:
msg = basic_lib.output_err(705, ldev=ldev)
raise exception.HBSDError(data=msg)
if vol_attr not in PERMITTED_TYPE:
msg = basic_lib.output_err(702, ldev=ldev)
raise exception.HBSDError(data=msg)
# Hitachi storage calculates volume sizes in a block unit, 512 bytes.
# So, units.Gi is divided by 512.
if size % (units.Gi / 512):
msg = basic_lib.output_err(703, ldev=ldev)
raise exception.HBSDError(data=msg)
if num_port:
msg = basic_lib.output_err(704, ldev=ldev)
raise exception.HBSDError(data=msg)
return size / (units.Gi / 512)

View File

@ -418,3 +418,14 @@ class HBSDISCSIDriver(cinder.volume.driver.ISCSIDriver):
super(HBSDISCSIDriver, self).copy_volume_to_image(context, volume,
image_service,
image_meta)
def manage_existing(self, volume, existing_ref):
return self.common.manage_existing(volume, existing_ref)
def manage_existing_get_size(self, volume, existing_ref):
self.do_setup_status.wait()
return self.common.manage_existing_get_size(volume, existing_ref)
def unmanage(self, volume):
self.do_setup_status.wait()
self.common.unmanage(volume)

View File

@ -18,6 +18,8 @@ import shlex
import threading
import time
from oslo_utils import excutils
from oslo_utils import units
import six
from cinder import exception
@ -99,6 +101,21 @@ class HBSDSNM2(basic_lib.HBSDBasicLib):
return loop.start(interval=interval).wait()
def _execute_with_exception(self, cmd, args, **kwargs):
ret, stdout, stderr = self.exec_hsnm(cmd, args, **kwargs)
if ret:
cmds = '%(cmd)s %(args)s' % {'cmd': cmd, 'args': args}
msg = basic_lib.output_err(
600, cmd=cmds, ret=ret, out=stdout, err=stderr)
raise exception.HBSDError(data=msg)
return ret, stdout, stderr
def _execute_and_return_stdout(self, cmd, args, **kwargs):
result = self._execute_with_exception(cmd, args, **kwargs)
return result[1]
def get_comm_version(self):
ret, stdout, stderr = self.exec_hsnm('auman', '-help')
m = re.search('Version (\d+).(\d+)', stdout)
@ -132,6 +149,15 @@ class HBSDSNM2(basic_lib.HBSDBasicLib):
return hlu
return None
def _get_lu(self, lu=None):
# When 'lu' is 0, it should be true. So, it cannot remove 'is None'.
if lu is None:
args = '-unit %s' % self.unit_name
else:
args = '-unit %s -lu %s' % (self.unit_name, lu)
return self._execute_and_return_stdout('auluref', args)
def get_unused_ldev(self, ldev_range):
start = ldev_range[0]
end = ldev_range[1]
@ -1084,3 +1110,48 @@ class HBSDSNM2(basic_lib.HBSDBasicLib):
self.add_used_hlun('auhgmap', port, gid, list, DUMMY_LU)
return list
def get_ldev_size_in_gigabyte(self, ldev, existing_ref):
param = 'unit_name'
if param not in existing_ref:
msg = basic_lib.output_err(700, param=param)
raise exception.HBSDError(data=msg)
storage = existing_ref.get(param)
if storage != self.conf.hitachi_unit_name:
msg = basic_lib.output_err(648, resource=param)
raise exception.HBSDError(data=msg)
try:
stdout = self._get_lu(ldev)
except exception.HBSDError:
with excutils.save_and_reraise_exception():
basic_lib.output_err(648, resource='LDEV')
lines = stdout.splitlines()
line = lines[2]
splits = shlex.split(line)
vol_type = splits[len(splits) - 1]
if basic_lib.NORMAL_VOLUME_TYPE != vol_type:
msg = basic_lib.output_err(702, ldev=ldev)
raise exception.HBSDError(data=msg)
dppool = splits[5]
if 'N/A' == dppool:
msg = basic_lib.output_err(702, ldev=ldev)
raise exception.HBSDError(data=msg)
# Hitachi storage calculates volume sizes in a block unit, 512 bytes.
# So, units.Gi is divided by 512.
size = int(splits[1])
if size % (units.Gi / 512):
msg = basic_lib.output_err(703, ldev=ldev)
raise exception.HBSDError(data=msg)
num_port = int(splits[len(splits) - 2])
if num_port:
msg = basic_lib.output_err(704, ldev=ldev)
raise exception.HBSDError(data=msg)
return size / (units.Gi / 512)