La virtualizzazione dei sistemi operativi – Capitolo 3.2.2

La virtualizzazione della CPU presenta diverse implicazioni per i sistemi operativi guest. Principalmente, l’inserimento di un hypervisor al di sotto del sistema operativo viola il principio per cui il sistema operativo deve essere eseguito con il privilegio maggiore. Per proteggere l’hypervisor da comportamenti inaspettati dei sistemi operativi guest e per garantire isolamento tra le macchine virtuali, essi devono essere eseguiti con privilegi inferiori.

Questo è possibile sull’architettura x86 che supporta quattro distinti livelli di privilegio chiamati rings. Il livello 0 con privilegi massimi e altri tre meno privilegiati. È pratica comune che il sistema operativo venga eseguito nel ring 0 e le applicazioni sul ring 3. I ring 1 e 2 non sono utilizzati. Gli unici esempi di sistemi operativi che utilizzavano il ring 1 e 2 furono Novell e OS/2.

Qualsiasi sistema operativo che opera solamente a ring 0 può essere modificato per lavorare sul ring 1 ed essere paravirtualizzato (o virtualizzato) con Xen. In questo modo il sistema operativo non può eseguire direttamente le istruzioni privilegiate, ma rimane comunque isolato dalle applicazione che lavorano sul ring 3.


Fig.3.9: i protection ring nell’architettura x86 fisica e con la paravirtualizzazione di Xen.

Le istruzioni privilegiate sono paravirtualizzate e la loro esecuzione deve essere validata da Xen. Un’istruzione privilegiata eseguita direttamente dal sistema operativo guest fallisce per privilegi insufficienti.

Le eccezioni, inclusi i memory faults e le trap, sono facilmente virtualizzate nell’architettura x86. Xen dispone di una tabella che descrive le modalità di gestione di ogni tipo di eccezione. Essa è generalmente identica a quella presente nell’ambiente non virtualizzato.

Una delle differenza più importanti riguarda la gestione degli errori di pagina (page fault), per la quale si legge abitualmente il registro CR2 per recuperare l’indirizzo della pagina che ha causato l’errore. Dato che questo non è possibile, in quanto il sistema operativo guest eseguito in ring 1 non ha accesso a tale registro, Xen scrive l’informazione in una zona diversa. Questa tecnica permette di trattare gli errori di pagina in modo efficiente, senza penalizzare le prestazioni, visto che i page fault si verificano con elevata frequenza.

Un’altra eccezione che avviene con un ritmo tale da influenzare le prestazioni del sistema è l’invocazione di una system call. Xen ha migliorato le performance delle system calls, permettendo a ciascun sistema operativo guest di salvare il gestore dell’eccezione in un’area al quale il processore può accedere senza aumentare il privilegio a ring 0.

Lo scheduling delle CPU tra le macchine virtuali

È possibile scegliere tra diverse tecniche di allocazione delle CPU tra le varie macchine virtuali. Di seguito elenco le tre attualmente in uso.

Borrowed Virtual Time

La prima è basata su un algoritmo chiamato Borrowed Virtual Time. La scelta di questo algoritmo è dovuta al fatto che è work-conserving, ossia che alloca tutti i processori fisici disponibili garantendone la copertura, ed è dotato di un sistema di ripresa immediata di un Domain U nel momento in cui questo riceve un evento di notifica. Attraverso questa tecnica è possibile assegnare a ciascun Domain U una quota definita in base ad un peso relativo. Attraverso questo parametro viene assegnato ad ogni sistema operativo guest un virtual time slot che viene calcolato anche in considerazione degli eventi in corso, ad esempio il fatto che altri sistemi operativi guest sono in fase di avvio o di spegnimento.

Simple Earliest Deadline First

La seconda è chiamata SEDF (Simple Earliest Deadline First) e supporta l’allocazione sia work-conservative, sia non-work-conservative. È possibile quindi assegnare a un Domain U il 50% di una CPU e non di più. La macchina virtuale non supererà quella soglia, anche se non ci sono altri sistemi operativi guest in esecuzione sull’host fisico.

Come nel Borrowed virtual time, è possibile assegnare delle priorità tra le varie macchine virtuali utilizzando il concetto di slice e di period (ad esempio 20ms di slice su 100ms di period).

Credit Scheduler

La terza è detta Credit Scheduler e anche questa supporta l’assegnamento work-conservative e non-work-conservative.

Per garantire livelli di priorità tra le macchine virtuali utilizza il concetto di weight e di cap. Il weight è un parametro proporzionale per cui domain U che ha un weight di 512 riceve tempo di CPU doppio rispetto a quella con 256 (quota di default). Il cap è un parametro opzionale e fissa la quota massima che un domain U è in grado di utilizzare. Ad esempio 100 è l’utilizzo di una CPU, 50 di mezza e 400 di 4 CPU. Il default è 0 e significa che non sono imposti limiti di utilizzo.

Notizie: abbiamo molto da raccontare