VirtualizationService

VirtualizationService gestisce più VM guest, protette o meno, in esecuzione su un sistema Android, principalmente gestendo le istanze di crosvm. VirtualizationService espone un'API AIDL che i servizi di sistema o le app possono utilizzare per avviare, monitorare e arrestare le VM. Per utilizzare VirtualizationService, esegui virtmgr direttamente o importa javalib o rustlib che esegue virtmgr come processo figlio.

Ciclo di vita di una VM

L'accesso a una VM viene monitorato dall'oggetto IVirtualMachine. Finché esiste almeno un riferimento all'oggetto IVirtualMachine, la VM continua a essere eseguita (a meno che non si arresti in modo anomalo o si arresti di propria iniziativa). Se tutti i riferimenti all'oggetto IVirtualMachine vengono eliminati prima dell'arresto della VM, VirtualizationService arresta automaticamente la VM. Questa procedura implica che se il client che ha avviato la VM viene arrestato dal killer di memoria insufficiente, anche la VM viene arrestata, impedendo così perdite di risorse.

Ogni VM viene gestita dalla propria istanza di crosvm, che a sua volta VirtualizationService gestisce per conto del client. VirtualizationService in virtmgr avvia questi processi secondari crosvm in base alle esigenze con le risorse globali allocate incluso il CID concesso da VirtualizationServiceInternal in virtualizationservice, e passa loro i descrittori di file per le immagini di cui la VM ha bisogno. VirtualizationService monitora quindi il processo secondario per quando si arresta in modo anomalo, in modo da poter notificare di conseguenza i client rimanenti.

Packaging VM

crosvm supporta due modi diversi per avviare una VM: viene fornito un kernel e initrd oppure viene fornito un bootloader. In entrambi i casi, è possibile fornire anche un numero arbitrario di immagini disco, che potrebbero essere un'immagine non elaborata o un insieme di più partizioni. Le varie immagini vengono fornite dal client come descrittori di file.

VirtualizationService crea immagini disco composite on demand. Questa procedura è necessaria perché il file disco composito fa riferimento internamente ai vari file immagine della partizione che compongono il disco, che vengono passati dal client e potrebbero non essere accessibili direttamente da crosvm. Per risolvere questo problema, VirtualizationService garantisce che i numeri dei descrittori del file ereditati da crosvm siano gli stessi utilizzati da VirtualizationService per la creazione delle immagini composite. L'immagine disco composita utilizza nomi di file nel formato /proc/self/fd/N per rappresentare ogni file di partizione.

Per le 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 principale per la comunicazione tra le pVM è vsock, un'interfaccia socket virtio standard. Ogni VM è identificata da un identificatore di contesto (CID) a 32 bit , analogo a un indirizzo IP, che VirtualizationServiceInternal assegna alla VM quando VirtualizationService crea la VM e può esporre i servizi su qualsiasi numero di porta scelto dalla VM. Il CID è univoco durante l'esecuzione della VM, ma il valore CID può essere riciclato quando la VM viene terminata e tutti gli handle del binder IVirtualMachine alla VM sono stati eliminati.

Interfaccia di debug

Il comando vm viene fornito per scopi di debug. Questo comando consente a uno sviluppatore di avviare una VM dalla shell, visualizzarne i log e terminarla. Con il comando vm o altre interfacce fornite da AVF, una VM può essere avviata in modalità di cui è possibile eseguire il debug (FULL) o non di cui è possibile eseguire il debug (NONE). Con una VM di cui è possibile eseguire il debug, puoi visualizzare i log a livello di sistema operativo, accedere alla shell ADB e acquisire il payload di dump di arresto anomalo o dell'app. È consigliabile utilizzare una VM non di debug in produzione. Per saperne di più su llo strumento da riga di comando e su altre interfacce di debug fornite da AVF, consulta debug/README.md.