1
0
Fork 0

Merging upstream version 2.3~rc3.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-16 12:54:59 +01:00
parent 55e7d80fc6
commit 892b155d7d
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
20 changed files with 189 additions and 75 deletions

View file

@ -13,13 +13,13 @@ Bug fixes:
* For TCP transport: use `sysfs` controller `src_addr` attribute when matching to a configured "candidate" controller. This is to determine when an existing controller (located under the `sysfs`) can be reused instead of creating a new one. This avoids creating unnecessary duplicate connections.
* Udev event handling: use `systemctl restart` instead of `systemctl start`. There is a small chance that a `start` operation has not completed when a new `start` is required. Issuing a `start` while a `start` is being performed has no effect. However, a `restart` will be handled properly.
* `stafd`: Do not delete and recreate DC objects on kernel events indicating that an nvme device associated to a discovery controller was removed by the kernel. This was done to kick start the reconnect process, but was also causing the DLPE (Discovery Log Page Entries) cache to be lost. This could potentially result in `stacd` disconnecting from I/O controllers. Instead, keep the existing DC object which contains a valid DLPE cache and simply restart the "retry to connect" timer. This way the DLPE cache is maintained throughout the reconnect to DC process.
* While testing Boot from SAN (BFS) and using a Host NQN during boot that is different from the Host NQN used after boot (i.e. the Host NQN defined in `/etc/nvme/hostnqn`), we found that nvme-stas and libnvme are reusing existing connections even if the Host NQN doesn't match. nvme-stas will now take a connection's Host NQN into consideration before deciding if a connection can be reused. A similar fix will be provided in libnvme as well.
## Changes with release 2.2.3
Bug fixes:
* When processing kernel nvme events, only react to `rediscover` and not to `connected` events. The `connected` event happens too early (before the nvme device has been fully identified).
*
## Changes with release 2.2.2

View file

