From patchwork Tue Nov 12 11:17:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Donald Hunter X-Patchwork-Id: 13872112 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-wm1-f49.google.com (mail-wm1-f49.google.com [209.85.128.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8D400213159 for ; Tue, 12 Nov 2024 11:17:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731410258; cv=none; b=o1T/IHQG9uIA5fWFYWfaQ5ELPFHHeD0bRSxRm959k0YxLJ8UK0pDQPPs5Czrq8IC55wElaIiYOkHCXu6UkHp/3WHzJDPQnQza6rfrmvOcOkbkX2ETKGjhPHfm9BR03G1HmLsa+EO97bG5kWy1vURIt0wps9gQhlCubIueF7phsA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731410258; c=relaxed/simple; bh=ohjqzMpsu21GuDKSMl0u0Kku7h3y+NzZyYyujI8tG/E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Td7bUzmsB1FODI/CjyYbjfPmnkdXNLHH2qGPAYtKCaAqCjBvFoJF6pLFFTEZiW1pBx8Nk+zz0xHMWrrWsqs095+eT9FKLfqRw/l68clVEqaEYm4H/Z8nZlx3Re1epc4m7MdR7EYWomhnt+hLgx14CQ76J7QR6zQsB99ALw58Uyg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=ToYk00vD; arc=none smtp.client-ip=209.85.128.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ToYk00vD" Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-43155afca99so36661395e9.1 for ; Tue, 12 Nov 2024 03:17:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731410254; x=1732015054; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8NYGGqDNm/aoW1tOjWuU2CXuiumwETODf+xi+nymdIk=; b=ToYk00vDEJ+QYowoWIgypW6Z3vgIlKOhS0freOmxCwzn2XCrMzcPrPRI7tCkLASXO0 lKJDSMHewf9ltg3lp0N4Vg1AMzEJnRvNrQdVe7J6Ow6m/LC4DmzEZdyGtimF5J7RH77b 7xbyW4qunEmYdfBNJHKBSzqsjX8AzztNuvawAedCB8BZGxOyUs++KAX1kuqmD9UfC9GC Ke6PjVVyuqtsmhsTTKyl0Ygsjo/YGzK279z3jIScMOfh45/llkgZ5lTYnHNKkyl9A5dX b2HE7YAPYDt8lpFX5arysKmV0ypkBu0bKMZJcmft/FqzY1OW5Af12rr4kaULQxRLaxs3 BRrw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731410254; x=1732015054; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8NYGGqDNm/aoW1tOjWuU2CXuiumwETODf+xi+nymdIk=; b=Cv75ho2SJyf+ZgLfz2uFIkl6cT0O9zFtDDzCXDM6mwK80ky37GKBd+2s29ConeRhEp m9DkhbWouiuGXmqqWonvs0vt35t2X4hOOfvoaucUMikaBHpJwJ7xf0EADphFKK+YEfZY 5jfOYsOqrqShpKHS0jRWJnFsbkDh/fdX6NZ7W3xUdyEbRRmkcqI8aGvklaYZkspmDOro 0jcu0uztVTh7TbbZX0USPV16Kh8LZAeD+S2j9ll8FW5GjkPTXNNcRj7MVA3joUHeEYMs 5x2b7lJGWuSQ3+OhE95twSbzifEnG/llyx3JGOaVDhUH4t2EtWPufqTh+SlPKA9In6KS Lxow== X-Gm-Message-State: AOJu0YyQ3DprbBpIBnpKXRbR9nPA8PUOKPn1K2sjRqXt0b6F/SVe/ar2 YMEi1kqtxsECYR1IbkcrSDwG2o7+2ILrXQvK9dTi4jMEMk1/gLf9QFwKhksM X-Google-Smtp-Source: AGHT+IHnmTuq+k96RgSd4MEmSv0/h6oLWg5DuARLzdgkjfYwiYg9AcNtJj4ii2poVb7s0hRbV9HVPw== X-Received: by 2002:a05:600c:548d:b0:42c:b67b:816b with SMTP id 5b1f17b1804b1-432b684f329mr134763755e9.1.1731410254268; Tue, 12 Nov 2024 03:17:34 -0800 (PST) Received: from imac.lan ([2a02:8010:60a0:0:a1ef:92f5:9114:b131]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432b054b3fesm203543685e9.17.2024.11.12.03.17.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2024 03:17:33 -0800 (PST) From: Donald Hunter To: netdev@vger.kernel.org, Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Xiao Liang , Jiri Pirko Cc: donald.hunter@redhat.com, Donald Hunter Subject: [PATCH net-next v2 1/2] Revert "tools/net/ynl: improve async notification handling" Date: Tue, 12 Nov 2024 11:17:26 +0000 Message-ID: <20241112111727.91575-2-donald.hunter@gmail.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241112111727.91575-1-donald.hunter@gmail.com> References: <20241112111727.91575-1-donald.hunter@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org This reverts commit 1bf70e6c3a5346966c25e0a1ff492945b25d3f80. This modification to check_ntf() is being reverted so that its behaviour remains equivalent to ynl_ntf_check() in the C YNL. Instead a new poll_ntf() will be added in a separate patch. Signed-off-by: Donald Hunter --- tools/net/ynl/cli.py | 10 +++----- tools/net/ynl/lib/ynl.py | 49 ++++++++++++++++------------------------ 2 files changed, 23 insertions(+), 36 deletions(-) diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/cli.py index 9e95016b85b3..b8481f401376 100755 --- a/tools/net/ynl/cli.py +++ b/tools/net/ynl/cli.py @@ -5,7 +5,6 @@ import argparse import json import pprint import time -import signal from lib import YnlFamily, Netlink, NlError @@ -18,8 +17,6 @@ class YnlEncoder(json.JSONEncoder): return list(obj) return json.JSONEncoder.default(self, obj) -def handle_timeout(sig, frame): - exit(0) def main(): description = """ @@ -84,8 +81,7 @@ def main(): ynl.ntf_subscribe(args.ntf) if args.sleep: - signal.signal(signal.SIGALRM, handle_timeout) - signal.alarm(args.sleep) + time.sleep(args.sleep) if args.list_ops: for op_name, op in ynl.ops.items(): @@ -110,8 +106,8 @@ def main(): exit(1) if args.ntf: - for msg in ynl.check_ntf(): - output(msg) + ynl.check_ntf() + output(ynl.async_msg_queue) if __name__ == "__main__": diff --git a/tools/net/ynl/lib/ynl.py b/tools/net/ynl/lib/ynl.py index 92f85698c50e..c22c22bf2cb7 100644 --- a/tools/net/ynl/lib/ynl.py +++ b/tools/net/ynl/lib/ynl.py @@ -12,8 +12,6 @@ import sys import yaml import ipaddress import uuid -import queue -import time from .nlspec import SpecFamily @@ -491,7 +489,7 @@ class YnlFamily(SpecFamily): self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_GET_STRICT_CHK, 1) self.async_msg_ids = set() - self.async_msg_queue = queue.Queue() + self.async_msg_queue = [] for msg in self.msgs.values(): if msg.is_async: @@ -905,39 +903,32 @@ class YnlFamily(SpecFamily): msg['name'] = op['name'] msg['msg'] = attrs - self.async_msg_queue.put(msg) + self.async_msg_queue.append(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 done while checking for ntf", decoded) + continue - try: - yield self.async_msg_queue.get_nowait() - except queue.Empty: - try: - time.sleep(interval) - except KeyboardInterrupt: - return + self.handle_ntf(decoded) def operation_do_attributes(self, name): """ From patchwork Tue Nov 12 11:17:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Donald Hunter X-Patchwork-Id: 13872113 X-Patchwork-Delegate: kuba@kernel.org Received: from mail-lf1-f47.google.com (mail-lf1-f47.google.com [209.85.167.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 30224218D93 for ; Tue, 12 Nov 2024 11:17:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731410260; cv=none; b=RAWpGzR9Nxea5ffFeo4YikI71hCg+KnQrvMMm1RvlGYrVWp7CJS+uhORm/uZ4vBZBDPh6RJKFtg7nou5mEeUVCFrRDRb6sCYXLmkadyhhK3cql0AzlRWmdRafix7WeW7FQG9QDSc1eYUrv4DOh+ITTowYAWuTNxZJCmtMTnH6vo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1731410260; c=relaxed/simple; bh=Gxojs+r3yLJvy+VKhHr7QoFeI3xt1LpaF00PFbC6RVg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HtVITeymN0d23o4WjWlqQHAPpV/D96wgxXhoNy5Ho/uIdKwmaqprKKO/YvJT/onO5yoY/RGKyvQIJ3yns2DYniuufHfeIYk/mgAm8UsqOt8JrSVZlUG/xK9EThHjIaHIab0PfVXWNMILMenNuKxRoAry+l4SI1KlQQsfcSDFvxo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=T1olZ8tA; arc=none smtp.client-ip=209.85.167.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="T1olZ8tA" Received: by mail-lf1-f47.google.com with SMTP id 2adb3069b0e04-539f4d8ef84so6951214e87.0 for ; Tue, 12 Nov 2024 03:17:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1731410256; x=1732015056; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=KQVfeZc6NJ075HA3ZdT+0D/cjgvXW3jWBY5YdxUCC+w=; b=T1olZ8tA78lso4qY2bKROdCeK0YGYL1qg8eozLwJxnI0XmhSpdx8xw0V4IpYcoDGCA LnTpdQo2MfTlcsRJyvH/IUYDLpC4GgqOEj2dt0F5CSpX1qzdPLMMsbACE3DThvNxyFAj At2S47CzO8/2uy5VZvmK+Dd0NfB6CTUHOXl6iybQft/2bhpB7yC1dUJH8xaJa3Gtc6lu 4Z1PZaXpetGv/ipfDXrlCk7SFPbrVuVFjRJlL7/+yW7HodaBI9/ijr1u9NhQbQDO5ZLL r4sOpjDTE4ScA4Zs48zj0sjsDXO6P8oIJX4cM0U0w2n2rfN1VVK5Z+E2h3fgzW+jrFMh uuXQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1731410256; x=1732015056; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=KQVfeZc6NJ075HA3ZdT+0D/cjgvXW3jWBY5YdxUCC+w=; b=m+FLMZAHdBjz6WrCDbJARLoAKH+FMLfBux9oTptmM4HT+Xr8uUXIsiWDGKEETuzdTL SeWeIta+Hs0tdnI0EXRpA9IPb/gcA/otgsGQAP3HjXITK8WyQXhL75Tt/1ar8DbSKm38 85WdSd60yTyDjVOi2ItfyrjLC8JTLMLWcNSFXnW9JlNFt4tBkc0JI6Hlv+VL7JXgi6YK l5NIg/ozuGTaEQYOfyyxtg36UPZPIfUQpgff2+5CqXCqxz84ByWYy2cLWoA//NREv5XE i52MZiUigw1IstN5cJCNmz+E4wAzkaVmIXiNJIPTyQf0m2mPOmKcA66BZXeVrUHLWXwe 6aFw== X-Gm-Message-State: AOJu0YzCXVm2JeSOUMbTYD+aFy8+SWatkC/UUZMhqZm4nO6+CQWL8PNU 8s/t3kCn6o51SpONTExBhaRzYh9vFp+q4kqZjBXyMSxYeX5OjL+Ndl9SluXU X-Google-Smtp-Source: AGHT+IEjGpKgmreHst5YJ5zx59jBB4wzD7My11iaMb6THS3IqFmmUrLyi04LhrGq05XowPBuD7lrHQ== X-Received: by 2002:a05:6512:104f:b0:539:f36c:dbac with SMTP id 2adb3069b0e04-53d86228009mr7501022e87.4.1731410255502; Tue, 12 Nov 2024 03:17:35 -0800 (PST) Received: from imac.lan ([2a02:8010:60a0:0:a1ef:92f5:9114:b131]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-432b054b3fesm203543685e9.17.2024.11.12.03.17.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 12 Nov 2024 03:17:34 -0800 (PST) From: Donald Hunter To: netdev@vger.kernel.org, Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Simon Horman , Xiao Liang , Jiri Pirko Cc: donald.hunter@redhat.com, Donald Hunter Subject: [PATCH net-next v2 2/2] tools/net/ynl: add async notification handling Date: Tue, 12 Nov 2024 11:17:27 +0000 Message-ID: <20241112111727.91575-3-donald.hunter@gmail.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20241112111727.91575-1-donald.hunter@gmail.com> References: <20241112111727.91575-1-donald.hunter@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-Delegate: kuba@kernel.org The notification handling in ynl is currently very simple, using sleep() to wait a period of time and then handling all the buffered messages in a single batch. This patch adds async notification handling so that messages can be processed as they are received. This makes it possible to use ynl as a library that supplies notifications in a timely manner. - Add poll_ntf() to be a generator that yields 1 notification at a time and blocks until a notification is available. - Add a --duration parameter to the CLI, with --sleep as an alias. ./tools/net/ynl/cli.py \ --spec --subscribe [ --duration ] The cli will report any notifications for duration seconds and then exit. If duration is not specified, then it will poll forever, until interrupted. Here is an example python snippet that shows how to use ynl as a library for receiving notifications: ynl = YnlFamily(f"{dir}/rt_route.yaml") ynl.ntf_subscribe('rtnlgrp-ipv4-route') for event in ynl.poll_ntf(): handle(event) Signed-off-by: Donald Hunter Acked-by: Jakub Kicinski --- tools/net/ynl/cli.py | 16 +++++++++------- tools/net/ynl/lib/ynl.py | 28 +++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/tools/net/ynl/cli.py b/tools/net/ynl/cli.py index b8481f401376..0601fcc53601 100755 --- a/tools/net/ynl/cli.py +++ b/tools/net/ynl/cli.py @@ -4,7 +4,6 @@ import argparse import json import pprint -import time from lib import YnlFamily, Netlink, NlError @@ -43,7 +42,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) @@ -80,9 +82,6 @@ def main(): if args.ntf: ynl.ntf_subscribe(args.ntf) - if args.sleep: - time.sleep(args.sleep) - if args.list_ops: for op_name, op in ynl.ops.items(): print(op_name, " [", ", ".join(op.modes), "]") @@ -106,8 +105,11 @@ def main(): exit(1) if args.ntf: - ynl.check_ntf() - output(ynl.async_msg_queue) + 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 c22c22bf2cb7..ffb1c4263d09 100644 --- a/tools/net/ynl/lib/ynl.py +++ b/tools/net/ynl/lib/ynl.py @@ -12,6 +12,9 @@ import sys import yaml import ipaddress import uuid +import queue +import selectors +import time from .nlspec import SpecFamily @@ -489,7 +492,7 @@ class YnlFamily(SpecFamily): self.sock.setsockopt(Netlink.SOL_NETLINK, Netlink.NETLINK_GET_STRICT_CHK, 1) self.async_msg_ids = set() - self.async_msg_queue = [] + self.async_msg_queue = queue.Queue() for msg in self.msgs.values(): if msg.is_async: @@ -903,7 +906,7 @@ class YnlFamily(SpecFamily): msg['name'] = op['name'] msg['msg'] = attrs - self.async_msg_queue.append(msg) + self.async_msg_queue.put(msg) def check_ntf(self): while True: @@ -925,11 +928,30 @@ class YnlFamily(SpecFamily): decoded = self.nlproto.decode(self, nl_msg, None) if decoded.cmd() not in self.async_msg_ids: - print("Unexpected msg id done while checking for ntf", decoded) + print("Unexpected msg id while checking for ntf", decoded) continue self.handle_ntf(decoded) + def poll_ntf(self, duration=None): + endtime = time.time() + duration if duration is not None else None + selector = selectors.DefaultSelector() + selector.register(self.sock, selectors.EVENT_READ) + + while True: + try: + yield self.async_msg_queue.get_nowait() + except queue.Empty: + if endtime is not None: + interval = endtime - time.time() + if interval <= 0: + return + else: + interval = None + events = selector.select(interval) + if events: + self.check_ntf() + def operation_do_attributes(self, name): """ For a given operation name, find and return a supported