VirtualizationService

VirtualizationService administra varias VMs invitadas, 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 VMs. Para usar VirtualizationService, ejecuta virtmgr directamente o importa javalib o rustlib, que ejecuta virtmgr como un proceso secundario.

Ciclo de vida de la VM

El objeto IVirtualMachine hace un seguimiento del acceso a una VM. Mientras haya al menos una referencia al objeto IVirtualMachine, la VM seguirá ejecutándose (a menos que falle o se cierre por sí sola). Si se descartan todas las referencias al objeto IVirtualMachine antes de que se apague la VM, VirtualizationService apagará automáticamente la VM. Este proceso implica que, si el cliente que inició la VM se cierra por el proceso de eliminación por falta de memoria, la VM también se cierra, lo que evita pérdidas de recursos.

Cada VM se administra con su propia instancia de crosvm, que, a su vez, VirtualizationService 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 hasta que finaliza para poder notificar a los clientes restantes según corresponda.

Empaquetado de la VM

crosvm admite dos formas diferentes de iniciar una VM: se proporciona un kernel y un initrd, o se proporciona un cargador de arranque. En cualquier caso, también se puede proporcionar una cantidad arbitraria de imágenes de disco, que pueden ser una imagen sin procesar o una composición de varias particiones. El cliente proporciona las distintas 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 internamente a los distintos archivos de imagen de partición que componen el disco, que el cliente pasa y a los que crosvm podría no acceder directamente. Para solucionar este problema, VirtualizationService garantiza que los números de descriptores de archivos heredados por crosvm sean los mismos que los que VirtualizationService usó para crear las imágenes compuestas. La imagen de disco compuesta usa nombres de archivo con 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 estándar de Inicio verificado de Android.

Sockets 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 los números de puerto que elija la VM. El CID es único mientras la VM se ejecuta, pero el valor del CID se puede reciclar cuando se finaliza la VM y se descartan todos los identificadores de vinculador IVirtualMachine a la VM.

Interfaz de depuración

El comando vm se proporciona para fines de depuración. Este comando permite que un desarrollador inicie una VM desde el shell, vea sus registros y la finalice. Con el comando vm o cualquier otra interfaz que proporcione AVF, una VM puede iniciarse en modo depurable (FULL) o no depurable (NONE). Con una VM depurable, puedes ver los registros a nivel del SO, acceder al shell de ADB y capturar el volcado de memoria ante fallas o la carga útil de la app. Se recomienda usar una VM que no se pueda depurar 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.