URL: https://linuxfr.org/users/laurentu/journaux/uml-est-vivant Title: UML est vivant Authors: passke Date: 2021年05月14日T20:11:49+02:00 License: CC By-SA Tags: virtualisation, noyau_linux et debian Score: 36 Salut Nal, Il y a longtemps, bien longtemps, les solutions de virtualisation libres sous *Linux* n'étaient pas bien nombreuses. Pas de *kvm*, *docker*, *lxc* ou *podman* et *qemu* en était à ses débuts. Il existait des solutions légères comme [*linux-vservers*](http://linux-vserver.org/) et [*openvz*](https://openvz.org/) mais qui nécessitaient un patch du noyau *Linux* (pour la petite histoire, il s'agissait de solutions qui aujourd'hui entreraient dans la catégorie conteneurs). Si tu avais de la chance, ta distribution fournissait des noyaux patchés (c'était le cas de la Debian par exemple), mais sinon tu avais droit à une recompilation du noyau. C'est là que "user mode linux" entrait en jeu, car il te permettait de tester ton noyau fraîchement compilé sans avoir à l'installer sur une machine physique au risque de la voir se planter au démarrage. "User Mode Linux" ou plus simplement *UML* c'était à l'époque un noyau *Linux* patché qui pouvait être lancé comme un exécutable standard dans un système existant. On lui fournissait une image de système de fichier pour qu'il puisse démarrer un système (plus ou moins) complet, dans l'espace utilisateur, et ce sans privilèges particuliers. D'abord conçu pour tester les noyaux, il était aussi possible de l'utiliser comme solution de virtualisation. En terme de performance, il était bien en-dessous des solutions type conteneurs comme *openvz*, mais meilleur que des solutions de virtualisation pure telle que *qemu* ou *bochs*. Je me suis récemment lancé dans la construction d'un système minimaliste avec [*buildroot*](https://buildroot.org/) et je me suis demandé comment tester ce système au fur et à mesure de sa progression. J'aurai bien évidemment pu utiliser *kvm*, mais en cherchant un peu j'ai vu que *UML* était toujours bien vivant, et qu'en plus la Debian fournissait un noyau précompilé. En plus *buildroot* semblait capable de générer un système de fichier tel que *UML* devrait pouvoir le gérer. Alignement de planètes, il fallait que j'essaie. # Création du rootfs avec buildroot # Le but est d'avoir un système Linux minimaliste en utilisant notamment busybox. *buildroot* permet de générer un tel système non seulement pour l'architecture sur laquelle il lancé, mais également pour d'autres architectures, pour les *raspberry PI* par exemple. Il automatise la mécanique de compilation croisée nécessaire à la création d'un tel système tout en intégrant la possibilité d'installer toute un série de logiciels. On commence par télécharger et extraire la version stable de *buildroot* (la 2021年02月2日 au moment ou j'écris ceci). ```bash wget https://buildroot.org/downloads/buildroot-2021年02月2日.tar.gz tar xzf buildroot-2021年02月2日.tar.gz cd buildroot-2021年02月2日/ ``` Pour fonctionner, il est indispensable d'installer un certain nombre de dépendances: ```bash sudo apt install build-essential libncurses-dev unzip rsync bc ``` La première étape consiste à configurer la cible que l'on désire générer. Pour cela *buildroot* propose un menu très détaillé lorsque l'on passe la commande ```make menuconfig```. Pour un premier essai, j'ai configuré les éléments suivants: * Target options -> Target Architecture (x86_64) * Filesystem images -> [*] ext2/3/4 root filesystem -> ext2/3/4 variant (ext4) Il est maintenant possible de générer l'image du système avec *make*, mais attention cela va prendre un peu de temps et de disque. Si tu as plusieurs coeurs (de processeurs) disponibles, tu peux utiliser l'option ```-j``` pour lancer **n** constructions parallèles histoire de réduire le temps de compilation. ```bash make -j2 ``` A la fin du processus l'image générée est *output/images/rootfs.ext4*. # User Mode Linux # Le [site officiel](http://user-mode-linux.sourceforge.net/) peut facilement laisser penser que le projet est moribond. Il faut fouiller un peu plus pour voir que depuis un bon moment *UML* est intégré au noyau *Linux* standard. On trouve dans la [documentation](https://www.kernel.org/doc/html/v5.12/virt/uml/user_mode_linux_howto_v2.html) des noyaux récents une section dédiée à *UML* bien plus à jour et utile. La version *Buster* de Debian fournit un noyau *UML* pré-compilé et correspondant au noyau de la distribution. Pour l'installer il suffit d'un ```apt install user-mode-linux```. Le paquet fourni donc l'exécutable */usr/bin/linux* ainsi qu'une série de modules pour ce noyau dans */usr/lib/uml/modules*. Pour lancer notre système il nous suffit de passer la commande suivante: ```bash linux mem=256M ubd0=output/images/rootfs.ext4 umid=test Core dump limits : soft - 0 hard - NONE Checking that ptrace can change system call numbers...OK Checking syscall emulation patch for ptrace...OK Checking advanced syscall emulation patch for ptrace...OK ... Run /sbin/init as init process random: fast init done EXT4-fs (ubda): re-mounted. Opts: (null) Starting syslogd: OK Starting klogd: OK Running sysctl: OK Initializing random number generator: OK Saving random seed: random: dd: uninitialized urandom read (512 bytes read) OK Starting network: OK Welcome to Buildroot buildroot login: root # ``` Voilà, tu viens de lancer un système Linux/busybox en tant qu'utilisateur non privilégié et tu peux t'amuser en tant que *root* dans ce système. Si ça ne fonctionne pas tu auras l'occasion pour une fois de faire un: ```bash killall linux ``` Un point intéressant est que tu peux facilement avoir accès au système de fichier de l'hôte grâce à *hostfs*. Par exemple pour monter dans ton *UML* le répertoire utilisateur de l'hôte: ```bash mount -t hostfs -o /home/passke hostfs /mnt mount /dev/root on / type ext4 (rw,relatime) devtmpfs on /dev type devtmpfs (rw,relatime,mode=755) proc on /proc type proc (rw,relatime) devpts on /dev/pts type devpts (rw,relatime,gid=5,mode=620,ptmxmode=666) tmpfs on /dev/shm type tmpfs (rw,relatime,mode=777) tmpfs on /tmp type tmpfs (rw,relatime) tmpfs on /run type tmpfs (rw,nosuid,nodev,relatime,mode=755) sysfs on /sys type sysfs (rw,relatime) hostfs on /mnt type hostfs (rw,relatime,/home/passke) ``` Le noyau de ton *UML* ne peut pour l'instant pas charger de modules, le répertoire */lib/modules* étant vide. Mais comme cité plus haut, la Debian fournit les modules nécessaires sur l'hôte dans */usr/lib/uml/modules* et il suffit donc de le monter au bon endroit: ```bash mkdir /lib/modules mount -t hostfs -o /usr/lib/uml/modules/ hostfs /lib/modules modprobe loop loop: module loaded ``` # Compilation d'un noyau Linux en mode user # Pour l'instant on a utilisé le paquet fourni par la distribution, mais on peut également compiler un noyau récent en mode user assez facilement. La première étape consiste assez classiquement à télécharger et extraire une version du noyau à partir de *kernel.org*. ```bash wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.12.4.tar.xz tar xJf linux-5.12.4.tar.xz cd linux-5.12.4/ ``` Puis on installe quelques dépendances: ```bash sudo apt install flex bison ``` D'habitude pour configurer un noyau on utilise le fichier de configuration fourni par la distribution (dans */boot* sur Debian). Pour *UML*, c'est un peu différent, on commence par générer une nouvelle configuration en précisant qu'il s'agit d'une architecture *um* (=user mode). Puis le reste du processus est identique à la compilation d'un noyau classique, excepté qu'il faut systématiquement préciser l'architecture *um*. ```bash make defconfig ARCH=um make menuconfig ARCH=um make ARCH=um ``` Le processus devrait avoir généré un fichier exécutable *linux* à la racine des sources, et on peut donc maintenant lancer notre *UML* avec un noyau plus récent: ```bash ./linux mem=256M ubd0=../buildroot-2021年02月2日/output/images/rootfs.ext4 umid=test Initializing random number generator: OK Saving random seed: random: dd: uninitialized urandom read (512 bytes read) OK Starting network: OK Welcome to Buildroot buildroot login: root # uname -a Linux buildroot 5.12.4 #1 Fri May 14 15:13:12 CEST 2021 x86_64 GNU/Linux ``` Pour l'instant par de modules du noyau disponbiles, on va arranger ça vite fait (sur l'hôte): ```bash export INSTALL_MOD_PATH=../modules make modules_install ARCH=um ``` On peut maintenant les utiliser dans l'*UML*: ```bash mount -t hostfs -o /home/passke/modules/lib/modules hostfs /lib/modules modprobe loop loop: module loaded ``` Je vais m'arrêter là, mais il y a encore plein de choses à expérimenter, le réseau par exemple. De ce côté, même si la configuration reste un peu complexe, elle a quand même bien évolué. *UML* peut être intéressant par exemple pour faire de la virtualisation sur des machines ne disposant pas du support *kvm*, ou alors pour expérimenter des fonctionnalités offertes par les noyaux récents, [eBPF](https://ebpf.io/) par exemple ou alors construire des images sans avoir besoin des droits *root* sur le système hôte.

AltStyle によって変換されたページ (->オリジナル) /