Skip to content

Refactor slow activities from nm-dispatcher script into separate listener service - #680

Open
lmagyar wants to merge 6 commits into
hassio-addons:mainfrom
lmagyar:pr-nm-dispatcher
Open

Refactor slow activities from nm-dispatcher script into separate listener service#680
lmagyar wants to merge 6 commits into
hassio-addons:mainfrom
lmagyar:pr-nm-dispatcher

Conversation

@lmagyar

@lmagyar lmagyar commented May 3, 2026

Copy link
Copy Markdown
Collaborator

Proposed Changes

There is a plain linux pipe between the 2 services, each nm-dispatcher action is 1 line in it, then all the slow thing happen in the listener service sequentially - as currently, but returning to nm-dispatcher quickly.

Related Issues

fixes #678
closes #679

Summary by CodeRabbit

  • Refactor
    • Reorganized subnet protection services around a dedicated NetworkManager event listener.
    • Improved handling of network interface and DHCP changes, including route reapplication when needed.
    • Updated service lifecycle management to ensure reliable initialization, cleanup, and failure handling.

@coderabbitai

coderabbitai Bot commented May 3, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 69217eec-7f4f-4f48-9c8f-bf9005d40381

📥 Commits

Reviewing files that changed from the base of the PR and between 666141d and 88ed8b6.

📒 Files selected for processing (5)
  • tailscale/rootfs/etc/NetworkManager/dispatcher.d/protect-subnets
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/notification-fd
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/finish
🚧 Files skipped from review as they are similar to previous changes (2)
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/finish
  • tailscale/rootfs/etc/NetworkManager/dispatcher.d/protect-subnets

Walkthrough

The dispatcher now queues selected NetworkManager events. A dedicated s6-overlay listener processes route protection asynchronously. Separate initialization and finish scripts manage route protection during service startup and shutdown.

Changes

Subnet protection orchestration

Layer / File(s) Summary
Subnet protection service lifecycle
tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/*, tailscale/rootfs/etc/s6-overlay/s6-rc.d/protect-subnets/type
The new oneshot service protects subnet routes during startup and removes protection during shutdown. protect-subnets is now a bundle.
Dispatcher queue handoff
tailscale/rootfs/etc/NetworkManager/dispatcher.d/protect-subnets, tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/run, tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/type
The dispatcher writes interface actions to /run/nm-dispatcher-listener-queue. The nm-dispatcher service only starts NetworkManager’s dispatcher daemon.
Listener processing and supervision
tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/*, tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/finish
The listener consumes queued actions, updates subnet routes, rejects unknown actions, cleans up the queue, and propagates service termination state.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
    participant NetworkManager
    participant Dispatcher
    participant Queue
    participant Listener
    participant RouteProtection

    NetworkManager->>Dispatcher: NetworkManager action
    Dispatcher->>Queue: Enqueue interface and action
    Dispatcher-->>NetworkManager: Return after queue write
    Queue->>Listener: Deliver queued action
    Listener->>RouteProtection: Update subnet routes
    RouteProtection-->>Listener: Protection result
Loading

Possibly related PRs

Suggested labels: refactor

Suggested reviewers: frenck

Poem

🐰 Events hop into the queue,
The listener knows what to do.
Routes guard the subnet path,
Finish scripts clean the aftermath.
No dispatcher waits too long.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The listener refactor addresses #678, but #679's required no-wait.d placement and top-level symlink are absent. Place protect-subnets in no-wait.d and add the required top-level symlink, or update the issue criteria to approve the FIFO listener design.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes moving slow NetworkManager dispatcher work into a separate listener service.
Out of Scope Changes check ✅ Passed The changes support the dispatcher listener refactor, service lifecycle, route protection, and graceful shutdown objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@lmagyar lmagyar added the refactor Improvement of existing code, not introducing new features. label May 3, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tailscale/rootfs/etc/NetworkManager/dispatcher.d/protect-subnets`:
- Around line 17-21: Before writing to the listener queue, verify
NM_DISPATCHER_LISTENER_QUEUE exists and is a FIFO (use [ -p
"$NM_DISPATCHER_LISTENER_QUEUE" ]) and wait with a short timeout (e.g., loop up
to a few seconds) for it to appear as a FIFO; if it never becomes a FIFO, log
fatal and exit (same behavior as current error path). Do not create a regular
file by redirecting into a non-existent path; instead fail fast when the FIFO is
absent or wrong type. Use the existing variables DEVICE_IP_IFACE and
NM_DISPATCHER_ACTION for the payload and preserve the current exit behavior that
writes to /run/s6-linux-init-container-results/exitcode and calls halt if the
check/write fails.

In `@tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/run`:
- Around line 22-25: The script must fail fast if mkfifo fails or the path is
not a FIFO: before executing "exec 4<>\"${NM_DISPATCHER_LISTENER_QUEUE}\"",
attempt to create the FIFO with mkfifo and then validate the path is a FIFO
using a POSIX test (e.g., [ -p "$NM_DISPATCHER_LISTENER_QUEUE" ]); if mkfifo
fails and the path is absent or exists but is not a FIFO, write an error and
exit non‑zero so the listener doesn't proceed to "exec 4<>" on a regular file.
Update the run script around the mkfifo/exec 4<> sequence to perform this
validation and early exit when the queue is not a proper FIFO.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 44d4ff22-5e51-49a1-9aa9-a5143aac6027

📥 Commits

Reviewing files that changed from the base of the PR and between 7a10013 and 666141d.

📒 Files selected for processing (19)
  • tailscale/rootfs/etc/NetworkManager/dispatcher.d/protect-subnets
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/dependencies.d/local-network
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/down
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/init-protect-subnets/up
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/dependencies.d/init-protect-subnets
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/dependencies.d/nm-dispatcher-listener
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/finish
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/run
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher/type
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/protect-subnets/contents.d/init-protect-subnets
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/protect-subnets/contents.d/nm-dispatcher
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/protect-subnets/contents.d/nm-dispatcher-listener
  • tailscale/rootfs/etc/s6-overlay/s6-rc.d/protect-subnets/type

Comment thread tailscale/rootfs/etc/NetworkManager/dispatcher.d/protect-subnets
Comment thread tailscale/rootfs/etc/s6-overlay/s6-rc.d/nm-dispatcher-listener/run
@agners

agners commented May 6, 2026

Copy link
Copy Markdown

Looks quite neat, and I've tested it on my end, Tailscale no longer blocks Supervisor restart with this change (even with 90-nm-cloud-setup.sh present).

✔️ LGTM!

@lmagyar

lmagyar commented May 6, 2026

Copy link
Copy Markdown
Collaborator Author

Thank you for the feedback!

@lmagyar lmagyar added the no-stale This issue or PR is exempted from the stable bot. label May 8, 2026
@lmagyar lmagyar added bugfix Inconsistencies or issues which will cause a problem for users or implementors. priority-high After critical issues are fixed, these should be dealt with before any further issues. and removed refactor Improvement of existing code, not introducing new features. labels May 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Inconsistencies or issues which will cause a problem for users or implementors. no-stale This issue or PR is exempted from the stable bot. priority-high After critical issues are fixed, these should be dealt with before any further issues.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tailscale add-on causes Supervisor restart to block 10 minutes

2 participants