@ -9,7 +9,7 @@
project(
'nvme-stas',
meson_version: '>= 0.53.0',
version: '2.3-rc2',
version: '2.3-rc3',
license: 'Apache-2.0',
default_options: [
'buildtype=release',

View file

@ -39,9 +39,10 @@ def _extract_cid(ctrl):
ctrl['transport'],
ctrl['traddr'],
ctrl['trsvcid'],
ctrl['subsysnqn'],
ctrl['host-traddr'],
ctrl['host-iface'],
ctrl['subsysnqn'],
ctrl['host-nqn'],
)
@ -52,9 +53,9 @@ def status(args): # pylint: disable=unused-argument
info = json.loads(iface.process_info())
info['controllers'] = iface.list_controllers(True)
for controller in info['controllers']:
transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn = _extract_cid(controller)
transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn = _extract_cid(controller)
controller.update(
json.loads(iface.controller_info(transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn))
json.loads(iface.controller_info(transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn))
)
print(pprint.pformat(info, width=120))

View file

@ -90,10 +90,10 @@ if __name__ == '__main__':
return json.dumps(info)
def controller_info( # pylint: disable=too-many-arguments,no-self-use
self, transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn
self, transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn
) -> str:
'''@brief D-Bus method used to return information about a controller'''
controller = STAC.get_controller(transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn)
controller = STAC.get_controller(transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn)
return json.dumps(controller.info()) if controller else '{}'
def list_controllers(self, detailed) -> list: # pylint: disable=no-self-use

View file

@ -15,7 +15,7 @@ import pprint
from argparse import ArgumentParser
import dasbus.error
from dasbus.connection import SystemMessageBus
from staslib import defs
from staslib import conf, defs
def tron(args): # pylint: disable=unused-argument
@ -39,9 +39,10 @@ def _extract_cid(ctrl):
ctrl['transport'],
ctrl['traddr'],
ctrl['trsvcid'],
ctrl['subsysnqn'],
ctrl['host-traddr'],
ctrl['host-iface'],
ctrl['subsysnqn'],
ctrl['host-nqn'],
)
@ -52,10 +53,12 @@ def status(args): # pylint: disable=unused-argument
info = json.loads(iface.process_info())
info['controllers'] = iface.list_controllers(True)
for controller in info['controllers']:
transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn = _extract_cid(controller)
controller['log_pages'] = iface.get_log_pages(transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn)
transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn = _extract_cid(controller)
controller['log_pages'] = iface.get_log_pages(
transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn
)
controller.update(
json.loads(iface.controller_info(transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn))
json.loads(iface.controller_info(transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn))
)
print(pprint.pformat(info, width=120))
@ -75,7 +78,15 @@ def dlp(args):
'''@brief retrieve a controller's discovery log pages from stafd'''
bus = SystemMessageBus()
iface = bus.get_proxy(defs.STAFD_DBUS_NAME, defs.STAFD_DBUS_PATH)
info = iface.get_log_pages(args.transport, args.traddr, args.trsvcid, args.host_traddr, args.host_iface, args.nqn)
info = iface.get_log_pages(
args.transport,
args.traddr,
args.trsvcid,
args.nqn,
args.host_traddr,
args.host_iface,
args.host_nqn,
)
print(pprint.pformat(info, width=120))
@ -153,6 +164,14 @@ PRSR.add_argument(
help='This field specifies the network interface used on the host to connect to the Controller (default: "%(default)s")',
default='',
)
PRSR.add_argument(
'-q',
'--host-nqn',
metavar='<nqn>',
action='store',
help='This field specifies the host NQN (default: "%(default)s")',
default=conf.SysConf().hostnqn,
)
PRSR.add_argument(
'-n',
'--nqn',

View file

@ -70,9 +70,10 @@ if __name__ == '__main__':
transport: str,
traddr: str,
trsvcid: str,
subsysnqn: str,
host_traddr: str,
host_iface: str,
subsysnqn: str,
host_nqn: str,
device: str,
):
'''@brief Signal sent when log pages have changed.'''
@ -108,17 +109,17 @@ if __name__ == '__main__':
return json.dumps(info)
def controller_info( # pylint: disable=no-self-use,too-many-arguments
self, transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn
self, transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn
) -> str:
'''@brief D-Bus method used to return information about a controller'''
controller = STAF.get_controller(transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn)
controller = STAF.get_controller(transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn)
return json.dumps(controller.info()) if controller else '{}'
def get_log_pages( # pylint: disable=no-self-use,too-many-arguments
self, transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn
self, transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn
) -> list:
'''@brief D-Bus method used to retrieve the discovery log pages from one controller'''
controller = STAF.get_controller(transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn)
controller = STAF.get_controller(transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn)
return controller.log_pages() if controller else list()
def get_all_log_pages(self, detailed) -> str: # pylint: disable=no-self-use

View file

@ -333,15 +333,19 @@ class Avahi: # pylint: disable=too-many-instance-attributes
'transport': tcp,
'traddr': str(),
'trsvcid': str(),
'host-iface': str(),
'subsysnqn': 'nqn.2014-08.org.nvmexpress.discovery',
'host-traddr': str(),
'host-iface': str(),
'host-nqn': str(),
},
{
'transport': tcp,
'traddr': str(),
'trsvcid': str(),
'host-iface': str(),
'subsysnqn': 'nqn.2014-08.org.nvmexpress.discovery',
'host-traddr': str(),
'host-iface': str(),
'host-nqn': str(),
},
[...]
]

View file

