用于 Linux 测试的 Machina 运行时

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

Machina 在 Linux 虚拟机内运行测试,使用我们的目标内核版本提供隔离且标准化的环境。请注意,运行基于 Machina 的 Starnix 测试需要本地提供 Debian 客机映像。 Google 员工默认拥有此类映像,而外部开发者则需要自带映像。外部开发者应阅读 虚拟化入门指南,详细了解如何构建和提供自己的 Debian 映像。

在本地运行现有的 Machina 测试

主机前提条件

Machina 是一种虚拟化环境,仅限于基于现代 Intel 的主机。对于 Google 员工,支持虚拟机的现代 Cloudtop 提供了理想的环境。较旧的已废弃 Cloudtop 可能需要调整大小以使用更现代的映像。确保您的主机与以下检查兼容:

  • 基于 Intel

    lscpu | grep "Vendor ID"

    您应该会看到:Vendor ID: GenuineIntel。如果不是,您需要购买基于 Intel 的机器。对于 Google 员工,具有嵌套虚拟化的 Cloudtop 应该足够。

  • 支持虚拟化

    按照启用虚拟机加速中的说明操作。

  • 现代、高性能的 CPU

    if lscpu | grep -qE "Clear CPU buffers"; then echo 'CPU has performance-hindering mitigations.'; else echo 'No performance issues found.'; fi

    您应该会看到:No performance issues found。某些较旧的 Intel CPU 可能具有安全漏洞缓解措施,这些措施会极大地影响 Machina 的性能。

如果您的环境满足 Intel 要求,但不满足其他要求,您可以考虑增加 fx test 超时时间作为一种解决方法。

环境设置

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

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

    fx add-test //src/starnix/tests:linux_vm_tests
  3. 使用标准工作流启动无头模拟器和软件包代码库。如果您不熟悉,可以参考 设置 FEMU 指南。

运行测试

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

  • 运行所有系统调用测试套件

    fx test linux_syscalls_cpp_tests
  • 运行单个套件

    fx test linux_fcntl_test
  • 同时在 Starnix 和 Linux 上运行: 指定目标的基本名称,该名称将运行您的环境可能配置为运行的所有变体(Starnix、Machina、主机)。例如:

    fx test mount_test

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

了解日志

系统调用测试是 gTest 套件,输出通过测试框架进行管道传输。这意味着,在测试失败时,gTest 调用中的输出会显示在 stdout 中。无论结果如何,您都可以使用 fx test 调用中的 --output 实参查看所有 gTest 日志。

与 Machina 运行时相关的日志会输出到系统日志 (ffx log),并且通常与标识标记相关联。目前,所有系统调用测试都使用一个运行时,并使用 linux_guest 标记。此规则的例外情况是与内核端虚拟化相关的系统日志,例如 Zircon 虚拟机监控程序发出的日志。这些日志不会与特定于客机的标识符相关联。

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

  1. 初始客机启动

    在以下日志中,您会看到 starnix_test_runner 组件请求带有 linux_guest 标记的 Machina 客机。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. 测试作业和处理

    完成环境设置步骤后,您应该会看到发出的执行命令。这会在客机上执行 gTest 二进制文件。同样,此二进制文件执行的输出会管道传输到终端上的 stdout 中,就像您对 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. 系统调用测试在 CML 中通过 test_type: "syscall" 程序标记在 [syscalls_cpp_test.cml][syscalls-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 客机的相当标准的命令行界面。请注意,测试二进制文件和工件默认情况下将不会 出现在映像中,因为它们是由测试运行程序脚手架动态推送的。如需详细了解如何将测试二进制文件和工件放入客机,请参阅以下部分。以下是访问此 shell 的步骤:

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

    fx shell
  3. 启动 Debian 客机:

    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

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