VirtualizationService
gestisce più VM guest, protette o meno, in esecuzione su un sistema Android, principalmente gestendo istanze di crosvm. VirtualizationService
espone un'API AIDL che i servizi di sistema o le app possono utilizzare per avviare, monitorare e arrestare le macchine virtuali. Per utilizzare VirtualizationService
, eseguire direttamente virtmgr
o importare javalib o rugginelib che esegue virtmgr
come processo figlio.
Ciclo di vita delle macchine virtuali
L'accesso a una macchina virtuale viene monitorato dall'oggetto IVirtualMachine
. Finché è presente almeno un riferimento all'oggetto IVirtualMachine
, la VM continua a funzionare (a meno che non si arresti in modo anomalo o si spenga da sola). Se tutti i riferimenti all'oggetto IVirtualMachine
vengono eliminati prima dell'arresto della macchina virtuale, VirtualizationService
arresta automaticamente la macchina virtuale. Questo processo implica che se il client che ha avviato la VM viene arrestato dal killer con memoria insufficiente, anche la VM verrà arrestata, evitando così perdite di risorse.
Ogni VM è gestita dalla propria istanza di crosvm, che VirtualizationService
a sua volta gestisce per conto del client. VirtualizationService
in virtmgr
avvia questi processi secondari crosvm come richiesto con le risorse globali allocate incluso il CID concesso da VirtualizationServiceInternal
in virtualizationservice
e passa loro i descrittori di file per le immagini necessarie alla VM. VirtualizationService
monitora quindi il processo figlio per quando muore, in modo che possa avvisare di conseguenza tutti i client rimanenti.
Confezione della macchina virtuale
crosvm supporta due diversi modi di avviare una VM: vengono forniti un kernel e initrd oppure viene fornito un bootloader. In entrambi i casi, può essere fornito anche un numero arbitrario di immagini del disco, che potrebbe essere un'immagine grezza o un composto di diverse partizioni. Le varie immagini vengono fornite dal cliente come descrittori di file.
VirtualizationService
crea immagini del disco composito su richiesta. Questo processo è necessario perché il file del disco composito fa riferimento internamente ai vari file immagine della partizione che compongono il disco, che vengono passati dal client e potrebbero non essere direttamente accessibili da crosvm. Per aggirare questo problema, VirtualizationService
garantisce che i numeri dei descrittori di file ereditati da crosvm siano gli stessi dei numeri dei descrittori di file utilizzati VirtualizationService
nella creazione delle immagini composite. L'immagine del disco composito utilizza nomi di file nel formato /proc/self/fd/N
per rappresentare ciascun file di partizione.
Per i pVM Microdroid, AVF include un bootloader, che carica il kernel da una partizione di un'immagine disco composita, seguendo il flusso standard di avvio verificato di Android.
Socket VM (vsock)
L'interfaccia primaria per la comunicazione tra pVM è vsock, un'interfaccia socket virtio standard. Ogni VM è identificata da un identificatore di contesto a 32 bit (CID), analogo a un indirizzo IP, che VirtualizationServiceInternal
assegna alla VM quando VirtualizationService
crea la VM e può esporre servizi su qualsiasi numero di porta scelto dalla VM. Il CID è univoco mentre la VM è in esecuzione, ma il valore CID può essere riciclato quando la VM viene terminata e tutti gli handle del raccoglitore IVirtualMachine
sulla VM sono stati eliminati.
Interfaccia di debug
Il comando vm
viene fornito a scopo di debug. Questo comando consente a uno sviluppatore di avviare una VM dalla shell, visualizzarne i log e terminare la VM. Con il comando vm
o altre interfacce fornite da AVF, una VM può essere avviata in modalità debugging (FULL) o non debugging (NONE). Con la VM debuggabile, puoi visualizzare i log a livello di sistema operativo, accedere alla shell ADB e acquisire crash-dump o payload dell'app. Si consiglia di utilizzare una macchina virtuale non debuggabile in produzione. Per ulteriori informazioni sullo strumento da riga di comando e sulle altre interfacce di debug fornite da AVF, vedere debug/README.md .