@ -334,9 +334,10 @@ class SvcConf(metaclass=singleton.Singleton): # pylint: disable=too-many-public
'transport': [TRANSPORT],
'traddr': [TRADDR],
'trsvcid': [TRSVCID],
'subsysnqn': [NQN],
'host-traddr': [TRADDR],
'host-iface': [IFACE],
'subsysnqn': [NQN],
'host-nqn': [NQN],
'dhchap-ctrl-secret': [KEY],
'hdr-digest': [BOOL]
'data-digest': [BOOL]
@ -721,9 +722,11 @@ class NbftConf(metaclass=singleton.Singleton):
hfis = data.get('hfi', [])
discovery = data.get('discovery', [])
subsystem = data.get('subsystem', [])
host = data.get('host', {})
hostnqn = host.get('nqn', None) if host.get('host_nqn_configured', False) else None
self._disc_ctrls.extend(NbftConf.__nbft_disc_to_cids(discovery, hfis))
self._subs_ctrls.extend(NbftConf.__nbft_subs_to_cids(subsystem, hfis))
self._disc_ctrls.extend(NbftConf.__nbft_disc_to_cids(hostnqn, discovery, hfis))
self._subs_ctrls.extend(NbftConf.__nbft_subs_to_cids(hostnqn, subsystem, hfis))
dcs = property(lambda self: self._disc_ctrls)
iocs = property(lambda self: self._subs_ctrls)
@ -738,12 +741,14 @@ class NbftConf(metaclass=singleton.Singleton):
return self.dcs if defs.PROG_NAME == 'stafd' else []
@staticmethod
def __nbft_disc_to_cids(discovery, hfis):
def __nbft_disc_to_cids(hostnqn, discovery, hfis):
cids = []
for ctrl in discovery:
cid = NbftConf.__uri2cid(ctrl['uri'])
cid['subsysnqn'] = ctrl['nqn']
if hostnqn:
cid['host-nqn'] = hostnqn
host_iface = NbftConf.__get_host_iface(ctrl.get('hfi_index'), hfis)
if host_iface:
@ -754,7 +759,7 @@ class NbftConf(metaclass=singleton.Singleton):
return cids
@staticmethod
def __nbft_subs_to_cids(subsystem, hfis):
def __nbft_subs_to_cids(hostnqn, subsystem, hfis):
cids = []
for ctrl in subsystem:
@ -766,6 +771,8 @@ class NbftConf(metaclass=singleton.Singleton):
'hdr-digest': ctrl['pdu_header_digest_required'],
'data-digest': ctrl['data_digest_required'],
}
if hostnqn:
cid['host-nqn'] = hostnqn
indexes = ctrl.get('hfi_indexes')
if isinstance(indexes, list) and len(indexes) > 0:

View file

@ -393,9 +393,10 @@ class Stac(Service):
for staf_data in self._get_log_pages_from_stafd():
host_traddr = staf_data['discovery-controller']['host-traddr']
host_iface = staf_data['discovery-controller']['host-iface']
host_nqn = staf_data['discovery-controller']['host-nqn']
for dlpe in staf_data['log-pages']:
if dlpe.get('subtype') == 'nvme': # eliminate discovery controllers
tid = stas.tid_from_dlpe(dlpe, host_traddr, host_iface)
tid = stas.tid_from_dlpe(dlpe, host_traddr, host_iface, host_nqn)
discovered_ctrls[tid] = dlpe
discovered_ctrl_list = list(discovered_ctrls.keys())
@ -476,19 +477,20 @@ class Stac(Service):
logging.debug('Stac._disconnect_from_staf() - Disconnected from staf')
def _log_pages_changed( # pylint: disable=too-many-arguments
self, transport, traddr, trsvcid, host_traddr, host_iface, subsysnqn, device
self, transport, traddr, trsvcid, subsysnqn, host_traddr, host_iface, host_nqn, device
):
if not self._alive():
return
logging.debug(
'Stac._log_pages_changed() - transport=%s, traddr=%s, trsvcid=%s, host_traddr=%s, host_iface=%s, subsysnqn=%s, device=%s',
'Stac._log_pages_changed() - transport=%s, traddr=%s, trsvcid=%s, subsysnqn=%s, host_traddr=%s, host_iface=%s, host_nqn=%s, device=%s',
transport,
traddr,
trsvcid,
subsysnqn,
host_traddr,
host_iface,
subsysnqn,
host_nqn,
device,
)
if self._cfg_soak_tmr:
@ -693,9 +695,10 @@ class Staf(Service):
controller.tid.transport,
controller.tid.traddr,
controller.tid.trsvcid,
controller.tid.subsysnqn,
controller.tid.host_traddr,
controller.tid.host_iface,
controller.tid.subsysnqn,
controller.tid.host_nqn,
device,
)
@ -708,7 +711,12 @@ class Staf(Service):
def _referrals(self) -> list:
return [
stas.tid_from_dlpe(dlpe, controller.tid.host_traddr, controller.tid.host_iface)
stas.tid_from_dlpe(
dlpe,
controller.tid.host_traddr,
controller.tid.host_iface,
controller.tid.host_nqn,
)
for controller in self.get_controllers()
for dlpe in controller.referrals()
]

