跳到主要内容

控制台生命周期通知

管理控制台需要在客户机没有输出时感知自主停止,并在持续输出时继续处理输入。ConsolePump::turn() 保留每轮 128 条输出的限额及输入处理顺序,生命周期感知改由 AxVM 状态发布驱动。该设计不改变客户机协议、页面缓存、管理命令或浏览器事件流。

1. 状态发布​

生命周期状态仍由 AxVM 控制任务持有,VmSnapshot 是对外观察入口。通知只要求重新读取当前状态,不携带可能晚到的停止状态,也不建立第二份虚拟机登记表。

1.1 所有权与订阅​

VmManager::subscribe_lifecycle() 返回独占消费的 VmLifecycleSubscription。每个管理器拥有一个 LifecycleEvents,实例的 ControlExit 共享该通知源;通知源仅持有订阅者的弱引用。订阅从待对账状态开始,覆盖登记前的状态发布;丢弃订阅后不再选择该订阅,已被选择的唤醒可以结束。

ControlShared::publish() 在快照锁内比较并提交 VmStatus 与 RunId,在锁外发布失效通知。普通计数变化不触发通知。ControlExit::remove_exact() 只在移除匹配 VmKey 的实例后通知,并先释放登记表锁。创建失败、正常销毁和客户机自主停止均沿原有权威路径传播。

1.2 合并与代次​

原子待处理标志合并多次变化。消费者先以 take_changed() 清除标志,再读取登记表与快照;并发发布会重新置位,留给下一轮处理。该协议没有有限位宽版本计数的回绕问题。

通知不直接更新控制台状态,迟到通知只能促成当前状态检查。reconcile_vm_states() 继续在读取登记表之前捕获后端代次,并使用现有代次过滤应用结果;VmKey 和 RunId 仍由 AxVM 分配。旧实例或旧运行代次的停止记录不能作为新实例的当前状态使用。

2. 等待与验证​

Axvisor 适配层组合生命周期通知、物理输入和有序日志。运行时仅提供外部条件等待能力,不理解虚拟机,也不新增转发任务或定时器。

2.1 唤醒闭环​

TaskConsoleInput::event_waker() 返回现有控制台等待队列的任务上下文唤醒能力,wait_event_until() 同时检查输入、日志和外部条件。日志单独订阅和 raw-HAL 输入提供对应能力;没有输入输出订阅时,Axvisor 使用自身的生命周期等待队列。

发布者先提交快照,再置位待处理标志,最后在锁外唤醒。WaitQueue::wait_until() 的通知代次与登记协议覆盖条件检查到休眠之间的窗口;谓词只读取 has_changed(),不消费标志。控制台仅在初始化或消费标志时对账,空闲等待没有周期截止时间。运行时停止仍返回错误。

ConsolePump 先处理生命周期变化,再有界消费输出,在输入交给可能阻塞的命令前调用 flush_output_retries()。生命周期通知不替换有序输出,不改变 FIFO 和背压所有权。

2.2 取舍与验收​

仅在宿主 stop_vm() 补通知会遗漏自主停止;调整扫描周期仍有空闲唤醒和发现延迟;新增观察任务会增加调度与释放责任。因此扩展已有快照发布边界,并在通知后复用已有全量对账。扫描成本只在发生变化时出现,按实例增量对账不属于本次范围。

组件回归验证无变化不重复对账、持续输出下输入推进及批量背压通知顺序。AxVM 宿主测试覆盖实际快照发布、合并、运行代次变化、移除和订阅取消,原有后端代次用例保留。Axvisor 的 axtest 在真实 QEMU 中覆盖发布先于等待、发布发生在检查与登记之间,以及独立生产任务唤醒无输入输出的消费者。运行器超时只保护挂起,不作为成功条件。

本次不承诺 64 台实体客户机的性能结果。回滚需一并恢复快照通知、等待接口与服务策略,避免只删除通知却留下无超时等待。接口和并发边界需要领域审查,设计与定向验证结果共同作为复核材料。