用于 Linux 测试的 Machina 运行时

本指南介绍了如何使用 Machina 针对 Linux 环境运行和调试 Starnix 测试。

Machina 在 Linux 虚拟机内运行测试,使用目标内核版本提供隔离且标准化的环境。请注意,运行 Machina 需要基于 Intel 的 CPU 来执行,还需要本地可用的 Debian guest 映像。Google 员工默认可以使用此类映像,而外部开发者需要自带此类映像。外部开发者应参阅虚拟化入门指南,详细了解如何构建自己的 Debian 映像。

在本地运行现有的 Machina 测试

环境设置

  1. 确保您使用的是具有虚拟化功能的高性能 Intel 机器。对于 Google 员工,专用 Cloudtop 将提供理想的环境。如果您不确定自己的机器配备了哪种 CPU,可以按如下方式使用 lscpu

    lscpu | grep "Vendor ID"
    Vendor ID: GenuineIntel
  2. 设置支持虚拟化的产品配置。只要主板是 x64,大多数产品都可以正常运行。以下是一个配置示例:

    fx set fuchsia.x64 --main-pb workbench_eng.x64
  3. 添加 linux_vm_tests 目标:

    fx add-test //src/starnix/tests:linux_vm_tests
  4. 使用标准 fx buildffx emu start 工作流引导模拟器。

运行测试

测试套件与原始系统调用相同,但带有 linux_ 前缀。以下是一些常见的目标包含示例:

  • 运行整个套件

    fx test linux_syscalls_cpp_tests
  • 运行单个测试

    fx test linux_fcntl_test
  • 同时在 Starnix 和 Linux 上运行:指定测试的基本名称,这将运行您的环境可能配置为运行的所有变体(Starnix、Machina、Host):

    fx test mount_test

调试失败的基于 Machina 的系统调用测试

了解日志

系统调用测试是 gTest 套件,输出通过测试框架进行管道传输。换句话说,在测试失败时,gTest 调用产生的输出会显示在标准输出中。您可以在 fx test 调用中使用 --output 实参来查看所有 gTest 日志,无论结果如何。

与 Machina 运行时相关的日志会输出到系统日志 (ffx log),并且通常与标识标记相关联。目前,所有系统调用测试都使用一个运行时(使用 linux_guest 标记)。不过,与内核端虚拟化相关的系统日志(例如由 Zircon Hypervisor 发出的日志)除外。这些日志不会包含与访客相关的特定标识符。