View file

@ -9,9 +9,10 @@
<arg direction="in" type="s" name="transport"/>
<arg direction="in" type="s" name="traddr"/>
<arg direction="in" type="s" name="trsvcid"/>
<arg direction="in" type="s" name="subsysnqn"/>
<arg direction="in" type="s" name="host_traddr"/>
<arg direction="in" type="s" name="host_iface"/>
<arg direction="in" type="s" name="subsysnqn"/>
<arg direction="in" type="s" name="host_nqn"/>
<arg direction="out" type="s" name="info_json"/>
</method>
</interface>

View file

@ -9,9 +9,10 @@
<arg direction="in" type="s" name="transport"/>
<arg direction="in" type="s" name="traddr"/>
<arg direction="in" type="s" name="trsvcid"/>
<arg direction="in" type="s" name="subsysnqn"/>
<arg direction="in" type="s" name="host_traddr"/>
<arg direction="in" type="s" name="host_iface"/>
<arg direction="in" type="s" name="subsysnqn"/>
<arg direction="in" type="s" name="host_nqn"/>
<arg direction="out" type="s" name="info_json"/>
</method>
</interface>
@ -25,9 +26,10 @@
<arg direction="in" type="s" name="transport"/>
<arg direction="in" type="s" name="traddr"/>
<arg direction="in" type="s" name="trsvcid"/>
<arg direction="in" type="s" name="subsysnqn"/>
<arg direction="in" type="s" name="host_traddr"/>
<arg direction="in" type="s" name="host_iface"/>
<arg direction="in" type="s" name="subsysnqn"/>
<arg direction="in" type="s" name="host_nqn"/>
<arg direction="out" type="aa{ss}" name="log_pages"/>
</method>
<method name="get_all_log_pages">
@ -38,9 +40,10 @@
<arg direction="out" type="s" name="transport"/>
<arg direction="out" type="s" name="traddr"/>
<arg direction="out" type="s" name="trsvcid"/>
<arg direction="out" type="s" name="subsysnqn"/>
<arg direction="out" type="s" name="host_traddr"/>
<arg direction="out" type="s" name="host_iface"/>
<arg direction="out" type="s" name="subsysnqn"/>
<arg direction="out" type="s" name="host_nqn"/>
<arg direction="out" type="s" name="device"/>
</signal>
<signal name="dc_removed"></signal>

View file

@ -125,7 +125,7 @@ def remove_invalid_addresses(controllers: list):
# ******************************************************************************
def tid_from_dlpe(dlpe, host_traddr, host_iface):
def tid_from_dlpe(dlpe, host_traddr, host_iface, host_nqn):
'''@brief Take a Discovery Log Page Entry and return a Controller ID as a dict.'''
cid = {
'transport': dlpe['trtype'],
@ -135,6 +135,8 @@ def tid_from_dlpe(dlpe, host_traddr, host_iface):
'host-iface': host_iface,
'subsysnqn': dlpe['subnqn'],
}
if host_nqn:
cid['host-nqn'] = host_nqn
return trid.TID(cid)
@ -416,16 +418,24 @@ class ServiceABC(abc.ABC): # pylint: disable=too-many-instance-attributes
return self._controllers.values()
def get_controller(
self, transport: str, traddr: str, trsvcid: str, host_traddr: str, host_iface: str, subsysnqn: str
self,
transport: str,
traddr: str,
trsvcid: str,
subsysnqn: str,
host_traddr: str,
host_iface: str,
host_nqn: str,
): # pylint: disable=too-many-arguments
'''@brief get the specified controller object from the list of controllers'''
cid = {
'transport': transport,
'traddr': traddr,
'trsvcid': trsvcid,
'subsysnqn': subsysnqn,
'host-traddr': host_traddr,
'host-iface': host_iface,
'subsysnqn': subsysnqn,
'host-nqn': host_nqn,
}
return self._controllers.get(trid.TID(cid))

View file

@ -30,6 +30,7 @@ class TID: # pylint: disable=too-many-instance-attributes
'trsvcid': str, # [optional]
'host-traddr': str, # [optional]
'host-iface': str, # [optional]
'host-nqn': str, # [optional]
# Connection parameters
'dhchap-ctrl-secret': str, # [optional]
@ -58,59 +59,54 @@ class TID: # pylint: disable=too-many-instance-attributes
self._trsvcid = (
trsvcid if trsvcid else (TID.RDMA_IP_PORT if self._transport == 'rdma' else TID.DISC_IP_PORT)
)
sysconf = conf.SysConf()
self._host_traddr = cid.get('host-traddr', '')
self._host_iface = '' if conf.SvcConf().ignore_iface else cid.get('host-iface', '')
self._host_nqn = cid.get('host-nqn', sysconf.hostnqn)
self._subsysnqn = cid.get('subsysnqn', '')
self._key = (self._transport, self._traddr, self._trsvcid, self._subsysnqn, self._host_traddr, self._host_iface)
self._key = (
self._transport,
self._traddr,
self._trsvcid,
self._subsysnqn,
self._host_traddr,
self._host_iface,
self._host_nqn,
)
self._hash = int.from_bytes(
hashlib.md5(''.join(self._key).encode('utf-8')).digest(), 'big'
) # We need a consistent hash between restarts
self._id = f'({self._transport}, {self._traddr}, {self._trsvcid}{", " + self._subsysnqn if self._subsysnqn else ""}{", " + self._host_iface if self._host_iface else ""}{", " + self._host_traddr if self._host_traddr else ""})' # pylint: disable=line-too-long
@property
def transport(self): # pylint: disable=missing-function-docstring
return self._transport
@property
def traddr(self): # pylint: disable=missing-function-docstring
return self._traddr
@property
def trsvcid(self): # pylint: disable=missing-function-docstring
return self._trsvcid
@property
def host_traddr(self): # pylint: disable=missing-function-docstring
return self._host_traddr
@property
def host_iface(self): # pylint: disable=missing-function-docstring
return self._host_iface
@property
def subsysnqn(self): # pylint: disable=missing-function-docstring
return self._subsysnqn
@property
def cfg(self): # pylint: disable=missing-function-docstring
return self._cfg
host_traddr = property(lambda self: self._host_traddr)
host_iface = property(lambda self: self._host_iface)
subsysnqn = property(lambda self: self._subsysnqn)
transport = property(lambda self: self._transport)
host_nqn = property(lambda self: self._host_nqn)
trsvcid = property(lambda self: self._trsvcid)
traddr = property(lambda self: self._traddr)
cfg = property(lambda self: self._cfg)
def as_dict(self):
'''Return object members as a dictionary'''
data = {
'transport': self.transport,
'traddr': self.traddr,
'subsysnqn': self.subsysnqn,
'trsvcid': self.trsvcid,
'host-traddr': self.host_traddr,
'transport': self.transport,
'subsysnqn': self.subsysnqn,
'host-iface': self.host_iface,
'host-traddr': self.host_traddr,
}
# When migrating an old last known config, the "_cfg" member may
# not exist. Therefor retrive it with getattr() to avoid a crash.
# When migrating an old last known config, some members may not
# exist. Therefore retrieve them with getattr() to avoid a crash.
cfg = getattr(self, '_cfg', None)
if cfg:
data.update(cfg)
sysconf = conf.SysConf()
data['host-nqn'] = getattr(self, '_host_nqn', sysconf.hostnqn)
return data
def __str__(self):

View file

