Commit 59b6c043 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'tools-net-ynl-rework-async-notification-handling'

Donald Hunter says:

====================
tools/net/ynl: rework async notification handling

Revert patch 1bf70e6c 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: default avatarJakub Kicinski <kuba@kernel.org>
parents 76e81a5a 8aefcfa0
Loading
Loading
Loading
Loading
+9 −11
Original line number Diff line number Diff line
@@ -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():
        try:
            for msg in ynl.poll_ntf(duration=args.duration):
                output(msg)
        except KeyboardInterrupt:
            pass


if __name__ == "__main__":
+35 −22
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ import yaml
import ipaddress
import uuid
import queue
import selectors
import time

from .nlspec import SpecFamily
@@ -907,10 +908,13 @@ 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)
            except BlockingIOError:
                return

            nms = NlMsgs(reply)
            self._recv_dbg_print(reply, nms)
            for nl_msg in nms:
@@ -928,16 +932,25 @@ class YnlFamily(SpecFamily):
                    continue

                self.handle_ntf(decoded)
            except BlockingIOError:
                pass

    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:
                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):
      """