part 5 修复 3:P2-9 degraded_logged=False——降级日志文案漂移

定位结论(已定位,不是时序、不是日志路径变化):part 4 提交
7a22732 把 serve() 从 peer_allowed 切到 peer_allowed_multi 时,
降级分支的 reason 与警告行都被改写成了“无 cell pid 文件”,
“cell.pid 缺失”这个串自此再也没进过 journal——P2-9 驱动
grep 'cell.pid 缺失' 自然命中不了,RETEST4 的
degraded_logged=False 即由此来。RETEST3 同项为 True,是因为
当时跑的还是 part 4 之前的 broker(serve 直接打印含该串的
警告行)。降级 ping 本身一直 ok=True,降级逻辑没坏,坏的是
日志里的认领字符串。

修复:peer_allowed_multi 无 pid 文件时的 reason 改回与单 cell
版 peer_allowed 完全一致的“uid 在范围内(cell.pid 缺失,未做
pid ns 对照)”;serve() 的警告行改走新 helper
_degraded_warning(reason, pid, uid),把 reason 原样打进日志
(不再手写第二份文案,避免两者再次悄悄漂移;今后改文案只改
reason 一处)。journalctl grep 'cell.pid 缺失' 恢复命中。

新测试 cloud/tests/test_chv_muse_p2.py::BrokerMultiTest(2 项):
reason 含“cell.pid 缺失”、警告行含该串且带 pid/uid。
This commit is contained in:
host committed 2026-11-07 12:07:32 +00:00
1 parent adc7bf6666
commit 0203f32627
2 files changed
+36 -4

No files matched your search

+21 -4
View File
@@ -89,7 +89,12 @@ def peer_allowed_multi(peer_uid, peer_pid, cell_pids, proc_root="/proc"):
return False, "uid %d 不在单元映射范围 [%d, %d)" % ( return False, "uid %d 不在单元映射范围 [%d, %d)" % (
peer_uid, UID_BASE, UID_BASE + UID_COUNT) peer_uid, UID_BASE, UID_BASE + UID_COUNT)
if not cell_pids: if not cell_pids:
return True, "uid 在范围内(无 cell pid 文件,未做 pid ns 对照)" # part 5:reason 文案与单 cell 版 peer_allowed 对齐,保留
# “cell.pid 缺失”字样——P2-9 驱动 grep 该串认降级日志;
# part 4 切到 multi 版时把这里改写成“无 cell pid 文件”,
# 该串自此再也没进过 journal,是 RETEST4
# degraded_logged=False 的根因(不是时序、不是日志路径)。
return True, "uid 在范围内(cell.pid 缺失,未做 pid ns 对照)"
peer_ns = _read_ns_link(peer_pid, proc_root) peer_ns = _read_ns_link(peer_pid, proc_root)
if peer_ns is None: if peer_ns is None:
return False, "对端 pid ns 读不到,拒绝" return False, "对端 pid ns 读不到,拒绝"
@@ -131,6 +136,19 @@ def _read_cell_pids(cell_dir="/run/chv"):
return pids return pids
def _degraded_warning(reason, pid, uid):
"""降级警告行:reason 原样进日志。serve() 在无 cell pid 文件
时打这条;P2-9 驱动 grep 'cell.pid 缺失' 认的就是它(part 5:
part 4 之前 serve 直接打印含该串的警告行,RETEST3 同项为
True;part 4 切到 peer_allowed_multi 后警告行改写成
“无 cell pid 文件”,该串再也没进过 journal——RETEST4 的
degraded_logged=False 即由此来,不是时序、不是日志路径
变化。reason 与警告行分开写曾让两者悄悄漂移,今后改文案
只改 peer_allowed_multi 的 reason,警告行自动跟随)。"""
return ("chv-broker: 警告:%s (pid=%d uid=%d)"
% (reason, pid, uid))
def _resolve_repo(repo): def _resolve_repo(repo):
"""仓目录只允许 ~/workspace 下。repo 为空时返回 None(由 """仓目录只允许 ~/workspace 下。repo 为空时返回 None(由
chv-sync 自己取唯一仓)。返回解析后的绝对路径或抛 ValueError。""" chv-sync 自己取唯一仓)。返回解析后的绝对路径或抛 ValueError。"""
@@ -267,9 +285,8 @@ def serve(sock_path=BROKER_SOCK, browser_sock=BROWSER_SOCK):
conn.close() conn.close()
continue continue
if not cell_pids: if not cell_pids:
print("chv-broker: 警告:无 cell pid 文件,只做了 uid 检查 " print(_degraded_warning(reason, pid, uid),
"(pid=%d uid=%d)" % (pid, uid), file=sys.stderr, file=sys.stderr, flush=True)
flush=True)
conn.settimeout(310) conn.settimeout(310)
data = b"" data = b""
while len(data) < MAX_REQUEST_BYTES: while len(data) < MAX_REQUEST_BYTES:
+15
View File
@@ -1086,6 +1086,21 @@ class BrokerMultiTest(unittest.TestCase):
ok, reason = BROKER.peer_allowed_multi(1000, 200, []) ok, reason = BROKER.peer_allowed_multi(1000, 200, [])
self.assertTrue(ok) self.assertTrue(ok)
self.assertIn("未做 pid ns 对照", reason) self.assertIn("未做 pid ns 对照", reason)
# part 5:reason 须保留“cell.pid 缺失”字样——P2-9 驱动
# grep 该串认降级日志;part 4 切到 multi 版时改写成
# “无 cell pid 文件”,该串再也没进过 journal,
# RETEST4 的 degraded_logged 即因此为 False。
self.assertIn("cell.pid 缺失", reason)
def test_degraded_warning_carries_probe_string(self):
# serve() 打的警告行就是 _degraded_warning 的返回值:
# reason 原样进日志,journalctl grep 'cell.pid 缺失'
# 才能命中;pid/uid 也在行里(排障用)。
_, reason = BROKER.peer_allowed_multi(1000, 200, [])
line = BROKER._degraded_warning(reason, 123, 1000)
self.assertIn("cell.pid 缺失", line)
self.assertIn("pid=123", line)
self.assertIn("uid=1000", line)
def test_read_cell_pids_glob_and_legacy(self): def test_read_cell_pids_glob_and_legacy(self):
with tempfile.TemporaryDirectory() as tmp: with tempfile.TemporaryDirectory() as tmp: