diff options
Diffstat (limited to 'staslib/conf.py')
-rw-r--r-- | staslib/conf.py | 106 |
1 files changed, 101 insertions, 5 deletions
diff --git a/staslib/conf.py b/staslib/conf.py index a54da98..e5c038b 100644 --- a/staslib/conf.py +++ b/staslib/conf.py @@ -14,7 +14,8 @@ import sys import logging import functools import configparser -from staslib import defs, singleton, timeparse +from urllib.parse import urlparse +from staslib import defs, iputil, nbft, singleton, timeparse __TOKEN_RE = re.compile(r'\s*;\s*') __OPTION_RE = re.compile(r'\s*=\s*') @@ -83,7 +84,8 @@ def _to_ip_family(text): class OrderedMultisetDict(dict): '''This class is used to change the behavior of configparser.ConfigParser and allow multiple configuration parameters with the same key. The - result is a list of values. + result is a list of values, where values are sorted by the order they + appear in the file. ''' def __setitem__(self, key, value): @@ -317,7 +319,7 @@ class SvcConf(metaclass=singleton.Singleton): # pylint: disable=too-many-public option = 'persistent-connections' value = self.get_option(section, option, ignore_default=True) - legacy = self.get_option('Global', 'persistent-connections', ignore_default=True) + legacy = self.get_option('Global', option, ignore_default=True) if value is None and legacy is None: return self._defaults.get((section, option), True) @@ -381,7 +383,7 @@ class SvcConf(metaclass=singleton.Singleton): # pylint: disable=too-many-public controller_list = self.get_option('Controllers', 'exclude') # 2022-09-20: Look for "blacklist". This is for backwards compatibility - # with releases 1.0 to 1.1.6. This is to be phased out (i.e. remove by 2024) + # with releases 1.0 to 1.1.x. This is to be phased out (i.e. remove by 2024) controller_list += self.get_option('Controllers', 'blacklist') excluded = [_parse_controller(controller) for controller in controller_list] @@ -572,7 +574,7 @@ class SysConf(metaclass=singleton.Singleton): try: value = self.__get_value('Host', 'key', defs.NVME_HOSTKEY) except FileNotFoundError as ex: - logging.info('Host key undefined: %s', ex) + logging.debug('Host key undefined: %s', ex) value = None return value @@ -701,3 +703,97 @@ class NvmeOptions(metaclass=singleton.Singleton): def dhchap_ctrlkey_supp(self): '''This option allows specifying the controller DHCHAP key used for authentication.''' return self._supported_options['dhchap_ctrl_secret'] + + +# ****************************************************************************** +class NbftConf(metaclass=singleton.Singleton): + '''Read and cache configuration file.''' + + def __init__(self, root_dir=defs.NBFT_SYSFS_PATH): + self._disc_ctrls = [] + self._subs_ctrls = [] + + nbft_files = nbft.get_nbft_files(root_dir) + if len(nbft_files): + logging.info('NBFT location(s): %s', list(nbft_files.keys())) + + for data in nbft_files.values(): + hfis = data.get('hfi', []) + discovery = data.get('discovery', []) + subsystem = data.get('subsystem', []) + + self._disc_ctrls.extend(NbftConf.__nbft_disc_to_cids(discovery, hfis)) + self._subs_ctrls.extend(NbftConf.__nbft_subs_to_cids(subsystem, hfis)) + + dcs = property(lambda self: self._disc_ctrls) + iocs = property(lambda self: self._subs_ctrls) + + def get_controllers(self): + '''Retrieve the list of controllers. Stafd only cares about + discovery controllers. Stacd only cares about I/O controllers.''' + + # For now, only return DCs. There are still unanswered questions + # regarding I/O controllers, e.g. what if multipathing has been + # configured. + return self.dcs if defs.PROG_NAME == 'stafd' else [] + + @staticmethod + def __nbft_disc_to_cids(discovery, hfis): + cids = [] + + for ctrl in discovery: + cid = NbftConf.__uri2cid(ctrl['uri']) + cid['subsysnqn'] = ctrl['nqn'] + + host_iface = NbftConf.__get_host_iface(ctrl.get('hfi_index'), hfis) + if host_iface: + cid['host-iface'] = host_iface + + cids.append(cid) + + return cids + + @staticmethod + def __nbft_subs_to_cids(subsystem, hfis): + cids = [] + + for ctrl in subsystem: + cid = { + 'transport': ctrl['trtype'], + 'traddr': ctrl['traddr'], + 'trsvcid': ctrl['trsvcid'], + 'subsysnqn': ctrl['subsys_nqn'], + 'hdr-digest': ctrl['pdu_header_digest_required'], + 'data-digest': ctrl['data_digest_required'], + } + + indexes = ctrl.get('hfi_indexes') + if isinstance(indexes, list) and len(indexes) > 0: + host_iface = NbftConf.__get_host_iface(indexes[0], hfis) + if host_iface: + cid['host-iface'] = host_iface + + cids.append(cid) + + return cids + + @staticmethod + def __get_host_iface(indx, hfis): + if indx is None or indx >= len(hfis): + return None + + mac = hfis[indx].get('mac_addr') + if mac is None: + return None + + return iputil.mac2iface(mac) + + @staticmethod + def __uri2cid(uri: str): + '''Convert a URI of the form "nvme+tcp://100.71.103.50:8009/" to a Controller ID''' + obj = urlparse(uri) + return { + 'transport': obj.scheme.split('+')[1], + 'traddr': obj.hostname, + 'trsvcid': str(obj.port), + } |