VirtualizationService
verwaltet alle Gast-VMs, ob geschützt oder anderweitig, die auf einem Android-System ausgeführt werden, hauptsächlich durch die Verwaltung von crosvm-Instanzen. VirtualizationService
stellt eine AIDL-API bereit, die Systemdienste oder Apps zum Starten, Überwachen und Beenden von VMs verwenden können.
AIDL-API
VirtualizationService
stellt eine AIDL-API bereit, die Clients verwenden können, um Images bereitzustellen und eine VM zu starten. Diese Beschreibung kann entweder eine rohe VM-Konfiguration mit Dateideskriptoren für den Bootloader oder Kernel und verschiedene Disk-Images sein, die in die VM aufgenommen werden sollen, oder eine Microdroid-Konfiguration, bei der der Client nur die Nutzlast bereitstellt und die VM mit einem Standard-Microdroid-Kernel und einer Infrastruktur gestartet wird . VirtualizationService
gibt dann ein IVirtualMachine
Binder-Objekt zurück, das die VM darstellt. Der Client, der die VM gestartet hat, kann wählen, ob er das Binder-Objekt mit anderen Prozessen gemeinsam nutzen möchte, indem er die üblichen Binder-Mechanismen verwendet.
IVirtualMachine
verfügt über AIDL-Methoden zum Abrufen von Informationen über die VM, z. B. die CID, die zur Kommunikation mit ihr über vsock verwendet werden kann, und ermöglicht auch die Registrierung eines Rückrufs, der aufgerufen wird, wenn die VM anhält. Bei Microdroid-VMs kann das IVirtualMachine
Objekt auch verwendet werden, um Binder-Verbindungen zur VM einzurichten.
VM-Lebenszyklus
Der Zugriff auf eine VM wird vom IVirtualMachine
Objekt nachverfolgt. Solange es mindestens einen Verweis auf das IVirtualMachine
Objekt gibt, wird die VM weiter ausgeführt (es sei denn, sie stürzt ab oder wird von selbst heruntergefahren). Wenn alle Verweise auf das IVirtualMachine
Objekt gelöscht werden, bevor die VM heruntergefahren wird, fährt VirtualizationService
die VM automatisch herunter. Dieser Prozess impliziert, dass, wenn der Client, der die VM gestartet hat, durch den Low-Memory-Killer heruntergefahren wird, die VM ebenfalls heruntergefahren wird, wodurch Ressourcenlecks verhindert werden.
Jede VM wird von einer eigenen Instanz von crosvm verwaltet, die VirtualizationService
wiederum im Auftrag des Clients verwaltet. VirtualizationService
startet diese untergeordneten crosvm-Prozesse nach Bedarf und übergibt ihnen die Dateideskriptoren für die Images, die die VM benötigt. VirtualizationService
überwacht dann den untergeordneten Prozess darauf, wann er stirbt, sodass er alle verbleibenden Clients entsprechend benachrichtigen kann.
VM-Verpackung
crosvm unterstützt zwei verschiedene Möglichkeiten, eine VM zu booten: Entweder werden ein Kernel und eine initrd bereitgestellt, oder es wird ein Bootloader bereitgestellt. In beiden Fällen kann auch eine beliebige Anzahl von Disk-Images bereitgestellt werden, die entweder ein Raw-Image oder ein Verbund aus mehreren Partitionen sein können. Die verschiedenen Bilder werden vom Client als Dateideskriptoren bereitgestellt.
VirtualizationService
erstellt zusammengesetzte Disk-Images nach Bedarf. Dieser Vorgang ist notwendig, da die zusammengesetzte Festplattendatei intern auf die verschiedenen Partitions-Image-Dateien verweist, aus denen die Festplatte besteht, die vom Client übergeben werden und möglicherweise nicht direkt von crosvm zugänglich sind. Um dieses Problem zu umgehen, stellt VirtualizationService
sicher, dass die von crosvm geerbten Dateideskriptornummern mit den Dateideskriptornummern übereinstimmen, die VirtualizationService beim Erstellen der zusammengesetzten Images verwendet hat. Das zusammengesetzte Disk-Image verwendet Dateinamen in der Form /proc/self/fd/N
, um jede Partitionsdatei darzustellen.
Für Microdroid-pVMs enthält AVF einen Bootloader, der den Kernel von einer Partition eines zusammengesetzten Disk-Images lädt und dabei dem standardmäßigen Android Verified Boot-Flow folgt.
VM-Sockets (vsock)
Die primäre Schnittstelle für die Kommunikation zwischen pVMs ist vsock, eine standardmäßige Virtio-Socket-Schnittstelle. Jede VM wird durch eine 32-Bit-Kontextkennung (CID) identifiziert, die analog zu einer IP-Adresse ist, die VirtualizationService
der VM zuweist, wenn die VM erstellt wird, und Dienste auf den von der VM gewählten Portnummern verfügbar machen kann. Die CID ist eindeutig, während die VM ausgeführt wird, aber der CID-Wert kann wiederverwendet werden, wenn die VM beendet wird und alle IVirtualMachine
Binder-Handles für die VM gelöscht wurden.
Debug-Schnittstelle
Der vm
Befehl wird zu Debug-Zwecken bereitgestellt. Mit diesem Befehl kann ein Entwickler eine VM über die Shell starten, ihre Protokolle anzeigen und die VM beenden. Der Befehl vm
enthält auch eine Option zum Auflisten aktuell ausgeführter VMs, einschließlich ihres Status und der zugehörigen Prozesse. Diese Option ist als zusätzliche Methode auf der AIDL-API des VirtualizationService
implementiert, die zur Vermeidung von Missbrauch nur vom Shell-Benutzer aufgerufen werden kann.
AVF umfasst auch Unterstützung für die Weiterleitung einer adb
-Verbindung über vsock, um adb
-Zugriff auf Gast-VMs bereitzustellen. Für eine Microdroid-VM mit CID 10, auf der adbd
auf Port 5555 ausgeführt wird, kann der Entwickler beispielsweise mit den folgenden Befehlen eine Shell in der Microdroid-VM von seiner Workstation abrufen:
$ adb forward tcp:8000 vsock:10:5555
$ adb connect localhost:8000
$ adb -s localhost:8000 shell
Das Weiterleiten einer adb
-Verbindung über vsock ist nur für VMs verfügbar, die im Debugmodus ausgeführt werden.