Archive for the ‘virtualizzazione’ Category
XEN High Availability
Recentemente mi sono state fatte alcune domande sulla implementazione di un piccolo cluster XEN HA. Per rispondere a quelle, e ad alcuni dubbi che possono venire quando si parla di cluster di questo tipo ho stilato una piccola guida introduttiva.

Un cluster HA XEN utilizza una SAN per condividere il disco della macchina virtuale e (almeno) due macchine XEN su cui poi si installerà il software per la realizzazione del cluster. Il passaggio di una macchina virtuale da una parte all’altra in caso di failure è effettuato attraverso migrazione. Le configurazioni delle macchine host sono del tutto indipendenti, per implementare un cluster HA non è infatti necessario avere hardware identico. Prima di fare una migrazione avviene un processo chiamato reservation: dom0 verifica sull’altro sistema se c’è spazio per allocare la macchina virtuale che vuole migrare. Questo consente banalmente di essere certi che la macchina virtuale migrata potrà eseguire sul nuovo host.
Volendo invece quantificare le risorse hardware necessarie (oltre alla SAN) è indispensabile un minimo di 2 macchine su cui è installato XEN, anche se è comunque consigliabile utilizzarne 3. Per quanto riguarda le caratteristiche di queste macchine, ipotizzando il caso più semplice con due sistemi host, bisogna calcolare tutto in modo che se una cade l’altra abbia le capacità (CPU e RAM, ecc) per gestire il carico.
Migrare macchine paravirtualizzate è un processo ottimizzato e abbastanza stabile. La migrazione di macchine HVM invece è possibile, ma c’è da considerare che, a differenza delle soluzioni paravirtualizzate, la virtual machine non è conscia della migrazione. Dunque potrebbero esserci dei problemi che dipendono dal sistema operativo installato nella vm. Per questo e per motivi di velocità è meglio migrare macchine paravirtualizzate. Infatti nell’ultima versione (XEN 4) ci sono alcun bug aperti relativi proprio alla migrazione HVM.
Virtualizzare con Parallels Workstation 4.0 Extreme
Parallels è una delle società leader nel mondo della virtualizzazione. Workstation 4.0 Extreme presenta caratteristiche molto interessanti tutte da scoprire. Vi segnalo una recensione estesa della soluzione di virtualizzazione di fascia alta di Parallels pubblicata su pctuner.net.
A voi il link all’articolo.
come redirigere porta VM sul sistema guest
in QEMU/KVM è possibile redirigere le porte della macchina virtuale all’esterno in due modi. Il primo è utilizzabile solo a macchina virtuale spenta. Avviando infatti la VM con l’opzione -redir è possibile mappare porte del sistema ospite sull’host:
kvm -hda harddisk -redir tcp:6001:10.0.2.15:22 Leggi il seguito di questo post »
Come funziona Intel Virtualization Technology: VT-x
L’architettura x86 non è virtualizzabile. Intel Virtualization Technology è una estensione del set di istruzioni che aumenta le performance e facilita la scrittura di un hypervisor. Esistono due tipi di Intel VT, VT-x per l’architettura x86, VT-i per Itanium.
Il ruolo principale di un hypervisor è quello di gestire gli accessi all’hardware per fare in modo che le risorse possano essere condivise dalle diverse macchine virtuali. Alcuni dei problemi nel virtualizzare l’architettura x86 sono:
- ring deprivileging: eseguendo una macchina virtuale come una applicazione il sistema operativo ospite esegue a un livello di privilegio che non gli è proprio.
- ring aliasing: alcune istruzioni non privilegiate vengono eseguite direttamente sul processore senza intervento dell’hypervisor.
- ring compression: il sistema operativo della macchina virtuale esegue allo stesso livello delle applicazioni
prossime frontiere della virtualizzazione
Ultimamente la ricerca nel campo della virtualizzazione si è spostata nel campo dei sistemi mobile/embedded. In pratica grandi vendor come VMWare stanno lavorando per portare gli hypervisor direttamente su cellulari e dispositivi leggeri. Ciò consentirebbe non solo l’esecuzione di sistemi operativi leggeri (Xp, Linux) sugli smartphone di ultima generazione ma potrebbe addirittura abbattere le differenze che oggi esistono tra i vari iOS, Symbian, Android, Bada.
macchina virtuale Jolicloud: scarichiamola!!
ho creato per pctuner.net una macchina virtuale del sistema operativo Jolicloud 1.1. Esso è stato giudicato il migliore tra quelli del netbook da riviste e siti del settore, perché non provarla?
7 motivi per utilizzare una virtual machine (VM)
Dopo le mie Tre volte in cui una macchina virtuale mi salvò la vita, ecco un mio nuovo articolo che riprende ed estende il concetto precedentemente espresso: Perché mai dovremmo usare una macchina virtuale?
Nelle grandi imprese la virtualizzazione viene utilizzate per ridurre costi e consumi ed aumentare la semplicità di gestione. Ma per gli utenti desktop?
Tre volte in cui una macchina virtuale mi salvò la vita
Ovviamente in senso metaforico, più di una volta mi sono servito della virtualizzazione per semplificare e molto la risoluzione di piccoli e grandi problemi.
Ve li elenco qui di seguito :
VMware Workstation: il principe della virtualizzazione desktop
come sempre posto il link alla review che ho scritto per pctuner.net..buona lettura
link
Uno scheduler per XEN
questo è uno scheduler (random) per XEN. Il suo valore è semplicemente accademico senza alcuna applicazione pratica.
This is a random scheduler for XEN. I wrote this scheduler for academic purposes only.
/****************************************************************************
* (C) 2010 - Michele Paolino
****************************************************************************
*
* File: common/sched_random.c
* Author: Michele Paolino
*
* Description: Random CPU scheduler
*/
#include <xen/lib.h>
#include <xen/sched.h>
#include <xen/time.h>
#include <xen/sched-if.h>
#include <xen/softirq.h>
#include <xen/errno.h>
#include <xen/list.h>
#include <xen/timer.h>
#include <xen/randmd5.h>
int tot_vcpu=0;
MD5_CTX mdContext;
#define RAND_PCPU(_c) ((struct random_pcpu *)per_cpu(schedule_data, _c).sched_priv)
#define RAND_VCPU(_vcpu) ((struct random_vcpu *) (_vcpu)->sched_priv)
#define RUNQ(_cpu) (&(RAND_PCPU(_cpu)->runq))
struct random_pcpu {
struct list_head runq;
};
struct random_vcpu{
struct list_head runq_elem;
struct vcpu *vcpu;
};
static inline void __runq_tickle(unsigned int cpu, struct random_vcpu *new)
{
struct random_vcpu * const cur = RAND_VCPU(per_cpu(schedule_data, cpu).curr);
cpumask_t mask;
ASSERT(cur);
cpus_clear(mask);
printk("\nTickle vcpu %d\n", cur->vcpu->vcpu_id);
if ( vcpu_runnable(cur->vcpu) )
{
cpu_set(cpu, mask);
printk("\nI'm setting the mask for the current vcpu\n");
}
/* Send scheduler interrupts to designated CPUs */
if ( !cpus_empty(mask) ){
printk("\nRaising softirq\n");
cpumask_raise_softirq(mask, SCHEDULE_SOFTIRQ);
}
}
static inline int __vcpu_on_runq(struct random_vcpu *svc)
{
return !list_empty(&svc->runq_elem);
}
static inline void __runq_insert(unsigned int cpu, struct random_vcpu *svc)
{
struct list_head *runq = RUNQ(cpu);
BUG_ON( cpu != svc->vcpu->processor );
if (!__vcpu_on_runq(svc)) list_add(&svc->runq_elem,runq);
return;
}
static inline void __runq_remove(struct random_vcpu *svc)
{
BUG_ON( !__vcpu_on_runq(svc) );
list_del_init(&svc->runq_elem);
}
static inline void __random_vcpu_check(struct vcpu *vc)
{
struct random_vcpu * const svc = RAND_VCPU(vc);
BUG_ON( (svc->vcpu) != vc );
}
static int random_pcpu_init(int cpu)
{
struct random_pcpu *spc;
/* Allocate per-PCPU info */
spc = xmalloc(struct random_pcpu);
if ( spc == NULL )
return -1;
memset(spc, 0, sizeof(*spc));
INIT_LIST_HEAD(&spc->runq);
per_cpu(schedule_data, cpu).sched_priv = spc;
return 0;
}
static int random_vcpu_init(struct vcpu *vc){
struct random_vcpu *svc;
svc = xmalloc(struct random_vcpu);
if ( svc == NULL )
return -1;
memset(svc, 0, sizeof(*svc));
INIT_LIST_HEAD(&svc->runq_elem);
svc->vcpu = vc;
vc->sched_priv = svc;
/* Allocate per-PCPU info */
if ( unlikely(!RAND_PCPU(vc->processor)) )
{
if ( random_pcpu_init(vc->processor) != 0 )
return -1;
}
__random_vcpu_check(vc);
tot_vcpu++;
printk("\nadd VCPU %d tot_vcpu=%d\n", vc->vcpu_id, tot_vcpu);
return 0;
}
static void random_vcpu_destroy(struct vcpu *vc)
{
struct random_vcpu * const svc = RAND_VCPU(vc);
printk("\n\nDestroying vcpu %d\n\n",vc->vcpu_id);
tot_vcpu--;
BUG_ON( !list_empty(&svc->runq_elem) );
list_del(&svc->runq_elem);
xfree(svc);
}
struct task_slice random_schedule(s_time_t now){
const unsigned int cpu = smp_processor_id();
struct list_head * runq = RUNQ(cpu);
struct random_vcpu * const scurr = RAND_VCPU(current);
struct random_vcpu *snext;
struct task_slice ret;
int next_vcpu=0;
next_vcpu = (MD5Final (&mdContext)) % tot_vcpu;
__random_vcpu_check(current);
if ( vcpu_runnable(current) )
__runq_insert(cpu, scurr);
else
BUG_ON( is_idle_vcpu(current) || list_empty(runq) );
while (next_vcpu!=0){
next_vcpu--;
list_move(runq, runq->next);
}
snext = list_entry(runq->next, struct random_vcpu, runq_elem);
__runq_remove(snext);
ret.time = MILLISECS(10);
ret.task=snext->vcpu;
__random_vcpu_check(current);
return ret;
}
static void __random_init(void){
unsigned char digest[16];
int i;
long unsigned int mask= 0xFF;
long unsigned int string_now = NOW();
MD5Init (&mdContext);
for (i=0;i<8;i++){
digest[i]=(char) ((string_now & mask) >> 8*i);
mask <<=8;
}
MD5Update (&mdContext, (unsigned char*)digest, sizeof(s_time_t));
}
static void random_vcpu_wake( struct vcpu *vc){
struct random_vcpu * const svc = RAND_VCPU(vc);
const unsigned int cpu = vc->processor;
BUG_ON ( is_idle_vcpu(vc) );
/* Put the VCPU on the runq and tickle CPUs */
__runq_insert(cpu, svc); //inserisco in coda
__runq_tickle(cpu, svc); // raise softirq
return;
}
static void random_vcpu_sleep(struct vcpu *vc)
{
struct random_vcpu * const svc = RAND_VCPU(vc);
printk("Sleeping..\n");
BUG_ON( is_idle_vcpu(vc) );
if ( per_cpu(schedule_data, vc->processor).curr == vc )
cpu_raise_softirq(vc->processor, SCHEDULE_SOFTIRQ);
else if ( __vcpu_on_runq(svc) )
__runq_remove(svc);
}
static void random_init(void)
{
tot_vcpu=0;
__random_init();
}
struct scheduler sched_rand_def = {
.name = "Random Scheduler",
.opt_name = "random",
.sched_id = 17,
.init_vcpu = random_vcpu_init,
.wake = random_vcpu_wake,
.sleep = random_vcpu_sleep,
.destroy_vcpu = random_vcpu_destroy,
.do_schedule = random_schedule,
.init = random_init,
};





