一条 run 命令的调用链

定义

a3s-box run 是创建并启动一次本地执行的用户入口。它不直接调用 hypervisor,也不直接 clone 出容器进程。命令行层负责解析与交互;LocalExecutionManager 负责持久状态;具体后端负责启动。把这一条链走通,即可把第四层的各个 crate 放回原位。

问题背景

仓库体积大,若按文件名搜索 start,会同时命中 CLI、CRI、VM、OCI 与 guest init。沿一条用户命令向下追踪,可以避免把适配层误认为执行层。

机制说明

1. 命令行入口

src/cli/src/commands/run.rs 中的 execute

  1. 校验互斥参数(例如 -d-t--timeout 与 detach);
  2. 若指定池套接字,转入 execute_pool_run,见 Warm pool 与 snapshot-fork
  3. 否则调用 setup_and_bootrun/setup.rs)准备镜像、卷、网络与 CreateExecutionRequest
  4. 记录审计事件;
  5. -d-t 或前台模式进入等待、健康检查或 TTY。

-- 之后的参数属于客户机 argv,不属于 Box 选项。

2. 产品状态机

LocalExecutionManager::create_and_start

  1. Router 盖上 BoxVmOciSdk
  2. 后端预检隔离与能力;
  3. 计划并持久化资源身份;
  4. 调用 backend.start

失败发生在预检阶段时,不应留下半创建的产品对象;失败发生在启动阶段时,清理必须按已写入的路由进行。

3a. MicroVM 路径(默认)

vm_backend.start
→ src/runtime/src/vm/ 生成 InstanceSpec
→ 拉起 a3s-box-shim(src/shim/src/main.rs)
→ libkrun krun_start_enter
→ guest-init(src/guest/init/src/main.rs)作为 PID 1
→ vsock 上的 exec / PTY / 证明 / 端口服务
→ 入口进程

父进程保留 ExecutionManager 与日志;子进程成为 VMM。

3b. Sandbox 路径(--isolation sandbox

oci_backend.start
→ oci_production 编译 bundle(rootfs + config.json + 附件清单)
→ oci_owner 启动或复用身份围栏的 a3s-oci 所有者
→ a3s-oci-sdk 发送 create / start
→ 分离的日志投影 worker 写入 Box 控制台文件

所有者二进制的路径与摘要在启动前校验。OCI 失败不得重试 Box 拥有的 socket。

4. 返回之后的命令

execlogsstatscpattachstoprm 不再做创建期路由,只读取记录中的 ManagedRuntimeRoute。因此,升级 Box 或更改 A3S_BOX_OCI_MIGRATION 不会把旧实例搬到另一后端。

其他入口如何汇合

入口 汇合点
Rust / 桥接 SDK 同一 LocalExecutionManager
Compose 对每个服务构造等价的创建请求
CRI config_mapper.rs 译为创建 / 启动调用
containerd shim 再进入 ExecutionManager 或与之等价的本地管理器

在 Box 中的位置

关键文件路径即上一节所列。阅读顺序建议:

  1. cli/src/commands/run.rs
  2. cli/src/commands/run/setup.rs
  3. runtime/src/local_execution/router.rs
  4. runtime/src/local_execution/vm_backend.rsoci_backend.rs
  5. shim/src/main.rsguest/init/src/main.rs(仅 MicroVM)

验证命令

a3s-box run --rm alpine:3.20 -- echo hello
a3s-box run --rm --isolation sandbox alpine:3.20 -- echo hello

在合格主机上,两条命令都应打印 hello,但 uname -r 不同。用 inspect 查看记录中的隔离与路由字段,可与本词条的 3a / 3b 对照。

相关与易混