User Mode Linux

Un portage du noyau Linux vers

l'espace utilisateur

Frédéric Tronel

15 Avril 2004

Plan

Le projet

Concept

Historique

Principe de fonctionnement

mode trace

mode à espace d'adressage commuté

Démonstration

Le futur

Conclusion

Présentation du projet

Projet initié par Jeff Dike (New Hampshire, USA).

Projet débuté en Février 1999, et rendu public en juin 1999.

Transformation du noyau Linux en un processus utilisateur.

Applications

Hébergement de plusieurs systèmes (distributions, noyaux) sur un même système hôte:

Mise au point d'applications critiques

Pot de miel

Mutualisation de ressources (ferme de serveurs)

Déverminage plus aisé du noyau

Niveaux de virtualisation

Donner l'impression à un processus qu'il s'exécute sur une autre architecture

Plusieurs niveaux d'abstraction sont possibles:

chroot: seul le système de fichiers est modifié.

wine: exécution d'applications Win32 sur Linux (les appels système sont détournés).

vmware: virtualisation complète (instructions machines exécutées en mode pas à pas).

UML se situe au même niveau que wine

Problèmes à résoudre

Instructions natives sont directement exécutées:

Rien à faire !

Détournement des appels systèmes vers le noyau UML:

Ce que fait déjà strace

Séparation de l'espace d'adressage des processus UML / noyau UML:

Les processus natifs bénéficient déjà d'espace d'adressage séparés (on peut en profiter)

Modes de fonctionnement

Mode trace:

Plus ancien

Ne nécessite pas de modifier le noyau de la machine hôte

Lent

Mode à espace d'adressage séparé (skas):

Nécessité de patcher le noyau de la machine hôte

Résout certains problèmes de lenteur du mode trace

Appels natifs et
appels au système

main:

pushl %ebp

movl %esp, %ebp

subl $8, %esp

andl $-16, %esp

movl $0, %eax

subl %eax, %esp

movl $10, -4(%ebp)

leal -4(%ebp), %eax

incl (%eax)

call getpid

movl %eax, -4(%ebp)

movl $0, %eax

leave

ret

#include <stdio.h>

#include <stdlib.h>

int main(){

int i;

i=10;

i=i+1;

i = getpid();

return 0;

}

Détournement
des appels systèmes

On utilise l'appel système ptrace

Utilisé par strace pour tracer les appels systèmes effectués par les programmes

Le processus père s'endort sur un appel wait. Réveil sur:

Réception d'un signal par le processus fils

Entrée/sortie d'un appel système

Mode pas à pas

Terminaison

Possibilité de récupérer le contexte (registres, pile)

strace minimal

int main(){

int res,pid; struct user data;struct user_regs_struct regs;

char *arguments[]={"/bin/uname",NULL};

if((pid=fork())==0){

printf("Je suis le fils\n");

ptrace(PTRACE_TRACEME,NULL,NULL);

execv("/bin/uname",arguments);

}

else{

printf("Je suis le père\n");

while(1){

wait(&res);

traitement_signal(res,pid);

}

}

}

strace minimal

int traitement_signal(int res, int pid){

int signal,appel;struct user contexte;

if(WIFSTOPPED(res)){

signal=WSTOPSIG(res);

switch(signal){

case SIGTRAP:

// On entre dans un appel système

// On récupère le contexte

ptrace(PTRACE_GETREGS,pid,NULL,&contexte);

appel=contexte.regs.orig_eax;

printf("Appel système %s\n",nom[appel]);

// On continue sans délivrer le signal jusqu'au retour de l'appel

ptrace(PTRACE_SYSCALL,pid,NULL,NULL);

wait(NULL);

// On continue jusqu'au prochain appel système

ptrace(PTRACE_SYSCALL,pid,NULL,NULL);

break;

default:

// Signal autre que SIGTRAP que l'on délivre de manière transparente

printf("Le processus fils reçoit un signal: %d\n",signal);

ptrace(PTRACE_CONT,pid,NULL,signal);

}

}

else{

printf("Terminé\n");

exit(0);

}

}

Tracing Thread (mode tt)

Mode le plus ancien

Processus traceur

Un processus sur la machine hôte par processus dans la machine virtuelle

On profite des espaces d'adressage séparés entre processus natifs pour simuler la séparation des espaces d'adressage sur la machine virtuelle

Fonctionnement

Espace d'adressage
Processus « normal »

Espace noyau hôte

0xc0000000

(1Go)

Code processus

0x08000000-...

Librairies partagées

0x40000000-...

Pile

...-0xc0000000

Espace d'adressage
Processus « UML » en mode tt

Code processus

0x08000000-...

Espace noyau hôte

0xc0000000

(1Go)

Librairies partagées

0x40000000-...

Pile

...-0xa0000000

Noyau UML

0xa0000000

(0.5Go)

Fonctionnement
(appel système)

Processus traceur:

Transforme l'appel système en getpid() et sauve l'état du processus fils

Arrête le mode trace pour le processus fils

Envoi d'un signal SIGUSR2

Processus fils:

Handler du signal SIGUSR2 change le mode d'exécution (code noyau UML)

Exécution de l'appel système (noyau UML)

Remise en place du mode trace et envoi d'un signal SIGUSR1

Fonctionnement
(appel système)

Processus traceur:

Annulation du signal SIGUSR1

Restauration de l'état du processus fils et de la valeur de retour de l'appel système

Continue le processus fils

Processus fils continue avec la valeur de retour de l'appel système !

Fonctionnement

Avantages et inconvénients

Avantages:

Pas besoin de patcher le noyau hôte

Inconvénients:

Grande consommation de ressources (nombreux processus créés)

L'espace noyau n'est pas bien protégé

Lenteur due aux nombreux:

changements de contexte

signaux à délivrer

Mode à espaces d'adressage
séparés (skas)

Différences par rapport au mode tt:

Nécessite de patcher le noyau hôte

Permet à un processus de posséder plusieurs espaces d'adressage indépendants

Permet de switcher entre ces différents espaces

Moins de ressources consommées

Deux processus natifs:

Processus noyau

Processus courant (un par processeur virtuel en fait)

Fonctionnement

Appels système

Processus noyau intercepte les appels systèmes:

Exécute les appels

Retourne la valeur de l'appel dans le processus appelant

Changements de contexte sont transformés en changement d'espace d'adressage

Espace d'adressage
mode skas

Espace noyau hôte

0xc0000000

(1Go)

Code processus

0x08000000-...

Librairies partagées

0x40000000-...

Pile

...-0xc0000000

Processus en cours d'exécution

Espace d'adressage
mode skas

Processus noyau

Espace noyau hôte

0xc0000000

(1Go)

Librairies partagées

0x40000000-...

Pile

...-0xa0000000

Noyau UML

0xa0000000

(0.5Go)

Avantages et inconvénients

Avantages:

Beaucoup plus rapide que le mode tt

Plus sûr (les processus ne peuvent plus accéder à l'espace noyau)

Moins gourmand en ressources

Inconvénients:

Nécessite de patcher le noyau

Démonstration

Le futur

Projets de Jeff Dike

Portage pour d'autres architectures

Création de patchs « skas » acceptables pour Linus Torvalds:)

Meilleure coopération entre le noyau hôte et le noyau utilisateur en ce qui concerne la gestion de la mémoire virtuelle

Compatibilité avec la suspension sur le disque (swsusp des noyaux 2.6.x)

Conclusion

Projet déjà mature

Utilisable en environnement industriel

Mode skas est plus rapide et sûr

Des questions ?

User Mode Linux

2004-03-29T10:53:09