Service de virtualisation

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.