checkRtorrent watchdog: alive process with unlinked SCGI socket file gets grace forever, never restarts

Open Beginner friendly
#723 15 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
73/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
php
Domain
devops

Research direction

Read scripts/lib/rtorrent/process.php:295 and the rtorrentProcessScgiUnresponsiveDecision function first, then inspect scripts/lib/rtorrent/watchdog.php:36 for the stale-socket cleanup behavior. Done means an alive process with a missing SCGI socket file triggers restart, while existing grace behavior remains for a present but slow socket and D-state processes.

Written by the indexing model from the issue text.

Description

agentic blocked bug customer-reported

Problem

checkRtorrent.php's alive-but-SCGI-unresponsive decision (scripts/lib/rtorrent/process.php:295, rtorrentProcessScgiUnresponsiveDecision returns extend_grace when "rtorrent still alive") does not distinguish two very different unresponsive states:

  • socket file exists but slow to answer — genuinely transient; grace is correct.
  • socket file UNLINKED while the process still holds the fd — NOT transient. The SCGI path is gone from the filesystem and only a restart recreates it, yet grace is re-extended on every tick, forever.

Result: a healthy-looking rtorrent (State S, sleeping in epoll_wait) whose ~/.rtorrent.socket FILE has been removed from the filesystem stays wedged indefinitely. ruTorrent connects by path (unix:///home/<user>/.rtorrent.socket), so connect() fails with ENOENT and the panel shows "no connection", while the watchdog keeps extending grace because the process exists.

Evidence (observed live, reported via support ticket)

  • test -S ~/.rtorrent.socket -> missing; ls -> No such file or directory.
  • ss -xlp | grep .rtorrent.socket -> still LISTENING at that path, owned by the rtorrent pid. The kernel keeps the bind path after the filesystem entry is unlinked, so an ss-based "is it listening" probe reports a false positive while the path clients actually connect to is gone.
  • rtorrent process alive and healthy (not D-state); had been running ~14 days in this wedged state.
  • scripts/lib/rtorrent/watchdog.php:36pmssCheckRtorrentCleanupStaleSocket does if (!file_exists($socketPath)) return;, so an already-unlinked socket is a no-op and nothing forces a restart.
  • Not covered by #717 (fixes the .rtorrentRestart.php comm-match duplicate on a manual restart) nor #720 (fixes the post-escalation retry-disabled branch). This case never reaches escalation — it sits in the grace branch permanently.

Suggested Fix

In the alive-but-unresponsive decision, add a check: if the SCGI socket FILE does not exist (!file_exists($socketPath) after clearstatcache), do NOT extend grace — treat it as a definitive restart trigger, because the file cannot reappear without a restart. Targeted addition to the existing decision function, not a new subsystem. Keep the existing grace behavior for the socket-exists-but-slow and D-state cases.

Environment

PMSS git/main; observed on a Debian 12 host. Refs #717, #720.

Dominant language
PHP
Stars
36
Forks
11
PR merge metrics
No merged PRs in 30d

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from MagnaCapax/PMSS

All issues in MagnaCapax/PMSS

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.