如果systemd的版本没有变,我执行 daemon-reexec 后如何判断进程是否重启过

spider · · 19 次点击
观察进程内部的内存布局变化(高级) /proc/1/maps 记录了进程的内存映射布局。即使二进制文件相同,两次 reexec 后内存映射的起始地址或加载顺序也可能因为 ASLR(地址空间布局随机化)而略有不同。 ``` # 执行 reexec 前 cat /proc/1/maps | head -5 > /tmp/before.txt # 执行 reexec sudo systemctl daemon-reexec # 执行后 cat /proc/1/maps | head -5 > /tmp/after.txt # 对比差异 diff /tmp/before.txt /tmp/after.txt ``` 如果看到差异,说明进程确实重新加载了二进制和库文件。但注意:ASLR 是内核在 exec() 时随机化的,但 reexec 会触发新的随机化吗?会,因为 exec() 会重新初始化 ASLR。所以理论上会有差异。 不过这种方法受内核版本和配置影响,并非 100% 可靠。
#1
更多评论
另一种方式,通过观察进程打开的文件描述符变化, reexec 会关闭一些临时的、不需要继承的文件描述符。虽然 systemd 会尽量保留关键 socket,但某些内部文件句柄会重新打开。 ``` # 执行前 ls -l /proc/1/fd/ | wc -l # 执行 reexec sudo systemctl daemon-reexec # 执行后 ls -l /proc/1/fd/ | wc -l ``` 最后还有一种最直接的方式,使用 strace 或审计日志(需要预判) 如果你能提前准备,可以在执行 reexec 前开启对 PID 1 的系统调用追踪: ``` # 在另一个终端,追踪 PID 1 的系统调用(需要 root) sudo strace -p 1 -o /tmp/systemd-strace.log ``` 然后在另一个终端执行 `sudo systemctl daemon-reexec`。回到 strace 终端,你会看到大量的 execve() 调用和重新初始化的过程。这是最直接的证据。注意:strace 会影响 PID 1 的性能,避免在生产系统上这样做。
#2