VirtualizationService
gère toutes les machines virtuelles invitées, protégées ou non, exécutées sur un système Android, principalement en gérant des instances de crosvm. VirtualizationService
expose une API AIDL, que les services système ou les applications peuvent utiliser pour démarrer, surveiller et arrêter les machines virtuelles.
API AIDL
VirtualizationService
expose une API AIDL que les clients peuvent utiliser pour fournir des images et démarrer une machine virtuelle. Cette description peut être soit une configuration de machine virtuelle brute avec des descripteurs de fichiers pour le chargeur de démarrage ou le noyau et diverses images de disque à inclure dans la machine virtuelle, soit une configuration Microdroid où le client fournit simplement la charge utile et la machine virtuelle est démarrée avec un noyau et une infrastructure Microdroid standard. . VirtualizationService
renvoie ensuite un objet IVirtualMachine
Binder qui représente la machine virtuelle. Le client qui a démarré la VM peut choisir de partager l'objet Binder avec d'autres processus, en utilisant les mécanismes Binder habituels.
IVirtualMachine
dispose de méthodes AIDL pour obtenir des informations sur la machine virtuelle, telles que le CID, qui peut être utilisé pour communiquer avec elle via vsock, et permet également d'enregistrer un rappel à appeler lorsque la machine virtuelle s'arrête. Dans le cas des machines virtuelles IVirtualMachine
, l'objet IVirtualMachine peut également être utilisé pour configurer les connexions Binder à la machine virtuelle.
Cycle de vie des machines virtuelles
L'accès à une machine virtuelle est suivi par l'objet IVirtualMachine
. Tant qu'il y a au moins une référence à l'objet IVirtualMachine
, la machine virtuelle continue de fonctionner (à moins qu'elle ne plante ou ne s'arrête de sa propre initiative). Si toutes les références à l'objet IVirtualMachine
sont supprimées avant l'arrêt de la machine virtuelle, VirtualizationService
arrête automatiquement la machine virtuelle. Ce processus implique que si le client qui a démarré la machine virtuelle est arrêté par le tueur de mémoire faible, la machine virtuelle est également arrêtée, évitant ainsi les fuites de ressources.
Chaque machine virtuelle est gérée par sa propre instance de crosvm, que VirtualizationService
gère à son tour au nom du client. VirtualizationService
démarre ces processus enfants crosvm selon les besoins et leur transmet les descripteurs de fichier pour les images dont la machine virtuelle a besoin. VirtualizationService
surveille ensuite le processus enfant lorsqu'il meurt, afin qu'il puisse informer tous les clients restants en conséquence.
Emballage VM
crosvm prend en charge deux manières différentes de démarrer une machine virtuelle : soit un noyau et un initrd sont fournis, soit un chargeur de démarrage est fourni. Dans les deux cas, un nombre arbitraire d'images de disque peut également être fourni, qui peut être soit une image brute, soit un composite de plusieurs partitions. Les différentes images sont fournies par le client sous forme de descripteurs de fichiers.
VirtualizationService
crée des images de disque composites à la demande. Ce processus est nécessaire car le fichier de disque composite fait référence en interne aux différents fichiers image de partition composant le disque, qui sont transmis par le client et peuvent ne pas être directement accessibles par crosvm. Pour contourner ce problème, VirtualizationService
s'assure que les numéros de descripteur de fichier hérités par crosvm sont les mêmes que les numéros de descripteur de fichier que VirtualizationService a utilisés pour créer les images composites. L'image disque composite utilise des noms de fichiers sous la forme /proc/self/fd/N
pour représenter chaque fichier de partition.
Pour les pVM Microdroid, AVF inclut un chargeur de démarrage, qui charge le noyau à partir d'une partition d'une image de disque composite, en suivant le flux de démarrage vérifié Android standard.
Sockets VM (vsock)
L'interface principale de communication entre les pVM est vsock, une interface de socket virtio standard. Chaque machine virtuelle est identifiée par un identifiant de contexte (CID) 32 bits, qui est analogue à une adresse IP, que VirtualizationService
attribue à la machine virtuelle lors de la création de la machine virtuelle, et peut exposer des services sur n'importe quel numéro de port choisi par la machine virtuelle. Le CID est unique lorsque la machine virtuelle est en cours d'exécution, mais la valeur CID peut être recyclée lorsque la machine virtuelle est arrêtée et que tous les IVirtualMachine
Binder de la machine virtuelle ont été supprimés.
Interface de débogage
La commande vm
est fournie à des fins de débogage. Cette commande permet à un développeur de démarrer une machine virtuelle à partir du shell, d'afficher ses journaux et de terminer la machine virtuelle. La commande vm
inclut également une option permettant de répertorier les machines virtuelles en cours d'exécution, y compris leurs statuts et les processus associés. Cette option est implémentée en tant que méthode supplémentaire sur l'API VirtualizationService
AIDL qui, pour éviter les abus, ne peut être appelée que par l'utilisateur du shell.
AVF inclut également la prise en charge du transfert d'une connexion adb
sur vsock, afin de fournir un accès adb
aux machines virtuelles invitées. Par exemple, pour une VM Microdroid avec CID 10 exécutant adbd
sur le port 5555, le développeur peut obtenir un shell dans la VM Microdroid depuis son poste de travail avec les commandes suivantes :
$ adb forward tcp:8000 vsock:10:5555
$ adb connect localhost:8000
$ adb -s localhost:8000 shell
Le transfert d'une connexion adb
via vsock n'est disponible que pour les machines virtuelles exécutées en mode débogage.