diff options
author | Jakub Kicinski <kuba@kernel.org> | 2024-11-15 05:09:08 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2024-11-15 05:09:08 +0300 |
commit | 59b6c043da0bb12631cf4e84e0be58727c0eab17 (patch) | |
tree | 524f0b3b6b7d50d38898f3f8fcf5e1fe4ce3286f | |
parent | 76e81a5a1749e638a09b424641f0b9d3ece1f2a7 (diff) | |
parent | 8aefcfa04beaab070a2009828da40bdd4888eee6 (diff) | |
download | linux-59b6c043da0bb12631cf4e84e0be58727c0eab17.tar.xz |
Merge branch 'tools-net-ynl-rework-async-notification-handling'
Donald Hunter says:
====================
tools/net/ynl: rework async notification handling
Revert patch 1bf70e6c3a53 which modified check_ntf() and instead add a
new poll_ntf() with async notification semantics. See patch 2 for a
detailed description.
====================
Link: https://patch.msgid.link/20241113090843.72917-1-donald.hunter@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
-rwxr-xr-x | tools/net/ynl/cli.py | 20 | ||||
-rw-r--r-- | tools/net/ynl/lib/ynl.py | 57 |
2 files changed, 44 insertions, 33 deletions
diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/cli.py index 5e2913a7f3e4..41d9fa5c818d 100755 --- a/tools/net/ynl/cli.py +++ b/tools/net/ynl/cli.py @@ -6,8 +6,6 @@ import json import pathlib import pprint import sys -import time -import signal sys.path.append(pathlib.Path(__file__).resolve().parent.as_posix()) from lib import YnlFamily, Netlink, NlError @@ -21,8 +19,6 @@ class YnlEncoder(json.JSONEncoder): return list(obj) return json.JSONEncoder.default(self, obj) -def handle_timeout(sig, frame): - exit(0) def main(): description = """ @@ -49,7 +45,10 @@ def main(): group.add_argument('--list-ops', action='store_true') group.add_argument('--list-msgs', action='store_true') - parser.add_argument('--sleep', dest='sleep', type=int) + parser.add_argument('--duration', dest='duration', type=int, + help='when subscribed, watch for DURATION seconds') + parser.add_argument('--sleep', dest='duration', type=int, + help='alias for duration') parser.add_argument('--subscribe', dest='ntf', type=str) parser.add_argument('--replace', dest='flags', action='append_const', const=Netlink.NLM_F_REPLACE) @@ -86,10 +85,6 @@ def main(): if args.ntf: ynl.ntf_subscribe(args.ntf) - if args.sleep: - signal.signal(signal.SIGALRM, handle_timeout) - signal.alarm(args.sleep) - if args.list_ops: for op_name, op in ynl.ops.items(): print(op_name, " [", ", ".join(op.modes), "]") @@ -113,8 +108,11 @@ def main(): exit(1) if args.ntf: - for msg in ynl.check_ntf(): - output(msg) + try: + for msg in ynl.poll_ntf(duration=args.duration): + output(msg) + except KeyboardInterrupt: + pass if __name__ == "__main__": diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py index 92f85698c50e..01ec01a90e76 100644 --- a/tools/net/ynl/lib/ynl.py +++ b/tools/net/ynl/lib/ynl.py @@ -13,6 +13,7 @@ import yaml import ipaddress import uuid import queue +import selectors import time from .nlspec import SpecFamily @@ -907,37 +908,49 @@ class YnlFamily(SpecFamily): msg['msg'] = attrs self.async_msg_queue.put(msg) - def check_ntf(self, interval=0.1): + def check_ntf(self): while True: try: reply = self.sock.recv(self._recv_size, socket.MSG_DONTWAIT) - nms = NlMsgs(reply) - self._recv_dbg_print(reply, nms) - for nl_msg in nms: - if nl_msg.error: - print("Netlink error in ntf!?", os.strerror(-nl_msg.error)) - print(nl_msg) - continue - if nl_msg.done: - print("Netlink done while checking for ntf!?") - continue + except BlockingIOError: + return - decoded = self.nlproto.decode(self, nl_msg, None) - if decoded.cmd() not in self.async_msg_ids: - print("Unexpected msg id while checking for ntf", decoded) - continue + nms = NlMsgs(reply) + self._recv_dbg_print(reply, nms) + for nl_msg in nms: + if nl_msg.error: + print("Netlink error in ntf!?", os.strerror(-nl_msg.error)) + print(nl_msg) + continue + if nl_msg.done: + print("Netlink done while checking for ntf!?") + continue - self.handle_ntf(decoded) - except BlockingIOError: - pass + decoded = self.nlproto.decode(self, nl_msg, None) + if decoded.cmd() not in self.async_msg_ids: + print("Unexpected msg id while checking for ntf", decoded) + continue + + self.handle_ntf(decoded) + def poll_ntf(self, duration=None): + start_time = time.time() + selector = selectors.DefaultSelector() + selector.register(self.sock, selectors.EVENT_READ) + + while True: try: yield self.async_msg_queue.get_nowait() except queue.Empty: - try: - time.sleep(interval) - except KeyboardInterrupt: - return + if duration is not None: + timeout = start_time + duration - time.time() + if timeout <= 0: + return + else: + timeout = None + events = selector.select(timeout) + if events: + self.check_ntf() def operation_do_attributes(self, name): """ |