@ -259,8 +259,13 @@ class Udev:
cid.src_addr can only be read from the sysfs starting with kernel
6.1.
'''
# 'transport', 'traddr', 'trsvcid', and 'subsysnqn' must exactly match.
if cid['transport'] != tid.transport or cid['trsvcid'] != tid.trsvcid or cid['subsysnqn'] != tid.subsysnqn:
# 'transport', 'traddr', 'trsvcid', 'subsysnqn', and 'host-nqn' must exactly match.
if (
cid['transport'] != tid.transport
or cid['trsvcid'] != tid.trsvcid
or cid['subsysnqn'] != tid.subsysnqn
or cid['host-nqn'] != tid.host_nqn
):
return False
if tid.transport in ('tcp', 'rdma'):
@ -489,6 +494,7 @@ class Udev:
'host-iface': Udev._get_property(device, 'NVME_HOST_IFACE'),
'subsysnqn': Udev._get_attribute(device, 'subsysnqn'),
'src-addr': Udev.get_key_from_attr(device, 'address', 'src_addr='),
'host-nqn': Udev._get_attribute(device, 'hostnqn'),
}
return cid

View file

@ -118,6 +118,7 @@ class Test(TestCase):
'trsvcid': '8009',
'host-traddr': '1.2.3.4',
'host-iface': 'wlp0s20f3',
'host-nqn': 'nqn.1988-11.com.dell:poweredge:1234',
}
)
@ -186,6 +187,7 @@ class Test(TestCase):
'host-iface': 'wlp0s20f3',
'subsysnqn': 'nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
'device': 'nvme?',
'host-nqn': 'nqn.1988-11.com.dell:poweredge:1234',
},
)
@ -198,6 +200,7 @@ class Test(TestCase):
'trsvcid': '8009',
'host-traddr': '1.2.3.4',
'host-iface': 'wlp0s20f3',
'host-nqn': 'nqn.1988-11.com.dell:poweredge:1234',
'device': 'nvme?',
'connect attempts': '1',
'retry connect timer': '60.0s [off]',
@ -215,6 +218,7 @@ class Test(TestCase):
'trsvcid': '8009',
'host-traddr': '1.2.3.4',
'host-iface': 'wlp0s20f3',
'host-nqn': 'nqn.1988-11.com.dell:poweredge:1234',
'subsysnqn': 'nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
'device': 'nvme?',
'connect attempts': '1',

View file

@ -39,7 +39,7 @@ NBFT_DATA = {
"host_nqn_configured": True,
"id": "44454c4c-3400-1036-8038-b2c04f313233",
"nqn": "nqn.1988-11.com.dell:PowerEdge.R760.1234567",
"primary_admin_host_flag": "not " "indicated",
"primary_admin_host_flag": "not indicated",
},
"subsystem": [
{

View file

@ -11,6 +11,7 @@ EXPECTED_DCS = [
'traddr': '100.71.103.50',
'transport': 'tcp',
'trsvcid': '8009',
'host-nqn': 'nqn.1988-11.com.dell:PowerEdge.R760.1234567',
}
]
EXPECTED_IOCS = [
@ -21,6 +22,7 @@ EXPECTED_IOCS = [
'traddr': '100.71.103.48',
'transport': 'tcp',
'trsvcid': '4420',
'host-nqn': 'nqn.1988-11.com.dell:PowerEdge.R760.1234567',
},
{
'data-digest': False,
@ -29,6 +31,7 @@ EXPECTED_IOCS = [
'traddr': '100.71.103.49',
'transport': 'tcp',
'trsvcid': '4420',
'host-nqn': 'nqn.1988-11.com.dell:PowerEdge.R760.1234567',
},
]

View file

@ -58,9 +58,10 @@ class Test(TestCase):
transport='tcp',
traddr='10.10.10.10',
trsvcid='8009',
subsysnqn='nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
host_traddr='1.2.3.4',
host_iface='wlp0s20f3',
subsysnqn='nqn.1988-11.com.dell:SFSS:2:20220208134025e8',
host_nqn='nqn.2014-08.org.nvmexpress:uuid:01234567-0123-0123-0123-0123456789ab',
),
None,
)

View file

@ -13,6 +13,7 @@ class Test(unittest.TestCase):
TRSVCID = '8009'
HOST_TRADDR = '1.2.3.4'
HOST_IFACE = 'wlp0s20f3'
HOST_NQN = 'nqn.1988-11.com.dell:12345'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@ -23,6 +24,7 @@ class Test(unittest.TestCase):
'trsvcid': Test.TRSVCID,
'host-traddr': Test.HOST_TRADDR,
'host-iface': Test.HOST_IFACE,
'host-nqn': Test.HOST_NQN,
}
self.other_cid = {
'transport': Test.TRANSPORT,
@ -31,6 +33,7 @@ class Test(unittest.TestCase):
'trsvcid': Test.TRSVCID,
'host-traddr': Test.HOST_TRADDR,
'host-iface': Test.HOST_IFACE,
'host-nqn': Test.HOST_NQN,
}
self.tid = trid.TID(self.cid)

View file

@ -33,6 +33,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-iface': ifname,
'host-nqn': '',
}
),
True,
@ -47,6 +48,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-iface': ifname,
'host-nqn': '',
}
),
False,
@ -61,6 +63,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-iface': ifname,
'host-nqn': '',
}
),
False,
@ -75,6 +78,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-iface': ifname,
'host-nqn': '',
}
),
False,
@ -89,6 +93,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': '255.255.255.255',
'host-iface': ifname,
'host-nqn': '',
}
),
False,
@ -103,6 +108,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-iface': 'blah',
'host-nqn': '',
}
),
False,
@ -117,6 +123,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'bob',
'host-traddr': src_ip,
'host-iface': ifname,
'host-nqn': '',
}
),
False,
@ -130,6 +137,7 @@ def get_tids_to_test(family, src_ip, ifname):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-iface': ifname,
'host-nqn': '',
}
),
True,
@ -143,6 +151,7 @@ def get_tids_to_test(family, src_ip, ifname):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-nqn': '',
}
),
True,
@ -155,6 +164,7 @@ def get_tids_to_test(family, src_ip, ifname):
'traddr': traddr(family),
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-nqn': '',
}
),
True,
@ -169,6 +179,7 @@ def get_tids_to_test(family, src_ip, ifname):
'subsysnqn': 'hello',
'host-traddr': src_ip,
'host-iface': ifname,
'host-nqn': '',
}
),
True,
@ -182,6 +193,7 @@ def get_tids_to_test(family, src_ip, ifname):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-iface': ifname,
'host-nqn': '',
}
),
True,
@ -296,6 +308,7 @@ class Test(unittest.TestCase):
'host-traddr': src_ipv4,
'host-iface': ifname,
'src-addr': src_ipv4,
'host-nqn': '',
}
cid_legacy = {
'transport': 'tcp',
@ -305,6 +318,7 @@ class Test(unittest.TestCase):
'host-traddr': src_ipv4,
'host-iface': ifname,
'src-addr': '', # Legacy
'host-nqn': '',
}
for case_id, tid, match in get_tids_to_test(4, src_ipv4, ifname):
self.assertEqual(match, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case {case_id} failed')
@ -321,6 +335,7 @@ class Test(unittest.TestCase):
'host-traddr': '',
'host-iface': '',
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -329,6 +344,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': '1.1.1.1',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case A4.1 failed')
@ -341,6 +357,7 @@ class Test(unittest.TestCase):
'host-traddr': '',
'host-iface': ifname,
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -348,6 +365,7 @@ class Test(unittest.TestCase):
'traddr': traddr(4),
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case A4.2 failed')
@ -363,6 +381,7 @@ class Test(unittest.TestCase):
'host-traddr': src_ipv4,
'host-iface': '',
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -371,6 +390,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': '1.1.1.1',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case B4 failed')
@ -382,6 +402,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-iface': 'blah',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case C4 failed')
@ -393,6 +414,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-iface': ifname,
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case D4 failed')
@ -405,6 +427,7 @@ class Test(unittest.TestCase):
'host-traddr': '',
'host-iface': ifname,
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -414,6 +437,7 @@ class Test(unittest.TestCase):
'subsysnqn': 'hello',
'host-traddr': '1.1.1.1',
'host-iface': 'blah',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case E4 failed')
@ -425,6 +449,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': '1.1.1.1',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case F4 failed')
@ -436,6 +461,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': ipv4_addrs[0],
'host-nqn': '',
}
)
match = len(ipv4_addrs) == 1 and iputil.get_ipaddress_obj(
@ -456,6 +482,7 @@ class Test(unittest.TestCase):
'host-traddr': src_ipv6,
'host-iface': ifname,
'src-addr': src_ipv6,
'host-nqn': '',
}
cid_legacy = {
'transport': 'tcp',
@ -465,6 +492,7 @@ class Test(unittest.TestCase):
'host-traddr': src_ipv6,
'host-iface': ifname,
'src-addr': '', # Legacy
'host-nqn': '',
}
for case_id, tid, match in get_tids_to_test(6, src_ipv6, ifname):
self.assertEqual(match, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case {case_id} failed')
@ -480,6 +508,7 @@ class Test(unittest.TestCase):
'host-traddr': '',
'host-iface': '',
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -488,6 +517,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': 'AAAA::FFFF',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case A6.1 failed')
@ -500,6 +530,7 @@ class Test(unittest.TestCase):
'host-traddr': '',
'host-iface': ifname,
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -507,6 +538,7 @@ class Test(unittest.TestCase):
'traddr': traddr(6),
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case A6.2 failed')
@ -522,6 +554,7 @@ class Test(unittest.TestCase):
'host-traddr': src_ipv6,
'host-iface': '',
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -530,6 +563,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': 'AAAA::FFFF',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case B6 failed')
@ -541,6 +575,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-iface': 'blah',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case C6 failed')
@ -552,6 +587,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-iface': ifname,
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case D6 failed')
@ -564,6 +600,7 @@ class Test(unittest.TestCase):
'host-traddr': '',
'host-iface': ifname,
'src-addr': '', # Legacy
'host-nqn': '',
}
tid = trid.TID(
{
@ -573,6 +610,7 @@ class Test(unittest.TestCase):
'subsysnqn': 'hello',
'host-traddr': 'AAA::BBBB',
'host-iface': 'blah',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case E6 failed')
@ -584,6 +622,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': 'AAA::BBB',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid_legacy), msg=f'Legacy Test Case F6 failed')
@ -595,6 +634,7 @@ class Test(unittest.TestCase):
'trsvcid': '8009',
'subsysnqn': 'hello',
'host-traddr': ipv6_addrs[0],
'host-nqn': '',
}
)
match = len(ipv6_addrs) == 1 and iputil.get_ipaddress_obj(
@ -612,6 +652,7 @@ class Test(unittest.TestCase):
'host-traddr': 'AAA::BBBB',
'host-iface': '',
'src-addr': '',
'host-nqn': '',
}
tid = trid.TID(
{
@ -620,6 +661,7 @@ class Test(unittest.TestCase):
'trsvcid': '',
'subsysnqn': 'hello',
'host-traddr': 'AAA::BBBB',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case FC-1 failed')
@ -631,6 +673,7 @@ class Test(unittest.TestCase):
'trsvcid': '',
'subsysnqn': 'hello',
'host-traddr': 'BBBB::AAA',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case FC-2 failed')
@ -645,6 +688,7 @@ class Test(unittest.TestCase):
'host-traddr': '5.4.3.2',
'host-iface': '',
'src-addr': '',
'host-nqn': '',
}
tid = trid.TID(
{
@ -653,6 +697,7 @@ class Test(unittest.TestCase):
'trsvcid': '4444',
'subsysnqn': 'hello',
'host-traddr': '5.4.3.2',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case RDMA-1 failed')
@ -664,6 +709,7 @@ class Test(unittest.TestCase):
'trsvcid': '4444',
'subsysnqn': 'hello',
'host-traddr': '5.5.6.6',
'host-nqn': '',
}
)
self.assertEqual(False, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case RDMA-2 failed')
@ -674,6 +720,7 @@ class Test(unittest.TestCase):
'traddr': '2.3.4.5',
'trsvcid': '4444',
'subsysnqn': 'hello',
'host-nqn': '',
}
)
self.assertEqual(True, udev.UDEV._cid_matches_tid(tid, cid), msg=f'Test Case RDMA-3 failed')