Servicio de virtualización

VirtualizationService administra varias VMs de invitado, protegidas o no, que se ejecutan en un sistema Android, principalmente a través de la administración de instancias de crosvm. VirtualizationService expone una API de AIDL, que los servicios del sistema o las apps pueden usar para iniciar, supervisar y detener VM. Para usar VirtualizationService, ejecuta virtmgr directamente o importa javalib o rustlib, que ejecuta virtmgr como un proceso secundario.

Ciclo de vida de las VMs

El objeto IVirtualMachine realiza un seguimiento del acceso a una VM. Siempre que haya al menos una referencia al objeto IVirtualMachine, la VM continuará ejecutándose (a menos que falle o se apague por su cuenta). Si todas las referencias al objeto IVirtualMachine se descartan antes de que la VM se apague, VirtualizationService la cierra de forma automática. Este proceso implica que, si el asesino de memoria baja cierra el cliente que inició la VM, esta también se cierra, lo que evita fugas de recursos.

Cada VM está administrada por su propia instancia de crosvm, que VirtualizationService a su vez administra en nombre del cliente. VirtualizationService en virtmgr inicia estos procesos secundarios de crosvm según sea necesario con recursos globales asignados, incluido el CID que otorga VirtualizationServiceInternal en virtualizationservice, y les pasa los descriptores de archivos para las imágenes que necesita la VM. Luego, VirtualizationService supervisa el proceso secundario para detectar cuándo finaliza, de modo que pueda notificar a los clientes restantes según corresponda.

Empaque de VM

crosvm admite dos formas diferentes de iniciar una VM: se proporciona un kernel y un initrd, o bien un bootloader. En cualquier caso, también se puede proporcionar una cantidad arbitraria de imágenes de disco, que pueden ser una imagen sin procesar o un compuesto de varias particiones. El cliente proporciona las diferentes imágenes como descriptores de archivos.

VirtualizationService compila imágenes de disco compuestas a pedido. Este proceso es necesario porque el archivo de disco compuesto hace referencia de forma interna a los diversos archivos de imagen de partición que componen el disco, que pasa el cliente y a los que crosvm podría no tener acceso directo. Para evitar este problema, VirtualizationService garantiza que los números del descriptor de archivos que hereda Crosvm sean los mismos que los números del descriptor de archivos que VirtualizationService usó para crear las imágenes compuestas. La imagen de disco compuesta usa nombres de archivo en el formato /proc/self/fd/N para representar cada archivo de partición.

En el caso de las pVM de Microdroid, AVF incluye un bootloader, que carga el kernel desde una partición de una imagen de disco compuesta, siguiendo el flujo de inicio verificado estándar de Android.

Zócalos de VM (vsock)

La interfaz principal para la comunicación entre las pVM es vsock, una interfaz de socket virtio estándar. Cada VM se identifica con un identificador de contexto (CID) de 32 bits, que es análogo a una dirección IP, que VirtualizationServiceInternal asigna a la VM cuando VirtualizationService crea la VM y puede exponer servicios en el número de puerto que elija la VM. El CID es único mientras la VM está en ejecución, pero su valor se puede reciclar cuando la VM se finaliza y todos los controladores de Binder IVirtualMachine de la VM se descartan.

Interfaz de depuración

El comando vm se proporciona para fines de depuración. Este comando permite que un desarrollador inicie una VM desde la shell, vea sus registros y la finalice. Con el comando vm o con otras interfaces que proporciona AVF, una VM puede iniciarse en modo depurable (FULL) o no depurable (NONE). Con una VM depurable, puedes ver registros a nivel del SO, acceder a la shell de ADB y capturar volcados de fallas o cargas útiles de la app. Se recomienda usar una VM no depurable en producción. Para obtener más información sobre la herramienta de línea de comandos y otras interfaces de depuración que proporciona AVF, consulta debug/README.md.