下文记录了与典型流程相关的系统日志。

  1. 初始 guest 引导加载程序

    在以下日志中,您会看到 starnix_test_runner 组件请求带有 linux_guest 标记的 Machina Guest。starnix_test_runner 会记录有关其互动请求的两行日志。第三行来自 interactive-debian-guest 组件,可以将其视为正在运行的 Machina 访客组件。它会收到请求并开始启动。您可以看到,整个系统中的所有日志都带有标识符 (linux_guest)。如日志所示,Machina 访客是延迟启动的。此初始启动通常需要 ~60 秒才能准备好进行互动,但仅在首次运行时需要。

    [00043.071313][starnix_test_runner][linux_guest] INFO: Pushing data to guest (destination: /data/tests/deps/clone_exec_helper)
    [00043.071321][starnix_test_runner][linux_guest] INFO: Interaction requested, lazily starting the guest instance.
    [00046.686157][interactive-debian-guest][linux_guest] INFO: [interactive_debian_guest_impl.cc(110)] Start requested for an interactive Debian guest.
    
  2. 推送测试依赖项和二进制文件

    来宾启动后,系统会开始将初步数据推送到来宾。以下是系统调用测试所需的依赖项,后面是测试二进制文件本身:

    [00439.934416][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Pushing data to guest (destination: /data/tests/deps/simple_ext4.img)
    [00441.040568][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Successfully pushed data to guest (destination: /data/tests/deps/simple_ext4.img)
    [00444.834216][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Pushing data to guest (destination: /starnix_linux_fuse_test_fuse_test_bin)
    [00448.652779][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Successfully pushed data to guest (destination: /starnix_linux_fuse_test_fuse_test_bin)
    
  3. 测试作业和处理

    完成环境设置步骤后,您应该会看到已发出执行命令。这会在 guest 上执行 gTest 二进制文件。与针对 gTest 套件的任何其他 fx test 调用一样,此二进制文件执行的输出会再次通过管道传输到终端上的标准输出。执行完成后,结果文件会复制回主机以供处理:

    [00448.653126][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Executing command on guest: /starnix_linux_fuse_test_fuse_test_bin --gtest_output=json:/test_result-ccde95ca-acb3-4b84-af4d-f371b9582d20.json)
    [00448.848658][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Command '/starnix_linux_fuse_test_fuse_test_bin --gtest_output=json:/test_result-ccde95ca-acb3-4b84-af4d-f371b9582d20.json'
    ...terminated with status Status(OK), return code 0
    [00448.849066][starnix_test_runner.cm][linux_guest,starnix_test_runner] INFO: Fetching file from guest (remote_path: /test_result-ccde95ca-acb3-4b84-af4d-f371b9582d20.json)
    

了解运行时

Starnix 测试运行程序负责编排测试,可以看作是 Fuchsia 测试框架和 Machina 运行时之间的粘合剂。您需要了解与运行时相关的两个关键事项:

  1. 系统调用测试通过 [syscalls_cpp_test.cml][syscalls-cml]test_type: "syscall" 程序标记在 CML 中进行标识。
  2. Starnix 测试运行程序在处理套件请求时会查找此标记,并相应地分支逻辑来处理这些测试。核心处理逻辑位于 [syscalls.rs][syscalls-rs] 中,主要入口点为 run_syscall_tests

虽然运行时不仅仅包含这两个方面,但如果将所有内容都记录在文档中,那将是一项艰巨的任务。希望这两个核心系统组件能为您的调查和调试提供坚实的锚点。

高级调试

详细的 Linux 内核日志记录

如果您怀疑 Linux 内核本身出了问题,可以通过设置以下 GN 实参来启用更详细的 Linux 内核日志记录:

redirect_guest_serial_logs = true

这会将 Linux 内核日志输送到标准系统输出,这意味着您可以通过 ffx log 查看客户机内核日志。日志在 vmm 组件下发出,并会标记 (guest klog) 为清晰起见,以明确来源。例如:

[00352.454169][vmm.cm][vmm] INFO: [vmm.cc(491)] (guest klog): [    0.000000] Linux version 6.6.13-amd64 (debian-kernel@lists.debian.org) (gcc-13 (Debian 13.2.0-10) 13.2.0, GNU ld (GNU Binutils for Debian) 2.41.90.20240115) #1 SMP PREEMPT_DYNAMIC Debian 6.6.13-1 (2024-01-20)

在此日志示例中,您会看到 vmm 组件发出 Linux 内核日志行。vmm 在系统正常运行时间为 00352.454169 时发出了此日志。(guest klog) 表示 Linux 内核在 [ 0.000000](从内核角度来看,这是正常运行时间的第 0 秒)发出了相应行。

通过 shell 进入 Machina

您可以访问正在运行的 Linux 虚拟机的相当标准的命令行界面。请注意,测试二进制文件和制品默认情况下不会出现在映像中,因为它们是由测试运行程序框架动态推送的。如需详细了解如何将测试二进制文件和制品放入 guest 中,请参阅以下部分。以下是获取此 shell 的步骤:

  1. 按照虚拟化入门指南操作,该指南会向您展示如何设置本地 GN 实参以启用虚拟化工具。
  2. 启动模拟器并连接到 shell:

    fx shell
  3. 启动 Debian guest:

    guest launch debian

    这会将您置于 Debian shell 中。

请注意,shell 行为可能会令人困惑:

  • exit不会退出访客 shell。
  • CTRL+C不会终止正在运行的程序,而是退出 Debian shell 返回到 Fuchsia。

提示:如果您不小心按 CTRL+C 从 Linux 客户机退出并进入 Fuchsia,可以使用 guest attach debian 返回到 shell。

修改 Debian 映像

在某些情况下,您可能希望更改默认的 Debian 映像(例如,添加二进制文件或调试程序)。由于没有简单的方法来推送伪影,您必须直接修改图片。

  1. 装载映像:在 Linux 主机上,安装工具并装载映像:

    sudo apt-get install libguestfs-tools
    sudo mkdir /mnt/machina_guest_img
    sudo guestmount -a prebuilt/virtualization/packages/debian_guest/images/x64/rootfs.qcow2 -m /dev/vda /mnt/machina_guest_img/
  2. 与映像互动:您现在可以将文件复制到已挂载的目录。例如,如需复制装载测试二进制文件和依赖项,请执行以下操作:

    sudo cp ./out/core.x64-balanced/linux_x64/linux_mount_test_bin /mnt/machina_guest_img/home/
    sudo mkdir -p /mnt/machina_guest_img/home/data/tests/deps/
    sudo cp src/starnix/tests/syscalls/cpp/data/* /mnt/machina_guest_img/home/data/tests/deps/
  3. 卸载映像

    sudo guestunmount /mnt/machina_guest_img

卸载后,映像将包含您所做的更改。然后,您可以进入环境(如上文所述),并根据需要执行二进制文件。