Gris Ge
2014-05-19 15:21:15 UTC
* Convert SMI-S SPEC version into integer for better comparison.
Please check _spec_ver_str_to_num() for detail.
* Let _root_cim_syss() handle the fall back checking. It will return a list
of CIM_ComputerSystem for fallback mode or not.
* Checking for 1.4 'Array' profile support in startup().
As 'Block Services Package' (AKA: BSP) is mandatory for that profile, we
don't do extra check in methods using BSP profile.
* Noting down the method naming scheme for consistency.
* Move SNIA related constants to a standalone class SNIA which shorter the
constant variable name.
* _profile_is_supported() now support raise error if not found.
* Split _cim_sys_of_id() out to raise LsmError ErrorNumber.NOT_FOUND_SYSTEM.
* Add RegisteredOrganization checking in CIM_RegisteredProfile.
Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 505 ++++++++++++++++++--------------------------------
1 file changed, 182 insertions(+), 323 deletions(-)
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index c63d8cd..e0a0d97 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -37,6 +37,16 @@ from lsm import (IStorageAreaNetwork, Error, uri_parse, LsmError, ErrorNumber,
# pool Object of LSM Pool
# vol Object of LSM Volume
+## Method Naming schme:
+# _cim_xxx()
+# Return CIMInstance without any Associators() call.
+# _cim_xxx_of(cim_yyy)
+# Return CIMInstance associated to cim_yyy
+# _adj_cim_xxx()
+# Retrun CIMInstance with 'adj' only
+# _cim_xxx_of_id(some_id)
+# Return CIMInstance for given ID
+
def handle_cim_errors(method):
def cim_wrapper(*args, **kwargs):
@@ -65,6 +75,35 @@ def handle_cim_errors(method):
traceback.format_exc())
return cim_wrapper
+def _spec_ver_str_to_num(spec_ver_str):
+ """
+ Convert version string stored in CIM_RegisteredProfile to a integer.
+ Example:
+ "1.5.1" -> 1,005,001
+ """
+ tmp_list = [0,0,0]
+ tmp_list = spec_ver_str.split(".")
+ if len(tmp_list) == 2:
+ tmp_list.extend([0])
+ if len(tmp_list) == 3:
+ return (int(tmp_list[0]) * 10 ** 6 +
+ int(tmp_list[1]) * 10 ** 3 +
+ int(tmp_list[2]))
+ return None
+
+class SNIA(object):
+ BLK_ROOT_PROFILE = 'Array'
+ BLK_SRVS_PROFILE = 'Block Services'
+ DISK_LITE_PROFILE = 'Disk Drive Lite'
+ MULTI_SYS_PROFILE = 'Multiple Computer System'
+ SMIS_SPEC_VER_1_4 ='1.4'
+ SMIS_SPEC_VER_1_5 ='1.5'
+ SMIS_SPEC_VER_1_6 ='1.6'
+ _FAKE_SPEC_VER_FALLBACK = '0.1'
+ # This version is indicate we are in fallback mode.
+ # Used by _profile_is_supported()
+ REG_ORG_CODE = pywbem.Uint16(11)
+
class Smis(IStorageAreaNetwork):
"""
@@ -252,13 +291,6 @@ class Smis(IStorageAreaNetwork):
# DSP 1033 Profile Registration
DMTF_INTEROP_NAMESPACES = ['interop', 'root/interop']
SMIS_DEFAULT_NAMESPACE = 'interop'
- SNIA_BLK_ROOT_PROFILE = 'Array'
- SNIA_BLK_SRVS_PROFILE = 'Block Services'
- SNIA_DISK_LITE_PROFILE = 'Disk Drive Lite'
- SNIA_MULTI_SYS_PROFILE = 'Multiple Computer System'
- SNIA_SMIS_SPEC_VER_1_4='1.4'
- SNIA_SMIS_SPEC_VER_1_5='1.5'
- SNIA_SMIS_SPEC_VER_1_6='1.6'
IAAN_WBEM_HTTP_PORT = 5988
IAAN_WBEM_HTTPS_PORT = 5989
@@ -350,7 +382,7 @@ class Smis(IStorageAreaNetwork):
self._c = None
self.tmo = 0
self.system_list = None
- self.cim_reg_profiles = []
+ self.cim_rps = []
self.cim_root_profile_dict = dict()
self.fallback_mode = True # Means we cannot use profile register
@@ -555,31 +587,29 @@ class Smis(IStorageAreaNetwork):
try:
for interop_namespace in Smis.DMTF_INTEROP_NAMESPACES:
- self.cim_reg_profiles = self._c.EnumerateInstances(
+ self.cim_rps = self._c.EnumerateInstances(
'CIM_RegisteredProfile',
namespace=interop_namespace,
- PropertyList=['RegisteredName', 'RegisteredVersion'],
+ PropertyList=['RegisteredName', 'RegisteredVersion',
+ 'RegisteredOrganization'],
LocalOnly=False)
- if len(self.cim_reg_profiles) != 0:
+ if len(self.cim_rps) != 0:
break
- if len(self.cim_reg_profiles) >= 1:
+ if len(self.cim_rps) >= 1:
self.fallback_mode = False
# 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
- for cim_reg_profile in self.cim_reg_profiles:
- if 'RegisteredName' not in cim_reg_profile or \
- 'RegisteredVersion' not in cim_reg_profile:
- continue
- if cim_reg_profile['RegisteredName'] == \
- Smis.SNIA_BLK_ROOT_PROFILE:
- ver = cim_reg_profile['RegisteredVersion']
- self.cim_root_profile_dict[ver]= cim_reg_profile
- if len(self.cim_root_profile_dict) == 0:
+ if not self._profile_is_supported(
+ SNIA.BLK_ROOT_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False):
raise LsmError(ErrorNumber.NO_SUPPORT,
- "SMI-S provider does not support 'Array'"
- "profile which is prerequisite")
+ "SMI-S provider does not support "
+ "SNIA SMI-S SPEC %s '%s' profile" %
+ (SNIA.SMIS_SPEC_VER_1_4,
+ SNIA.BLK_ROOT_PROFILE))
except CIMError as e:
if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
e[0] == pywbem.CIM_ERR_INVALID_NAMESPACE:
@@ -720,12 +750,8 @@ class Smis(IStorageAreaNetwork):
# Get the cim object that represents the system
cim_sys = None
cim_pcms = None
+ cim_sys = self._cim_sys_of_id(system.id)
if self.fallback_mode:
- cim_sys = self._get_cim_syss_fallback(
- sys_id=system.id,
- property_list=[])[0] # Surely, we will get at least one
- # cim_sys since LSM system already
- # provided.
# Using 'ExposePathsSupported of
# CIM_ProtocolControllerMaskingCapabilities
@@ -752,26 +778,16 @@ class Smis(IStorageAreaNetwork):
cap.set(Capabilities.ACCESS_GROUP_DEL_INITIATOR)
return
else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- sys_id=system.id,
- property_list=[])
- # we might not get any cim_sys on unsupported system.
- if len(cim_syss) == 1:
- cim_sys = cim_syss[0]
- # Since SNIA SMI-S 1.4rev6:
- # CIM_ControllerConfigurationService is mandatory
- # and it's ExposePaths() and HidePaths() are mandatory
- cap.set(Capabilities.ACCESS_GROUP_LIST)
- cap.set(Capabilities.ACCESS_GROUP_GRANT)
- cap.set(Capabilities.ACCESS_GROUP_REVOKE)
- cap.set(Capabilities.ACCESS_GROUP_ADD_INITIATOR)
- cap.set(Capabilities.ACCESS_GROUP_DEL_INITIATOR)
- cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
- else:
- return
+ # Since SNIA SMI-S 1.4rev6:
+ # CIM_ControllerConfigurationService is mandatory
+ # and it's ExposePaths() and HidePaths() are mandatory
+ cap.set(Capabilities.ACCESS_GROUP_LIST)
+ cap.set(Capabilities.ACCESS_GROUP_GRANT)
+ cap.set(Capabilities.ACCESS_GROUP_REVOKE)
+ cap.set(Capabilities.ACCESS_GROUP_ADD_INITIATOR)
+ cap.set(Capabilities.ACCESS_GROUP_DEL_INITIATOR)
+ cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
+ cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
def _common_capabilities(self, system):
cap = Capabilities()
@@ -1283,19 +1299,15 @@ class Smis(IStorageAreaNetwork):
|
v
CIM_StorageVolume
+ As 'Block Services Package' is mandatory for 'Array' profile, we
+ don't check support status here as startup() already checked 'Array'
+ profile.
"""
rc = []
cim_syss = []
cim_sys_pros = self._property_list_of_id("System")
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
+
+ cim_syss = self._root_cim_syss(cim_sys_pros)
cim_vol_pros = self._new_vol_cim_vol_pros()
for cim_sys in cim_syss:
sys_id = self._sys_id(cim_sys)
@@ -1405,22 +1417,16 @@ class Smis(IStorageAreaNetwork):
|
v
CIM_StoragePool
+ As 'Block Services Package' is mandatory for 'Array' profile, we
+ don't check support status here as startup() already checked 'Array'
+ profile.
"""
rc = []
cim_pool_pros = self._new_pool_cim_pool_pros(
flags == Pool.RETRIEVE_FULL_INFO)
cim_sys_pros = self._property_list_of_id("System")
- cim_syss = []
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
+ cim_syss = self._root_cim_syss(cim_sys_pros)
for cim_sys in cim_syss:
system_id = self._sys_id(cim_sys)
@@ -1535,20 +1541,14 @@ class Smis(IStorageAreaNetwork):
def systems(self, flags=0):
"""
Return the storage arrays accessible from this plug-in at this time
+
+ As 'Block Services Package' is mandatory for 'Array' profile, we
+ don't check support status here as startup() already checked 'Array'
+ profile.
"""
cim_sys_pros = self._cim_sys_pros()
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_ROOT_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
-
- if cim_syss is None:
- return []
+ cim_syss = self._root_cim_syss(cim_sys_pros)
+
return [Smis._cim_sys_2_lsm_sys(s) for s in cim_syss]
def _new_init(self, cim_st_hwid):
@@ -2246,33 +2246,30 @@ class Smis(IStorageAreaNetwork):
rc = []
cim_syss = []
cim_sys_pros = self._property_list_of_id("System")
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_DISK_LITE_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
-
+ self._profile_is_supported(SNIA.DISK_LITE_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False,
+ raise_error=True)
+
+ # In SNIA SMI-S 1.6rev4 Common Book,
+ # 30.1.5 Associations between ComputerSystems and other Logical
+ # Elements
+ # "If the device may become unavailable while the system as a
+ # whole remains available, the device shall be associated to a
+ # non-top-level system that has availability equivalent to the
+ # device. This system could be a real system or a system in an
+ # intermediate tier (representing some redundancy less than full
+ # redundancy)."
+
+ # Hence DiskDrive might not associated to top level
+ # CIM_ComputerSystem
flag_multi_sys = None
- if not self.fallback_mode:
- flag_multi_sys = self._profile_is_supported(
- Smis.SNIA_MULTI_SYS_PROFILE, Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False)
- # In SNIA SMI-S 1.6rev4 Common Book,
- # 30.1.5 Associations between ComputerSystems and other Logical
- # Elements
- # "If the device may become unavailable while the system as a
- # whole remains available, the device shall be associated to a
- # non-top-level system that has availability equivalent to the
- # device. This system could be a real system or a system in an
- # intermediate tier (representing some redundancy less than full
- # redundancy)."
-
- # Hence DiskDrive might not associated to top level
- # CIM_ComputerSystem
+ if not self.fallback_mode and \
+ self._profile_is_supported(SNIA.MULTI_SYS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False,
+ raise_error=False):
+ flag_multi_sys = True
for cim_sys in cim_syss:
cim_disk_pros = Smis._new_disk_cim_disk_pros(flags)
@@ -3008,15 +3005,15 @@ class Smis(IStorageAreaNetwork):
"""
cim_sys_pros = self._property_list_of_id("System")
if not self.fallback_mode and \
- self._profile_is_supported(Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
+ self._profile_is_supported(SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
strict=False) is None:
raise LsmError(ErrorNumber.NO_SUPPORT,
"SMI-S %s version %s is not supported" %
- (Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4))
+ (SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4))
- cim_sys = self._get_cim_sys_by_id(pool.system_id)
+ cim_sys = self._cim_sys_of_id(pool.system_id)
cim_pool = self._get_cim_pool_by_id(cim_sys.path, pool.id)
cim_scs = self._get_cim_scs(cim_sys.path)
@@ -3039,15 +3036,15 @@ class Smis(IStorageAreaNetwork):
CreateOrModifyStoragePool()
"""
if not self.fallback_mode and \
- self._profile_is_supported(Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
+ self._profile_is_supported(SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
strict=False) is None:
raise LsmError(ErrorNumber.NO_SUPPORT,
"SMI-S %s version %s is not supported" %
- (Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4))
+ (SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4))
- cim_sys = self._get_cim_sys_by_id(system.id)
+ cim_sys = self._cim_sys_of_id(system.id)
# we does not support defining thinp_type yet.
# just using whatever provider set.
@@ -3371,238 +3368,106 @@ class Smis(IStorageAreaNetwork):
"CIM_StorageConfigurationService of " +
"CIM_ComputerSystem %s" % cim_sys_path)
- def _profile_is_supported(self, profile_name, spec_ver, strict=False):
+ def _profile_is_supported(self, profile_name, spec_ver, strict=False,
+ raise_error=False):
"""
Usage:
Check whether we support certain profile at certain SNIA
specification version.
- When strict == False(default), profile spec version newer than
- require spec_ver will also be consider as found.
+ 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.
+ When in fallback mode, we just return
+ _spec_ver_str_to_num(SNIA._FAKE_SPEC_VER_FALLBACK)
Parameter:
- profile_name # Smis.SNIA_REGISTERED_PROFILE_XXX
- spec_ver # Smis.SNIA_SMIS_SPEC_VER_XXX
- property_list # a list of properties should contained in
- # returned CIM_ComputerSystem
- # When property_list == None, we retrieve full
- # data, when property_list == [], we retrieve
- # nothing but a CIMInstanceName.
+ 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.
+ raise_error # Raise LsmError if not found
Returns:
None # Not supported.
or
- spec_version # the vendor implemented version. like '1.4.1'
- # This is a string, NOT float.
- """
- max_spec_ver = 0
- max_spec_ver_flt = 0
- # assuming spec_ver is well formatted, since we are internal
- # method, we can do that guess.
- req_ver_main = spec_ver.split('.')[0]
- req_ver_sub = spec_ver.split('.')[1]
-
- for cim_reg_profile in self.cim_reg_profiles:
- if 'RegisteredName' not in cim_reg_profile or \
- 'RegisteredVersion' not in cim_reg_profile:
+ spec_int # Integer. Converted by _spec_ver_str_to_num()
+ """
+ if self.fallback_mode:
+ return _spec_ver_str_to_num(SNIA._FAKE_SPEC_VER_FALLBACK)
+ 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_reg_profile['RegisteredName'] == profile_name:
+ if cim_rp['RegisteredName'] == profile_name:
# check spec version
- cur_ver = cim_reg_profile['RegisteredVersion']
- cur_ver_list = cur_ver.split('.')
- if len(cur_ver_list) < 2:
- continue
- cur_ver_flt = float("%s.%s" % tuple(cur_ver_list[0:2]))
- req_ver_flt = float("%s.%s" % (req_ver_main, req_ver_sub))
+ cur_ver = _spec_ver_str_to_num(cim_rp['RegisteredVersion'])
- if strict and cur_ver_flt == req_ver_flt:
+ if strict and cur_ver == req_ver:
return cur_ver
-
- if strict is False and cur_ver_flt >= req_ver_flt:
- if cur_ver_flt > max_spec_ver_flt:
+ 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_flt = cur_ver_flt
+ max_spec_ver_str = cim_rp['RegisteredVersion']
+ if strict or max_spec_ver is None:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "SNIA SMI-S %s '%s' profile is not supported" %
+ (spec_ver, profile_name))
- if max_spec_ver == 0:
- return None
return max_spec_ver
- def _get_cim_syss(self, profile_name, spec_ver, property_list=None,
- strict=False, sys_id=None, raise_error=False):
+ def _root_cim_syss(self, property_list=None):
"""
- Usage:
- Check whether we support certain profile at certain SNIA
- specification version.
- When strict == False(default), profile spec version newer than
- require spec_ver will also be consider as found.
- When strict == True, only defined spec_version is allowed.
+ 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:
- If found, follow this procedure to get CIM_ComputerSystem:
CIM_RegisteredProfile # Root Profile('Array') in interop
|
| CIM_ElementConformsToProfile
v
CIM_ComputerSystem # vendor namespace
- We depend on self.cim_reg_profiles which was updated by startup().
- But this method does not check it, you should check
- self.fallback_mode == True before call this method.
-
- Please use constant spec_ver and profile_name for better
- code management.
- We also apply to system filter in URI which is stored in
- self.system_list
- When returning None, it means current provider does not support
- requested profile or version.
- Parameter:
- profile_name # Smis.SNIA_REGISTERED_PROFILE_XXX
- spec_ver # Smis.SNIA_SMIS_SPEC_VER_XXX
- property_list # a list of properties should contained in
- # returned CIM_ComputerSystem
- # When property_list == None, we retrieve full
- # data, when property_list == [], we retrieve
- # nothing but a CIMInstanceName.
- strict # False or True. If True, only defined
- # spec_version is consider as supported
- sys_id # Only return CIM_ComputerSystem for certain
- # system ID.
- Returns:
- cim_syss # a list of CIMInstanceName of CIM_ComputerSystem
- or
- None # Current SMI-S provider does not support this
- # profile at certain version.
- """
- max_spec_ver = self._profile_is_supported(
- profile_name, spec_ver, strict)
-
- if max_spec_ver is None:
- if raise_error:
- error_msg = ("Current SMI-S provider does not support "
- "SMI-S %s profile, version %s" %
- (profile_name, spec_ver))
- if not strict:
- error_msg = "%s(or later version)" % error_msg
- raise LsmError(ErrorNumber.NO_SUPPORT, error_msg)
- else:
- return None
-
- if max_spec_ver not in self.cim_root_profile_dict.keys():
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
- "Failed to find out CIM_RegisteredProfile " +
- "for profile %s with version %s " %
- (Smis.SNIA_BLK_ROOT_PROFILE, max_spec_ver) +
- "even its subprofile found.")
-
- cim_root_profile = self.cim_root_profile_dict[max_spec_ver]
-
- if property_list is None:
- cim_syss = self._c.Associators(
- cim_root_profile.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile')
- else:
- sys_id_pros = self._property_list_of_id('System')
- for key in sys_id_pros:
- if key not in property_list:
- property_list.extend([key])
- cim_syss = self._c.Associators(
- cim_root_profile.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile',
- PropertyList=property_list)
-
- if self.system_list is None:
- return cim_syss
-
- # Method level filter
- if sys_id is not None:
- return [s for s in cim_syss if self._sys_id(s) == sys_id][0]
-
- # Apply URI system filter
- 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
-
- def _get_cim_syss_fallback(self, sys_id=None, property_list=None):
- """
- Usage:
- 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.
- Parameter:
- property_list # a list of properties should contained in
- # returned CIM_ComputerSystem
- # When property_list == None, we retrieve full
- # data, when property_list == [], we retrieve
- # nothing but a CIMInstanceName.
- Returns:
- cim_syss # A list of CIMInstanceName of CIM_ComputerSystem
- or
- None
+ 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.
"""
- sys_id_pros = self._property_list_of_id('System')
- flag_full_info = False
+ cim_sys_id_pros = self._property_list_of_id('System')
if property_list is None:
- flag_full_info = True
+ property_list = cim_sys_id_pros
else:
- for key in sys_id_pros:
- if key not in property_list:
- property_list.extend([key])
+ for key_name in cim_sys_id_pros:
+ if key_name not in property_list:
+ property_list.extend([key_name])
- cim_syss = []
- cim_scss_path = []
- try:
- # Note: Please be informed, if PropertyList is an empty list,
- # XIV will return NOTHING, so use EnumerateInstanceNames()
- # when you need nothing but the CIMInstanceName
- 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:
- if flag_full_info:
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem', LocalOnly=False)
- else:
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem',
- PropertyList=property_list,
- LocalOnly=False)
- else:
- raise e
- if not cim_syss:
- for cim_scs_path in cim_scss_path:
- cim_tmp = None
- if flag_full_info:
- cim_tmp = self._c.Associators(
- cim_scs_path,
- AssocClass='CIM_HostedService',
- ResultClass='CIM_ComputerSystem')
- else:
- cim_tmp = self._c.Associators(
- cim_scs_path,
- AssocClass='CIM_HostedService',
+ cim_syss = None
+ if self.fallback_mode:
+ cim_syss = self._c.EnumerateInstances(
+ 'CIM_ComputerSystem',
+ PropertyList=property_list)
+ 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',
- PropertyList=property_list)
- if cim_tmp and cim_tmp[0]:
- cim_syss.extend([cim_tmp[0]])
-
- # Method level filter
- if sys_id is not None:
- return [s for s in cim_syss if self._sys_id(s) == sys_id]
+ AssocClass='CIM_ElementConformsToProfile')
+ if cim_syss is None:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "SMI-S provider is not supporting SNIA SMI-S "
+ "Array profile")
# System URI Filtering
if self.system_list:
@@ -3614,7 +3479,8 @@ class Smis(IStorageAreaNetwork):
else:
return cim_syss
- def _get_cim_sys_by_id(self, system_id, property_list=None):
+
+ def _cim_sys_of_id(self, system_id, property_list=None):
"""
Return a CIMInstance of CIM_ComputerSystem for given system id.
"""
@@ -3626,15 +3492,8 @@ class Smis(IStorageAreaNetwork):
if pro not in property_list:
property_list.extend([pro])
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=property_list,
- raise_error=True)
+ cim_syss = self._root_cim_syss(property_list)
+
for cim_sys in cim_syss:
if self._sys_id(cim_sys) == system_id:
return cim_sys
Please check _spec_ver_str_to_num() for detail.
* Let _root_cim_syss() handle the fall back checking. It will return a list
of CIM_ComputerSystem for fallback mode or not.
* Checking for 1.4 'Array' profile support in startup().
As 'Block Services Package' (AKA: BSP) is mandatory for that profile, we
don't do extra check in methods using BSP profile.
* Noting down the method naming scheme for consistency.
* Move SNIA related constants to a standalone class SNIA which shorter the
constant variable name.
* _profile_is_supported() now support raise error if not found.
* Split _cim_sys_of_id() out to raise LsmError ErrorNumber.NOT_FOUND_SYSTEM.
* Add RegisteredOrganization checking in CIM_RegisteredProfile.
Signed-off-by: Gris Ge <***@redhat.com>
---
plugin/smispy/smis.py | 505 ++++++++++++++++++--------------------------------
1 file changed, 182 insertions(+), 323 deletions(-)
diff --git a/plugin/smispy/smis.py b/plugin/smispy/smis.py
index c63d8cd..e0a0d97 100644
--- a/plugin/smispy/smis.py
+++ b/plugin/smispy/smis.py
@@ -37,6 +37,16 @@ from lsm import (IStorageAreaNetwork, Error, uri_parse, LsmError, ErrorNumber,
# pool Object of LSM Pool
# vol Object of LSM Volume
+## Method Naming schme:
+# _cim_xxx()
+# Return CIMInstance without any Associators() call.
+# _cim_xxx_of(cim_yyy)
+# Return CIMInstance associated to cim_yyy
+# _adj_cim_xxx()
+# Retrun CIMInstance with 'adj' only
+# _cim_xxx_of_id(some_id)
+# Return CIMInstance for given ID
+
def handle_cim_errors(method):
def cim_wrapper(*args, **kwargs):
@@ -65,6 +75,35 @@ def handle_cim_errors(method):
traceback.format_exc())
return cim_wrapper
+def _spec_ver_str_to_num(spec_ver_str):
+ """
+ Convert version string stored in CIM_RegisteredProfile to a integer.
+ Example:
+ "1.5.1" -> 1,005,001
+ """
+ tmp_list = [0,0,0]
+ tmp_list = spec_ver_str.split(".")
+ if len(tmp_list) == 2:
+ tmp_list.extend([0])
+ if len(tmp_list) == 3:
+ return (int(tmp_list[0]) * 10 ** 6 +
+ int(tmp_list[1]) * 10 ** 3 +
+ int(tmp_list[2]))
+ return None
+
+class SNIA(object):
+ BLK_ROOT_PROFILE = 'Array'
+ BLK_SRVS_PROFILE = 'Block Services'
+ DISK_LITE_PROFILE = 'Disk Drive Lite'
+ MULTI_SYS_PROFILE = 'Multiple Computer System'
+ SMIS_SPEC_VER_1_4 ='1.4'
+ SMIS_SPEC_VER_1_5 ='1.5'
+ SMIS_SPEC_VER_1_6 ='1.6'
+ _FAKE_SPEC_VER_FALLBACK = '0.1'
+ # This version is indicate we are in fallback mode.
+ # Used by _profile_is_supported()
+ REG_ORG_CODE = pywbem.Uint16(11)
+
class Smis(IStorageAreaNetwork):
"""
@@ -252,13 +291,6 @@ class Smis(IStorageAreaNetwork):
# DSP 1033 Profile Registration
DMTF_INTEROP_NAMESPACES = ['interop', 'root/interop']
SMIS_DEFAULT_NAMESPACE = 'interop'
- SNIA_BLK_ROOT_PROFILE = 'Array'
- SNIA_BLK_SRVS_PROFILE = 'Block Services'
- SNIA_DISK_LITE_PROFILE = 'Disk Drive Lite'
- SNIA_MULTI_SYS_PROFILE = 'Multiple Computer System'
- SNIA_SMIS_SPEC_VER_1_4='1.4'
- SNIA_SMIS_SPEC_VER_1_5='1.5'
- SNIA_SMIS_SPEC_VER_1_6='1.6'
IAAN_WBEM_HTTP_PORT = 5988
IAAN_WBEM_HTTPS_PORT = 5989
@@ -350,7 +382,7 @@ class Smis(IStorageAreaNetwork):
self._c = None
self.tmo = 0
self.system_list = None
- self.cim_reg_profiles = []
+ self.cim_rps = []
self.cim_root_profile_dict = dict()
self.fallback_mode = True # Means we cannot use profile register
@@ -555,31 +587,29 @@ class Smis(IStorageAreaNetwork):
try:
for interop_namespace in Smis.DMTF_INTEROP_NAMESPACES:
- self.cim_reg_profiles = self._c.EnumerateInstances(
+ self.cim_rps = self._c.EnumerateInstances(
'CIM_RegisteredProfile',
namespace=interop_namespace,
- PropertyList=['RegisteredName', 'RegisteredVersion'],
+ PropertyList=['RegisteredName', 'RegisteredVersion',
+ 'RegisteredOrganization'],
LocalOnly=False)
- if len(self.cim_reg_profiles) != 0:
+ if len(self.cim_rps) != 0:
break
- if len(self.cim_reg_profiles) >= 1:
+ if len(self.cim_rps) >= 1:
self.fallback_mode = False
# 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
- for cim_reg_profile in self.cim_reg_profiles:
- if 'RegisteredName' not in cim_reg_profile or \
- 'RegisteredVersion' not in cim_reg_profile:
- continue
- if cim_reg_profile['RegisteredName'] == \
- Smis.SNIA_BLK_ROOT_PROFILE:
- ver = cim_reg_profile['RegisteredVersion']
- self.cim_root_profile_dict[ver]= cim_reg_profile
- if len(self.cim_root_profile_dict) == 0:
+ if not self._profile_is_supported(
+ SNIA.BLK_ROOT_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False):
raise LsmError(ErrorNumber.NO_SUPPORT,
- "SMI-S provider does not support 'Array'"
- "profile which is prerequisite")
+ "SMI-S provider does not support "
+ "SNIA SMI-S SPEC %s '%s' profile" %
+ (SNIA.SMIS_SPEC_VER_1_4,
+ SNIA.BLK_ROOT_PROFILE))
except CIMError as e:
if e[0] == pywbem.CIM_ERR_NOT_SUPPORTED or \
e[0] == pywbem.CIM_ERR_INVALID_NAMESPACE:
@@ -720,12 +750,8 @@ class Smis(IStorageAreaNetwork):
# Get the cim object that represents the system
cim_sys = None
cim_pcms = None
+ cim_sys = self._cim_sys_of_id(system.id)
if self.fallback_mode:
- cim_sys = self._get_cim_syss_fallback(
- sys_id=system.id,
- property_list=[])[0] # Surely, we will get at least one
- # cim_sys since LSM system already
- # provided.
# Using 'ExposePathsSupported of
# CIM_ProtocolControllerMaskingCapabilities
@@ -752,26 +778,16 @@ class Smis(IStorageAreaNetwork):
cap.set(Capabilities.ACCESS_GROUP_DEL_INITIATOR)
return
else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- sys_id=system.id,
- property_list=[])
- # we might not get any cim_sys on unsupported system.
- if len(cim_syss) == 1:
- cim_sys = cim_syss[0]
- # Since SNIA SMI-S 1.4rev6:
- # CIM_ControllerConfigurationService is mandatory
- # and it's ExposePaths() and HidePaths() are mandatory
- cap.set(Capabilities.ACCESS_GROUP_LIST)
- cap.set(Capabilities.ACCESS_GROUP_GRANT)
- cap.set(Capabilities.ACCESS_GROUP_REVOKE)
- cap.set(Capabilities.ACCESS_GROUP_ADD_INITIATOR)
- cap.set(Capabilities.ACCESS_GROUP_DEL_INITIATOR)
- cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
- cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
- else:
- return
+ # Since SNIA SMI-S 1.4rev6:
+ # CIM_ControllerConfigurationService is mandatory
+ # and it's ExposePaths() and HidePaths() are mandatory
+ cap.set(Capabilities.ACCESS_GROUP_LIST)
+ cap.set(Capabilities.ACCESS_GROUP_GRANT)
+ cap.set(Capabilities.ACCESS_GROUP_REVOKE)
+ cap.set(Capabilities.ACCESS_GROUP_ADD_INITIATOR)
+ cap.set(Capabilities.ACCESS_GROUP_DEL_INITIATOR)
+ cap.set(Capabilities.ACCESS_GROUPS_GRANTED_TO_VOLUME)
+ cap.set(Capabilities.VOLUMES_ACCESSIBLE_BY_ACCESS_GROUP)
def _common_capabilities(self, system):
cap = Capabilities()
@@ -1283,19 +1299,15 @@ class Smis(IStorageAreaNetwork):
|
v
CIM_StorageVolume
+ As 'Block Services Package' is mandatory for 'Array' profile, we
+ don't check support status here as startup() already checked 'Array'
+ profile.
"""
rc = []
cim_syss = []
cim_sys_pros = self._property_list_of_id("System")
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
+
+ cim_syss = self._root_cim_syss(cim_sys_pros)
cim_vol_pros = self._new_vol_cim_vol_pros()
for cim_sys in cim_syss:
sys_id = self._sys_id(cim_sys)
@@ -1405,22 +1417,16 @@ class Smis(IStorageAreaNetwork):
|
v
CIM_StoragePool
+ As 'Block Services Package' is mandatory for 'Array' profile, we
+ don't check support status here as startup() already checked 'Array'
+ profile.
"""
rc = []
cim_pool_pros = self._new_pool_cim_pool_pros(
flags == Pool.RETRIEVE_FULL_INFO)
cim_sys_pros = self._property_list_of_id("System")
- cim_syss = []
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
+ cim_syss = self._root_cim_syss(cim_sys_pros)
for cim_sys in cim_syss:
system_id = self._sys_id(cim_sys)
@@ -1535,20 +1541,14 @@ class Smis(IStorageAreaNetwork):
def systems(self, flags=0):
"""
Return the storage arrays accessible from this plug-in at this time
+
+ As 'Block Services Package' is mandatory for 'Array' profile, we
+ don't check support status here as startup() already checked 'Array'
+ profile.
"""
cim_sys_pros = self._cim_sys_pros()
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_ROOT_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
-
- if cim_syss is None:
- return []
+ cim_syss = self._root_cim_syss(cim_sys_pros)
+
return [Smis._cim_sys_2_lsm_sys(s) for s in cim_syss]
def _new_init(self, cim_st_hwid):
@@ -2246,33 +2246,30 @@ class Smis(IStorageAreaNetwork):
rc = []
cim_syss = []
cim_sys_pros = self._property_list_of_id("System")
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list=cim_sys_pros)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_DISK_LITE_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=cim_sys_pros,
- raise_error=True)
-
+ self._profile_is_supported(SNIA.DISK_LITE_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False,
+ raise_error=True)
+
+ # In SNIA SMI-S 1.6rev4 Common Book,
+ # 30.1.5 Associations between ComputerSystems and other Logical
+ # Elements
+ # "If the device may become unavailable while the system as a
+ # whole remains available, the device shall be associated to a
+ # non-top-level system that has availability equivalent to the
+ # device. This system could be a real system or a system in an
+ # intermediate tier (representing some redundancy less than full
+ # redundancy)."
+
+ # Hence DiskDrive might not associated to top level
+ # CIM_ComputerSystem
flag_multi_sys = None
- if not self.fallback_mode:
- flag_multi_sys = self._profile_is_supported(
- Smis.SNIA_MULTI_SYS_PROFILE, Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False)
- # In SNIA SMI-S 1.6rev4 Common Book,
- # 30.1.5 Associations between ComputerSystems and other Logical
- # Elements
- # "If the device may become unavailable while the system as a
- # whole remains available, the device shall be associated to a
- # non-top-level system that has availability equivalent to the
- # device. This system could be a real system or a system in an
- # intermediate tier (representing some redundancy less than full
- # redundancy)."
-
- # Hence DiskDrive might not associated to top level
- # CIM_ComputerSystem
+ if not self.fallback_mode and \
+ self._profile_is_supported(SNIA.MULTI_SYS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
+ strict=False,
+ raise_error=False):
+ flag_multi_sys = True
for cim_sys in cim_syss:
cim_disk_pros = Smis._new_disk_cim_disk_pros(flags)
@@ -3008,15 +3005,15 @@ class Smis(IStorageAreaNetwork):
"""
cim_sys_pros = self._property_list_of_id("System")
if not self.fallback_mode and \
- self._profile_is_supported(Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
+ self._profile_is_supported(SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
strict=False) is None:
raise LsmError(ErrorNumber.NO_SUPPORT,
"SMI-S %s version %s is not supported" %
- (Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4))
+ (SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4))
- cim_sys = self._get_cim_sys_by_id(pool.system_id)
+ cim_sys = self._cim_sys_of_id(pool.system_id)
cim_pool = self._get_cim_pool_by_id(cim_sys.path, pool.id)
cim_scs = self._get_cim_scs(cim_sys.path)
@@ -3039,15 +3036,15 @@ class Smis(IStorageAreaNetwork):
CreateOrModifyStoragePool()
"""
if not self.fallback_mode and \
- self._profile_is_supported(Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
+ self._profile_is_supported(SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4,
strict=False) is None:
raise LsmError(ErrorNumber.NO_SUPPORT,
"SMI-S %s version %s is not supported" %
- (Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4))
+ (SNIA.BLK_SRVS_PROFILE,
+ SNIA.SMIS_SPEC_VER_1_4))
- cim_sys = self._get_cim_sys_by_id(system.id)
+ cim_sys = self._cim_sys_of_id(system.id)
# we does not support defining thinp_type yet.
# just using whatever provider set.
@@ -3371,238 +3368,106 @@ class Smis(IStorageAreaNetwork):
"CIM_StorageConfigurationService of " +
"CIM_ComputerSystem %s" % cim_sys_path)
- def _profile_is_supported(self, profile_name, spec_ver, strict=False):
+ def _profile_is_supported(self, profile_name, spec_ver, strict=False,
+ raise_error=False):
"""
Usage:
Check whether we support certain profile at certain SNIA
specification version.
- When strict == False(default), profile spec version newer than
- require spec_ver will also be consider as found.
+ 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.
+ When in fallback mode, we just return
+ _spec_ver_str_to_num(SNIA._FAKE_SPEC_VER_FALLBACK)
Parameter:
- profile_name # Smis.SNIA_REGISTERED_PROFILE_XXX
- spec_ver # Smis.SNIA_SMIS_SPEC_VER_XXX
- property_list # a list of properties should contained in
- # returned CIM_ComputerSystem
- # When property_list == None, we retrieve full
- # data, when property_list == [], we retrieve
- # nothing but a CIMInstanceName.
+ 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.
+ raise_error # Raise LsmError if not found
Returns:
None # Not supported.
or
- spec_version # the vendor implemented version. like '1.4.1'
- # This is a string, NOT float.
- """
- max_spec_ver = 0
- max_spec_ver_flt = 0
- # assuming spec_ver is well formatted, since we are internal
- # method, we can do that guess.
- req_ver_main = spec_ver.split('.')[0]
- req_ver_sub = spec_ver.split('.')[1]
-
- for cim_reg_profile in self.cim_reg_profiles:
- if 'RegisteredName' not in cim_reg_profile or \
- 'RegisteredVersion' not in cim_reg_profile:
+ spec_int # Integer. Converted by _spec_ver_str_to_num()
+ """
+ if self.fallback_mode:
+ return _spec_ver_str_to_num(SNIA._FAKE_SPEC_VER_FALLBACK)
+ 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_reg_profile['RegisteredName'] == profile_name:
+ if cim_rp['RegisteredName'] == profile_name:
# check spec version
- cur_ver = cim_reg_profile['RegisteredVersion']
- cur_ver_list = cur_ver.split('.')
- if len(cur_ver_list) < 2:
- continue
- cur_ver_flt = float("%s.%s" % tuple(cur_ver_list[0:2]))
- req_ver_flt = float("%s.%s" % (req_ver_main, req_ver_sub))
+ cur_ver = _spec_ver_str_to_num(cim_rp['RegisteredVersion'])
- if strict and cur_ver_flt == req_ver_flt:
+ if strict and cur_ver == req_ver:
return cur_ver
-
- if strict is False and cur_ver_flt >= req_ver_flt:
- if cur_ver_flt > max_spec_ver_flt:
+ 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_flt = cur_ver_flt
+ max_spec_ver_str = cim_rp['RegisteredVersion']
+ if strict or max_spec_ver is None:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "SNIA SMI-S %s '%s' profile is not supported" %
+ (spec_ver, profile_name))
- if max_spec_ver == 0:
- return None
return max_spec_ver
- def _get_cim_syss(self, profile_name, spec_ver, property_list=None,
- strict=False, sys_id=None, raise_error=False):
+ def _root_cim_syss(self, property_list=None):
"""
- Usage:
- Check whether we support certain profile at certain SNIA
- specification version.
- When strict == False(default), profile spec version newer than
- require spec_ver will also be consider as found.
- When strict == True, only defined spec_version is allowed.
+ 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:
- If found, follow this procedure to get CIM_ComputerSystem:
CIM_RegisteredProfile # Root Profile('Array') in interop
|
| CIM_ElementConformsToProfile
v
CIM_ComputerSystem # vendor namespace
- We depend on self.cim_reg_profiles which was updated by startup().
- But this method does not check it, you should check
- self.fallback_mode == True before call this method.
-
- Please use constant spec_ver and profile_name for better
- code management.
- We also apply to system filter in URI which is stored in
- self.system_list
- When returning None, it means current provider does not support
- requested profile or version.
- Parameter:
- profile_name # Smis.SNIA_REGISTERED_PROFILE_XXX
- spec_ver # Smis.SNIA_SMIS_SPEC_VER_XXX
- property_list # a list of properties should contained in
- # returned CIM_ComputerSystem
- # When property_list == None, we retrieve full
- # data, when property_list == [], we retrieve
- # nothing but a CIMInstanceName.
- strict # False or True. If True, only defined
- # spec_version is consider as supported
- sys_id # Only return CIM_ComputerSystem for certain
- # system ID.
- Returns:
- cim_syss # a list of CIMInstanceName of CIM_ComputerSystem
- or
- None # Current SMI-S provider does not support this
- # profile at certain version.
- """
- max_spec_ver = self._profile_is_supported(
- profile_name, spec_ver, strict)
-
- if max_spec_ver is None:
- if raise_error:
- error_msg = ("Current SMI-S provider does not support "
- "SMI-S %s profile, version %s" %
- (profile_name, spec_ver))
- if not strict:
- error_msg = "%s(or later version)" % error_msg
- raise LsmError(ErrorNumber.NO_SUPPORT, error_msg)
- else:
- return None
-
- if max_spec_ver not in self.cim_root_profile_dict.keys():
- raise LsmError(ErrorNumber.INTERNAL_ERROR,
- "Failed to find out CIM_RegisteredProfile " +
- "for profile %s with version %s " %
- (Smis.SNIA_BLK_ROOT_PROFILE, max_spec_ver) +
- "even its subprofile found.")
-
- cim_root_profile = self.cim_root_profile_dict[max_spec_ver]
-
- if property_list is None:
- cim_syss = self._c.Associators(
- cim_root_profile.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile')
- else:
- sys_id_pros = self._property_list_of_id('System')
- for key in sys_id_pros:
- if key not in property_list:
- property_list.extend([key])
- cim_syss = self._c.Associators(
- cim_root_profile.path,
- ResultClass='CIM_ComputerSystem',
- AssocClass='CIM_ElementConformsToProfile',
- PropertyList=property_list)
-
- if self.system_list is None:
- return cim_syss
-
- # Method level filter
- if sys_id is not None:
- return [s for s in cim_syss if self._sys_id(s) == sys_id][0]
-
- # Apply URI system filter
- 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
-
- def _get_cim_syss_fallback(self, sys_id=None, property_list=None):
- """
- Usage:
- 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.
- Parameter:
- property_list # a list of properties should contained in
- # returned CIM_ComputerSystem
- # When property_list == None, we retrieve full
- # data, when property_list == [], we retrieve
- # nothing but a CIMInstanceName.
- Returns:
- cim_syss # A list of CIMInstanceName of CIM_ComputerSystem
- or
- None
+ 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.
"""
- sys_id_pros = self._property_list_of_id('System')
- flag_full_info = False
+ cim_sys_id_pros = self._property_list_of_id('System')
if property_list is None:
- flag_full_info = True
+ property_list = cim_sys_id_pros
else:
- for key in sys_id_pros:
- if key not in property_list:
- property_list.extend([key])
+ for key_name in cim_sys_id_pros:
+ if key_name not in property_list:
+ property_list.extend([key_name])
- cim_syss = []
- cim_scss_path = []
- try:
- # Note: Please be informed, if PropertyList is an empty list,
- # XIV will return NOTHING, so use EnumerateInstanceNames()
- # when you need nothing but the CIMInstanceName
- 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:
- if flag_full_info:
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem', LocalOnly=False)
- else:
- cim_syss = self._c.EnumerateInstances(
- 'CIM_ComputerSystem',
- PropertyList=property_list,
- LocalOnly=False)
- else:
- raise e
- if not cim_syss:
- for cim_scs_path in cim_scss_path:
- cim_tmp = None
- if flag_full_info:
- cim_tmp = self._c.Associators(
- cim_scs_path,
- AssocClass='CIM_HostedService',
- ResultClass='CIM_ComputerSystem')
- else:
- cim_tmp = self._c.Associators(
- cim_scs_path,
- AssocClass='CIM_HostedService',
+ cim_syss = None
+ if self.fallback_mode:
+ cim_syss = self._c.EnumerateInstances(
+ 'CIM_ComputerSystem',
+ PropertyList=property_list)
+ 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',
- PropertyList=property_list)
- if cim_tmp and cim_tmp[0]:
- cim_syss.extend([cim_tmp[0]])
-
- # Method level filter
- if sys_id is not None:
- return [s for s in cim_syss if self._sys_id(s) == sys_id]
+ AssocClass='CIM_ElementConformsToProfile')
+ if cim_syss is None:
+ raise LsmError(ErrorNumber.NO_SUPPORT,
+ "SMI-S provider is not supporting SNIA SMI-S "
+ "Array profile")
# System URI Filtering
if self.system_list:
@@ -3614,7 +3479,8 @@ class Smis(IStorageAreaNetwork):
else:
return cim_syss
- def _get_cim_sys_by_id(self, system_id, property_list=None):
+
+ def _cim_sys_of_id(self, system_id, property_list=None):
"""
Return a CIMInstance of CIM_ComputerSystem for given system id.
"""
@@ -3626,15 +3492,8 @@ class Smis(IStorageAreaNetwork):
if pro not in property_list:
property_list.extend([pro])
- if self.fallback_mode:
- cim_syss = self._get_cim_syss_fallback(property_list)
- else:
- cim_syss = self._get_cim_syss(
- Smis.SNIA_BLK_SRVS_PROFILE,
- Smis.SNIA_SMIS_SPEC_VER_1_4,
- strict=False,
- property_list=property_list,
- raise_error=True)
+ cim_syss = self._root_cim_syss(property_list)
+
for cim_sys in cim_syss:
if self._sys_id(cim_sys) == system_id:
return cim_sys
--
1.8.3.1
1.8.3.1