* Profile register check in plugin_register() has been moved to
SmisCommon.profile_register_load().
* New _plugin_register_vendor_workaround() with NetApp profile register typo
fix:
NetApp: 'FC Target Port'
SMI-S: 'FC Target Ports'
* Fallback mode has been removed.
* The 'force_fallback_mode' has been changed to silently ignored.
No provider are facing issue on this.
* Updated self._root_cim_syss() to use SmisSys.root_cim_sys().
* Replaced _get_cim_instance_by_id('System', sys_id) with
self._cim_sys_of_sys_id(sys_id).
* The SNIA class has been merged into SmisCommon.
* Change _iscsi_tgt_is_supported() to check 1.2 version of 'iSCSI Target
Port' profile as it has not been changed since then and many(HP and HDS)
are still using 1.2 version string.
* These lsm.System related methods has been moved to SmisSys:
* self._sys_id() -> SmisSys.sys_id_of_cim_sys()
* self._cim_sys_to_lsm -> SmisSys.cim_sys_to_lsm_sys()
* self._cim_sys_pros() -> SmisSys.cim_sys_pros()
* self._property_list_of_id('System') -> SmisSys.cim_sys_id_pros()
Tested on these arrays for 'lsmcli list --type systems' and
'list --type target_ports':
* LSI/Avago MegaRAID
* EMC VNX
* EMC CX
* EMC VMAX
* IBM XIV
* Fujitsu DX80S2
* HP 3PAR
* Dell/Compellent Storage Center
* Dot Hill AssuredSAN 4524
* HDS AMS2100
* NetApp ONTAP
* NetApp-E
Tested on this array for 'lsmcli volume-mask', 'lsmcli volume-create' and
'lsmcli volume-unmask' for _get_cim_instance_by_id() changes:
* EMC VNX
Plugin_test PASS[1] on EMC VNX.
[1] Except plugin_test failed on IS_MASKED when deleting a volume and access
group.
Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 586 +++++++++++---------------------------------------
1 file changed, 130 insertions(+), 456 deletions(-)
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index 870c6c1..c433ed0 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -35,6 +35,8 @@ from lsm import (IStorageAreaNetwork, error, uri_parse, LsmError, ErrorNumber,
search_property)
from dmtf import DMTF
+from smis_common import SmisCommon
+from smis_sys import SmisSys
## Variable Naming scheme:
# cim_xxx CIMInstance
@@ -188,21 +190,6 @@ def _lsm_init_type_to_dmtf(init_type):
"Does not support provided init_type: %d" % init_type)
-class SNIA(object):
- BLK_ROOT_PROFILE = 'Array'
- BLK_SRVS_PROFILE = 'Block Services'
- DISK_LITE_PROFILE = 'Disk Drive Lite'
- MULTI_SYS_PROFILE = 'Multiple Computer System'
- MASK_PROFILE = 'Masking and Mapping'
- GROUP_MASK_PROFILE = 'Group Masking and Mapping'
- FC_TGT_PORT_PROFILE = 'FC Target Ports'
- ISCSI_TGT_PORT_PROFILE = 'iSCSI Target Ports'
- SMIS_SPEC_VER_1_4 = '1.4'
- SMIS_SPEC_VER_1_5 = '1.5'
- SMIS_SPEC_VER_1_6 = '1.6'
- REG_ORG_CODE = pywbem.Uint16(11)
-
-
class Smis(IStorageAreaNetwork):
"""
SMI-S plug-ing which exposes a small subset of the overall provided
@@ -327,7 +314,6 @@ class Smis(IStorageAreaNetwork):
DMTF_STATUS_POWER_MODE = 18
# DSP 1033 Profile Registration
- DMTF_INTEROP_NAMESPACES = ['interop', 'root/interop']
SMIS_DEFAULT_NAMESPACE = 'interop'
IAAN_WBEM_HTTP_PORT = 5988
@@ -405,11 +391,11 @@ class Smis(IStorageAreaNetwork):
self._c = None
self.tmo = 0
self.system_list = None
- self.cim_rps = []
- self.cim_root_profile_dict = dict()
- self.fallback_mode = True # Means we cannot use profile register
self.all_vendor_namespaces = []
self.debug_path = None
+ self._profile_dict = {}
+ self._blk_root_cim_rp = None
+ self._vendor_namespace = None
def _get_cim_instance_by_id(self, class_type, requested_id,
property_list=None, raise_error=True):
@@ -583,48 +569,30 @@ class Smis(IStorageAreaNetwork):
if 'force_fallback_mode' in u['parameters'] and \
u['parameters']['force_fallback_mode'] == 'yes':
- return
+ # force_fallback_mode is not needed any more.
+ # silently ignore.
+ pass
- # Checking profile registration support status unless
- # force_fallback_mode is enabled in URI.
- namespace_check_list = Smis.DMTF_INTEROP_NAMESPACES
- if 'namespace' in u['parameters'] and \
- u['parameters']['namespace'] not in namespace_check_list:
- namespace_check_list.extend([u['parameters']['namespace']])
+ (self._profile_dict, self._blk_root_cim_rp) = \
+ SmisCommon.profile_register_load(self._c)
- for interop_namespace in Smis.DMTF_INTEROP_NAMESPACES:
- try:
- self.cim_rps = self._c.EnumerateInstances(
- 'CIM_RegisteredProfile',
- namespace=interop_namespace,
- PropertyList=['RegisteredName', 'RegisteredVersion',
- 'RegisteredOrganization'],
- LocalOnly=False)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_NAMESPACE or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- pass
- else:
- raise
- if len(self.cim_rps) != 0:
- break
+ self._plugin_register_vendor_workaround()
- if len(self.cim_rps) >= 1:
- self.fallback_mode = False
- self.all_vendor_namespaces = []
- # Support 'Array' profile is step 0 for this whole plugin.
- # We find out all 'Array' CIM_RegisteredProfile and stored
- # them into self.cim_root_profile_dict
- if not self._profile_is_supported(
- SNIA.BLK_ROOT_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False):
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support "
- "SNIA SMI-S SPEC %s '%s' profile" %
- (SNIA.SMIS_SPEC_VER_1_4,
- SNIA.BLK_ROOT_PROFILE))
+ SmisCommon.profile_check(
+ self._profile_dict, SmisCommon.SNIA_BLK_ROOT_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4, raise_error=True)
+
+ def _plugin_register_vendor_workaround(self):
+ """
+ Vendor specfic wround for plugin_register()
+ """
+ # NetApp ONTAP typo on FC Target profile:
+ # NetApp: 'FC Target Port'
+ # SMI-S: 'FC Target Ports'
+ if 'FC Target Port' in self._profile_dict.keys():
+ self._profile_dict[SmisCommon.SNIA_FC_TGT_PORT_PROFILE] = \
+ self._profile_dict['FC Target Port']
+ return None
def time_out_set(self, ms, flags=0):
self.tmo = ms
@@ -643,20 +611,6 @@ class Smis(IStorageAreaNetwork):
volume_resize()
volume_delete()
"""
- if self.fallback_mode:
- # pools() is mandatory, we will try pools() related methods first
- try:
- self._cim_pools_of(cim_sys_path)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support "
- "CIM_StoragePool querying which is "
- "mandatory for pools() method")
- else:
- raise
-
# CIM_StorageConfigurationService is optional.
cim_scs_path = self._get_cim_service_path(
cim_sys_path, 'CIM_StorageConfigurationService')
@@ -708,23 +662,10 @@ class Smis(IStorageAreaNetwork):
return
def _disk_cap_set(self, cim_sys_path, cap):
- if self.fallback_mode:
- try:
- # Assuming provider support disk drive when systems under it
- # support it.
- self._enumerate('CIM_DiskDrive')
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- return
- else:
- raise
- else:
- if not self._profile_is_supported(SNIA.DISK_LITE_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=False):
- return
+ if not self._profile_is_supported(SmisCommon.SNIA_DISK_LITE_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
+ raise_error=False):
+ return
cap.set(Capabilities.DISKS)
return
@@ -807,16 +748,9 @@ class Smis(IStorageAreaNetwork):
Fallback mode means target provider does not support interop, but
they still need to follow at least SNIA SMI-S 1.4rev6
"""
- if self.fallback_mode:
- cim_ccs_path = self._get_cim_service_path(
- cim_sys_path, 'CIM_ControllerConfigurationService')
- if cim_ccs_path is None:
- return
-
- elif not self._profile_is_supported(SNIA.MASK_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=False):
+ if not self._profile_is_supported(SmisCommon.SNIA_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
+ raise_error=False):
return
cap.set(Capabilities.ACCESS_GROUPS)
@@ -831,9 +765,9 @@ class Smis(IStorageAreaNetwork):
if cim_sys_path.classname == 'Clar_StorageSystem':
return
- if self._fc_tgt_is_supported(cim_sys_path):
+ if self._fc_tgt_is_supported():
cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
- if self._iscsi_tgt_is_supported(cim_sys_path):
+ if self._iscsi_tgt_is_supported():
cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
return
@@ -845,51 +779,8 @@ class Smis(IStorageAreaNetwork):
def _tgt_cap_set(self, cim_sys_path, cap):
- # LSI MegaRAID actually not support FC Target and iSCSI target,
- # They expose empty list of CIM_FCPort
- if cim_sys_path.classname == 'LSIESG_MegaRAIDHBA':
- return
-
- flag_fc_support = False
- flag_iscsi_support = False
- if self.fallback_mode:
- flag_fc_support = True
- flag_iscsi_support = True
- # CIM_FCPort is the control class of FC Targets profile
- try:
- self._cim_fc_tgt_of(cim_sys_path)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- flag_fc_support = False
-
- try:
- self._cim_iscsi_pg_of(cim_sys_path)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- flag_iscsi_support = False
- else:
- flag_fc_support = self._profile_is_supported(
- SNIA.FC_TGT_PORT_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=False)
- # One more check for NetApp Typo:
- # NetApp: 'FC Target Port'
- # SMI-S: 'FC Target Ports'
- # Bug reported.
- if not flag_fc_support:
- flag_fc_support = self._profile_is_supported(
- 'FC Target Port',
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=False)
- flag_iscsi_support = self._profile_is_supported(
- SNIA.ISCSI_TGT_PORT_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=False)
+ flag_fc_support = self._fc_tgt_is_supported()
+ flag_iscsi_support = self._iscsi_tgt_is_supported()
if flag_fc_support or flag_iscsi_support:
cap.set(Capabilities.TARGET_PORTS)
@@ -914,10 +805,10 @@ class Smis(IStorageAreaNetwork):
cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
cap.set(Capabilities.VOLUME_MASK)
- if self._fc_tgt_is_supported(cim_sys_path):
+ if self._fc_tgt_is_supported():
cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_WWPN)
cap.set(Capabilities.ACCESS_GROUP_CREATE_WWPN)
- if self._iscsi_tgt_is_supported(cim_sys_path):
+ if self._iscsi_tgt_is_supported():
cap.set(Capabilities.ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN)
cap.set(Capabilities.ACCESS_GROUP_CREATE_ISCSI_IQN)
@@ -960,8 +851,7 @@ class Smis(IStorageAreaNetwork):
@handle_cim_errors
def capabilities(self, system, flags=0):
- cim_sys = self._get_cim_instance_by_id(
- 'System', system.id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(system.id)
cap = Capabilities()
@@ -1098,8 +988,6 @@ class Smis(IStorageAreaNetwork):
rc = []
if class_type == 'Volume':
rc = ['SystemName', 'DeviceID']
- elif class_type == 'System':
- rc = ['Name']
elif class_type == 'Pool':
rc = ['InstanceID']
elif class_type == 'SystemChild':
@@ -1126,12 +1014,6 @@ class Smis(IStorageAreaNetwork):
"""
return self._id('SystemChild', cim_xxx)
- def _sys_id(self, cim_sys):
- """
- Return CIM_ComputerSystem['Name']
- """
- return self._id('System', cim_sys)
-
def _pool_id(self, cim_pool):
"""
Return CIM_StoragePool['InstanceID']
@@ -1518,11 +1400,11 @@ class Smis(IStorageAreaNetwork):
profile.
"""
rc = []
- cim_sys_pros = self._property_list_of_id("System")
+ cim_sys_pros = SmisSys.cim_sys_id_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)
cim_vol_pros = self._cim_vol_pros()
for cim_sys in cim_syss:
- sys_id = self._sys_id(cim_sys)
+ sys_id = SmisSys.sys_id_of_cim_sys(cim_sys)
pool_pros = self._property_list_of_id('Pool')
for cim_pool in self._cim_pools_of(cim_sys.path, pool_pros):
pool_id = self._pool_id(cim_pool)
@@ -1583,11 +1465,11 @@ class Smis(IStorageAreaNetwork):
rc = []
cim_pool_pros = self._new_pool_cim_pool_pros()
- cim_sys_pros = self._property_list_of_id("System")
+ cim_sys_pros = SmisSys.cim_sys_id_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)
for cim_sys in cim_syss:
- system_id = self._sys_id(cim_sys)
+ system_id = SmisSys.sys_id_of_cim_sys(cim_sys)
for cim_pool in self._cim_pools_of(cim_sys.path, cim_pool_pros):
# Skip spare storage pool.
if 'Usage' in cim_pool and \
@@ -1629,12 +1511,12 @@ class Smis(IStorageAreaNetwork):
Find out the system ID for certain CIM_StoragePool.
Will return '' if failed.
"""
- sys_pros = self._property_list_of_id('System')
+ sys_pros = SmisSys.cim_sys_id_pros()
cim_syss = self._c.Associators(cim_pool.path,
ResultClass='CIM_ComputerSystem',
PropertyList=sys_pros)
if len(cim_syss) == 1:
- return self._sys_id(cim_syss[0])
+ return SmisSys.sys_id_of_cim_sys(cim_syss[0])
return ''
@handle_cim_errors
@@ -1668,29 +1550,6 @@ class Smis(IStorageAreaNetwork):
total_space, free_space,
status, status_info, system_id)
- @staticmethod
- def _cim_sys_to_lsm(cim_sys):
- # In the case of systems we are assuming that the System Name is
- # unique.
- status = System.STATUS_UNKNOWN
- status_info = ''
-
- if 'OperationalStatus' in cim_sys:
- (status, status_info) = \
- DMTF.cim_sys_status_of(cim_sys['OperationalStatus'])
-
- return System(cim_sys['Name'], cim_sys['ElementName'], status,
- status_info)
-
- def _cim_sys_pros(self):
- """
- Return a list of properties required to create a LSM System
- """
- cim_sys_pros = self._property_list_of_id('System',
- ['ElementName',
- 'OperationalStatus'])
- return cim_sys_pros
-
@handle_cim_errors
def systems(self, flags=0):
"""
@@ -1700,10 +1559,10 @@ class Smis(IStorageAreaNetwork):
don't check support status here as startup() already checked 'Array'
profile.
"""
- cim_sys_pros = self._cim_sys_pros()
+ cim_sys_pros = SmisSys.cim_sys_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)
- return [Smis._cim_sys_to_lsm(s) for s in cim_syss]
+ return [SmisSys.cim_sys_to_lsm_sys(s) for s in cim_syss]
def _check_for_dupe_vol(self, volume_name, original_exception):
"""
@@ -2142,8 +2001,7 @@ class Smis(IStorageAreaNetwork):
target ports(all FC and FCoE port for access_group.init_type == WWPN,
and the same to iSCSI)
"""
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
cim_init_mg = self._cim_init_mg_of_id(access_group.id,
raise_error=True)
@@ -2225,8 +2083,7 @@ class Smis(IStorageAreaNetwork):
mask_type = self._mask_type(raise_error=True)
# Workaround for EMC VNX/CX
if mask_type == Smis.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(volume.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = Smis.MASK_TYPE_MASK
@@ -2245,8 +2102,7 @@ class Smis(IStorageAreaNetwork):
access_group.id +
"will not do volume_mask()")
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(volume.system_id)
cim_css_path = self._get_cim_service_path(
cim_sys.path, 'CIM_ControllerConfigurationService')
@@ -2274,8 +2130,7 @@ class Smis(IStorageAreaNetwork):
"""
cim_vol = self._get_cim_instance_by_id(
'Volume', volume.id, raise_error=True)
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(volume.system_id)
cim_gmm_cap = self._c.Associators(
cim_sys.path,
@@ -2369,8 +2224,7 @@ class Smis(IStorageAreaNetwork):
mask_type = self._mask_type(raise_error=True)
# Workaround for EMC VNX/CX
if mask_type == Smis.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(volume.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = Smis.MASK_TYPE_MASK
@@ -2379,8 +2233,7 @@ class Smis(IStorageAreaNetwork):
return self._volume_unmask_old(access_group, volume)
def _volume_unmask_old(self, access_group, volume):
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
cim_ccs_path = self._get_cim_service_path(
cim_sys.path, 'CIM_ControllerConfigurationService')
@@ -2522,11 +2375,9 @@ class Smis(IStorageAreaNetwork):
if property_list is None:
property_list = []
- if (not self.fallback_mode and
- self._profile_is_supported(SNIA.MASK_PROFILE,
- SNIA.SMIS_SPEC_VER_1_6,
- strict=False,
- raise_error=False)):
+ if self._profile_is_supported(SmisCommon.SNIA_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_6,
+ raise_error=False):
return self._c.Associators(
cim_spc_path,
AssocClass='CIM_AssociatedPrivilege',
@@ -2570,8 +2421,7 @@ class Smis(IStorageAreaNetwork):
# Workaround for EMC VNX/CX
if mask_type == Smis.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = Smis.MASK_TYPE_MASK
@@ -2610,8 +2460,7 @@ class Smis(IStorageAreaNetwork):
# Workaround for EMC VNX/CX
if mask_type == Smis.MASK_TYPE_GROUP:
- cim_sys = self._get_cim_instance_by_id(
- 'System', volume.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(volume.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
mask_type = Smis.MASK_TYPE_MASK
@@ -2698,31 +2547,30 @@ class Smis(IStorageAreaNetwork):
def _mask_type(self, raise_error=False):
"""
Return Smis.MASK_TYPE_NO_SUPPORT, MASK_TYPE_MASK or MASK_TYPE_GROUP
- For fallback_mode, return MASK_TYPE_MASK
if 'Group Masking and Mapping' profile is supported, return
- MASK_TYPE_GROUP
+ 'MASK_TYPE_GROUP'
+ if 'Masking and Mapping' profile is supported, return
+ 'MASK_TYPE_MASK'
If raise_error == False, just return Smis.MASK_TYPE_NO_SUPPORT
or, raise NO_SUPPORT error.
"""
- if self.fallback_mode:
- return Smis.MASK_TYPE_MASK
- if self._profile_is_supported(SNIA.GROUP_MASK_PROFILE,
- SNIA.SMIS_SPEC_VER_1_5,
- strict=False,
+ if self._profile_is_supported(SmisCommon.SNIA_GROUP_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_5,
raise_error=False):
return Smis.MASK_TYPE_GROUP
- if self._profile_is_supported(SNIA.MASK_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
+ if self._profile_is_supported(SmisCommon.SNIA_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
raise_error=False):
return Smis.MASK_TYPE_MASK
if raise_error:
raise LsmError(ErrorNumber.NO_SUPPORT,
"Target SMI-S provider does not support "
"%s version %s or %s version %s" %
- (SNIA.MASK_PROFILE, SNIA.SMIS_SPEC_VER_1_4,
- SNIA.GROUP_MASK_PROFILE, SNIA.SMIS_SPEC_VER_1_5))
+ (SmisCommon.SNIA_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
+ SmisCommon.SNIA_GROUP_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_5))
return Smis.MASK_TYPE_NO_SUPPORT
@handle_cim_errors
@@ -2730,7 +2578,7 @@ class Smis(IStorageAreaNetwork):
rc = []
mask_type = self._mask_type(raise_error=True)
- cim_sys_pros = self._property_list_of_id('System')
+ cim_sys_pros = SmisSys.cim_sys_id_pros()
cim_syss = self._root_cim_syss(cim_sys_pros)
cim_spc_pros = self._cim_spc_pros()
@@ -2741,7 +2589,7 @@ class Smis(IStorageAreaNetwork):
# CIM_RegisteredProfile, but actually they don't support it.
mask_type = Smis.MASK_TYPE_MASK
- system_id = self._sys_id(cim_sys)
+ system_id = SmisSys.sys_id_of_cim_sys(cim_sys)
if mask_type == Smis.MASK_TYPE_GROUP:
cim_init_mg_pros = self._cim_init_mg_pros()
cim_init_mgs = self._cim_init_mg_of(cim_sys.path,
@@ -2800,8 +2648,7 @@ class Smis(IStorageAreaNetwork):
expect_class='CIM_StorageHardwareID')
def _ag_init_add_group(self, access_group, init_id, init_type):
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
raise LsmError(ErrorNumber.NO_SUPPORT,
@@ -2858,8 +2705,7 @@ class Smis(IStorageAreaNetwork):
def _ag_init_add_old(self, access_group, init_id, init_type):
# CIM_StorageHardwareIDManagementService.CreateStorageHardwareID()
# is mandatory since 1.4rev6
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
if cim_sys.path.classname == 'Clar_StorageSystem':
raise LsmError(ErrorNumber.NO_SUPPORT,
@@ -2905,8 +2751,7 @@ class Smis(IStorageAreaNetwork):
Call CIM_GroupMaskingMappingService.RemoveMembers() against
CIM_InitiatorMaskingGroup.
"""
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
cim_init_mg_pros = self._cim_init_mg_pros()
cim_init_mg = self._cim_init_mg_of_id(
@@ -2960,8 +2805,7 @@ class Smis(IStorageAreaNetwork):
return self._ag_init_del_old(access_group, init_id)
def _ag_init_del_old(self, access_group, init_id):
- cim_sys = self._get_cim_instance_by_id(
- 'System', access_group.system_id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
cim_spc = self._cim_spc_of_id(access_group.id, raise_error=True)
@@ -3029,11 +2873,9 @@ class Smis(IStorageAreaNetwork):
by ourselves in case URI contain 'system=xxx'.
"""
rc = []
- if not self.fallback_mode:
- self._profile_is_supported(SNIA.DISK_LITE_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=True)
+ self._profile_is_supported(SmisCommon.SNIA_DISK_LITE_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
+ raise_error=True)
cim_disk_pros = Smis._new_disk_cim_disk_pros(flags)
cim_disks = self._enumerate('CIM_DiskDrive', cim_disk_pros)
for cim_disk in cim_disks:
@@ -3251,210 +3093,62 @@ class Smis(IStorageAreaNetwork):
return element_type, unsupported
- def _profile_is_supported(self, profile_name, spec_ver, strict=False,
+ def _profile_is_supported(self, profile_name, spec_ver,
raise_error=False):
"""
Usage:
- Check whether we support certain profile at certain SNIA
- specification version.
- When strict == False(default), profile spec version later or equal
- than require spec_ver will also be consider as found.
- When strict == True, only defined spec_version is allowed.
- Require self.cim_rps containing all CIM_RegisteredProfile
- Will raise LsmError(ErrorNumber.NO_SUPPORT, 'xxx') if raise_error
- is True when nothing found.
+ Just a wrapper of SmisCommon.profile_check().
Parameter:
- profile_name # SNIA.XXXX_PROFILE
- spec_ver # SNIA.SMIS_SPEC_VER_XXX
- strict # False or True. If True, only defined
- # spec_version is consider as supported
- # If false, will return the maximum version of
- # spec.
+ profile_name # SmisCommon.SNIA_XXXX_PROFILE
+ spec_ver # SmisCommon.SMIS_SPEC_VER_XXX
raise_error # Raise LsmError if not found
Returns:
- None # Not supported.
+ True
or
- spec_int # Integer. Converted by _spec_ver_str_to_num()
+ False
"""
- req_ver = _spec_ver_str_to_num(spec_ver)
-
- max_spec_ver_str = None
- max_spec_ver = None
- for cim_rp in self.cim_rps:
- if 'RegisteredName' not in cim_rp or \
- 'RegisteredVersion' not in cim_rp:
- continue
- if cim_rp['RegisteredName'] == profile_name:
- # check spec version
- cur_ver = _spec_ver_str_to_num(cim_rp['RegisteredVersion'])
-
- if strict and cur_ver == req_ver:
- return cur_ver
- elif cur_ver >= req_ver:
- if max_spec_ver is None or \
- cur_ver > max_spec_ver:
- max_spec_ver = cur_ver
- max_spec_ver_str = cim_rp['RegisteredVersion']
- if (strict or max_spec_ver is None) and raise_error:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "SNIA SMI-S %s '%s' profile is not supported" %
- (spec_ver, profile_name))
-
- return max_spec_ver
+ return SmisCommon.profile_check(
+ self._profile_dict, profile_name, spec_ver, raise_error)
def _root_cim_syss(self, property_list=None):
"""
- For fallback mode, this just enumerate CIM_ComputerSystem.
- We require vendor to implement profile registration when using
- "Multiple System Profile".
- For normal mode, this just find out the root CIM_ComputerSystem
- via:
-
- CIM_RegisteredProfile # Root Profile('Array') in interop
- |
- | CIM_ElementConformsToProfile
- v
- CIM_ComputerSystem # vendor namespace
-
- We also assume no matter which version of root profile can lead to
- the same CIM_ComputerSystem instance.
- As CIM_ComputerSystem has no property indicate SNIA SMI-S version,
- this is assumption should work. Tested on EMC SMI-S provider which
- provide 1.4, 1.5, 1.6 root profile.
+ Provide simplfied(less argument) version of SmisSys.root_cim_sys()
+ internally.
"""
- cim_scss_path = []
- id_pros = self._property_list_of_id('System', property_list)
- if property_list is None:
- property_list = id_pros
- else:
- property_list = _merge_list(property_list, id_pros)
+ return SmisSys.root_cim_sys(
+ self._c, self._blk_root_cim_rp, self.system_list, property_list)
- cim_syss = []
- if self.fallback_mode:
- # Fallback mode:
- # Find out the root CIM_ComputerSystem using the fallback method:
- # CIM_StorageConfigurationService # Enumerate
- # |
- # | CIM_HostedService
- # v
- # CIM_ComputerSystem
- # If CIM_StorageConfigurationService is not support neither,
- # we enumerate CIM_ComputerSystem.
- try:
- cim_scss_path = self._c.EnumerateInstanceNames(
- 'CIM_StorageConfigurationService')
- except CIMError as e:
- # If array does not support CIM_StorageConfigurationService
- # we use CIM_ComputerSystem which is mandatory.
- # We might get some non-storage array listed as system.
- # but we would like to take that risk instead of
- # skipping basic support of old SMIS provider.
- if e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem',
- PropertyList=property_list,
- LocalOnly=False)
- else:
- raise
+ def _cim_sys_of_sys_id(self, sys_id, property_list=None):
+ """
+ Return CIMInstance of
+ """
+ cim_syss = self._root_cim_syss(property_list)
+ for cim_sys in cim_syss:
+ if SmisSys.sys_id_of_cim_sys(cim_sys) == sys_id:
+ return cim_sys
+ raise LsmError(
+ ErrorNumber.NOT_FOUND_SYSTEM,
+ "System %s not found" % sys_id)
- if not cim_syss:
- for cim_scs_path in cim_scss_path:
- cim_tmp = None
- # CIM_ComputerSystem is one-one map to
- # CIM_StorageConfigurationService
- cim_tmp = self._c.Associators(
- cim_scs_path,
- AssocClass='CIM_HostedService',
- ResultClass='CIM_ComputerSystem',
- PropertyList=property_list)
- if cim_tmp and cim_tmp[0]:
- cim_syss.extend([cim_tmp[0]])
- else:
- for cim_rp in self.cim_rps:
- if cim_rp['RegisteredName'] == SNIA.BLK_ROOT_PROFILE and\
- cim_rp['RegisteredOrganization'] == SNIA.REG_ORG_CODE:
- cim_syss = self._c.Associators(
- cim_rp.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile',
- PropertyList=property_list)
- # Any version of 'Array' profile can get us to root
- # CIM_ComputerSystem. startup() already has checked the
- # 1.4 version
- break
- if len(cim_syss) == 0:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Current SMI-S provider does not provide "
- "the root CIM_ComputerSystem associated "
- "to 'Array' CIM_RegisteredProfile. Try "
- "add 'force_fallback_mode=yes' into URI")
-
- # System URI Filtering
- if self.system_list:
- needed_cim_syss = []
- for cim_sys in cim_syss:
- if self._sys_id(cim_sys) in self.system_list:
- needed_cim_syss.extend([cim_sys])
- return needed_cim_syss
- else:
- return cim_syss
+ cim_sys = self._cim_sys_of_sys_id(access_group.system_id)
- def _fc_tgt_is_supported(self, cim_sys_path):
+ def _fc_tgt_is_supported(self):
"""
Return True if FC Target Port 1.4+ profile is supported.
- For fallback_mode, we call self._cim_fc_tgt_of() and do try-except
"""
- if self.fallback_mode:
- try:
- self._cim_fc_tgt_of(cim_sys_path)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- return False
- return True
-
- flag_fc_support = self._profile_is_supported(
- SNIA.FC_TGT_PORT_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
+ return self._profile_is_supported(
+ SmisCommon.SNIA_FC_TGT_PORT_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
raise_error=False)
- # One more check for NetApp Typo:
- # NetApp: 'FC Target Port'
- # SMI-S: 'FC Target Ports'
- # Bug reported.
- if not flag_fc_support:
- flag_fc_support = self._profile_is_supported(
- 'FC Target Port',
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
- raise_error=False)
- if flag_fc_support:
- return True
- else:
- return False
- def _iscsi_tgt_is_supported(self, cim_sys_path):
+ def _iscsi_tgt_is_supported(self):
"""
- Return True if FC Target Port 1.4+ profile is supported.
- For fallback_mode, we call self._cim_iscsi_pg_of() and do try-except
- For fallback_mode:
- Even CIM_EthernetPort is the control class of iSCSI Target
- Ports profile, but that class is optional. :(
+ Return True if FC Target Port 1.2+ profile is supported.
We use CIM_iSCSIProtocolEndpoint as it's a start point we are
using in our code of target_ports().
"""
- if self.fallback_mode:
- try:
- self._cim_iscsi_pg_of(cim_sys_path)
- except CIMError as e:
- if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
- e[0] == pywbem.CIM_ERR_INVALID_CLASS:
- return False
- return True
-
- if self._profile_is_supported(SNIA.ISCSI_TGT_PORT_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
+ if self._profile_is_supported(SmisCommon.SNIA_ISCSI_TGT_PORT_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_2,
raise_error=False):
return True
return False
@@ -3462,15 +3156,11 @@ class Smis(IStorageAreaNetwork):
def _multi_sys_is_supported(self):
"""
Return True if Multiple ComputerSystem 1.4+ profile is supported.
- For fallback_mode, always return True.
Return False else.
"""
- if self.fallback_mode:
- return True
flag_multi_sys_support = self._profile_is_supported(
- SNIA.MULTI_SYS_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- strict=False,
+ SmisCommon.SNIA_MULTI_SYS_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_4,
raise_error=False)
if flag_multi_sys_support:
return True
@@ -3763,25 +3453,21 @@ class Smis(IStorageAreaNetwork):
cim_fc_tgt_pros = ['UsageRestriction', 'ElementName', 'SystemName',
'PermanentAddress', 'PortDiscriminator',
'LinkTechnology', 'DeviceID']
+ flag_fc_support = self._fc_tgt_is_supported()
+ flag_iscsi_support = self._iscsi_tgt_is_supported()
+ if flag_fc_support is False and flag_iscsi_support is False:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "Target SMI-S provider does not support any of"
+ "these profiles: '%s %s', '%s %s'"
+ % (SmisCommon.SMIS_SPEC_VER_1_4,
+ SmisCommon.SNIA_FC_TGT_PORT_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_2,
+ SmisCommon.SNIA_ISCSI_TGT_PORT_PROFILE))
cim_syss = self._root_cim_syss(
- property_list=self._property_list_of_id('System'))
+ property_list=SmisSys.cim_sys_id_pros())
for cim_sys in cim_syss:
- system_id = self._sys_id(cim_sys)
- flag_fc_support = self._fc_tgt_is_supported(cim_sys.path)
- flag_iscsi_support = self._iscsi_tgt_is_supported(cim_sys.path)
-
- # Assuming: if one system does not support target_ports(),
- # all systems from the same provider will not support
- # target_ports().
- if flag_fc_support is False and flag_iscsi_support is False:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "Target SMI-S provider does not support any of"
- "these profiles: '%s %s', '%s %s'"
- % (SNIA.SMIS_SPEC_VER_1_4,
- SNIA.FC_TGT_PORT_PROFILE,
- SNIA.SMIS_SPEC_VER_1_4,
- SNIA.ISCSI_TGT_PORT_PROFILE))
+ system_id = SmisSys.sys_id_of_cim_sys(cim_sys)
if flag_fc_support:
# CIM_FCPort might be not belong to root cim_sys
@@ -3978,14 +3664,9 @@ class Smis(IStorageAreaNetwork):
"""
org_init_id = init_id
init_id = _lsm_init_id_to_snia(init_id)
- if self.fallback_mode:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "access_group_create() is not supported in "
- "fallback mode")
- self._profile_is_supported(SNIA.GROUP_MASK_PROFILE,
- SNIA.SMIS_SPEC_VER_1_5,
- strict=False,
+ self._profile_is_supported(SmisCommon.SNIA_GROUP_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_5,
raise_error=True)
if init_type != AccessGroup.INIT_TYPE_WWPN and \
@@ -3994,8 +3675,7 @@ class Smis(IStorageAreaNetwork):
"SMI-S plugin only support creating FC/FCoE WWPN "
"and iSCSI AccessGroup")
- cim_sys = self._get_cim_instance_by_id(
- 'System', system.id, raise_error=True)
+ cim_sys = self._cim_sys_of_sys_id(system.id)
if cim_sys.path.classname == 'Clar_StorageSystem':
# EMC VNX/CX does not support Group M&M, which incorrectly exposed
# in CIM_RegisteredProfile
@@ -4083,14 +3763,8 @@ class Smis(IStorageAreaNetwork):
return self._cim_init_mg_to_lsm(cim_init_mg, system.id)
def access_group_delete(self, access_group, flags=0):
- if self.fallback_mode:
- raise LsmError(ErrorNumber.NO_SUPPORT,
- "access_group_create() is not supported in "
- "fallback mode")
-
- self._profile_is_supported(SNIA.GROUP_MASK_PROFILE,
- SNIA.SMIS_SPEC_VER_1_5,
- strict=False,
+ self._profile_is_supported(SmisCommon.SNIA_GROUP_MASK_PROFILE,
+ SmisCommon.SMIS_SPEC_VER_1_5,
raise_error=True)
cim_init_mg = self._cim_init_mg_of_id(
--
1.8.3.1