VirtualizationService
主要通过管理 crosvm 实例来管理在 Android 系统上运行的多个访客虚拟机(受保护的或其他虚拟机)。VirtualizationService
公开了 AIDL API,系统服务或应用可以使用该 API 来启动、监控和停止虚拟机。要使用 VirtualizationService
,请直接执行 virtmgr
,或导入 javalib 或 rustlib,它们会将 virtmgr
作为子进程执行。
虚拟机生命周期
对虚拟机的访问由 IVirtualMachine
对象跟踪。只要至少有一个对 IVirtualMachine
对象的引用,虚拟机就会继续运行(除非它崩溃或自行关闭)。如果在虚拟机关闭之前,对 IVirtualMachine
对象的所有引用都已删除,则 VirtualizationService
会自动关闭虚拟机。此过程意味着,如果启动虚拟机的客户端被低内存终止程序关闭,则虚拟机也会被关闭,从而防止资源泄漏。
每个虚拟机都由其自身的 crosvm 实例管理,而 VirtualizationService
又代表客户端管理该实例。VirtualizationService
在 virtmgr
中根据需要启动这些 crosvm 子进程,并分配全局资源(包括由 virtualizationservice
中的 VirtualizationServiceInternal
授予的 CID),并将虚拟机所需的映像的文件描述符传递给它们。VirtualizationService
随后会监控子进程的终止时间,以便它可以相应地通知任何剩余的客户端。
虚拟机打包
crosvm 支持两种不同的虚拟机启动方式:提供内核和 initrd,或提供启动加载程序。在这两种情况下,也可以提供任意数量的磁盘映像,磁盘映像可以是原始映像,也可以是多个分区的组合。各种映像由客户端以文件描述符的形式提供。
VirtualizationService
按需构建复合磁盘镜像。这个过程是必要的,因为复合磁盘文件在内部引用构成磁盘的各种分区镜像文件,这些文件由客户端传递,并且可能无法被 crosvm 直接访问。为了解决这个问题,VirtualizationService
确保 crosvm 继承的文件描述符编号与 VirtualizationService
在创建复合镜像时使用的文件描述符编号相同。复合磁盘镜像使用 /proc/self/fd/N
形式的文件名来表示每个分区文件。
对于 Microdroid pVM,AVF 包含一个引导加载程序,该程序遵循标准的 Android Verified Boot 流程,从复合磁盘镜像的分区加载内核。
VM 套接字 (vsock)
pVM 之间通信的主要接口是 vsock,一种标准的 virtio 套接字接口。每个 VM 由一个 32 位上下文标识符 (CID) 标识,它类似于 IP 地址。VirtualizationServiceInternal
在 VirtualizationService
创建 VM 时将 CID 分配给 VM,并且可以在 VM 选择的任何端口号上公开服务。CID 在 VM 运行时是唯一的,但是当 VM 终止并且所有指向 VM 的 IVirtualMachine
binder 句柄都被丢弃时,CID 值可以被回收。
调试接口
提供了 vm
命令用于调试目的。此命令允许开发人员从 shell 启动 VM,查看其日志并终止 VM。使用 vm
命令或 AVF 提供的其他接口,VM 可以以可调试 (FULL) 或不可调试 (NONE) 模式启动。使用可调试 VM,您可以查看操作系统级别的日志,访问 ADB shell,并捕获崩溃转储或应用程序有效负载。建议在生产环境中使用不可调试 VM。有关命令行工具和 AVF 提供的其他调试接口的更多信息,请参阅 debug/README.md。