☰
smolvm 在 Windows 上的持久化开发机器:验证记录、WHP 设备上限与 PowerShell 脚本驱动实战
2026/10/9 2:34:57 网站建设 项目流程
  • 虚拟化
  • AI Agent
  • 人工智能
  • CLI

【免费下载链接】smolvm

An embeddable, portable, branchable virtual machine to safely run Agents locally.

项目地址:https://gitcode.com/gh_mirrors/sm/smolvm
点击查看免费下载

本篇技术指南基于仓库 dev-env 技能包 的 Windows 专项验证文档,整理 smolvm 在 Windows 11 x86_64 上搭建"可随时回来继续工作的开发机器"的完整实测记录:哪些行为与 Linux/macOS 完全一致、停止后再启动能否保住已装依赖、Windows Hypervisor Platform(WHP)下挂载与端口发布的设备上限,以及被 PowerShell 输出捕获陷阱坑过的脚本正确写法。读完你将掌握在 Windows 上验证 smolvm 持久化开发机器、排查重启失败与规划资源预算的完整方法。

一、验证前提与记录说明

文档记录的是真实的运行回放,而非对任意 Windows 主机的承诺。需要先明确两次运行的边界:

  • 2026-10-03 重跑(v1.22.2):Windows 11 Home build 10.0.26200 UBR 9457 x86_64,Intel Core Ultra 9 185H,31.6 GB 内存,提升权限的会话,使用技能包自带的 assets/dev.smolfile,运行了三次停止与三次启动,每次启动约 0.8 秒,均打印Init already completed, skipping 3 command(s),标记文件与requests 2.34.2每次都能读回,init只计数一次。
  • 2026-09-11 运行(v1.14.6):UBR 9445,文档中的交互转录来自此次运行。
  • 性能计时:来自同主机更早的 v1.14.2 运行,未在 v1.22.2 重新测量;WHP 设备上限同样来自该次运行,并由 install 技能包 在 v1.22.2 的 Windows 运行中再次确认。

这个验证场景的核心结论一句话即可概括:Windows 上的开发机器经受住了停止与启动的考验,用例在 Windows 上与 Unix 同样成立。

二、与 Unix 完全一致的部分

在 v1.22.2 的 Windows 重跑中,create、start、stop 的行为与 Linux、macOS 逐项对应:

create in 0.5s Created machine: wd Init commands: 2 first start in 4.9s Running 2 init command(s)... init user / exec user initran=root execuser=app workdir=/tmp install requests in 9.1s 2.34.2 stop in 0.4s Stopped machine: wd

两个关键语义在 Windows 上得到验证:

  1. init以 root 运行,工作负载以 Smolfile 的user运行——与 Linux、macOS 一致。这是有意的安全设计而非缺陷:init负责供给(provisioning),workdir=/tmp由验证所用 dev.smolfile 设定。
  2. init只运行一次——第二次启动打印Init already completed, skipping 2 command(s)。

这背后有源码佐证:在 src/cli/vm_common.rs 中,首次启动完成init后会将init_completed = true持久化到机器记录(且刻意放在工作负载启动之前,避免 CMD 失败导致init被重复触发),后续启动走else if !record.init.is_empty()分支直接打印"Init already completed, skipping {} command(s)"。这正是 dev-env 技能文档 所强调的:machine create --help对--init的描述是"every VM start",依赖这种读法写的供给逻辑在第二次启动时会缺失——任何必须在每次启动时成立的东西(尤其是 bind mount)应放进机器运行的命令,而不是init。

三、停止与启动:该用例立身之本的完整验证

持久化开发机器的全部意义在于:第一会话装的包,第二会话还在。验证流程为 create → start → stop → start → stop → start,并在机器内写入标记文件、每次启动后读回:

Created machine: wd --- first start out: Machine 'wd' running (PID: 2028) MARKER_V1146 --- stop 1 Stopped machine: wd --- start 2 (this is what failed on v1.14.2 with Bad message os error 74) out: Machine 'wd' running (PID: 14784) --- marker after start 2 MARKER_V1146 --- stop 2 Stopped machine: wd --- start 3 out: Machine 'wd' running (PID: 13820) --- marker after start 3 MARKER_V1146

两次重启都成功,标记文件两次都存活。停止前写入机器内部的状态,停止后依然存在——这是该技能包在其它平台承诺的行为在 Windows 上的兑现。

