Adding upstream version 2.3~rc4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
e89431f274
commit
8b146d606d
16 changed files with 708 additions and 276 deletions
|
@ -36,18 +36,25 @@ KERNEL_IFACE_MIN_VERSION = KernelVersion('5.14')
|
|||
KERNEL_TP8013_MIN_VERSION = KernelVersion('5.16')
|
||||
KERNEL_HOSTKEY_MIN_VERSION = KernelVersion('5.20')
|
||||
KERNEL_CTRLKEY_MIN_VERSION = KernelVersion('5.20')
|
||||
KERNEL_ALL_MIN_VERSION = max(
|
||||
# Minimum version required to have support for all
|
||||
KERNEL_IFACE_MIN_VERSION,
|
||||
KERNEL_TP8013_MIN_VERSION,
|
||||
KERNEL_HOSTKEY_MIN_VERSION,
|
||||
KERNEL_CTRLKEY_MIN_VERSION,
|
||||
)
|
||||
|
||||
WELL_KNOWN_DISC_NQN = 'nqn.2014-08.org.nvmexpress.discovery'
|
||||
|
||||
PROG_NAME = os.path.basename(sys.argv[0])
|
||||
|
||||
NVME_HOSTID = '/etc/nvme/hostid'
|
||||
NVME_HOSTNQN = '/etc/nvme/hostnqn'
|
||||
NVME_HOSTKEY = '/etc/nvme/hostkey'
|
||||
NVME_HOSTID = '@ETC@/nvme/hostid'
|
||||
NVME_HOSTNQN = '@ETC@/nvme/hostnqn'
|
||||
NVME_HOSTKEY = '@ETC@/nvme/hostkey'
|
||||
|
||||
SYS_CONF_FILE = '/etc/stas/sys.conf'
|
||||
STAFD_CONF_FILE = '/etc/stas/stafd.conf'
|
||||
STACD_CONF_FILE = '/etc/stas/stacd.conf'
|
||||
SYS_CONF_FILE = '@ETC@/stas/sys.conf'
|
||||
STAFD_CONF_FILE = '@ETC@/stas/stafd.conf'
|
||||
STACD_CONF_FILE = '@ETC@/stas/stacd.conf'
|
||||
|
||||
HAS_NBFT_SUPPORT = hasattr(nvme, 'nbft_get')
|
||||
NBFT_SYSFS_PATH = "/sys/firmware/acpi/tables"
|
||||
|
|
|
@ -6,8 +6,8 @@
|
|||
#
|
||||
# Authors: Martin Belanger <Martin.Belanger@dell.com>
|
||||
#
|
||||
'''This module provides utility functions/classes to provide easier to use
|
||||
access to GLib/Gio/Gobject resources.
|
||||
'''This module provides utility functions (or classes) that simplify
|
||||
the use of certain GLib/Gio/Gobject functions/resources.
|
||||
'''
|
||||
|
||||
import logging
|
||||
|
@ -443,7 +443,7 @@ class TcpChecker: # pylint: disable=too-many-instance-attributes
|
|||
# the GLib context.
|
||||
family = socket.AF_INET if self._traddr.version == 4 else socket.AF_INET6
|
||||
self._native_sock = socket.socket(family, socket.SOCK_STREAM | socket.SOCK_NONBLOCK, socket.IPPROTO_TCP)
|
||||
if isinstance(self._host_iface, str):
|
||||
if self._host_iface and isinstance(self._host_iface, str):
|
||||
self._native_sock.setsockopt(socket.SOL_SOCKET, socket.SO_BINDTODEVICE, self._host_iface.encode('utf-8'))
|
||||
|
||||
# Convert socket.socket() to a Gio.Socket() object
|
||||
|
|
|
@ -131,66 +131,22 @@ def mac2iface(mac: str): # pylint: disable=too-many-locals
|
|||
|
||||
|
||||
# ******************************************************************************
|
||||
def _data_matches_ip(data_family, data, ip):
|
||||
if data_family == socket.AF_INET:
|
||||
try:
|
||||
other_ip = ipaddress.IPv4Address(data)
|
||||
except ValueError:
|
||||
return False
|
||||
if ip.version == 6:
|
||||
ip = ip.ipv4_mapped
|
||||
elif data_family == socket.AF_INET6:
|
||||
try:
|
||||
other_ip = ipaddress.IPv6Address(data)
|
||||
except ValueError:
|
||||
return False
|
||||
if ip.version == 4:
|
||||
other_ip = other_ip.ipv4_mapped
|
||||
else:
|
||||
def ip_equal(ip1, ip2):
|
||||
'''Check whther two IP addresses are equal.
|
||||
@param ip1: IPv4Address or IPv6Address object
|
||||
@param ip2: IPv4Address or IPv6Address object
|
||||
'''
|
||||
if not isinstance(ip1, ipaddress._BaseAddress): # pylint: disable=protected-access
|
||||
return False
|
||||
if not isinstance(ip2, ipaddress._BaseAddress): # pylint: disable=protected-access
|
||||
return False
|
||||
|
||||
return other_ip == ip
|
||||
if ip1.version == 4 and ip2.version == 6:
|
||||
ip2 = ip2.ipv4_mapped
|
||||
elif ip1.version == 6 and ip2.version == 4:
|
||||
ip1 = ip1.ipv4_mapped
|
||||
|
||||
|
||||
def _iface_of(src_addr): # pylint: disable=too-many-locals
|
||||
'''@brief Find the interface that has src_addr as one of its assigned IP addresses.
|
||||
@param src_addr: The IP address to match
|
||||
@type src_addr: Instance of ipaddress.IPv4Address or ipaddress.IPv6Address
|
||||
'''
|
||||
with socket.socket(socket.AF_NETLINK, socket.SOCK_RAW) as sock:
|
||||
sock.sendall(GETADDRCMD)
|
||||
nlmsg = sock.recv(8192)
|
||||
nlmsg_idx = 0
|
||||
while True:
|
||||
if nlmsg_idx >= len(nlmsg):
|
||||
nlmsg += sock.recv(8192)
|
||||
|
||||
nlmsghdr = nlmsg[nlmsg_idx : nlmsg_idx + NLMSG_HDRLEN]
|
||||
nlmsg_len, nlmsg_type, _, _, _ = struct.unpack('<LHHLL', nlmsghdr)
|
||||
|
||||
if nlmsg_type == NLMSG_DONE:
|
||||
break
|
||||
|
||||
if nlmsg_type == RTM_NEWADDR:
|
||||
msg_indx = nlmsg_idx + NLMSG_HDRLEN
|
||||
msg = nlmsg[msg_indx : msg_indx + IFADDRMSG_SZ] # ifaddrmsg
|
||||
ifa_family, _, _, _, ifa_index = struct.unpack('<BBBBL', msg)
|
||||
|
||||
rtattr_indx = msg_indx + IFADDRMSG_SZ
|
||||
while rtattr_indx < (nlmsg_idx + nlmsg_len):
|
||||
rtattr = nlmsg[rtattr_indx : rtattr_indx + RTATTR_SZ]
|
||||
rta_len, rta_type = struct.unpack('<HH', rtattr)
|
||||
if rta_type == IFLA_ADDRESS:
|
||||
data = nlmsg[rtattr_indx + RTATTR_SZ : rtattr_indx + rta_len]
|
||||
if _data_matches_ip(ifa_family, data, src_addr):
|
||||
return socket.if_indextoname(ifa_index)
|
||||
|
||||
rta_len = RTA_ALIGN(rta_len) # Round up to multiple of 4
|
||||
rtattr_indx += rta_len # Move to next rtattr
|
||||
|
||||
nlmsg_idx += nlmsg_len # Move to next Netlink message
|
||||
|
||||
return ''
|
||||
return ip1 == ip2
|
||||
|
||||
|
||||
# ******************************************************************************
|
||||
|
@ -221,21 +177,21 @@ def net_if_addrs(): # pylint: disable=too-many-locals
|
|||
source address.
|
||||
@example: {
|
||||
'wlp0s20f3': {
|
||||
4: ['10.0.0.28'],
|
||||
4: [IPv4Address('10.0.0.28')],
|
||||
6: [
|
||||
'fd5e:9a9e:c5bd:0:5509:890c:1848:3843',
|
||||
'fd5e:9a9e:c5bd:0:1fd5:e527:8df7:7912',
|
||||
'2605:59c8:6128:fb00:c083:1b8:c467:81d2',
|
||||
'2605:59c8:6128:fb00:e99d:1a02:38e0:ad52',
|
||||
'fe80::d71b:e807:d5ee:7614'
|
||||
IPv6Address('fd5e:9a9e:c5bd:0:5509:890c:1848:3843'),
|
||||
IPv6Address('fd5e:9a9e:c5bd:0:1fd5:e527:8df7:7912'),
|
||||
IPv6Address('2605:59c8:6128:fb00:c083:1b8:c467:81d2'),
|
||||
IPv6Address('2605:59c8:6128:fb00:e99d:1a02:38e0:ad52'),
|
||||
IPv6Address('fe80::d71b:e807:d5ee:7614'),
|
||||
],
|
||||
},
|
||||
'lo': {
|
||||
4: ['127.0.0.1'],
|
||||
6: ['::1'],
|
||||
4: [IPv4Address('127.0.0.1')],
|
||||
6: [IPv6Address('::1')],
|
||||
},
|
||||
'docker0': {
|
||||
4: ['172.17.0.1'],
|
||||
4: [IPv4Address('172.17.0.1')],
|
||||
6: []
|
||||
},
|
||||
}
|
||||
|
@ -295,14 +251,18 @@ def net_if_addrs(): # pylint: disable=too-many-locals
|
|||
|
||||
|
||||
# ******************************************************************************
|
||||
def get_interface(src_addr):
|
||||
def get_interface(ifaces: dict, src_addr):
|
||||
'''Get interface for given source address
|
||||
@param src_addr: The source address
|
||||
@type src_addr: str
|
||||
@param ifaces: Interface info previously returned by @net_if_addrs()
|
||||
@param src_addr: IPv4Address or IPv6Address object
|
||||
'''
|
||||
if not src_addr:
|
||||
if not isinstance(src_addr, ipaddress._BaseAddress): # pylint: disable=protected-access
|
||||
return ''
|
||||
|
||||
src_addr = src_addr.split('%')[0] # remove scope-id (if any)
|
||||
src_addr = get_ipaddress_obj(src_addr)
|
||||
return '' if src_addr is None else _iface_of(src_addr)
|
||||
for iface, addr_map in ifaces.items():
|
||||
for addrs in addr_map.values():
|
||||
for addr in addrs:
|
||||
if ip_equal(src_addr, addr):
|
||||
return iface
|
||||
|
||||
return ''
|
||||
|
|
257
staslib/udev.py
257
staslib/udev.py
|
@ -11,6 +11,7 @@
|
|||
import os
|
||||
import time
|
||||
import logging
|
||||
from functools import partial
|
||||
import pyudev
|
||||
from gi.repository import GLib
|
||||
from staslib import defs, iputil, trid
|
||||
|
@ -154,7 +155,7 @@ class Udev:
|
|||
return False
|
||||
|
||||
@staticmethod
|
||||
def _cid_matches_tcp_tid_legacy(tid, cid): # pylint: disable=too-many-return-statements,too-many-branches
|
||||
def _cid_matches_tcp_tid_legacy(tid, cid, ifaces): # pylint: disable=too-many-branches
|
||||
'''On kernels older than 6.1, the src_addr parameter is not available
|
||||
from the sysfs. Therefore, we need to infer a match based on other
|
||||
parameters. And there are a few cases where we're simply not sure
|
||||
|
@ -164,76 +165,66 @@ class Udev:
|
|||
cid_host_iface = cid['host-iface']
|
||||
cid_host_traddr = iputil.get_ipaddress_obj(cid['host-traddr'], ipv4_mapped_convert=True)
|
||||
|
||||
if not cid_host_iface: # cid.host_iface is undefined
|
||||
if not cid_host_traddr: # cid.host_traddr is undefined
|
||||
# When the existing cid.src_addr, cid.host_traddr, and cid.host_iface
|
||||
# are all undefined (which can only happen on kernels prior to 6.1),
|
||||
# we can't know for sure on which interface an existing connection
|
||||
# was made. In this case, we can only declare a match if both
|
||||
# tid.host_iface and tid.host_traddr are undefined as well.
|
||||
logging.debug(
|
||||
'Udev._cid_matches_tcp_tid_legacy() - cid=%s, tid=%s - Not enough info. Assume "match" but this could be wrong.',
|
||||
cid,
|
||||
tid,
|
||||
)
|
||||
return True
|
||||
# Only check host_traddr if candidate cares about it
|
||||
if tid.host_traddr:
|
||||
tid_host_traddr = iputil.get_ipaddress_obj(tid.host_traddr, ipv4_mapped_convert=True)
|
||||
|
||||
# cid.host_traddr is defined. If tid.host_traddr is also
|
||||
# defined, then it must match the existing cid.host_traddr.
|
||||
if tid.host_traddr:
|
||||
tid_host_traddr = iputil.get_ipaddress_obj(tid.host_traddr, ipv4_mapped_convert=True)
|
||||
if cid_host_traddr:
|
||||
if tid_host_traddr != cid_host_traddr:
|
||||
return False
|
||||
|
||||
# If tid.host_iface is defined, then the interface where
|
||||
# the connection is located must match. If tid.host_iface
|
||||
# is not defined, then we don't really care on which
|
||||
# interface the connection was made and we can skip this test.
|
||||
if tid.host_iface:
|
||||
# With the existing cid.host_traddr, we can find the
|
||||
# interface of the exisiting connection.
|
||||
connection_iface = iputil.get_interface(str(cid_host_traddr))
|
||||
if tid.host_iface != connection_iface:
|
||||
else:
|
||||
# If c->cfg.host_traddr is unknown, then the controller (c)
|
||||
# uses the interface's primary address as the source
|
||||
# address. If c->cfg.host_iface is defined we can
|
||||
# determine the primary address associated with that
|
||||
# interface and compare that to the candidate->host_traddr.
|
||||
if cid_host_iface:
|
||||
if_addrs = ifaces.get(cid_host_iface, {4: [], 6: []})
|
||||
source_addrs = if_addrs[tid_host_traddr.version]
|
||||
if len(source_addrs): # Make sure it's not empty
|
||||
primary_addr = iputil.get_ipaddress_obj(source_addrs[0], ipv4_mapped_convert=True)
|
||||
if primary_addr != tid_host_traddr:
|
||||
return False
|
||||
|
||||
else:
|
||||
# If both c->cfg.host_traddr and c->cfg.host_iface are
|
||||
# unknown, we don't have enough information to make a
|
||||
# 100% positive match. Regardless, let's be optimistic
|
||||
# and assume that we have a match.
|
||||
logging.debug(
|
||||
'Udev._cid_matches_tcp_tid_legacy() - [1] cid=%s, tid=%s - Not enough info. Assume "match" but this could be wrong.',
|
||||
cid,
|
||||
tid,
|
||||
)
|
||||
|
||||
# Only check host_iface if candidate cares about it
|
||||
if tid.host_iface:
|
||||
if cid_host_iface:
|
||||
if tid.host_iface != cid_host_iface:
|
||||
return False
|
||||
|
||||
return True
|
||||
else:
|
||||
if cid_host_traddr:
|
||||
connection_iface = iputil.get_interface(ifaces, cid_host_traddr)
|
||||
if tid.host_iface != connection_iface:
|
||||
return False
|
||||
|
||||
# cid.host_iface is defined
|
||||
if not cid_host_traddr: # cid.host_traddr is undefined
|
||||
if tid.host_iface and tid.host_iface != cid_host_iface:
|
||||
return False
|
||||
|
||||
if tid.host_traddr:
|
||||
# It's impossible to tell the existing connection source
|
||||
# address. So, we can't tell if it matches tid.host_traddr.
|
||||
# However, if the existing host_iface has only one source
|
||||
# address assigned to it, we can assume that the source
|
||||
# address used for the existing connection is that address.
|
||||
if_addrs = iputil.net_if_addrs().get(cid_host_iface, {4: [], 6: []})
|
||||
tid_host_traddr = iputil.get_ipaddress_obj(tid.host_traddr, ipv4_mapped_convert=True)
|
||||
source_addrs = if_addrs[tid_host_traddr.version]
|
||||
if len(source_addrs) != 1:
|
||||
return False
|
||||
|
||||
src_addr0 = iputil.get_ipaddress_obj(source_addrs[0], ipv4_mapped_convert=True)
|
||||
if src_addr0 != tid_host_traddr:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
# cid.host_traddr is defined
|
||||
if tid.host_iface and tid.host_iface != cid_host_iface:
|
||||
return False
|
||||
|
||||
if tid.host_traddr:
|
||||
tid_host_traddr = iputil.get_ipaddress_obj(tid.host_traddr, ipv4_mapped_convert=True)
|
||||
if tid_host_traddr != cid_host_traddr:
|
||||
return False
|
||||
else:
|
||||
# If both c->cfg.host_traddr and c->cfg.host_iface are
|
||||
# unknown, we don't have enough information to make a
|
||||
# 100% positive match. Regardless, let's be optimistic
|
||||
# and assume that we have a match.
|
||||
logging.debug(
|
||||
'Udev._cid_matches_tcp_tid_legacy() - [2] cid=%s, tid=%s - Not enough info. Assume "match" but this could be wrong.',
|
||||
cid,
|
||||
tid,
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def _cid_matches_tid(tid, cid): # pylint: disable=too-many-return-statements,too-many-branches
|
||||
def _cid_matches_tid(tid, cid, ifaces): # pylint: disable=too-many-return-statements,too-many-branches
|
||||
'''Check if existing controller's cid matches candidate controller's tid.
|
||||
@param cid: The Connection ID of an existing controller (from the sysfs).
|
||||
@param tid: The Transport ID of a candidate controller.
|
||||
|
@ -242,8 +233,8 @@ class Udev:
|
|||
be re-used for the candidate controller (specified by tid).
|
||||
|
||||
We do not have a match if the candidate's tid.transport, tid.traddr,
|
||||
tid.trsvcid, and tid.subsysnqn are not identical to those of the cid.
|
||||
These 4 parameters are mandatory for a match.
|
||||
tid.trsvcid, tid.subsysnqn, and tid.host_nqn are not identical to those
|
||||
of the cid. These 5 parameters are mandatory for a match.
|
||||
|
||||
The tid.host_traddr and tid.host_iface depend on the transport type.
|
||||
These parameters may not apply or have a different syntax/meaning
|
||||
|
@ -274,8 +265,9 @@ class Udev:
|
|||
tid_traddr = iputil.get_ipaddress_obj(tid.traddr, ipv4_mapped_convert=True)
|
||||
cid_traddr = iputil.get_ipaddress_obj(cid['traddr'], ipv4_mapped_convert=True)
|
||||
else:
|
||||
cid_traddr = cid['traddr']
|
||||
tid_traddr = tid.traddr
|
||||
# For FC and loop we can do a case-insensitive comparison
|
||||
tid_traddr = tid.traddr.lower()
|
||||
cid_traddr = cid['traddr'].lower()
|
||||
|
||||
if cid_traddr != tid_traddr:
|
||||
return False
|
||||
|
@ -290,7 +282,7 @@ class Udev:
|
|||
# For legacy kernels (i.e. older than 6.1), the existing cid.src_addr
|
||||
# is always undefined. We need to use advanced logic to determine
|
||||
# whether cid and tid match.
|
||||
return Udev._cid_matches_tcp_tid_legacy(tid, cid)
|
||||
return Udev._cid_matches_tcp_tid_legacy(tid, cid, ifaces)
|
||||
|
||||
# The existing controller's cid.src_addr is always defined for kernel
|
||||
# 6.1 and later. We can use the existing controller's cid.src_addr to
|
||||
|
@ -303,12 +295,12 @@ class Udev:
|
|||
return False
|
||||
|
||||
# host-iface is an optional tcp-only parameter.
|
||||
if tid.host_iface and tid.host_iface != iputil.get_interface(str(src_addr)):
|
||||
if tid.host_iface and tid.host_iface != iputil.get_interface(ifaces, src_addr):
|
||||
return False
|
||||
|
||||
elif tid.transport == 'fc':
|
||||
# host-traddr is mandatory for FC.
|
||||
if tid.host_traddr != cid['host-traddr']:
|
||||
if tid.host_traddr.lower() != cid['host-traddr'].lower():
|
||||
return False
|
||||
|
||||
elif tid.transport == 'rdma':
|
||||
|
@ -326,17 +318,20 @@ class Udev:
|
|||
Discovery Controller.
|
||||
@return The device if a match is found, None otherwise.
|
||||
'''
|
||||
for device in self._context.list_devices(
|
||||
devices = self._context.list_devices(
|
||||
subsystem='nvme', NVME_TRADDR=tid.traddr, NVME_TRSVCID=tid.trsvcid, NVME_TRTYPE=tid.transport
|
||||
):
|
||||
if not self.is_dc_device(device):
|
||||
continue
|
||||
)
|
||||
if devices:
|
||||
ifaces = iputil.net_if_addrs()
|
||||
for device in devices:
|
||||
if not self.is_dc_device(device):
|
||||
continue
|
||||
|
||||
cid = self.get_cid(device)
|
||||
if not self._cid_matches_tid(tid, cid):
|
||||
continue
|
||||
cid = self.get_cid(device)
|
||||
if not self._cid_matches_tid(tid, cid, ifaces):
|
||||
continue
|
||||
|
||||
return device
|
||||
return device
|
||||
|
||||
return None
|
||||
|
||||
|
@ -345,17 +340,20 @@ class Udev:
|
|||
I/O Controller.
|
||||
@return The device if a match is found, None otherwise.
|
||||
'''
|
||||
for device in self._context.list_devices(
|
||||
devices = self._context.list_devices(
|
||||
subsystem='nvme', NVME_TRADDR=tid.traddr, NVME_TRSVCID=tid.trsvcid, NVME_TRTYPE=tid.transport
|
||||
):
|
||||
if not self.is_ioc_device(device):
|
||||
continue
|
||||
)
|
||||
if devices:
|
||||
ifaces = iputil.net_if_addrs()
|
||||
for device in devices:
|
||||
if not self.is_ioc_device(device):
|
||||
continue
|
||||
|
||||
cid = self.get_cid(device)
|
||||
if not self._cid_matches_tid(tid, cid):
|
||||
continue
|
||||
cid = self.get_cid(device)
|
||||
if not self._cid_matches_tid(tid, cid, ifaces):
|
||||
continue
|
||||
|
||||
return device
|
||||
return device
|
||||
|
||||
return None
|
||||
|
||||
|
@ -364,68 +362,63 @@ class Udev:
|
|||
@return A list of pyudev.device._device.Device objects
|
||||
'''
|
||||
tids = []
|
||||
for device in self._context.list_devices(subsystem='nvme'):
|
||||
if device.properties.get('NVME_TRTYPE', '') not in transports:
|
||||
continue
|
||||
devices = self._context.list_devices(subsystem='nvme')
|
||||
if devices:
|
||||
ifaces = iputil.net_if_addrs()
|
||||
for device in devices:
|
||||
if device.properties.get('NVME_TRTYPE', '') not in transports:
|
||||
continue
|
||||
|
||||
if not self.is_ioc_device(device):
|
||||
continue
|
||||
if not self.is_ioc_device(device):
|
||||
continue
|
||||
|
||||
tids.append(self.get_tid(device))
|
||||
tids.append(self.get_tid(device, ifaces))
|
||||
|
||||
return tids
|
||||
|
||||
def _process_udev_event(self, event_source, condition): # pylint: disable=unused-argument
|
||||
if condition == GLib.IO_IN:
|
||||
event_count = 0
|
||||
while True:
|
||||
try:
|
||||
device = self._monitor.poll(timeout=0)
|
||||
except EnvironmentError as ex:
|
||||
device = None
|
||||
# This event seems to happen in bursts. So, let's suppress
|
||||
# logging for 2 seconds to avoid filling the syslog.
|
||||
self._log_event_count += 1
|
||||
now = time.time()
|
||||
if now > self._log_event_soak_time:
|
||||
logging.debug('Udev._process_udev_event() - %s [%s]', ex, self._log_event_count)
|
||||
self._log_event_soak_time = now + 2
|
||||
self._log_event_count = 0
|
||||
try:
|
||||
self.__handle_events()
|
||||
|
||||
if device is None:
|
||||
break
|
||||
|
||||
event_count += 1
|
||||
self._device_event(device, event_count)
|
||||
except EnvironmentError as ex:
|
||||
# Exceptions seem to happen in bursts. So, let's suppress
|
||||
# logging for 2 seconds to avoid filling the syslog.
|
||||
self._log_event_count += 1
|
||||
now = time.time()
|
||||
if now > self._log_event_soak_time:
|
||||
logging.debug('Udev._process_udev_event() - %s [%s]', ex, self._log_event_count)
|
||||
self._log_event_soak_time = now + 2
|
||||
self._log_event_count = 0
|
||||
|
||||
return GLib.SOURCE_CONTINUE
|
||||
|
||||
@staticmethod
|
||||
def __cback_names(action_cbacks, device_cback):
|
||||
names = []
|
||||
for cback in action_cbacks:
|
||||
names.append(cback.__name__ + '()')
|
||||
if device_cback:
|
||||
names.append(device_cback.__name__ + '()')
|
||||
return names
|
||||
def __handle_events(self):
|
||||
event_count = 0
|
||||
read_device = partial(self._monitor.poll, timeout=0)
|
||||
for device in iter(read_device, None):
|
||||
if device is None: # This should never happen,...
|
||||
break # ...but better safe than sorry.
|
||||
|
||||
def _device_event(self, device, event_count):
|
||||
action_cbacks = self._action_event_registry.get(device.action, set())
|
||||
device_cback = self._device_event_registry.get(device.sys_name, None)
|
||||
event_count += 1
|
||||
|
||||
logging.debug(
|
||||
'Udev._device_event() - %-8s %-6s %-8s %s',
|
||||
f'{device.sys_name}:',
|
||||
device.action,
|
||||
f'{event_count:2}:{device.sequence_number}',
|
||||
self.__cback_names(action_cbacks, device_cback),
|
||||
)
|
||||
action_cbacks = self._action_event_registry.get(device.action, None)
|
||||
device_cback = self._device_event_registry.get(device.sys_name, None)
|
||||
if action_cbacks or device_cback:
|
||||
logging.debug(
|
||||
'Udev.__handle_events() - %-7s %-6s %2s:%s',
|
||||
device.sys_name,
|
||||
device.action,
|
||||
event_count,
|
||||
device.sequence_number,
|
||||
)
|
||||
|
||||
for action_cback in action_cbacks:
|
||||
GLib.idle_add(action_cback, device)
|
||||
if action_cbacks:
|
||||
for action_cback in action_cbacks:
|
||||
GLib.idle_add(action_cback, device)
|
||||
|
||||
if device_cback is not None:
|
||||
GLib.idle_add(device_cback, device)
|
||||
if device_cback is not None:
|
||||
GLib.idle_add(device_cback, device)
|
||||
|
||||
@staticmethod
|
||||
def _get_property(device, prop, default=''):
|
||||
|
@ -470,7 +463,7 @@ class Udev:
|
|||
return attr_str[start:end]
|
||||
|
||||
@staticmethod
|
||||
def get_tid(device):
|
||||
def get_tid(device, ifaces):
|
||||
'''@brief return the Transport ID associated with a udev device'''
|
||||
cid = Udev.get_cid(device)
|
||||
if cid['transport'] == 'tcp':
|
||||
|
@ -479,7 +472,7 @@ class Udev:
|
|||
# We'll try to find the interface from the source address on
|
||||
# the connection. Only available if kernel exposes the source
|
||||
# address (src_addr) in the "address" attribute.
|
||||
cid['host-iface'] = iputil.get_interface(src_addr)
|
||||
cid['host-iface'] = iputil.get_interface(ifaces, iputil.get_ipaddress_obj(src_addr))
|
||||
|
||||
return trid.TID(cid)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue