feat(chv): 阶段 5 多会话并行——具名会话独立 context + storage-state 落盘 + execd 组杀

This commit is contained in:
host committed 2026-11-08 09:45:00 +00:00
1 parent f723eb8a88
commit 6466ea6024
5 files changed
+723 -24

No files matched your search

+18 -4
View File
@@ -11,7 +11,10 @@
`python3 /app/host.py <args>`(单元隔离口径不变,不绕
cell 直跑 host.py);子进程 setsid 脱离,execd 崩溃不
带走它;任务登记落盘 /run/chv/execd-tasks.json,execd
重启后按 pid 重新认领(reattach),任务状态不丢。
重启后按 pid 重新认领(reattach),任务状态不丢。阶段 5:
task-kill 先杀整个进程组(任务 pid 即组长,spawn 一律
start_new_session),组不存在时回落单杀——只动该任务的
组,不动其它任务。
客户端鉴权:SO_PEERCRED 的 uid 须是 0 或 1000(root / chv),
其余一律拒绝。socket /run/chv/execd.sock 0600 root:root。
@@ -365,13 +368,24 @@ class Execd:
return {"ok": False,
"error": "task not running: %s" % task.get("state")}
pid = task.get("pid")
if not isinstance(pid, int):
return {"ok": False,
"error": "task has no pid: %r" % (pid,)}
sig = signal.SIGTERM
if req.get("signal") == "KILL":
sig = signal.SIGKILL
# 阶段 5:先杀整个进程组——spawn 一律 start_new_session,
# 任务 pid 即组长,组杀才能带走 runuser/cell fork 出的
# 子进程(单杀组长会留孤儿继续跑);组不存在(如已收走)
# 时回落单杀 pid,仍失败才如实报错。
try:
os.kill(pid, sig)
except OSError as exc:
return {"ok": False, "error": "kill failed: %s" % exc}
os.killpg(pid, sig)
except OSError:
try:
os.kill(pid, sig)
except OSError as exc:
return {"ok": False,
"error": "kill failed: %s" % exc}
self.store.update(task_id, state="killed",
ended_at=time.time())
return {"ok": True, "id": task_id, "pid": pid}