fix(claw): detect the gateway's process title openclaw-gateway

Upstream sets process.title="openclaw-gateway" in the gateway run loop, so
the real daemon has comm "openclaw-gatewa" (15-char truncation) and no
`node … openclaw` argv for the script probe to match. Add the exact comm
probe; substring matching stays out.
This commit is contained in:
teknium1
2026-09-12 08:11:30 -07:00
committed by Teknium
parent 07ead2249b
commit 2b685f08fa
2 changed files with 13 additions and 2 deletions
+4 -1
View File
@@ -130,7 +130,10 @@ def _detect_openclaw_processes() -> list[str]:
# ~/.openclaw/config.json, ``tail -f openclaw.log``) and aborted cleanup on idle hosts (#12648).
# Mirror the Windows branch: exact binary names, plus node processes whose script mentions it.
pids: list[str] = []
for probe in (["pgrep", "-x", "openclaw"], ["pgrep", "-x", "clawd"], ["pgrep", "-f", _OPENCLAW_NODE_CMDLINE_RE]):
# ``-x`` matches the 15-char comm: the gateway sets process.title="openclaw-gateway", which
# the kernel truncates to "openclaw-gatewa".
for probe in (["pgrep", "-x", "openclaw"], ["pgrep", "-x", "openclaw-gatewa"], ["pgrep", "-x", "clawd"],
["pgrep", "-f", _OPENCLAW_NODE_CMDLINE_RE]):
result = _posix_probe(probe, 3)
if result is not None and result.returncode == 0:
pids.extend(result.stdout.split())
+9 -1
View File
@@ -355,6 +355,7 @@ class TestDetectOpenclawProcesses:
mock_subprocess.run.side_effect = [
MagicMock(returncode=1, stdout=""), # systemctl
MagicMock(returncode=0, stdout="1234\n"), # pgrep -x openclaw
MagicMock(returncode=1, stdout=""), # pgrep -x openclaw-gatewa
MagicMock(returncode=1, stdout=""), # pgrep -x clawd
MagicMock(returncode=0, stdout="1234\n5678\n"), # node cmdline probe
]
@@ -374,6 +375,12 @@ class TestDetectOpenclawProcesses:
bystander = subprocess.Popen(["bash", "-c", f"exec {idle} {tmp_path}/openclaw-notes.txt"])
# argv[0] renamed to ``node`` running an openclaw script: the real launch shape.
node_like = subprocess.Popen(["bash", "-c", f"exec -a node {idle} {tmp_path}/openclaw/entry.js"])
# The gateway sets process.title="openclaw-gateway" (comm truncates to 15 chars); a
# copied interpreter with that file name yields the same comm.
import shutil
titled_bin = tmp_path / "openclaw-gateway"
shutil.copy2(sys.executable, titled_bin)
titled = subprocess.Popen([str(titled_bin), "-c", "import time; time.sleep(30)"])
try:
time.sleep(0.3)
with patch.object(claw_mod, "_posix_probe", wraps=claw_mod._posix_probe) as probe:
@@ -382,9 +389,10 @@ class TestDetectOpenclawProcesses:
assert len(result) == 1
pids = result[0].split("PIDs: ")[1].rstrip(")").split(", ")
assert str(node_like.pid) in pids
assert str(titled.pid) in pids
assert str(bystander.pid) not in pids
finally:
for proc in (bystander, node_like):
for proc in (bystander, node_like, titled):
proc.kill()
proc.wait()