读懂这一篇,集群节点不下线(14)

在上一节最后 , 我们看到了问题出现的时候 , systemd 会输出一些 Operation not supported 报错 。 这个报错看起来和问题本身风马牛不相及 , 但是直觉告诉我 , 这或许是离问题最近的一个地方 , 所以我决定 , 先搞清楚这个报错因何而来 。

Systemd 代码量比较大 , 而报这个错误的地方也比较多 。 通过大量的代码分析(这里略去一千字) , 我发现有几处比较可疑地方 , 有了这些可疑的地方 , 接下来需要做的事情 , 就是等待 。 在等待了三周以后 , 终于有线上集群再次重现了这个问题 。

4. Live Debugging

在征求客户同意之后 , 下载 systemd 调试符号 , 挂载 gdb 到 systemd 上 , 在可疑的函数下断点 , continue 继续执行 。 经过多次验证 , 发现 systemd 最终踩到了 sd_bus_message_seal 这个函数里的 EOPNOTSUPP 报错 。

这个报错背后的道理是 , systemd 使用了一个变量 cookie , 来追踪自己处理的所有 dbus message 。 每次在加封一个新消息的时候 , systemd 都会先把 cookie 这个值加一 , 然后再把这个 cookie 值复制给这个新的 message 。

推荐阅读