fix(axvisor): improve multi-VM guest console multiplexing - #1912
Conversation
There was a problem hiding this comment.
本 PR 将 AxVisor guest console 从简单前台直出扩展为启动期按完整行复用、交互期前台直出/后台有界缓存,并将快捷键改为 Ctrl+X 前缀;同时调整 shell 的 VM attach/detach 流程。
阻塞问题:切回 shell 或切换 VM 时,未换行的前台客户机输出没有在 shell 直写通知前收尾,导致管理 shell 文本与客户机提示符粘连。详见行内评论。
影响范围集中在 AxVisor host console 的输入路由和串口输出仲裁,不涉及 StarryOS syscall/ABI;feature-development.md 的新能力设计门槛不适用(这是现有控制台路径的行为修复/重构)。没有发现基础分支已有等价实现,也没有发现同一 guest-console 的开放 PR;既有 review 和 PR discussion 均为空。
验证:cargo fmt --check 通过,git diff --check 通过;当前头组织 CI 的 Check formatting / run_host、Run clippy / run_host、AxVisor aarch64/riscv64/loongarch64 QEMU(含 smoke)及 x86_64 SVM 检查均成功。Test starry riscv64 qemu / run_container 失败,改动面与 AxVisor console 无关,未作为本 PR 缺陷。按项目指引未重复已通过的 AxVisor CI。额外尝试 cargo test --manifest-path os/axvisor/Cargo.toml --all-features,该宿主命令不启用 bare-metal target 依赖,因 axvm/ax-std 不可解析而失败,不能代表 PR 回归。
测试覆盖:新增 mux 单元测试覆盖缓存、切换与回放,但未覆盖“前台未换行提示符 -> detach/switch -> shell 直接通知”的行为,正是本次缺陷的触发路径。
待办审计:代码、锁顺序、生命周期、输出状态、调用路径、测试发现、CI、历史评论、重复/重叠和行锚均已核查;唯一未解决项为下述输出边界问题。建议先修复并添加回归测试后再复审。
Powered by gpt-5.6-terra
| b'h' => match state.attached.take() { | ||
| Some(vm_id) => { | ||
| enqueue_guest_input(&mut state, vm_id, &[ESC, byte]); | ||
| state.output.buffer_all(); |
There was a problem hiding this comment.
严重性:阻塞。这里切回 shell 时只调用 buffer_all() 重置了 physical_line_open,但没有把前台 VM 已经写出的未换行片段收尾。随后 shell 对 Detached 直接 println!,不会经过 mux;例如 VM 提示符为 ~ # 时,用户会看到 ~ # [Axvisor] detached ...,管理 shell 的输出与客户机输出重新粘连。请让退出/切换状态转换在持有输出锁时先输出必要的换行分隔符,并补充包含未换行提示符和 shell 通知的 detach/switch 回归测试。
2a92ff6 to
ecbbcdd
Compare
There was a problem hiding this comment.
本 PR 将 AxVisor guest console 扩展为启动期按完整行复用、交互期前台直出/后台有界缓存,并改用 Ctrl+X 前缀快捷键;影响集中在 host console 的输入路由、串口输出仲裁及 VM attach/detach,未改变 StarryOS syscall/Linux ABI。feature-development.md 按语义适用:这是既有共享控制台路径的低风险行为扩展,PR 已说明问题、交互语义和 16 KiB 缓存边界。
代码状态机、输出边界与锁序已审:输出操作统一按 output lock→state 锁序,写 host 前释放 state。上次 review 所指的“未换行 guest prompt 与 shell 提示粘连”在当前 head 已由 buffer_all() 返回换行分隔符并写回 host 的路径修复;该历史评论在当前版本不再成立。
验证:git diff --check、cargo fmt --check 通过;cargo xtask axvisor test qemu --arch aarch64 --test-group normal --test-case smoke 通过(1/1,含 rootfs 自动准备)。当前 head 的组织 CI 为 success=6、skipped=6、cancelled=1,未见失败;取消的是 container spin-lint,跳过项为矩阵/发布条件。当前 CI 没有可确认执行本 PR guest-console 状态机测试的专门 AxVisor case。未重复泛化 clippy,因为当前组织 CI 已通过相关 lint,且本地已运行实际 AxVisor QEMU smoke。
测试覆盖仍有一个阻塞缺口:新增 output 仲裁测试已进入 axtest,但新增 mux 状态机测试没有被可发现的 axtest/QEMU case 或受支持宿主 target 执行,详见行内评论。
重复/重叠:dev 基线没有等价实现;开放 PR 搜索仅命中本 PR。#1909 同样涉及 VM 生命周期但属于 HTTP 管理面,与本 PR 互补,不是重复实现。既有 review thread 的唯一问题已修复。
待办审计:约束、设计适用性、调用链、并发/状态机、测试发现、CI、QEMU 验证、历史评论和重复分析均已完成;唯一未解决项为下述状态机回归测试未接入 runner。请修复后重新请求审核。
Powered by gpt-5.6-terra
| use axvm as _; | ||
|
|
||
| #[path = "../src/guest_console/mux/output.rs"] | ||
| mod guest_console_output; |
There was a problem hiding this comment.
严重性:阻塞(测试覆盖)。这里仅引入了 guest_console_output,所以 QEMU axtest 只会运行 mux/output.rs 的测试;本 PR 新增的 mux/tests.rs 仍被 #[cfg(test)] 包裹,并未进入 axtest 二进制。该 crate 在宿主 Unix 下也没有可供 cargo test 使用的 axvm/ax-std 目标依赖,因而快捷键、attach/detach、切换和输入路由这些本次改动的状态机测试实际上不会被项目 runner 执行。请把 mux 状态机回归测试接入当前 axtest/QEMU 流程(或提供受支持的宿主测试 target),并验证具体用例确实被执行。
ecbbcdd to
ac59f4b
Compare
There was a problem hiding this comment.
本 PR 将 AxVisor guest console 扩展为:启动期按完整行复用、多 VM 交互期前台直出/后台 16 KiB 环形缓存,并以顺序式 Ctrl+X 快捷键处理 attach/detach/切换;改动集中在 host console 的输入路由、串口输出仲裁和 VM 生命周期,不涉及 StarryOS syscall/Linux ABI。
feature-development.md 适用:这是既有共享控制台路径的低风险行为扩展。实现通过 output lock→state lock 的固定顺序协调输出和状态,并在 detach/switch 时用 buffer_all() 收尾未完成物理行;此前关于 shell 文本与 guest 未换行提示符粘连的评论已由当前 head 的换行输出路径修复。
验证:git diff --check、本地 cargo xtask ktest qemu -p axvisor --test axtest --arch aarch64 均通过;后者实际得到 AXTEST_SUMMARY pass=68 fail=0。组织 CI 的格式化、lint 和 AxVisor 相关检查已核对;被跳过/取消的矩阵项不是本次 guest-console 改动的失败证据,因此未重复广泛本地测试。当前 QEMU axtest 命令也证明 axtest 构建、发现和运行链路本身可用。
但新增核心状态机测试没有进入该链路,见行内评论。现有 QEMU 成功只覆盖已有 axtest case,不能证明 Ctrl+X 路由、attach/detach、切换及生命周期清理在回归时会被检测。请修复并让具体 mux case 出现在 axtest 输出后重新请求审核。
重复/重叠:dev 基线没有等价实现;开放 PR 搜索仅命中本 PR。#1909 触及 VM 生命周期但属于 HTTP 管理面,和本 PR 互补。此前两条 review 里,未换行输出边界问题已解决;测试接入问题仍未解决。待办审计已完成,唯一阻塞项如下。
Powered by gpt-5.6-terra
| } | ||
|
|
||
| #[path = "../src/guest_console/mux/mod.rs"] | ||
| mod guest_console_mux; |
There was a problem hiding this comment.
严重性:阻塞(回归测试未实际执行)。这里虽然把 mux/mod.rs 纳入了 axtest 二进制,但该文件对新增状态机用例仍使用 #[cfg(test)] mod tests;;无 harness 的 axtest 构建只设置 cfg(axtest),不会设置 cfg(test)。因此 mux/tests.rs(以及 output.rs 内同样被 cfg(test) 包住的用例)没有被编译或注册,#[cfg_attr(axtest, axtest::axtest)] 也无法生效。我在当前 head 运行 cargo xtask ktest qemu -p axvisor --test axtest --arch aarch64 虽得到 AXTEST_SUMMARY pass=68 fail=0,但输出没有任何 guest_console_mux case,编译诊断还把该模块列为未使用。这样 Ctrl+X 路由、attach/detach、切换和生命周期清理这些本 PR 的核心状态机没有可执行回归覆盖。请将测试模块改为同时在 test 和 axtest 下编译(例如 #[cfg(any(test, axtest))]),或在 tests/axtest.rs 直接注册这些用例,并重新运行 QEMU axtest 来证明具体 case 被执行。
问题
AxVisor 同时运行多个 VM 时,各 VM 的串口输出会按字节交错,导致日志内容难以阅读。同时,向某个 VM 输入命令后,其输出可能无法及时显示。
原有的
Ctrl+Alt+h依赖终端传递修饰键信息,在 Zellij、部分终端及 QEMU 环境中无法可靠识别。修改内容
[VM n]前缀。Ctrl+X快捷键,避免依赖终端增强键盘协议:Ctrl+X h:返回 AxVisor 控制台。Ctrl+X [:切换到上一个 VM。Ctrl+X ]:切换到下一个 VM。Ctrl+X Ctrl+X:向当前 VM 输入原始Ctrl+X。实现逻辑
启动阶段仅输出已经完成的逻辑行,避免多个 VM 的分片内容相互穿插。未换行片段暂存在对应 VM 的队列中。
进入交互模式后,当前 VM 获得前台直出权限,其他 VM 的输出写入各自的有界环形日志。切换 VM 时先回放目标 VM 的缓存,再将其设为前台。
主机控制台仍是唯一输入读取方,由多路复用层将普通输入和快捷键事件路由到 AxVisor shell 或对应 VM。
验证
执行:
结果:
其中 guest-console 回归测试包括:
Ctrl+X快捷键、attach/detach、VM 切换、输入路由、后台日志回放、未换行输出收尾,以及 VM 停止、删除和串口后端替换后的状态清理。其他验证:
cargo fmt --all --check通过。cargo xtask axvisor build --arch aarch64通过。