历史背景值得记录:在 v1.14.2 上,第二次启动会以pull image: Bad message (os error 74)失败并把机器留在停止状态,对应 issue smolvm#1196,已在 v1.14.6 修复。这意味着 Windows 重启失败是一个已经被修复过的具体 bug,遇到此症状时版本对比是首要排查手段。

四、WHP 设备上限:Windows preflight 必须知道的硬约束

到 v1.22.2 为止,WHP 给客户机11 个 IRQ 预算,与 Linux x86_64 相同。在实测主机上量化如下:

  • 四个-v挂载可以启动,五个失败,报错no more IRQs are available;
  • 发布端口只增加一个网络设备(无论发布多少个端口),等价于--allow-host或--allow-cidr的效果——所以四个挂载加两个端口失败,而两个挂载加两个端口可以启动。

对开发机器的直接启示:一台同时挂载源码树、缓存目录、构建输出目录和配置目录的机器,在发布开发服务器端口之前就已经到了上限。规划 Windows 开发机器时,应把"4 个挂载"视为硬天花板,端口发布再从预算中扣掉一个。

上限的版本边界同样明确:该约束保持到 v1.22.2。v1.23.0 携带的 libkrun 让 x86_64 客户机拥有 IRQ 5 到 23(#1521),但未在 Windows 上运行过,因此其 Windows 上限未被测量——在 v1.23.x 上不能照搬本文数字。

五、从脚本驱动:捕获输出永不返回的陷阱与正确模式

machine start会把 VM 作为后台smolvm.exe _boot-vm子进程遗留,且继承父进程的 stdout 句柄。任何捕获该输出的调用方都会一直等到句柄关闭——而句柄只在 VM 退出时才关闭。这不是命令慢,是 shell 挂住了。install 技能包的 Windows 记录用三种方式对比了结果:

调用方式结果
& $exe machine start --name X 2>&1 \| Out-String阻塞超过 90 秒,而machine list显示机器已在running
cmd /c "smolvm.exe machine start ... > out.txt 2>&1"同样阻塞,尽管文件中已出现Machine 'X' running (PID ...)
Start-Process -RedirectStandardOutput out.txt -PassThru并轮询HasExited约 4.9 秒返回

实测中这个陷阱代价约一小时,并产生了两个错误结论:machine branch和machine checkpoint都像无限挂起,实际是它们之前的machine start阻塞了,这两个命令根本没执行。

正确的 PowerShell 模式:

$p = Start-Process -FilePath $exe -ArgumentList @('machine','start','--name','X') ` -RedirectStandardOutput out.txt -RedirectStandardError err.txt -WindowStyle Hidden -PassThru while (-not $p.HasExited) { Start-Sleep -Milliseconds 400 } Get-Content out.txt

一个使用注意:-ArgumentList自带一套引号处理,会破坏-- sh -c "echo $(id -un)"这类嵌套 shell 引号。对于含引号的exec命令,用cmd /c加文件重定向才是正确选择,且不会阻塞——因为exec不会遗留新的后台 VM。

六、Windows 上的状态位置与清理

Windows 上 smolvm 的状态无法迁移:数据落在%LOCALAPPDATA%\smolvm(含server\、rootfs\、vms\等子目录),Windows 二进制没有SMOLVM_DATA_DIR,把$env:LOCALAPPDATA指到临时目录也无效——smolvm 通过 Windows API 解析已知文件夹,忽略该变量,仍写入C:\Users\<user>\AppData\Local\smolvm。

两个连带后果:

  1. 没有隔离 HOME 的测试技巧——测试运行会直接写进真实用户配置文件;
  2. 清理必须手工删除整棵目录树——install 技能包记录一次会话后该目录达到30756 MB,因为每台机器的存储盘与 overlay 都是稀疏文件,表面大小分别为 20 GiB 与 10 GiB(与 dev-env 主文档 中 v1.22.2machine list的显示一致),实际只占实际持有量。参见 teardown 技能包。

另外注意machine list也并非只读:它会创建状态目录和server\smolvm.db。

七、更多值得记录的 Windows 行为

  • PowerShell 把 exe 的 stderr 变成错误记录:一次完全成功的运行会打印smolvm.exe : Starting ephemeral machine (...)后跟NativeCommandError。命令成功且$LASTEXITCODE为 0——不要在这类调用周围设置$ErrorActionPreference = 'Stop',也不要把红字当成失败。
  • 启动失败时先读客户机控制台再清理:自 v1.14.0 起,客户机控制台写入%LOCALAPPDATA%\smolvm\vms\<hash>\agent-console.log(与agent-startup-error.log相邻),里面有真正的原因(如 rootfs 解包损坏时的Couldn't execute '/sbin/init': ENOENT),而 CLI 只打印boot process exited (code 127)。该文件只在 VM 目录存在期间存在,因此要在失败后、任何清理删除该目录之前读取:
    Get-Content "$env:LOCALAPPDATA\smolvm\vms\<hash>\agent-console.log" -Tail 40

    补充背景:agent rootfs 在 Windows 上以 tarball 形式分发,解包在没有SeCreateSymbolicLinkPrivilege(非管理员或未开开发者模式)时会静默丢弃符号链接,导致/sbin/init无法执行——install 技能包给出了解包前检查该项权限的具体命令,且容忍解包失败被标记完成的分支仍存在于 src/agent/manager.rs。

  • 路径长度:本次运行所涉及路径中不是问题,237 字符的目录作为卷挂载源正常,接近 260 字符也无异常。
  • 平台补全:--net提供真实eth0并支持入站端口转发,--cuda可达真实 NVIDIA GPU,--gpu(Vulkan)被接受但静默无效。

八、验证脚本与实测输出

Windows 专项验证之外,技能包的可移植脚本可作为 Linux/macOS 上的对照基准,其断言方式同样适用于 Windows 手测(先等待工作负载返回一个值,而不是只检查退出码为零):

  • scripts/create-dev-machine.sh:创建带显式长生命周期工作负载命令的机器(while true; do sleep 3600; done),启动后等待工作负载应答,然后报告实际发生的事实而非"没报错";init_ran_as=root与exec_user=app并存是正确结果。
  • scripts/verify-persistence.sh:安装包并记录版本号(不崩溃的 import 可能由系统副本满足,证明不了你的安装存活)、在每个文件系统各写一个标记文件、停止、启动,然后逐一断言。每次启动都检查Init already completed,并区分$HOME文件(存活)、/storage文件(存活)与/tmp文件(WIPED——/tmp是 tmpfs,停止即清空)。

v1.22.2 在 macOS arm64 上的完整回放输出可作参照:init_ran_once=ok (yes)、package_version=ok (2.34.2)、home_file=ok (SURVIVES)、storage_file=ok (SURVIVES)、tmp_file=ok (WIPED)、exec_user=ok (app)、workdir=ok (/app)、result=persistent。

九、未覆盖与开放事项

文档明确列出未验证的部分,引用时务必注明边界:

  • Windows 上未覆盖:Windows 10、Windows Server、非管理员用户、WSL2 作为宿主;scripts/preflight.sh在 Windows 上报告result=blocked并指向本主题文档——dev-env 技能包不携带 PowerShell 脚本,因为没人执行过的脚本不如一份有人执行过的流程说明。
  • Windows 上未覆盖的还有:超出重启范畴的测试(v1.22.2 运行只覆盖了 create、三次停止启动、标记文件与init只跑一次);v1.23.0 在 Windows 上的设备上限;以及任何平台上的"checkpoint 恢复后init行为"。
  • 开放问题:镜像自带USER指令与init以 root 运行之间的交互仍待定(smolvm#1189)。

十、相关技能包索引

  • install / references/windows.md:Windows 安装、启动证明、输出捕获陷阱的完整测量与工作模式,以及本主题引用的设备上限确认。
  • teardown 技能包:Windows 状态目录手工清理流程。
  • dev-env 主文档:init只跑一次的语义、持久化矩阵(machine run瞬时、machine exec覆盖层持久、stop/start持久、create --from免拉取)与陷阱总表。
  • dev-env / SKILL.md:完整操作流程与评估提示词实测输出。
  • assets/dev.smolfile:本次 Windows 验证使用的起始配置文件。
  • 虚拟化
  • AI Agent
  • 人工智能
  • CLI

【免费下载链接】smolvm

An embeddable, portable, branchable virtual machine to safely run Agents locally.

项目地址:https://gitcode.com/gh_mirrors/sm/smolvm
点击查看免费下载
上一篇:comprehensive-rust 裸金属 AP 教程:用 safe-mmio 把 PL011 UART 驱动写成纯 safe 代码
下一篇:Cherry Studio 提供商注册表兼容性基线机制:远程目录的 Schema 版本化与前后向兼容实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询