Difference between revisions of "2018 Spring Term"

From vsd
Jump to navigation Jump to search
 
(51 intermediate revisions by 3 users not shown)
Line 49: Line 49:
  
 
== March 01 2018 ==
 
== March 01 2018 ==
 
[https://etherpad.wikimedia.org/p/W8ZohgqjJy etherpad]
 
  
 
===INFO===
 
===INFO===
Line 123: Line 121:
  
 
== March 06 2018 ==
 
== March 06 2018 ==
[https://etherpad.wikimedia.org/p/avNnD5LhXk Eterpad 06/03/2018]
+
 
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EcBK9t59dgVEjB6Y-Lx2tAEBaQ2THtSBZZk9W7p9j5cVSQ?e=tHE25e Registrazione 06/03/2018]
 +
 
 +
===I requisiti di virtualizzazione===
 +
 
 +
[https://en.wikipedia.org/wiki/Popek_and_Goldberg_virtualization_requirements I requisiti di virtualizzazione di Popek e Goldberg] sono delle condizioni sufficienti per un'architettura per supportare la virtualizzazione (in modo efficiente):
 +
 
 +
* '''Equivalenza / Fedeltà''' - Un programma virtualizzato dovrebbe esibire un comportamento essenzialmente identico a quello dimostrato quando viene eseguito su una macchina equivalente direttamente.
 +
 
 +
* '''Controllo delle risorse / Sicurezza''' - L'hypervisor deve avere il completo controllo delle risorse virtualizzate.
 +
 
 +
* '''Efficienza / Performance'''
 +
 
 +
Davoli: "Il livello di sicurezza richiesto dipende dall'applicazione"
 +
 
 +
Popek e Goldberg descrivono anche le caratteristiche che l'ISA della macchina ospite deve possedere per essere in grado di far girare un hypervisor che goda dei tre requisiti precedenti.
 +
 
 +
===Teoremi di virtualizzazione===
 +
 
 +
Le istruzioni di un'ISA sono classificate in tre gruppi:
 +
# '''Istruzioni privilegiate''' - le istruzioni che generano una trap se il processore è in '''user mode''' e non generano una trap se il processore è in '''kernel mode''' (e.g. divisione per zero, system call, accesso ad indirizzo di memoria non mappato).
 +
# '''Istruzioni control sensitive''' - le istruzioni che cercano di cambiare la configurazione delle risorse del sistema (e.g. assegnare memoria, acquisire una risorsa).
 +
# '''Istruzioni behavior sensitive''' - istruzioni che hanno comportamenti diversi a seconda della configurazione delle risorse (e.g. istruzioni che dipendono dal valore del registro di rilocazione o dalla modalità di esecuzione del processore).
 +
 
 +
====Teorema relativo alle istruzioni privilegiate====
 +
Si può creare una VM effettiva se e solo se le istruzioni privilegiate sono un sovrainsieme dell'unione delle istruzioni degli altri due tipi; in altre parole tutte le istruzioni "sensitive" generano una trap se eseguite in user mode.
 +
<br>Le istruzioni '''sensitive''' sono quelle che possono influenzare il corretto funzionamento dell'hypervisor. Queste istruzioni devono essere tutte privilegiate.
 +
<br>Le istruzioni '''control sensitive''' devono essere privilegiate perché il processo virtualizzato non deve essere in grado di allocare nuove risorse a sè stesso.
 +
<br>Le istruzioni '''behavior sensitive''' devono essere privilegiate perché il processo virtualizzato deve vedere ...
 +
 
 +
 
 +
(IBM Introduce le maccine virtuali per introdurre sistemi operativi multitasking su macchine monotask)
 +
 
 +
<br>Negli anni 90 si producono processori senza considerare il teorema di Popek e Goldberg. L'ISA di questi processori non soddisfaceva le condizioni del teorema.
 +
Vengono aggiunte istruzioni di virtualizzazione (da usare in ambienti virtuali) che non sono altro che le corrispettive istruzioni privilegiate delle istruzioni sensitive non privilegiate.
 +
 
 +
(''Robert P. Goldberg: Architectural Principles for Virtual Computer Systems'')
 +
 
 +
È difficile fare virtualizzazione tramite l'emulazione (problemi di efficienza).
 +
 
 +
L''''emulazione''' consiste nell'emulare ogni singola funzione del sistema operativo e lo traduce per il livello sottostante.
 +
<br>La '''simulazione''' consiste nel convertire il codice assembler per un certo processore in codice macchina del processore di base.
 +
<br>Simulatore: apparenza (Simulatore di volo)
 +
<br>Emulatore: funzione effettiva e veritiera al 100% ma per questa molto più lenta (Ali di cera del racconto greco)
 +
 
 +
Qemu può funzionare in due modalità:
 +
* Macchina virtuale: virtualità al livello di sistema (qemu-system-*).
 +
* Virtualizzare solo il processore: tutte le system call sono gestite dal sistema operativo reale (qemu-*).
 +
 
 +
Esperimento: Prendere busybox per architettura arm ed eseguirlo anche se siamo su un intel
 +
<br>Busybox: eseguibile che fa da contenitore per molti comandi. Permette di risparmiare RAM e disco.
 +
<br>Sistemi embedded: spesso fatti con kernel + busybox + applicazione per cui è nato il sistema.
 +
 
 +
 
 +
[https://www.finnix.org/ARM Finnix arm]
 +
Per far partire Finnix su Arm occorre prendere dall'immagine del file system dei file che servono all'esterno.
 +
Per far partire un sistema occorre sicuramente il kernel e poi in molti casi (non tutti) il file system.
 +
Il kernel viene caricato dal boot loader.
 +
 
 +
<syntaxhighlight lang="c">
 +
qemu-system-arm -display none -machine vexpress-a9 -m 256 \
 +
-kernel linux -initrd initrd.xz -dtb vexpress-v2p-ca9.dtb \
 +
-append "console=ttyAMA0,115200" -serial stdio \
 +
-drive file=finnix-armhf.iso,id=cd0,format=raw \
 +
-device virtio-blk-device,drive=cd0
 +
</syntaxhighlight>
 +
 
 +
 
 +
kernel linux --> cerca nella directory corrente un file "linux" contenente il kernel
 +
 
 +
 
 +
'''initrd''' è un file di configurazione che contiene i moduli kernel usato per l'inizializzazione.
 +
<br>Perché nasce initrd?
 +
<br>Il kernel quando fa boot ha bisogno dei driver per tutti i device che servono per caricare il kernel.
 +
Se vogliamo progettare un kernel che possa fare boot da vari dischi inserire tutti i device driver di questi dischi all'interno del kernel non è una scelta saggia.
 +
Possiamo studiare un modo per caricare solo i "moduli" che ci servono --> initrd
 +
 
 +
Quando il kernel è partito possiamo caricare i moduli che ci servono.
 +
initrd ha al suo interno un file system (banale, di sola lettura, ad allocazione contigua) che contiene un'altra copia dei moduli kernel (.ko).
 +
<br>In questo modo si ha un piccolo spreco di memoria: i moduli compaiono sia in initrd che in /sys/. Ad oggi anche nei sistemi embedded si preferisce accettare questo piccolo spreco di memoria flash.
 +
 
 +
'''DTB (Device Tree Binary)'''
 +
Descrive la configurazione del '''sistem on chip''' alla partenza.
 +
<br>'''sistem on chip''': integratore contenente processore ed altre cose. Lo stesso integrato può essere configurato per fare un sacco di cose diverse. Si possono scegliere le interfacce dei device da attivare.
 +
<br>Quando il kernel parte, il kernel deve sapere quali device ha a disposizione, quindi la configurazione del sistem on chip va fatta prima che il kernel parta.
 +
<br>Il vero file contenente le informazioni (in forma testuale) è il device tree, ma dato che queste informazioni devono essere usate in tempi rapidi al boot, questo file viene compilato e si ottiene il DTB.
 +
 
 +
 
 +
Possiamo ottenere i tre file di cui abbiamo bisogno montando l'immagine ISO:
 +
    mount -o ro finnix-armhf.iso /mnt
 +
ed andando nella cartella /mnt/boot/armhf/ possiamo trovare i file copiarli e smontare l'immagine.
 +
Possiamo far partire la macchina virtuale.
 +
 
 +
===Paravirtualizzazione===
 +
Il prefisso para significa simile, affine a.
 +
<br>La paravirtualizzazione è un'ottimizzazione del processo di virtualizzazione perché non il processore non viene emulato.
 +
<br>Il punto è che l'implementazione di una virtualizzazione completa talvolta non è efficiente.
 +
E.g. Algoritmi di minimizzazione delle seek su dischi virtuali sono inutili.
 +
 
 +
Il kernel del guest deve essere informato di stare girando su un device virtuale, questo viola i principi di Popek e Goldber.
 +
 
 +
===Meglio emulare perfettamente i sistemi reali o fare device ottimizzati per il mondo virtuale?===
 +
Dipende.
 +
<br>'''La virtualizzazione si può realizzare su vari livelli ed in varie modalità'''
 +
Uno dei modi è quello di catturare le system call ('''system call interposition''') o quello di catturare le chiamate ad una libreria.
 +
 
 +
====Catturare le system call====
 +
'''ptrace''' è una system call che si può usare per virtualizzare le system call.
 +
 
 +
====Catturare le chiamate a libreria====
 +
Funziona con le librerie dinamiche. Le librerie dinamiche sono linkate all'eseguibile solamente in fase di esecuzione.
 +
Un eseguibile non contiene le librerie, ma solamente le dipendenze alle librerie.
 +
Per vedere quali sono si può usare il comando ''ldd executablename''.
 +
 
 +
Esempio:
 +
<br>La system call open non è altro che una funzione che solleva una trap tramite il comando syscall.
 +
Potremmo trovare un modo per sovrascrivere la open della libreria standard (libc) in modo che la nuova open sia chiamata al posto dell'altra.
 +
 
 +
'''purelibc''' è una libreria che prende gran parte delle system call e le ridefinisce.
 +
 
 +
===Autovirtualizzazione===
 +
Il processo stesso virtualizza le sue chiamate.
 +
L'hypervisor è una libreria.
 +
 
 +
<u>Sicuro NO, utile SI</u>.
 +
 
 +
In ViewOS questo meccanismo viene usato in varie occasioni.
 +
Permette di utilizzare le librerie oltre il loro scopo originale; e.g. se abbiamo una libreria che agisce su dei file e siamo interessati esclusivamente alla logica possiamo fare in modo che le system call relative ai file siano virtualizzate
 +
in modo tale da fornire i dati in altro modo.
 +
 
 +
Libreria --> purelibc
 +
purelibc libreria di autovirtualizzazione
 +
 
 +
UserModeLinux e ViewOS virtualizzano entrambi tramite system call interposition.
 +
<br><u>User mode linux virtualizza tutte le chiamate, ViewOS no.</u>
 +
 
 +
'''Namespaces''': implementano la virtualizzazione parziale (come ViewOS) ma all'interno del kernel. Sono più efficienti ma complicano il kernel.
 +
 
 +
====Xen====
 +
L'idea su cui Xen si basa è quella di fondere insieme kernel ed hypervisor.
 +
<br>Siccome scrivere un intero kernel sarebbe un compito troppo impegnativo, Xen si ispira all'architettura a microkernel.
 +
Xen implementa uno strato, che si trova direttamente sull'hardware, che usa paravirtualizzazione e che contiene solo le funzioni necessarie a gestire le macchine virtuali.
 +
 
 +
In Xen <u>"tutte le macchine sono uguali, ma una è più uguale delle altre"</u>.
 +
 
 +
Di per sè Xen non supporta direttamente l'hardware della macchina reale, infatti non contiene i device driver, ma sfrutta quelli della prima macchina virtuale (domain0).
 +
Se non configurato diversamente tutti i device vengono gestiti dal domain0. Tutto ciò che arriva dall'hardware viene inoltrato al domain0. Domain0 vede quindi device virtuali che sono rappresentazioni esatte dei device fisici.
 +
 
 +
KVM ha dimostrato di avere ormai le stesse prestazioni di Xen. Quindi potrebbe essere una buona idea quella di usare un Linux minimale con KVM al posto di Xen.
  
 
== March 08 2018 ==
 
== March 08 2018 ==
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EQq0OH4TShpFpQB01x-TmAgB111c9tPOwkxV_BdP9swVJw?e=AbDxex Registrazione 08/03/18]
 +
 +
'''ptrace''' è una system call che permette ad un processo di controllare un altro processo.
 +
Inizialmente si usavano i segnali stop and continue.
 +
Nelle prime versioni era proibito usare i segnali stop e continue se il processo era tracciato.
 +
Nelle ultime versioni c'è un nuovo modo di collegarsi ad un processo: PTRACE_SEIZE.
 +
 +
(VUos usa virtualizzazione parziale)
 +
 +
'''3 tipologie di viste per un unico sistema'''
 +
 +
===Nei panni degli utenti===
 +
L'idea di VUos è di fornire ad un processo un ambiente diverso;
 +
VUos usa il concetto di modulo (come nel kernel) ovvero abilita delle funzionalità;
 +
abbiamo moduli e sottomoduli (usati per specifiche implementazioni delle funzionalità dei moduli):
 +
http://wiki.v2.cs.unibo.it/wiki/index.php?title=Main_Page
 +
 +
'''Moduli''':
 +
* '''UM-Fuse''' (versione vecchia) --> '''VUfuse''' (versione nuova) modulo per la virtualizzare file system.
 +
: Compatibile con Fuse; modulo del kernel di Linux con lo stesso scopo.
 +
: Fuse si trova nel kernel, i sottomoduli no.
 +
: Se si compilano gli stessi sorgenti per Fuse linkando la libreria di UM-Fuse lo stesso sorgente funziona con UM Fuse.
 +
: (Tip: meglio non riscoprire l'acqua calda ed uniformare le interfacce ed usarlo)
 +
: Sottomoduli:
 +
:* <u>umfuseext2</u> (fuseext2) (monta anche ext3 ed ext4)
 +
:* <u>umfusefat</u> (libfat)
 +
:* <u>umfuseiso</u>
 +
:* <u>umfusessh</u>
 +
:* <u>umfusecrypt</u>
 +
* '''UM Net''' --> '''VUnet'''
 +
: Consente di avere una visione virtualizzata della rete.
 +
: Sottomoduli:
 +
:* <u>umnetlwipv6</u> (lwipv6)
 +
* '''UM Dev'''
 +
: Sottomoduli:
 +
:* <u>umdevmbr</u> - Master Boot Record
 +
 +
Esempio UM Dev:
 +
 +
Possiamo montare l'immagine di un disco con UM Dev e montare la prima partizione con umfuseext2 (se la partizione è ext2).
 +
<br>Immagine di un disco = tabella partizioni (MBR o GPT) + partizioni (file system all'interno delle partizioni).
 +
<br><code>mount</code> ed il file system sono i punti cardine dell'architettura Unix; Unix da nome alle cose tramite il file system.
 +
 +
 +
 +
Esempio fatto dal prof:
 +
 +
<source lang="bash">
 +
truncate -s 1G mydisk    # creiamo l'immagine del disco
 +
umview xterm   # facciamo partire la macchina virtuale parziale su un terminale xterm
 +
 +
#nel terminale xterm
 +
 +
um_add_service umdev umfuse    # aggiungiamo i moduli
 +
 +
ls /dev/hda
 +
 +
mount -t umdevmbr mydisk /dev/hda    # umdevmbr è il tipo di montaggio
 +
 +
#Il disco montato sarà visibile solamente nel terminale della macchina virtuale (e nei suoi figli).
 +
#ViewOS si accerta che esista un modulo che faccia match con la prima parte del nome (umdev) e dà la chiamata in gestione al modulo.
 +
#A quel punto la libreria (umdevmbr.so) viene caricata in memoria.
 +
 +
locate umdevmbr.so
 +
ls -l /dev/hda    # verifichiamo il montaggio
 +
 +
/sbin/fdisk /dev/hda    # creaiamo la tabella delle partizioni come in un disco reale
 +
 +
# Il file mydisk è l'immagine di un disco in formato raw.
 +
# Se facessimo cat di mydisk e ridirezionassimo l'output in un disco da 1G, l'hard disk si partizionerebbe e conterrebbe esattamente il contenuto del file.
 +
# in alternativa a cat si usa dd perchè è ottimizzato per file di grandi dimensioni (usa grandi cache)
 +
 +
ls /dev/hda1
 +
 +
/sbin/mkfs.ext2 /dev/hda1 # make file system ext 2
 +
/sbin/fsck.ext2 -f /dev/hda1 # file system check
 +
 +
ls /mnt
 +
 +
mount -o rw+ -t umfuseext2 /dev/hda1 /mnt    # montiamo il disco ('''nidifichiamo la virtualizzazione''')
 +
 +
# ora tutte le chiamate verso /mnt saranno catturate e virtualizzate
 +
 +
ls /mnt    # dovrebbe comparire solo lost+found
 +
 +
# echo "ciao" > /mnt/ciao
 +
</source>
 +
 +
====Nidificazione della virtualizzazione====
 +
Se creiamo un file il nostro processo fa una <code>open</code> al pathname: la system call viene intercettata da ViewOS in quanto stiamo accedendo ad un path virtualizzato.
 +
L'hypervisor si accorgerà che il file system è virtualizzato da <code>umfuseext2</code>, che sa come fare la open sul file system virtuale (generando una <code>write</code> ad un certo offset nell'immagine della partizione).
 +
Anche la partizione però è virtualizzata: la chiamata dovrà essere intercettata dal modulo <code>umdevmbr</code> (che virtualizza le partizioni); questa chiamata tuttavia è generata dall'hypervisor.
 +
<br>Com'è possibile che l'hypervisor catturi la sua stessa chiamata e la virtualizzi nuovamente? --> '''purelibc'''
 +
 +
<code>/etc/fstab</code> contiene la tabella dei filesystem
 +
 +
Un file system non deve essere mai montato da più macchine; vale anche per i file dei filesystem virtuali.
 +
<br>Tramite i comandi standard siamo in grado, con i permessi di utente, di fare operazioni che potrebbero essere svolte solo da root.
 +
<br>Queste operazioni si potrebbero fare anche senza virtualizzazione, ma servirebbero i permessi di amministratore e avremmo molti limiti.
 +
 +
'''loop device''' dispositivo a blocchi asssociato dinamicamente ad un file e che serve per vedere il file come una memoria di massa.
 +
 +
====ViewFS====
 +
[http://wiki.v2.cs.unibo.it/wiki/index.php?title=ViewFS ViewFS] è un modulo che virtualizza la struttura dei file system.
 +
<source lang="bash">
 +
 +
um_add_service viewfs
 +
mkdir /tmp/newroot
 +
viewsu
 +
mount -t viewfs -o mincow,except=/tmp,vstat /tmp/newroot /
 +
 +
</source>
 +
 +
<code>mincow</code> ed <code>except</code> sono opzioni di ViewFS
 +
 +
=====COW=====
 +
'''COW (Copy On Write)''': Si accede un file in sola lettura ed ogni volta che lo si modifica ne si fa una copia.
 +
I risultati saranno visibili solamente a noi.
 +
<br>'''mincow''': ogni volta il sistema proverà ad accedere in scrittura al file e se non ce la fa lo farà in modalità '''cow'''.
 +
 +
Si possono installare pacchetti debian virtualmente usando metodo copy on write (possiamo testare l'installazione di nuovi pacchetti).
 +
 +
=====qcow=====
 +
Formato usato da qemu per le immagini dei dischi. Usa COW al livello dei blocchi di disco.
 +
 +
Se si modifica il file originale del cow si possono attuare varie politiche.
 +
Qemu non dà alcuna garanzia.
 +
ViewOS non permette la modifica.
 +
 +
umview è disponibile nei repository di debian o (aggiornato) su SourceForce.
 +
 +
=====unreal=====
 +
Modulo di test: fa vedere l'intero file system come se fosse in <code>/unreal</code> ed anche dentro <code>/unreal/unreal</code>.
 +
Si possono fare vari esperimenti, e.g. andare dentro <code>/unreal</code> e lanciare comandi come <code>make</code>.
 +
Se <code>make</code> si comporta nello stesso modo la virtualizzazione sta funzionando.
 +
 +
Tip: principio chiave del debugging - separare le responsabilità.
 +
 +
'''umview --> umvu'''
 +
 +
'''umbinfmt'''
 +
 +
=====KMVIEW=====
 +
Fratello di '''UMVIEW'''.
 +
Molto veloce perché usava un modulo kernel sperimentale che però non entrerà a far parte nel kernel.
 +
Permetteva, al livello del kernel, di distinguere i file descriptor reali da quelli virtuali.
 +
La virtualizzazione costava solo 4%.
 +
 +
====Berkeley socket====
 +
L'interfaccia '''Berkeley socket''' deve essere aggiornata nei tempi in quanto possiede intrinsecamente l'idea di view globale (global view assuption).
 +
<br>I parametri della chiamata socket sono tre:
 +
* famiglia (domain, ipv4)
 +
* servizio (type)
 +
* protocollo
 +
 +
Se vogliamo un socket AF_INET (ipv4), di tipo SOCK_STREAM, con protocollo di 0 (di default, TCP) non abbiamo modo di scegliere lo stack di rete.
 +
<br>Se potessimo avere a disposizione d'uso diversi stack di protocolli di rete potremmo avere nuovi tipi di applicazioni ed avere soluzioni più semplici a problemi noti.
 +
 +
In virtual square l'API dei Berkeley sockets è stata estesa con un API chiamata '''msockets''':
 +
- permette l'utilizzo di più stack di rete allo stesso tempo.
 +
- il file system viene usato per dare nome agli stack di rete (molto Unix consistent).
 +
- è compatibile con il passato.
 +
 +
Gli stack di rete appaiono quindi nel file system come file speciali.
 +
Si può fare mount dello stack.
 +
Vedere libro di Virtual square per maggiori informazioni.
 +
 +
=====umattach=====
 +
Si può virtualizzare qualche processo che sta già eseguendo.
 +
Se la view di un processo cambia improvvisamente potrebbero generarsi delle incoerenze.
 +
 +
===Nei panni degli sviluppatori===
 +
 +
====purelibc====
 +
[http://wiki.virtualsquare.org/wiki/index.php/PureLibc purelibc] è una libreria che a differenza di '''libc''' prevede l'esclusione delle systemcall in modo da lasciare la libertà di usare le systemcall che si preferisce.
 +
 +
libc = libreria c + libreria di system call (la libc è una libreria c ibrida)
 +
 +
Una vera libreria c quando avviene una printf deve svolgere i calcoli e chiamare la write.
 +
Non possiamo usare la libc ridefinendo le system call perché quando la printf chiama la write essendo una libreria unica il linker ha già risolto la chiamata.
 +
Per fare ciò abbiamo bisogno di una libreria pura, che non implementi le system call al suo interno.
 +
<u>L'hypervisor di ViewOS usa purelibc</u>.
 +
Attualmente la purelibc è complessa ed usa il meccanismo del <u>dynamic linker preload</u> per virtualizzare (vedere la documentazione di purelibc).
 +
 +
La purelibc al momento è implementata come layer al di sopra della libc. Questo è scomodo.
 +
Se qualche system call fosse aggiunta dovremmo aggiungerne un'altra anche in purelibc.
 +
 +
'''execs --> progetto praticamente concluso'''
 +
 +
====cado====
 +
cado: sudo con le '''capability''' (privilegio).
 +
<br>Le capability permettono di separare le prerogative di root e di poterle assegnare in maniera separata, possono essere assegnate a processi o a file.
 +
 +
<code>man capabilities</code>
 +
 +
Un processo può avere 4 classi di capability. Le possiamo vedere in <code>/proc/id_processo/status</code>
 +
 +
<code>cat /proc/$$/status</code>
 +
 +
=====Capabilities=====
 +
* <u>Permitted</u> - che possono essere attivate dal thread.
 +
* <u>Inheritable</u> - che possono essere ereditate.
 +
* <u>Effective</u> - attive. Sono sempre un sottoinsieme dei permitted.
 +
* <u>Ambient</u> - sono mantenute a patto che il file non sia privilegiato.
 +
 +
'''Bound''' - maschera non modificabile che indica quali capabilities il sistema è in grado di gestire.
 +
 +
=====Capabilities dei file=====
 +
 +
'''Capabilities ambient''': sono mantenute a patto che il file non sia privilegiato.
 +
Se si ha una capability ambient essa è considerata come permitted e come effective.
 +
 +
Come cambiano le capabilities quando si chiama una exec?
 +
 +
<code>/etc/sudoers</code> --> file di configurazione di sudo (anche cado ha un file di configurazione)
 +
 +
====namespace====
 +
Si possono dare ai processi visioni diverse sulle risorse.
 +
 +
<code>man namespaces</code>
 +
 +
Rete, IPC, PID.
 +
<br>I namespaces sono stati implementati male: funzionano ma sono molto pesanti da utilizzare e vengono usati dai processi senza che l'utente non ne abbia visibilità ( Chromium per creare dei sandbox usa i namespaces ).
 +
 +
I namespace si possono creare in 3 modi diversi:
 +
* <u>clone</u>: crea un nuovo processo con namespace associato.
 +
* <u>setns</u>: permette ad un processo di unirsi ad un namespace esistente.
 +
* <u>unshare</u>: il processo chiamante si collega ad un namespace nuovo.
 +
 +
===Nei panni degli sviluppatori core===
 +
 
== March 13 2018 ==
 
== March 13 2018 ==
 +
[https://etherpad.wikimedia.org/p/qKAqRNgtxt Etherpad 13/03/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/Ed7XFMhWD9tEjVhCAVij9PQB66auNxzCMUG53Xl9veDlkw?e=JHtQN1 Registrazione 13/03/18]
 +
 +
Quando si trasmette una lista di interfacce in protocollo <code>netlink</code> prevede il pacchetto "''done''" come sentinella finale. In alternativa si può usare <code>busybox ip addr</code> in quanto <code>ip addr</code> di busybox non fa nessun controllo sul pacchetto ''done''.
 +
 +
<syntaxhighlight lang=bash>
 +
#Facciamo partire una macchina virtuale in un terminale.
 +
umview xterm
 +
#Vediamo le vere interfacce di rete.
 +
ip addr
 +
#Carichiamo il supporto per le reti virtuali.
 +
um_add_service umnet
 +
 +
#vde vuole indirizzi simili agli url.
 +
#???????? vedere meglio nella documentazione ???????????????
 +
 +
mount -t umnetlwipv6 -o vde0=vxvde:// none /dev/net/mynet
 +
#Osserviamo di nuovo le interfacce di rete.
 +
ip link
 +
 +
#Vediamo le interfacce precedenti in quanto la nuova rete non è montata come rete di default.
 +
#Possiamo avere tanti stack diversi ognuno con le sue interfacce.
 +
 +
#mstack --> multiple stack; comando di umview usare lo stack selezionato.
 +
mstack /dev/net/mynet ip link
 +
#Se volessi far partire un browser su quello stack dovrei fare
 +
mstack /dev/net/mynet firefox
 +
#Se volessi far partire una connessione ssh
 +
mstack /dev/net/mynet ssh
 +
#Se volessimo avviare un terminale che vive nella rete nuova potremmo fare
 +
mstack /dev/net/mynet bash
 +
 +
ip addr add 10.0.0.1/24 dev vd0
 +
ip link set vd0 up
 +
</syntaxhighlight>
 +
 +
Se adesso su un'altra macchina della rete locale facessi le stesse operazioni con un indirizzo ip diverso, le macchine avrebbero la possibilità di mettersi in contatto.
 +
 +
Per completezza dell'esempio realizziamo l'altro stack con vdens (namespace di vde).
 +
 +
Parte dell'esempio fatto dal prof; qui viene usato in entrambi i terminali '''vdens''', mentre il prof a lezione ha usato per uno '''umnet''' e '''vdens''' per l'altro.
 +
Sono necessari '''[https://github.com/rd235/vdens vdens]''' ,'''[https://github.com/rd235/vdeplug4 vdeplug4]''' ( e forse anche '''[https://github.com/rd235/vxvdex vxvdex]''').
 +
 +
Per entrambe le sessioni del terminale setto una variabile d'ambiente in modo che mi cerchi la ''libvdeplug.so.4'' in ''/usr/local/lib''.
 +
 +
<source lang="bash">
 +
export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib
 +
</source>
 +
 +
Terminale 1
 +
<source lang="bash">
 +
vdens vxvde://
 +
ip link set vde0 up
 +
ip addr add 10.0.0.1/24 dev vde0
 +
 +
ping 10.0.0.2
 +
 +
nc 10.0.0.2 2222
 +
 +
#scrivendo dei messaggi nel terminale 1 compariranno nel 2 e viceversa
 +
</source>
 +
 +
Terminale 2
 +
<source lang="bash">
 +
vdens vxvde://
 +
ip link set vde0 up
 +
ip addr add 10.0.0.1/24 dev vde0
 +
 +
#ora nel terminale 1 posso eseguire ping 10.0.0.2
 +
 +
nc -l 2222
 +
#ora nel terminale 1 posso eseguire  nc 10.0.0.2 2222
 +
</source>
 +
 +
 +
'''Stack TCP/IP''': o implementato a livello utente come libreria o implementato nel kernel.
 +
<br><code>umview</code> --> prima opzione.
 +
<br><code>vdens</code> --> chiede al kernel di costruire un altro stack TCP/IP per questo utente (sfrutta i namespace).
 +
 +
<code>nc</code> (alias <code>netcat</code>) coltellino svizzero per esperimenti su rete.
 +
<syntaxhighlight lang=bash>
 +
#Connessione TCP alla porta 22 di maddalena
 +
nc mad.cs.unibo.it 22
 +
#Connessione alla porta 80
 +
nc 130.136.1.110 80
 +
nc permette di collegarsi tramite TCP e di scrivere HTTP manualmente
 +
 +
#Faccio un server TCP in ascolto su porta 2222
 +
nc -l 2222
 +
#Mi connetto alla porta 2222 dell'indirizzo 10.0.0.2
 +
nc 10.0.0.2 2222
 +
</syntaxhighlight>
 +
 +
Un utente può creare tutti gli stack di rete che vuole ed averne vari a disposizione con configurazioni diverse.
 +
<br>Esempio: possiamo lanciare un browser facendo in modo che il browser non sia logicamente dove siamo ma usi un ip di un'altra area geografica.
 +
* Così facendo inganneremmo where si my ip
 +
* Comodo per testare la neutralità della rete. Stessa pagina acceduta con ip di aree geografiche diverse appare nello stesso modo.
 +
 +
Se volessimo implementare un VPN per sicurezza aziendale normalmente dovremmo spostare tutta la macchina dentro il VPN, con questo metodo possiamo avere un solo stack connesso al VPN.
 +
 +
I supporti di rete, file system e device, portandoli fuori dal kernel in user mode ricordano il concetto di microkernel.
 +
<br>ViewOS serve anche per poter fare una transizione dolce dai kernel monolitici ai microkernel; è come avere un microkernel configurabile a runtime.
 +
* Possiamo decidere di tenere parti del kernel (moduli) in spazio utente tramite moduli di ViewOS. è meno efficiente ma più sicuro e si usa solo all'occorrenza.
 +
* Se dovessimo gestire un tipo di file system appena inventato (di cui non abbiamo il supporto nel kernel) per inserire il supporto del kernel dovremmo ricompilare tutto; Se usiamo un modulo a livello utente no.
 +
 +
ViewOS è una specifica; per ora è stato implementato tramite '''system call interposition (ptrace)''', ma può essere implementato in altri modi.
 +
 +
Potremmo implementare il tutto attraverso i '''namespace''', nel kernel (e.g. vdens). Creare diversi visioni dell'ambiente.
 +
 
== March 15 2018 ==
 
== March 15 2018 ==
 +
 +
Lezione sospesa causa lauree.
 +
 
== March 20 2018 ==
 
== March 20 2018 ==
 +
[https://etherpad.wikimedia.org/p/A4ZfDg1rtY Etherpad 20/03/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/Ea2A7wOIwqRJvvLoF7ekvr8BdBWJmjjz_fBx1zB5rr__2w?e=jxfToF Registrazione 20/03/18]
 +
 
== March 22 2018 ==
 
== March 22 2018 ==
 +
[https://etherpad.wikimedia.org/p/ya2BWaXTbl Etherpad 22/03/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EZ8AcVfOagpBnYHAN3EYcv0BpHlqcH0Lg-8l3sQb6_Drsg?e=7suh7a Registrazione 22/03/18]
 +
 
== March 27 2018 ==
 
== March 27 2018 ==
 +
[https://etherpad.wikimedia.org/p/GaJNvPo1wK Etherpad 27/03/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EYZUi8icxIpIhMrV_ZvwspIB5kCqMzEbL8plvCzZD8-BIA?e=VhO56l Registrazione 27/03/18 pt1]
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EWPHKBP4cqNEomwP7MQiodgBxbUQbwAYLA9f5gu14OFg-A?e=7sA6NE pt2]
 +
 +
 +
Esempio su veth
 +
 +
Terminale 1
 +
<source lang="bash">
 +
sudo bash
 +
 +
ip link add type veth
 +
ip link
 +
 +
# solo per avere una panoramica del comando
 +
ip netns help
 +
 +
ip netns add renzonet
 +
ip netns list
 +
 +
#trasferiamo veth1 nel namespace appena creato renzonet
 +
ip link set veth1 netns renzonet
 +
ip netns exec renzonet ip addr
 +
 +
 +
ip addr add 10.1.1.1/24 dev veth0
 +
ip link set veth0 up
 +
 +
</source>
 +
 +
Terminale 2
 +
<source lang="bash">
 +
 +
sudo bash
 +
 +
ip netns exec renzonet bash
 +
ip addr add 10.1.1.2/24 dev veth1
 +
ip link set veth1 up
 +
 +
 +
ping 10.1.1.1
 +
</source>
 +
 +
 +
<source lang="bash">
 +
# per riportare le cose allo stato precedente
 +
#il comando si prende la libertà di eliminare anche veth0 e veth1 create con 'ip link add type veth'
 +
ip netns delete renzonet
 +
</source>
 +
 
== April 05 2018 ==
 
== April 05 2018 ==
 +
[https://etherpad.wikimedia.org/p/f9dnp4d724 Etherpad 05/04/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EYo0VpOMc-lOttWR_EKsIesBVefwRpQ-h6lRCKjltgK5fw?e=M7dSqJ Registrazione 05/04/18]
 +
 +
Esempio fatto alla fine riguardo la gestione dei file in umvu
 +
 +
<source lang="bash">
 +
umvu xterm
 +
</source>
 +
 +
Terminale xterm 1
 +
<source lang="bash">
 +
#step 1
 +
xterm &
 +
 +
vu_insmod mountreal
 +
 +
#step 3
 +
ps -ax | grep less #leggo il pid di less /unreal/etc/services
 +
 +
cd /proc/pid/fd # pid è quello letto poco prima
 +
ls -l | grep .vu
 +
 +
</source>
 +
 +
Terminale xterm 2
 +
<source lang="bash">
 +
#step 2
 +
less /unreal/etc/services #less mostra il file e lo mantiene aperto
 +
</source>
 +
 
== April 10 2018 ==
 
== April 10 2018 ==
 +
[https://etherpad.wikimedia.org/p/ZEZWfThcnS Etherpad 19/04/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EYnk4m7381pKquyxcyaQVmABTjxlFvCud9FM7rq0ZIWr_A?e=64Yvr6 Registrazione 19/04/18]
 +
 
== April 12 2018 ==
 
== April 12 2018 ==
 +
[https://etherpad.wikimedia.org/p/J8bBJZoBiG Etherpad del 12/04/18]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EeqVKTQuh2FPg-xYiePRSa4BsgmjHxkbSgG97om2p87OGw?e=QLfLBA Registrazione del 12/04/18]
 +
 
== April 17 2018 ==
 
== April 17 2018 ==
 +
[https://etherpad.wikimedia.org/p/IGWnSwsVUO Etherpad del 17/04]
 +
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EViD9YtYf3VJrmCrSo56AiIBj_3fZOJKUGA_eS9bLoHaHw?e=1gq6mO Registrazione del 17/04 pt1]
 +
[https://liveunibo-my.sharepoint.com/:u:/g/personal/francesco_fornari2_studio_unibo_it/EYlXuY3DaihDtOIGTGzXKKkB_jILal-2nyIBIEjO-Zrn5Q?e=P4gpSZ pt2]
 +
 
== April 19 2018 ==
 
== April 19 2018 ==
 
== April 24 2018 ==
 
== April 24 2018 ==

Latest revision as of 16:19, 17 April 2018

February 27 2018

Virtualità

Virtualizzare qualcosa significa fornire un oggetto che possa essere usato (stessa interfaccia) efficacemente al posto dell'altro. Se si usa una scarpa per piantare un chiodo, la scarpa è un "martello virtuale".

Memoria virtuale

  • Interfaccia della memoria principale: load(indirizzo), store(indirizzo, oggetto).
  • Semantica: se eseguo store(i, a) seguito da load(i), la seconda operazione ritornerà a.

La memoria secondaria può essere usata per implementare l'interfaccia di quella primaria. Anche l'hardware di un calcolatore può essere visto come un'entità astratta che parla il linguaggio ISA del processore di cui fa uso. Se virtualizziamo l'hardware tramite un programma che ne implementa la stessa interfaccia otteniamo una macchina virtuale.


Possibilità di virtualizzare il tempo.


Significato di virtualsquare

Una piazza dove i vari tipi di virtualià coesistono, un laboratorio internazionale sulla virtualità.


Concetto di VIEW

I processi "vedono" l'ambiente di esecuzione. Se non stanno eseguendo istruzioni di calcolo, i processi si interfacciano ("vedono") al sistema (accedono a memoria, fanno routing) usando system calls. ogni processo può vedere un file diverso allo stesso path name

umview vecchia macchina parziale virtuale

L'Hypervisor agisce parzialmente come un debugger: intercetta le system calls ed intraprende azioni.


Virtual Distributed Ethernet (VDE)

VDE è una rete Ethernet virtuale che può essere distribuita su diverse macchine fisiche presenti in rete. Usare concetti reali nello "Standard" ethernet e vitualizzarli. ad esmpio uno switch con il vitual switch, più avanti nelle versioni sono stati creati dei "tasselli" che si posso interfacciare con vari altri tasselli per formare una rete virtuale personalizzata


Tip: "Trovate il nome giusto da dare a tutte le cose che pensate"

PeDaNTe S.P.A. (Physical, Data link, Network, Transport, Session, Presentation, Application)


Internet of Threads

Dare un indirizzo IP non alla macchina, ma direttamente al processo, questo ti pemette di migrare i processi da una macchina ad un'altra senza che il client deve riconfigurare l'IP della chiamata a quel processo (IPV6 è praticamente obbligatorio per rendere Internet of Threads utillizzabile, perchè IPV4 ha troppi pochi indirizzi) Se abbiamo due web servers virtuali sulla stessa macchina fisica vogliamo che abbiano comunque diversi indirizzi ip.

March 01 2018

INFO

Le comunicazioni e lo scambio di idee avverranno nel gruppo Telegram.

Per iscriversi/scrivere nel wiki occorre il numero magico usato già per il corso di Sistemi Operativi.

Vecchio materiale Virtual System Design

Altre risorse su GitHub

Nickname del docente

  • rd235 (derivato dai documenti RFC es. RFC 1166)
  • iz4dje

Tipi di virtualizzazione

finnix è un sistema operativo live da usare "quando si è nei guai", non ha interfaccia grafica e permette di provare i sistemi virtuali; la versione 1.0 è quella che funziona bene.

Il sistema operativo in cui viene eseguita la macchina virtuale, viene detto host (ospitante) mentre la macchina virtuale è chiamata guest (ospite).

Emulazione

Scrivendo un emulatore di una macchina emulo i passi di esecuzione dell'hardware: convertire le istruzioni dal linguaggio del processore che vuole essere emulato ad istruzioni per la macchina host.

QEMU è un esempio: traduce il codice macchina guest in codice macchina host (traduzione dinamica). QEMU contiene i sorgenti con le istruzioni del vari assembler (sottoforma di funzioni) che vengono messi in un vettore; fa uso di cache come fanno i browser: il codice non viene tradotto di continuo ma viene eseguito quello "in cache" e questo lo fa risultare 15/20 volte più veloce.

(NOTA: rimane in sospeso slirp, lo vedremo nel dettaglio in futuro)

Busybox è un piccolo eseguibile che combina diverse applicazioni standard Unix, in pratica le utility Unix non sono altro che un alias di busybox; si può scaricare e compilare i binari di busybox per mips (arm), se attivo il servizio binfmt-support il sistema utilizzerà QEMU per eseguire i binari mips, mentre disattivando il servizio sarà possibile utilizzare KVM.

Esempi di emulazione

qemu-system-* (wildcard) è il comando per lanciare un'architettura:

qemu-system-x86_64 -cdrom finnix-110.iso -m 512M

dove -m 512M è la quantità di ram che gli rendiamo disponibile.

Con QEMU possiamo eseguire finnix-armhf-111.iso su macchina x86_64 seguendo le istruzioni, per avere successo bisogna montare l'immagine iso ed estrarre il contenuto (initrd.xz, linux e vexpress-v2p-ca9.dtb) della directory /boot/armhf/ nella cartella da cui si lancia QEMU.

Virtualizzazione parziale

KVM, acronimo di Kernel-based Virtual Machine (utilizza VT per Intel e AMD-V per AMD), ha un comportamento a "trigger" il processore si comporta come la routine normale, soltanto quando vengono lanciate determinate call viene cambiata la routine da quella nativa a quella apposita per simulare altri processori. Questo permette di avere macchine virtuali molto più veloci, visto che girano direttamente sul processore escluse le varie eccezione rende una correlazione praticamente 1 a 1.

Si può abilitare la modalità KVM in QEMU usando l'opzione -enable-kvm che ovviamente richiede che i moduli siano stati caricati.

Virtualizzazione totale

VirtualBox è un esempio di virtualizzazione totale.

User-Mode Linux è una macchina virtuale i cui sorgenti sono presenti nel kernel linux; usa lo stesso supporto del comando strace (utile per vedere le system call di un comando); User-Mode Linux è molto vicino a umview (che appunto sta per User-Mode View); in quanto a velocità sta in mezzo tra qemu e kvm.

Differenze

QEMU virtualizzazione a livello di processo (PVM), KVM a livello di sistema (SVM), VirtualBox a livello di system call (SCVM). Vedere pag. 36 e a seguire.


qemu-system-* é formato dal processore di traduzioni dinamiche qemu_(arm, mips...) e dalle periferiche.

kvm invece non fa uso di qemu ma al posto suo usa l'accellerazione del processore (oltre alle periferiche).

qemu funziona come processo utente e non ha bisogno di permessi eccezionali; kvm invece risulta vincolato al processore (egrep '^flags.*(vmx|svm)' /proc/cpuinfo) e occorre anche il modulo kernel (lsmod | grep kvm).

VirtualBox non può convivere con KVM.

Macchine virtuali in rete

È possibile creare una propria macchina virtuale online usando le credenziali unibo okeanos grnet

Tip: molly-guard protects machines from accidental shutdowns/reboots (via ssh); è un software che se si tenta un reboot/poweroff chiede di digitare il nome della macchina, in questo modo si evita di spegnere una macchina virtuale non voluta tra le varie finestre aperte.

March 06 2018

Registrazione 06/03/2018

I requisiti di virtualizzazione

I requisiti di virtualizzazione di Popek e Goldberg sono delle condizioni sufficienti per un'architettura per supportare la virtualizzazione (in modo efficiente):

  • Equivalenza / Fedeltà - Un programma virtualizzato dovrebbe esibire un comportamento essenzialmente identico a quello dimostrato quando viene eseguito su una macchina equivalente direttamente.
  • Controllo delle risorse / Sicurezza - L'hypervisor deve avere il completo controllo delle risorse virtualizzate.
  • Efficienza / Performance

Davoli: "Il livello di sicurezza richiesto dipende dall'applicazione"

Popek e Goldberg descrivono anche le caratteristiche che l'ISA della macchina ospite deve possedere per essere in grado di far girare un hypervisor che goda dei tre requisiti precedenti.

Teoremi di virtualizzazione

Le istruzioni di un'ISA sono classificate in tre gruppi:

  1. Istruzioni privilegiate - le istruzioni che generano una trap se il processore è in user mode e non generano una trap se il processore è in kernel mode (e.g. divisione per zero, system call, accesso ad indirizzo di memoria non mappato).
  2. Istruzioni control sensitive - le istruzioni che cercano di cambiare la configurazione delle risorse del sistema (e.g. assegnare memoria, acquisire una risorsa).
  3. Istruzioni behavior sensitive - istruzioni che hanno comportamenti diversi a seconda della configurazione delle risorse (e.g. istruzioni che dipendono dal valore del registro di rilocazione o dalla modalità di esecuzione del processore).

Teorema relativo alle istruzioni privilegiate

Si può creare una VM effettiva se e solo se le istruzioni privilegiate sono un sovrainsieme dell'unione delle istruzioni degli altri due tipi; in altre parole tutte le istruzioni "sensitive" generano una trap se eseguite in user mode.
Le istruzioni sensitive sono quelle che possono influenzare il corretto funzionamento dell'hypervisor. Queste istruzioni devono essere tutte privilegiate.
Le istruzioni control sensitive devono essere privilegiate perché il processo virtualizzato non deve essere in grado di allocare nuove risorse a sè stesso.
Le istruzioni behavior sensitive devono essere privilegiate perché il processo virtualizzato deve vedere ...


(IBM Introduce le maccine virtuali per introdurre sistemi operativi multitasking su macchine monotask)


Negli anni 90 si producono processori senza considerare il teorema di Popek e Goldberg. L'ISA di questi processori non soddisfaceva le condizioni del teorema. Vengono aggiunte istruzioni di virtualizzazione (da usare in ambienti virtuali) che non sono altro che le corrispettive istruzioni privilegiate delle istruzioni sensitive non privilegiate.

(Robert P. Goldberg: Architectural Principles for Virtual Computer Systems)

È difficile fare virtualizzazione tramite l'emulazione (problemi di efficienza).

L'emulazione consiste nell'emulare ogni singola funzione del sistema operativo e lo traduce per il livello sottostante.
La simulazione consiste nel convertire il codice assembler per un certo processore in codice macchina del processore di base.
Simulatore: apparenza (Simulatore di volo)
Emulatore: funzione effettiva e veritiera al 100% ma per questa molto più lenta (Ali di cera del racconto greco)

Qemu può funzionare in due modalità:

  • Macchina virtuale: virtualità al livello di sistema (qemu-system-*).
  • Virtualizzare solo il processore: tutte le system call sono gestite dal sistema operativo reale (qemu-*).

Esperimento: Prendere busybox per architettura arm ed eseguirlo anche se siamo su un intel
Busybox: eseguibile che fa da contenitore per molti comandi. Permette di risparmiare RAM e disco.
Sistemi embedded: spesso fatti con kernel + busybox + applicazione per cui è nato il sistema.


Finnix arm Per far partire Finnix su Arm occorre prendere dall'immagine del file system dei file che servono all'esterno. Per far partire un sistema occorre sicuramente il kernel e poi in molti casi (non tutti) il file system. Il kernel viene caricato dal boot loader.

qemu-system-arm -display none -machine vexpress-a9 -m 256 \
-kernel linux -initrd initrd.xz -dtb vexpress-v2p-ca9.dtb \
-append "console=ttyAMA0,115200" -serial stdio \
-drive file=finnix-armhf.iso,id=cd0,format=raw \
-device virtio-blk-device,drive=cd0


kernel linux --> cerca nella directory corrente un file "linux" contenente il kernel


initrd è un file di configurazione che contiene i moduli kernel usato per l'inizializzazione.
Perché nasce initrd?
Il kernel quando fa boot ha bisogno dei driver per tutti i device che servono per caricare il kernel. Se vogliamo progettare un kernel che possa fare boot da vari dischi inserire tutti i device driver di questi dischi all'interno del kernel non è una scelta saggia. Possiamo studiare un modo per caricare solo i "moduli" che ci servono --> initrd

Quando il kernel è partito possiamo caricare i moduli che ci servono. initrd ha al suo interno un file system (banale, di sola lettura, ad allocazione contigua) che contiene un'altra copia dei moduli kernel (.ko).
In questo modo si ha un piccolo spreco di memoria: i moduli compaiono sia in initrd che in /sys/. Ad oggi anche nei sistemi embedded si preferisce accettare questo piccolo spreco di memoria flash.

DTB (Device Tree Binary) Descrive la configurazione del sistem on chip alla partenza.
sistem on chip: integratore contenente processore ed altre cose. Lo stesso integrato può essere configurato per fare un sacco di cose diverse. Si possono scegliere le interfacce dei device da attivare.
Quando il kernel parte, il kernel deve sapere quali device ha a disposizione, quindi la configurazione del sistem on chip va fatta prima che il kernel parta.
Il vero file contenente le informazioni (in forma testuale) è il device tree, ma dato che queste informazioni devono essere usate in tempi rapidi al boot, questo file viene compilato e si ottiene il DTB.


Possiamo ottenere i tre file di cui abbiamo bisogno montando l'immagine ISO:

   mount -o ro finnix-armhf.iso /mnt

ed andando nella cartella /mnt/boot/armhf/ possiamo trovare i file copiarli e smontare l'immagine. Possiamo far partire la macchina virtuale.

Paravirtualizzazione

Il prefisso para significa simile, affine a.
La paravirtualizzazione è un'ottimizzazione del processo di virtualizzazione perché non il processore non viene emulato.
Il punto è che l'implementazione di una virtualizzazione completa talvolta non è efficiente. E.g. Algoritmi di minimizzazione delle seek su dischi virtuali sono inutili.

Il kernel del guest deve essere informato di stare girando su un device virtuale, questo viola i principi di Popek e Goldber.

Meglio emulare perfettamente i sistemi reali o fare device ottimizzati per il mondo virtuale?

Dipende.
La virtualizzazione si può realizzare su vari livelli ed in varie modalità Uno dei modi è quello di catturare le system call (system call interposition) o quello di catturare le chiamate ad una libreria.

Catturare le system call

ptrace è una system call che si può usare per virtualizzare le system call.

Catturare le chiamate a libreria

Funziona con le librerie dinamiche. Le librerie dinamiche sono linkate all'eseguibile solamente in fase di esecuzione. Un eseguibile non contiene le librerie, ma solamente le dipendenze alle librerie. Per vedere quali sono si può usare il comando ldd executablename.

Esempio:
La system call open non è altro che una funzione che solleva una trap tramite il comando syscall. Potremmo trovare un modo per sovrascrivere la open della libreria standard (libc) in modo che la nuova open sia chiamata al posto dell'altra.

purelibc è una libreria che prende gran parte delle system call e le ridefinisce.

Autovirtualizzazione

Il processo stesso virtualizza le sue chiamate. L'hypervisor è una libreria.

Sicuro NO, utile SI.

In ViewOS questo meccanismo viene usato in varie occasioni. Permette di utilizzare le librerie oltre il loro scopo originale; e.g. se abbiamo una libreria che agisce su dei file e siamo interessati esclusivamente alla logica possiamo fare in modo che le system call relative ai file siano virtualizzate in modo tale da fornire i dati in altro modo.

Libreria --> purelibc purelibc libreria di autovirtualizzazione

UserModeLinux e ViewOS virtualizzano entrambi tramite system call interposition.
User mode linux virtualizza tutte le chiamate, ViewOS no.

Namespaces: implementano la virtualizzazione parziale (come ViewOS) ma all'interno del kernel. Sono più efficienti ma complicano il kernel.

Xen

L'idea su cui Xen si basa è quella di fondere insieme kernel ed hypervisor.
Siccome scrivere un intero kernel sarebbe un compito troppo impegnativo, Xen si ispira all'architettura a microkernel. Xen implementa uno strato, che si trova direttamente sull'hardware, che usa paravirtualizzazione e che contiene solo le funzioni necessarie a gestire le macchine virtuali.

In Xen "tutte le macchine sono uguali, ma una è più uguale delle altre".

Di per sè Xen non supporta direttamente l'hardware della macchina reale, infatti non contiene i device driver, ma sfrutta quelli della prima macchina virtuale (domain0). Se non configurato diversamente tutti i device vengono gestiti dal domain0. Tutto ciò che arriva dall'hardware viene inoltrato al domain0. Domain0 vede quindi device virtuali che sono rappresentazioni esatte dei device fisici.

KVM ha dimostrato di avere ormai le stesse prestazioni di Xen. Quindi potrebbe essere una buona idea quella di usare un Linux minimale con KVM al posto di Xen.

March 08 2018

Registrazione 08/03/18

ptrace è una system call che permette ad un processo di controllare un altro processo. Inizialmente si usavano i segnali stop and continue. Nelle prime versioni era proibito usare i segnali stop e continue se il processo era tracciato. Nelle ultime versioni c'è un nuovo modo di collegarsi ad un processo: PTRACE_SEIZE.

(VUos usa virtualizzazione parziale)

3 tipologie di viste per un unico sistema

Nei panni degli utenti

L'idea di VUos è di fornire ad un processo un ambiente diverso; VUos usa il concetto di modulo (come nel kernel) ovvero abilita delle funzionalità; abbiamo moduli e sottomoduli (usati per specifiche implementazioni delle funzionalità dei moduli): http://wiki.v2.cs.unibo.it/wiki/index.php?title=Main_Page

Moduli:

  • UM-Fuse (versione vecchia) --> VUfuse (versione nuova) modulo per la virtualizzare file system.
Compatibile con Fuse; modulo del kernel di Linux con lo stesso scopo.
Fuse si trova nel kernel, i sottomoduli no.
Se si compilano gli stessi sorgenti per Fuse linkando la libreria di UM-Fuse lo stesso sorgente funziona con UM Fuse.
(Tip: meglio non riscoprire l'acqua calda ed uniformare le interfacce ed usarlo)
Sottomoduli:
  • umfuseext2 (fuseext2) (monta anche ext3 ed ext4)
  • umfusefat (libfat)
  • umfuseiso
  • umfusessh
  • umfusecrypt
  • UM Net --> VUnet
Consente di avere una visione virtualizzata della rete.
Sottomoduli:
  • umnetlwipv6 (lwipv6)
  • UM Dev
Sottomoduli:
  • umdevmbr - Master Boot Record

Esempio UM Dev:

Possiamo montare l'immagine di un disco con UM Dev e montare la prima partizione con umfuseext2 (se la partizione è ext2).
Immagine di un disco = tabella partizioni (MBR o GPT) + partizioni (file system all'interno delle partizioni).
mount ed il file system sono i punti cardine dell'architettura Unix; Unix da nome alle cose tramite il file system.


Esempio fatto dal prof:

 truncate -s 1G mydisk    # creiamo l'immagine del disco
 umview xterm		  # facciamo partire la macchina virtuale parziale su un terminale xterm

#nel terminale xterm

 um_add_service umdev umfuse    # aggiungiamo i moduli

 ls /dev/hda

 mount -t umdevmbr mydisk /dev/hda    # umdevmbr è il tipo di montaggio

#Il disco montato sarà visibile solamente nel terminale della macchina virtuale (e nei suoi figli).
#ViewOS si accerta che esista un modulo che faccia match con la prima parte del nome (umdev) e dà la chiamata in gestione al modulo.
#A quel punto la libreria (umdevmbr.so) viene caricata in memoria.

 locate umdevmbr.so
 ls -l /dev/hda    # verifichiamo il montaggio

 /sbin/fdisk /dev/hda    # creaiamo la tabella delle partizioni come in un disco reale

# Il file mydisk è l'immagine di un disco in formato raw.
# Se facessimo cat di mydisk e ridirezionassimo l'output in un disco da 1G, l'hard disk si partizionerebbe e conterrebbe esattamente il contenuto del file.
# in alternativa a cat si usa dd perchè è ottimizzato per file di grandi dimensioni (usa grandi cache)

 ls /dev/hda1

 /sbin/mkfs.ext2 /dev/hda1	# make file system ext 2
 /sbin/fsck.ext2 -f /dev/hda1	# file system check 

 ls /mnt

 mount -o rw+ -t umfuseext2 /dev/hda1 /mnt    # montiamo il disco ('''nidifichiamo la virtualizzazione''')

# ora tutte le chiamate verso /mnt saranno catturate e virtualizzate

 ls /mnt    # dovrebbe comparire solo lost+found

# echo "ciao" > /mnt/ciao

Nidificazione della virtualizzazione

Se creiamo un file il nostro processo fa una open al pathname: la system call viene intercettata da ViewOS in quanto stiamo accedendo ad un path virtualizzato. L'hypervisor si accorgerà che il file system è virtualizzato da umfuseext2, che sa come fare la open sul file system virtuale (generando una write ad un certo offset nell'immagine della partizione). Anche la partizione però è virtualizzata: la chiamata dovrà essere intercettata dal modulo umdevmbr (che virtualizza le partizioni); questa chiamata tuttavia è generata dall'hypervisor.
Com'è possibile che l'hypervisor catturi la sua stessa chiamata e la virtualizzi nuovamente? --> purelibc

/etc/fstab contiene la tabella dei filesystem

Un file system non deve essere mai montato da più macchine; vale anche per i file dei filesystem virtuali.
Tramite i comandi standard siamo in grado, con i permessi di utente, di fare operazioni che potrebbero essere svolte solo da root.
Queste operazioni si potrebbero fare anche senza virtualizzazione, ma servirebbero i permessi di amministratore e avremmo molti limiti.

loop device dispositivo a blocchi asssociato dinamicamente ad un file e che serve per vedere il file come una memoria di massa.

ViewFS

ViewFS è un modulo che virtualizza la struttura dei file system.

um_add_service viewfs
mkdir /tmp/newroot
viewsu
mount -t viewfs -o mincow,except=/tmp,vstat /tmp/newroot /

mincow ed except sono opzioni di ViewFS

COW

COW (Copy On Write): Si accede un file in sola lettura ed ogni volta che lo si modifica ne si fa una copia. I risultati saranno visibili solamente a noi.
mincow: ogni volta il sistema proverà ad accedere in scrittura al file e se non ce la fa lo farà in modalità cow.

Si possono installare pacchetti debian virtualmente usando metodo copy on write (possiamo testare l'installazione di nuovi pacchetti).

qcow

Formato usato da qemu per le immagini dei dischi. Usa COW al livello dei blocchi di disco.

Se si modifica il file originale del cow si possono attuare varie politiche. Qemu non dà alcuna garanzia. ViewOS non permette la modifica.

umview è disponibile nei repository di debian o (aggiornato) su SourceForce.

unreal

Modulo di test: fa vedere l'intero file system come se fosse in /unreal ed anche dentro /unreal/unreal. Si possono fare vari esperimenti, e.g. andare dentro /unreal e lanciare comandi come make. Se make si comporta nello stesso modo la virtualizzazione sta funzionando.

Tip: principio chiave del debugging - separare le responsabilità.

umview --> umvu

umbinfmt

KMVIEW

Fratello di UMVIEW. Molto veloce perché usava un modulo kernel sperimentale che però non entrerà a far parte nel kernel. Permetteva, al livello del kernel, di distinguere i file descriptor reali da quelli virtuali. La virtualizzazione costava solo 4%.

Berkeley socket

L'interfaccia Berkeley socket deve essere aggiornata nei tempi in quanto possiede intrinsecamente l'idea di view globale (global view assuption).
I parametri della chiamata socket sono tre:

  • famiglia (domain, ipv4)
  • servizio (type)
  • protocollo

Se vogliamo un socket AF_INET (ipv4), di tipo SOCK_STREAM, con protocollo di 0 (di default, TCP) non abbiamo modo di scegliere lo stack di rete.
Se potessimo avere a disposizione d'uso diversi stack di protocolli di rete potremmo avere nuovi tipi di applicazioni ed avere soluzioni più semplici a problemi noti.

In virtual square l'API dei Berkeley sockets è stata estesa con un API chiamata msockets: - permette l'utilizzo di più stack di rete allo stesso tempo. - il file system viene usato per dare nome agli stack di rete (molto Unix consistent). - è compatibile con il passato.

Gli stack di rete appaiono quindi nel file system come file speciali. Si può fare mount dello stack. Vedere libro di Virtual square per maggiori informazioni.

umattach

Si può virtualizzare qualche processo che sta già eseguendo. Se la view di un processo cambia improvvisamente potrebbero generarsi delle incoerenze.

Nei panni degli sviluppatori

purelibc

purelibc è una libreria che a differenza di libc prevede l'esclusione delle systemcall in modo da lasciare la libertà di usare le systemcall che si preferisce.

libc = libreria c + libreria di system call (la libc è una libreria c ibrida)

Una vera libreria c quando avviene una printf deve svolgere i calcoli e chiamare la write. Non possiamo usare la libc ridefinendo le system call perché quando la printf chiama la write essendo una libreria unica il linker ha già risolto la chiamata. Per fare ciò abbiamo bisogno di una libreria pura, che non implementi le system call al suo interno. L'hypervisor di ViewOS usa purelibc. Attualmente la purelibc è complessa ed usa il meccanismo del dynamic linker preload per virtualizzare (vedere la documentazione di purelibc).

La purelibc al momento è implementata come layer al di sopra della libc. Questo è scomodo. Se qualche system call fosse aggiunta dovremmo aggiungerne un'altra anche in purelibc.

execs --> progetto praticamente concluso

cado

cado: sudo con le capability (privilegio).
Le capability permettono di separare le prerogative di root e di poterle assegnare in maniera separata, possono essere assegnate a processi o a file.

man capabilities

Un processo può avere 4 classi di capability. Le possiamo vedere in /proc/id_processo/status

cat /proc/$$/status

Capabilities
  • Permitted - che possono essere attivate dal thread.
  • Inheritable - che possono essere ereditate.
  • Effective - attive. Sono sempre un sottoinsieme dei permitted.
  • Ambient - sono mantenute a patto che il file non sia privilegiato.

Bound - maschera non modificabile che indica quali capabilities il sistema è in grado di gestire.

Capabilities dei file

Capabilities ambient: sono mantenute a patto che il file non sia privilegiato. Se si ha una capability ambient essa è considerata come permitted e come effective.

Come cambiano le capabilities quando si chiama una exec?

/etc/sudoers --> file di configurazione di sudo (anche cado ha un file di configurazione)

namespace

Si possono dare ai processi visioni diverse sulle risorse.

man namespaces

Rete, IPC, PID.
I namespaces sono stati implementati male: funzionano ma sono molto pesanti da utilizzare e vengono usati dai processi senza che l'utente non ne abbia visibilità ( Chromium per creare dei sandbox usa i namespaces ).

I namespace si possono creare in 3 modi diversi:

  • clone: crea un nuovo processo con namespace associato.
  • setns: permette ad un processo di unirsi ad un namespace esistente.
  • unshare: il processo chiamante si collega ad un namespace nuovo.

Nei panni degli sviluppatori core

March 13 2018

Etherpad 13/03/18

Registrazione 13/03/18

Quando si trasmette una lista di interfacce in protocollo netlink prevede il pacchetto "done" come sentinella finale. In alternativa si può usare busybox ip addr in quanto ip addr di busybox non fa nessun controllo sul pacchetto done.

#Facciamo partire una macchina virtuale in un terminale.
umview xterm
#Vediamo le vere interfacce di rete.
ip addr
#Carichiamo il supporto per le reti virtuali.
um_add_service umnet

#vde vuole indirizzi simili agli url.
#???????? vedere meglio nella documentazione ???????????????

mount -t umnetlwipv6 -o vde0=vxvde:// none /dev/net/mynet
#Osserviamo di nuovo le interfacce di rete.
ip link

#Vediamo le interfacce precedenti in quanto la nuova rete non è montata come rete di default.
#Possiamo avere tanti stack diversi ognuno con le sue interfacce.

#mstack --> multiple stack; comando di umview usare lo stack selezionato.
mstack /dev/net/mynet ip link
#Se volessi far partire un browser su quello stack dovrei fare
mstack /dev/net/mynet firefox
#Se volessi far partire una connessione ssh
mstack /dev/net/mynet ssh
#Se volessimo avviare un terminale che vive nella rete nuova potremmo fare
mstack /dev/net/mynet bash

ip addr add 10.0.0.1/24 dev vd0
ip link set vd0 up

Se adesso su un'altra macchina della rete locale facessi le stesse operazioni con un indirizzo ip diverso, le macchine avrebbero la possibilità di mettersi in contatto.

Per completezza dell'esempio realizziamo l'altro stack con vdens (namespace di vde).

Parte dell'esempio fatto dal prof; qui viene usato in entrambi i terminali vdens, mentre il prof a lezione ha usato per uno umnet e vdens per l'altro. Sono necessari vdens ,vdeplug4 ( e forse anche vxvdex).

Per entrambe le sessioni del terminale setto una variabile d'ambiente in modo che mi cerchi la libvdeplug.so.4 in /usr/local/lib.

 export LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib

Terminale 1

 vdens vxvde://
 ip link set vde0 up
 ip addr add 10.0.0.1/24 dev vde0
 
 ping 10.0.0.2

 nc 10.0.0.2 2222

#scrivendo dei messaggi nel terminale 1 compariranno nel 2 e viceversa

Terminale 2

 vdens vxvde://
 ip link set vde0 up
 ip addr add 10.0.0.1/24 dev vde0

#ora nel terminale 1 posso eseguire ping 10.0.0.2

 nc -l 2222
#ora nel terminale 1 posso eseguire  nc 10.0.0.2 2222


Stack TCP/IP: o implementato a livello utente come libreria o implementato nel kernel.
umview --> prima opzione.
vdens --> chiede al kernel di costruire un altro stack TCP/IP per questo utente (sfrutta i namespace).

nc (alias netcat) coltellino svizzero per esperimenti su rete.

#Connessione TCP alla porta 22 di maddalena
nc mad.cs.unibo.it 22
#Connessione alla porta 80 
nc 130.136.1.110 80
nc permette di collegarsi tramite TCP e di scrivere HTTP manualmente

#Faccio un server TCP in ascolto su porta 2222
nc -l 2222
#Mi connetto alla porta 2222 dell'indirizzo 10.0.0.2
nc 10.0.0.2 2222

Un utente può creare tutti gli stack di rete che vuole ed averne vari a disposizione con configurazioni diverse.
Esempio: possiamo lanciare un browser facendo in modo che il browser non sia logicamente dove siamo ma usi un ip di un'altra area geografica.

  • Così facendo inganneremmo where si my ip
  • Comodo per testare la neutralità della rete. Stessa pagina acceduta con ip di aree geografiche diverse appare nello stesso modo.

Se volessimo implementare un VPN per sicurezza aziendale normalmente dovremmo spostare tutta la macchina dentro il VPN, con questo metodo possiamo avere un solo stack connesso al VPN.

I supporti di rete, file system e device, portandoli fuori dal kernel in user mode ricordano il concetto di microkernel.
ViewOS serve anche per poter fare una transizione dolce dai kernel monolitici ai microkernel; è come avere un microkernel configurabile a runtime.

  • Possiamo decidere di tenere parti del kernel (moduli) in spazio utente tramite moduli di ViewOS. è meno efficiente ma più sicuro e si usa solo all'occorrenza.
  • Se dovessimo gestire un tipo di file system appena inventato (di cui non abbiamo il supporto nel kernel) per inserire il supporto del kernel dovremmo ricompilare tutto; Se usiamo un modulo a livello utente no.

ViewOS è una specifica; per ora è stato implementato tramite system call interposition (ptrace), ma può essere implementato in altri modi.

Potremmo implementare il tutto attraverso i namespace, nel kernel (e.g. vdens). Creare diversi visioni dell'ambiente.

March 15 2018

Lezione sospesa causa lauree.

March 20 2018

Etherpad 20/03/18

Registrazione 20/03/18

March 22 2018

Etherpad 22/03/18

Registrazione 22/03/18

March 27 2018

Etherpad 27/03/18

Registrazione 27/03/18 pt1 pt2


Esempio su veth

Terminale 1

 sudo bash

 ip link add type veth
 ip link

# solo per avere una panoramica del comando
 ip netns help 

 ip netns add renzonet
 ip netns list

#trasferiamo veth1 nel namespace appena creato renzonet
 ip link set veth1 netns renzonet
 ip netns exec renzonet ip addr


 ip addr add 10.1.1.1/24 dev veth0
 ip link set veth0 up

Terminale 2

 sudo bash

 ip netns exec renzonet bash
 ip addr add 10.1.1.2/24 dev veth1
 ip link set veth1 up


 ping 10.1.1.1


# per riportare le cose allo stato precedente
#il comando si prende la libertà di eliminare anche veth0 e veth1 create con 'ip link add type veth'
 ip netns delete renzonet

April 05 2018

Etherpad 05/04/18

Registrazione 05/04/18

Esempio fatto alla fine riguardo la gestione dei file in umvu

 umvu xterm

Terminale xterm 1

 #step 1
 xterm &
 
 vu_insmod mountreal

 #step 3
 ps -ax | grep less #leggo il pid di less /unreal/etc/services

 cd /proc/pid/fd # pid è quello letto poco prima
 ls -l | grep .vu

Terminale xterm 2

 #step 2
 less /unreal/etc/services #less mostra il file e lo mantiene aperto

April 10 2018

Etherpad 19/04/18

Registrazione 19/04/18

April 12 2018

Etherpad del 12/04/18

Registrazione del 12/04/18

April 17 2018

Etherpad del 17/04

Registrazione del 17/04 pt1 pt2

April 19 2018

April 24 2018

April 27 2018

May 03 2018

May 08 2018

May 10 2018

May 15 2018

May 17 2018

May 22 2018

May 24 2018