Un VPS sous Gentoo

Ceux qui ont déjà eu recours à des solutions de VPS offertes par iKoula, OVH, Behost, etc ont dû ressentir la même déception devant le nombre réduit de distributions disponibles à l’installation : toujours le bon vieux trio Debian/Ubuntu/CentOS (OVH propose tout de même ArchLinux). Quand on est un inconditionnel de Gentoo ou autre c’est plutôt frustrant. Je n’ai pas encore trouvé d’hébergeur qui fournisse une option de boot sur ISO comme ce qui se fait avec les serveurs dédiés (c’était encore possible sur les VPS Flex d’iKoula il y a peu de temps mais ça n’existe plus : https://fr.ikoula.wiki/fr/Netboot_sur_serveur_flex).

Qu’à cela ne tienne, on peut quand même tenter de démarrer sur un « livecd » depuis un système pré-installé. Le but de la manœuvre n’étant pas seulement d’installer un système Gentoo mais également d’avoir la possibilité de réparer un système existant ou de réaliser des sauvegardes des volumes disques depuis un système de secours.

Quel serveur virtuel ?

Mon choix s’est d’abord porté sur un serveur virtuel FlexiCloud de iKoula sous Debian Wheezy. La technologie utilisée est HyperV mais l’installation reste classique. Un unique disque présente une table de partition GPT (c’est une bonne chose : ça apporte la possibilité d’identifier depuis le noyau une partition par son PARTUUID). Le /boot est dimensionné à 1G, ça tombe bien il faudra de la place pour stocker plusieurs noyaux et initrd entre autres. Par contre bizarrement deux autres partitions primaires de 9 et 40 Gio sont affectées à un même volume groupe LVM qui contient le swap et le système de fichiers racine. Je n’ai pas trouvé l’intérêt, il s’agit peut-être des réminiscences d’un ancien partitionnement système/data. Un lecteur CDROM scsi virtuel est attaché mais il ne contient aucun média.

root@xxxxxxxxxx:~# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 50G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 954M 0 part /boot
├─sda3 8:3 0 9.1G 0 part
│ ├─vg01-root (dm-0) 253:0 0 48.1G 0 lvm /
│ └─vg01-swap (dm-1) 253:1 0 952M 0 lvm [SWAP]
└─sda4 8:4 0 40G 0 part
 └─vg01-root (dm-0) 253:0 0 48.1G 0 lvm /
sr0 11:0 1 1024M 0 rom

La console KVM

La condition essentielle pour pouvoir réaliser l’opération est d’avoir accès à la console de la machine virtuelle, au moins pour pouvoir interagir avec Grub lors de redémarrages. Il est toujours possible de se lancer à l’aveugle et de restaurer un système fonctionnel à partir d’un snapshot en cas de problème, mais dans le cadre de tests où l’on avance pas à pas c’est indispensable.

Le problème c’est que iKoula a récemment migré ses hyperviseurs vers HyperV3 et la procédure de connexion au KVM a changé : https://fr.ikoula.wiki/fr/Connexion_%C3%A0_la_console_virtuelle_KVM. La console intégrée accessible via le navigateur est inutilisable : je n’ai pas réussi à me servir du clavier que ce soit avec Firefox, Chrome ou IE. L’accès en client lourd nécessite l’utilisation de xfreerdp sous Linux ou wfreerdp sous Windows. Seulement à partir d’un système CentOS 6, la commande xfreerdp officielle ne reconnait pas certains paramètres fournis dans le script de connexion iKoula (l’installation du client fourni sous forme de RPM n’a pas fonctionné à cause d’un problème de dépendances). Je me suis donc rabattu vers la solution wfreerdp sans plus de résultats : la commande retourne sans aucun message d’erreur. Un test d’accès au port TCP 2179 utilisé par FreeRDP vers le serveur distant révèle que les flux sont bloqués chez iKoula. Une ouverture de ticket auprès du support est nécessaire pour autoriser l’accès à la console (depuis l’adresse IP publique de sa box uniquement).

Une fois l’accès à la console opérationnelle, on peut commencer sereinement.

Comme un liveCD

Un système liveCD/liveUSB Linux, ce n’est ni plus ni moins (pour la première phase) qu’un noyau et un initrd/initramfs chargés au boot à partir de grub ou syslinux. L’initrd est un système de fichiers déployé en mémoire contenant un ensemble réduit de commandes et de modules permettant d’initialiser le système avant d’avoir accès à la partition disque racine réelle. Dans le cas d’un système de type live, pas besoin du disque : le noyau continue à fonctionner sur le système « réduit ». A partir de là, les distributions live utilisent différents mécanismes pour obtenir au final un système aussi fonctionnel qu’une distribution sur disque classique.

Grub est installé sur le serveur virtuel pour lui permettre de booter sur le noyau Debian, il suffit donc en théorie d’adapter sa configuration pour lui faire charger le noyau et l’initrd présents sur un livecd. J’ai une préférence pour sysrecuecd qui est polyvalent, personnalisable et qui en plus est basé sur Gentoo. On commence par télécharger l’ISO d’un peu plus de 400 Mo sur le VPS.

wget http://downloads.sourceforge.net/project/systemrescuecd/sysresccd-x86/4.7.1/systemrescuecd-x86-4.7.1.iso

L’image est ensuite montée dans un répertoire local.

mount -o loop systemrescuecd-x86-4.7.1.iso /media/cdrom

Le répertoire isolinux de l’ISO contient des noyaux, un initramfs et la configuration utilisée par isolinux (le bootloader du projet syslinux utilisé pour les CDs/DVDs).

ls -al /media/cdrom/isolinux/
-rw-r--r-- 1 root root 12602160 Jan  1 23:52 altker32
-rw-r--r-- 1 root root 13857568 Jan  1 23:32 altker64
-r--r--r-- 1 root root     2048 Jan 18 21:46 boot.cat
-rwxrwxr-x 1 root root    38696 Oct 23  2012 chain.c32
-rw-r--r-- 1 root root     1394 Jan 18 21:46 f1boot.msg
-rw-r--r-- 1 root root     1363 Jan 18 21:46 f2images.msg
-rw-r--r-- 1 root root     1767 Jan 18 21:46 f3params.msg
-rw-r--r-- 1 root root     1519 Jan 18 21:46 f4arun.msg
-rw-r--r-- 1 root root     1655 Jan 18 21:46 f5troubl.msg
-rw-r--r-- 1 root root     1260 Jan 18 21:46 f6pxe.msg
-rw-r--r-- 1 root root     1360 Jan 18 21:46 f7net.msg
-rwxr-xr-x 1 root root     1312 Nov 11  2012 ifcpu64.c32
-rw-r--r-- 1 root root 15403208 Jan 18 21:46 initram.igz
-rw-r--r-- 1 root root    24576 Nov 11  2012 isolinux.bin
-rw-r--r-- 1 root root    18799 Jan 18 21:46 isolinux.cfg
-rw-r--r-- 1 root root     1952 Jan 18 21:46 isolinux.old
-rwxr-xr-x 1 root root     5212 Nov 11  2012 kbdmap.c32
drwxr-xr-x 1 root root     6144 Jul 17  2014 maps
-rw-r--r-- 1 root root    26140 Nov 11  2012 memdisk
-rwxrwxr-x 1 root root    56292 Nov 11  2012 menu.c32
-rw-r--r-- 1 root root   208154 Dec  5  2010 netboot
-rw-r--r-- 1 root root    26579 Nov 11  2012 pxelinux.0
-rwxr-xr-x 1 root root      800 Nov 11  2012 reboot.c32
-rw-r--r-- 1 root root 12560768 Jan  1 23:13 rescue32
-rw-r--r-- 1 root root 13701488 Jan  1 22:49 rescue64
-rwxrwxr-x 1 root root   155792 Oct 23  2012 vesamenu.c32

Selon le fichier de configuration isolinux.cfg, l’option de lancement 64 bits générique charge le noyau rescue64 et l’initramfs initram.igz.

LABEL rescue64_1
MENU LABEL 1. SystemRescueCd with default options
LINUX rescue64
INITRD initram.igz
TEXT HELP
Boot standard 64bit kernel with default options (should always work)
ENDTEXT

L’option de démarrage par défaut charge elle un binaire ifcpu64.c32 dont le rôle est apparemment de déterminer si le processeur supporte le mode 64 bits et de charger en conséquence un noyau 32 ou 64 bits. Je ne pense pas qu’il existe d’hébergeur utilisant encore des serveurs 32 bits, on peut donc se passer de ce « wrapper ».

Il suffit ensuite de copier les deux fichiers rescue64 et initram.igz dans le répertoire /boot et d’adapter le fichier de configuration de grub /boot/grub/brub.cfg pour y ajouter une nouvelle entrée, dupliquée à partir de celle existante pour Debian.

cp /media/cdrom/isolinux/rescue64 /boot/
cp /media/cdrom/isolinux/initram.igz /boot/

/boot/grub/brub.cfg

menuentry 'SysRescueCD' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='(/dev/sda,gpt2)'
        search --no-floppy --fs-uuid --set=root 9068308c-3790-44e7-82cb-f04fa8dcf9fe
        linux   /rescue64
        initrd  /initram.igz
}

Enfin on lance un reboot de la VM en s’assurant d’abord que l’on ait bien la main sur la console. A l’écran de sélection de Grub, on choisit la nouvelle entrée SysRescueCD.

Menu de sélction de Grub

Le noyau démarre, l’initramfs est reconnu mais après avoir renseigné un identifiant de keymap l’initialisation du système échoue, un fichier sysrcd.dat étant introuvable.

Démarrage du kernel rescue64

On dispose quand même d’un shell réduit qui nous permet de voir que le noyau prend bien en charge l’interface réseau mais malheureusement ne détecte pas de disque. Au delà du problème de fichier introuvable (on y reviendra), sans accès au disque attaché à la machine virtuelle cette solution n’a pas vraiment d’intérêt.

Minishell

On peut retenter l’expérience avec un noyau Linux alternatif en version 4.1.15 présent sur l’ISO de SystemRescueCD : altker64. Mais le même problème apparaît : toujours pas de disque détecté.

Une question de drivers

En redémarrant le VPS sur l’installation Debian d’origine, on remarque que le disque sda est présenté par un contrôleur virtuel HyperV.

root@xxxxxxxxx:~# ls -al /sys/block/sda
lrwxrwxrwx 1 root root 0 Mar  1 23:00 /sys/block/sda -> ../devices/LNXSYSTM:00/LNXSYBUS:00/PNP0A03:00/device:07/VMBUS:00/vmbus_0_1/host2/target2:0:0/2:0:0:0/block/sda
root@xxxxxxxxxx:~# dmesg |grep hv_
 [ 0.824936] hv_vmbus: Hyper-V Host OS Build:9600-6.3-18-0.18119
 [ 0.862979] hv_vmbus: registering driver hv_storvsc
 [ 0.863837] hv_vmbus: registering driver hid_hyperv
 [ 1.791940] hv_utils: Registering HyperV Utility Driver
 [ 1.791942] hv_vmbus: registering driver hv_util

Les drivers correspondants sont disponibles en tant que modules.

root@xxxxxxxxxx:~# lsmod | grep hv_
 hv_utils 12986 0
 hv_storvsc 17468 3
 hv_vmbus 36125 3 hv_storvsc,hid_hyperv,hv_utils
 scsi_mod 162321 6 libata,hv_storvsc,sd_mod,sg,sr_mod,mptctl

Après avoir redémarré une nouvelle fois sur le noyau SysRescueCD, on obtient confirmation qu’il a bien été compilé avec le support des devices HyperV, sous forme de modules également. Par contre, impossible de trouver ces modules dans le système restreint une fois l’initramfs monté en mémoire.

Pas de support pour HyperV

On le verra plus tard mais ces drivers sont en fait contenus dans le fameux fichier introuvable sysrcd.dat. Donc le liveCD est bien capable de prendre en charge ce type de disque mais il faut d’abord qu’il récupère les drivers qui sont en temps normal stockés sur CDROM ou clé USB. Or dans ce cas précis, il faudrait que l’on puisse charger depuis le disque les drivers qui sont justement censés nous y donner accès.

Exploration de l’initramfs

SystemRescueCD utilise un initramfs, le fichier initram.igz. Bien qu’ayant le même rôle, un initramfs est un peu différent d’un initrd. Le dernier est une image de système de fichiers potentiellement compressée qui va être mappée au boot sur un ramdisk (/dev/ram0) puis montée comme un périphérique bloc classique sur la racine du VFS. L’initramfs est une archive de type cpio qui peut également être compressée. Au boot, le noyau va monter un système de fichiers résidant en mémoire sur la racine et y extraire les fichiers de l’archive. La finalité est la même mais la deuxième solution présente quelques avantages, un des principaux étant que la taille de l’initramfs n’est pas limitée par la taille des ramdisks (https://en.wikipedia.org/wiki/Initrd).

On peut donc depuis le système Debian installé obtenir ce qui devient le système de fichiers restreint lorsque l’on boote sur le noyau rescue64. Il faut d’abord décompresser le fichier initram.igz, mais l’extension est trompeuse : il ne s’agit pas d’un fichier au format gzip mais bien xz.

root@xxxxxxxxx:~# file /boot/initram.igz
/boot/initram.igz: XZ compressed data

Après avoir fait une copie, l’archive est décompressée.

cp /boot/initram.igz /root/
unxz -S .igz initram.igz

Il s’agit bien d’une archive cpio.

root@xxxxxxxxx:~# file initram
initram: ASCII cpio archive (SVR4 with no CRC)

L’ensemble des fichiers est extrait dans un nouveau répertoire.

root@xxxxxxxxx:~# mkdir initram_sysrescd
root@xxxxxxxxx:~# cd initram_sysrescd/
root@xxxxxxxxx:~/initram_sysrescd# cpio -i < ../initram
71040 blocks

L’arborescence du système minimal est maintenant accessible.

root@xxxxxxxxx:~/initram_sysrescd# ls -Al
total 80
drwxr-xr-x 2 root root  4096 Mar  2 22:17 bin
drwxr-xr-x 2 root root  4096 Mar  2 22:17 dev
drwxr-xr-x 6 root root  4096 Mar  2 22:17 etc
-rwxr-xr-x 1 root root 55612 Mar  2 22:17 init
drwxr-xr-x 7 root root  4096 Mar  2 22:17 lib
drwxr-xr-x 2 root root  4096 Mar  2 22:17 sbin
drwxr-xr-x 3 root root  4096 Mar  2 22:17 usr

L’élément le plus important de l’initramfs se situe à la racine : init. Une fois le noyau initialisé, c’est ce programme qui va être exécuté en tant que processus numéro 1, comme sur un système classique. Il peut s’agir d’un binaire mais dans le cas présent c’est un script sh, ce qui va nous autoriser à regarder de plus près le déroulement du démarrage de SysRescueCD.

Init commence par initialiser un système minimal en utilisant busybox, un binaire de moins de 2 Mo capable de jouer le rôle d’un grand nombre de commandes comme cp, mount, cat, etc (busybox est souvent utilisé sur des systèmes embarqués pour en réduire l’empreinte mémoire). Plusieurs fonctions sont ensuite appelées pour récupérer les options de la ligne de commande, configurer le clavier, charger des modules noyau, configurer le réseau. Le reste du démarrage se déroule en 3 « stages ».

Il est bien indiqué dans la fonction du stage numéro 1 que son rôle est de chercher le fichier sysrcd.dat sur l’ensemble des périphériques de type bloc.

# find the device which contains sysrcd.dat and mount it on ${BOOTPATH}
sysresccd_stage1_normal()
{
    # search for sysrcd.dat on block devices
    good_msg "Searching for ${SUBDIR}/${LOOPDAT} on devices..."

A priori ce fichier contient des éléments supplémentaires au contenu de l’initramfs qui vont permettre de continuer l’initialisation du système. On remarque bien sa présence à la racine de l’ISO SysRescueCD, il représente un peu plus de 350 Mo.

root@xxxxxxxxx:~# ls -al /media/cdrom/sysrcd.dat
-rw-r--r-- 1 root root 353955840 Jan 18 21:46 /media/cdrom/sysrcd.dat

En temps normal, lorsque l’on démarre SysRescueCD à partir du CDROM ou d’une clé USB, le système primaire va pouvoir récupérer le sysrcd.dat à la racine du média. Seulement dans notre cas aucun média n’est présent. Par contre ce qui est intéressant, c’est que par défaut tous les périphériques de type bloc sont scannés. Il est donc possible de placer le sysrcd.dat à la racine de notre volume de boot (sda2), où sont déjà présents le noyau et l’initramfs. Par chance, le VPS iKoula est configuré de base avec une partition de boot de 1 Go, ce qui laisse assez de place pour y copier le fichier de 350 Mo.

root@xxxxxxxxx:~# cp /media/cdrom/sysrcd.dat /boot/
root@xxxxxxxxx:~# ls -Al /boot/
total 391798
-rw-r--r-- 1 root root    129281 Feb 29 18:10 config-3.2.0-4-amd64
drwxr-xr-x 3 root root      5120 Mar  7 05:24 grub
-rw-r--r-- 1 root root  15403208 Mar  7 18:28 initram.igz
-rw-r--r-- 1 root root  11451086 Mar  7 05:24 initrd.img-3.2.0-4-amd64
drwxr-xr-x 2 root root     12288 Dec 10  2014 lost+found
-rw-r--r-- 1 root root  13701488 Mar  7 18:28 rescue64
-rw-r--r-- 1 root root 353955840 Mar  7 20:58 sysrcd.dat
-rw-r--r-- 1 root root   2116318 Feb 29 18:10 System.map-3.2.0-4-amd64
-rw-r--r-- 1 root root   2845792 Feb 29 18:10 vmlinuz-3.2.0-4-amd64

Mais le problème reste entier : sans support des disques HyperV, il sera impossible de charger le sysrcd.dat à partir de la partition de boot. Il suffirait de mettre la main sur les modules adéquats pour pouvoir le contourner.

Dans la fonction du stage numéro 2 du script d’init, on découvre que le sysrcd.dat est en fait une image de type squashfs, destinée à être montée sur le système.

sysresccd_stage2_normal() # mount ${BOOTPATH}/sysrcd.dat on ${SQUASHFSMNT}
{
    good_msg "Mounting the squashfs root filesystem on ${SQUASHFSMNT}"

    mountok=''
    squashfsimg="${BOOTPATH}/${SUBDIR}/${LOOPDAT}"
    for fs in '-t squashfs' ''
    do
        if [ "$mountok" != "ok" ]
        then
            mount ${fs} ${squashfsopt} -o ro ${squashfsimg} ${SQUASHFSMNT} 2>/dev/null && mountok='ok'
        fi
    done

Squashfs est un système de fichiers compressés accessible en lecture seule. Les fichiers sont décompressés à la volée lors de leur lecture. Il n’est donc pas nécessaire de décompresser l’intégralité de ses éléments en mémoire avant de pouvoir les utiliser, comme ce qui se passe avec un initramfs. Avec SysRescueCD les fichiers du système sont donc récupérés au besoin directement depuis le CDROM ou la clé USB. Cette solution permet donc d’avoir un système beaucoup moins restreint en terme de taille et donc de pouvoir disposer de plus de commandes sans même avoir à utiliser busybox.

Il reste que le montage de l’image squashfs se fait obligatoirement en lecture seule, et un système Linux nécessite pour fonctionner correctement d’avoir accès en écriture à certains répertoires : /tmp et /run entre autres. C’est là qu’intervient le stage numéro 3 qui va combiner le système squashfs accessible en lecture seule et un emplacement accessible en écriture. Pour cela il utilise le « système de fichiers » Aufs pour superposer deux répertoires au contenu différent. Depuis l’espace utilisateur les fichiers en lecture seront toujours accessibles comme pour un système de fichiers classique. En cas de création ou de modification d’un fichier, ses données seront enregistrées sur le répertoire accessible en écriture.

    # 4. create the aufs filesystem
    if ! grep -q aufs /proc/filesystems
    then
        sysresccd_panic "Fatal error: aufs filesystem not supported by the kernel."
    fi
    if mount -t aufs none ${NEWROOT} -o dirs=${BACKSTORE_MEM}=rw:${AUFSEXTRA}${SQUASHFSMNT}=ro -o noatime
    then
        good_msg "The aufs filesystem has been created"

Au final, le système primaire busybox sera écrasé par ce système de fichiers combiné. Par défaut, SysRescueCD crée un système de fichier temporaire en mémoire pour stocker les modifications, mais il est également possible d’utiliser un fichier de « backstore » stocké sur un disque ou une clé USB. De cette manière, des données peuvent être conservées et survivre à un reboot.

Squashfs

De la même manière que dans le stage numéro 2, il est parfaitement possible de monter l’image squashfs contenue dans le fichier sysrcd.dat directement sur le système Debian.

root@xxxxxxxxx:~# mkdir /mnt/squashfs
root@xxxxxxxxx:~# mount -o loop -t squashfs /media/cdrom/sysrcd.dat /mnt/squashfs/

Ce qui deviendra le système de fichier final est alors disponible dans /mnt/squashfs.

root@xxxxxxxxx:~# ls -al /mnt/squashfs/
total 4
drwxr-xr-x 21 root root  322 Jan 18 21:42 .
drwxr-xr-x  3 root root 4096 Mar  7 21:15 ..
drwxr-xr-x  2 root root 1529 Jan 18 21:41 bin
drwxr-xr-x  3 root root   99 Jan 18 21:42 boot
drwxr-xr-x  3 root root 2302 Jan 16 13:53 dev
drwxr-xr-x 98 root root 3293 Jan 18 21:42 etc
drwxr-xr-x  2 root root   28 Jan 16 13:53 home
drwxr-xr-x 19 root root 4396 Jan 18 21:42 lib
drwxr-xr-x  3 root root   30 Jan  1 22:49 lib64
drwxr-xr-x  2 root root   28 Jan 16 13:53 media
drwxr-xr-x  2 root root   28 Jan 16 13:53 mnt
drwxr-xr-x  2 root root   28 Jan 16 13:53 opt
drwxr-xr-x  2 root root    3 Jan 16 13:52 proc
drwx------  7 root root  353 Jan 18 21:41 root
drwxr-xr-x  4 root root   55 Jan 18 20:50 run
drwxr-xr-x  2 root root 5200 Jan 18 21:41 sbin
drwxr-xr-x  2 root root   28 Jan 16 13:53 sys
drwxr-xr-x  2 root root   33 Jul 17  2014 tftpboot
drwxrwxrwt  2 root root    3 Jan 18 21:42 tmp
drwxr-xr-x 13 root root  265 Jan 18 21:42 usr
drwxr-xr-x 13 root root  188 Jan 18 21:42 var

Si comme on l’a vu le noyau a été compilé avec le support des devices HyperV en tant que modules, ils ont peut être été placés dans cette arborescence, moins restreinte en taille que l’initramfs. Les binaires des modules sont normalement placés dans /lib/modules/`uname -r`/, ce qui donne pour le noyau rescue64 /lib/modules/3.18.25-std471-amd64/. Ce répertoire est en fait un lien symbolique vers /lib64/modules/3.18.25-std471-amd64.

root@xxxxxxxxx:~# find /mnt/squashfs/lib64/modules/3.18.25-std471-amd64/ -name "hv_*"
/mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/hv/hv_balloon.ko
/mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/hv/hv_utils.ko
/mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/hv/hv_vmbus.ko
/mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/net/hyperv/hv_netvsc.ko
/mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/scsi/hv_storvsc.ko

Bingo ! Il ne reste plus qu’à copier les fichiers hv_storvsc.ko et hv_vmbus.ko dans l’arborescence de l’initramfs. Mais nouvelle surprise : le répertoire /lib/modules n’existe pas dans l’initramfs.

root@xxxxxxxxx:~# ls -al initram_sysrescuecd/lib/modules
ls: cannot access initram_sysrescuecd/lib/modules: No such file or directory

Il est pourtant bien disponible lorsque l’on boote sur le noyau rescue64.

Pas de répertoire modules

Il s’agit d’une astuce de SysRescueCD pour gagner un peu de place : en plus de l’initramfs initram.igz chargé par Grub, chaque noyau disponible (3.18 32 bits, 3.18 64 bits, 4.1.15 32 bits et 4.1.15 64 bits) inclut un second initramfs contenant uniquement les modules compilés pour sa version. En effet il est possible lors de la compilation du noyau Linux de spécifier un répertoire qui sera embarqué en tant qu’initramfs dans le bzimage. Lors du démarrage, les fichiers des deux initramfs sont combinés dans le système de fichiers en mémoire. Cette méthode évite de devoir stocker les quatre versions disponibles des modules dans le fichier initram.igz.

Mais rien ne nous empêche de placer les modules HyperV dans le fichier initram.igz, au boot ils seront ajoutés à l’arborescence de l’initramfs du noyau. Il suffit de créer l’arborescence nécessaire.

root@xxxxxxxxx:~# mkdir -p initram_sysrescuecd/lib/modules/3.18.25-std471-amd64/kernel/drivers/scsi
root@xxxxxxxxx:~# mkdir -p initram_sysrescuecd/lib/modules/3.18.25-std471-amd64/kernel/drivers/hv
root@xxxxxxxxx:~# cp /mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/hv/hv_vmbus.ko initram_sysrescuecd/lib/modules/3.18.25-std471-amd64/kernel/drivers/hv/
root@xxxxxxxxx:~# cp /mnt/squashfs/lib64/modules/3.18.25-std471-amd64/kernel/drivers/scsi/hv_storvsc.ko initram_sysrescuecd/lib/modules/3.18.25-std471-amd64/kernel/drivers/scsi/

On se place ensuite dans le répertoire initram_sysrescuecd pour créer une archive cpio à partir de cette arborescence.

root@xxxxxxxxx:~# cd initram_sysrescuecd/
root@xxxxxxxxx:~/initram_sysrescuecd# find . | cpio -o --format=newc > ../initram.cpio
71168 blocks

On compresse l’archive obtenue avec gzip (le noyau ne reconnait pas l’image si on la compresse avec l’utilitaire xz disponible sur le système Debian) et on la place dans /boot/.

root@xxxxxxxxx:~/initram_sysrescuecd# gzip ../initram.cpio
root@xxxxxxxxx:~/initram_sysrescuecd# mv ../initram.cpio.gz /boot

Dernière étape, on modifie le fichier de configuration de grub pour utiliser le nouvel initramfs.

menuentry 'SysRescueCD' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='(/dev/sda,gpt2)'
        search --no-floppy --fs-uuid --set=root 9068308c-3790-44e7-82cb-f04fa8dcf9fe
        linux   /rescue64
        initrd  /initram.cpio.gz
}

Il ne reste plus qu’à redémarrer.

Ca marche

Cette fois c’est bon : le fichier sysrcd.dat a pu être récupéré à partir de la partition de boot, le système de fichier squashfs a été monté et on obtient un système fonctionnel. Même le framebuffer HyperV est pris en charge, on a le droit à une belle console en haute résolution.

Et maintenant ?

A partir de là, tout est possible : on est capable de monter l’interface réseau avec l’IP et la passerelle fournie par iKoula (il n’y a pas de serveur DHCP disponible).

ifconfig enp0s10f0 <adresse_ip>/24
route add default gw <passerelle>

Il suffit de changer le mot de passe root pour pouvoir se connecter en SSH au VPS depuis n’importe où.

On accède aux partitions disque, on peut donc réaliser des sauvegardes avec partimage par exemple et les sauvegarder par FTP, SSHFS ou autre sur un serveur distant. Et puis toutes les conditions nécessaires sont réunies pour pouvoir installer un système Gentoo : il suffit de suivre le Gentoo Handbook à partir de là : https://wiki.gentoo.org/wiki/Handbook:AMD64/Installation/Disks (création des partitions, récupération du stage3, compilation du noyau, etc). Pas besoin d’installer Grub à la fin de la procédure à moins d’avoir reconstruit la partition de boot.

Seul petit bémol : si on souhaite faire une sauvegarde de la partition de boot ou si on souhaite installer un système Gentoo, il nous faudra un accès complet à la partition sda2. Or étant donné que l’on y a placé le sysrcd.dat, elle est encore montée dans /livemnt/boot/ pour que l’image squashfs puisse être disponible en lecture (le fichier sysrcd.dat est présenté comme périphérique bloc sur /dev/loop0, lui même monté sur /livemnt/squashfs/).

sda2 est monté

Encore une fois, SysRescueCD propose une option qui solutionne le problème. En ajoutant le mot clé docache à la ligne de commande du noyau dans la configuration de grub, le système va d’abord copier le sysrcd.dat dans le système de fichiers en mémoire avant de monter l’image squashfs.

menuentry 'SysRescueCD' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='(/dev/sda,gpt2)'
        search --no-floppy --fs-uuid --set=root 9068308c-3790-44e7-82cb-f04fa8dcf9fe
        linux   /rescue64 docache
        initrd  /initram.cpio.gz
}

De cette manière, la partition de boot sda2 peut être démontée et devient complètement accessible (au prix d’une utilisation accrue du cache en mémoire).

sda2 n'est plus monté

Pour aller plus loin

Il existe encore d’autres méthodes qui, en exploitant toutes les fonctionnalités de SysRescueCD, permettraient d’aller beaucoup plus loin. Par exemple il est possible de charger le fichier sysrcd.dat à partir d’un serveur HTTP, donc si on dispose de plusieurs serveurs virtuels, on peut utiliser une seule image mutualisée entre toutes les machines et gagner près de 400 Mo sur disque. On peut aussi imaginer scripter la configuration de l’interface et de la route réseau pour obtenir automatiquement un système accessible en SSH et pourquoi pas automatiser la sauvegarde des volumes.

Une alternative

A l’origine, étant donné que la finalité est d’installer un système Gentoo, plutôt que de copier les modules HyperV dans l’initramfs, l’idée était de compiler un noyau Gentoo avec le support de HyperV sur un autre serveur. Il faudra de toute façon construire un noyau pour le futur système donc autant utiliser le même pour le système de secours.

Je suis parti d’un noyau générique Gentoo en version 4.1.12. En choisissant d’activer toutes les fonctionnalités souhaitées dans le noyau plutôt qu’en module, il n’est pas nécessaire de modifier l’initramfs SysRescueCD pour y ajouter des fichiers. Pour supporter les devices HyperV, il suffit d’activer les options suivantes dans la configuration (source : http://www.funtoo.org/HyperV_Kernel_Configuration).

CONFIG_HYPERV: Device Drivers > Microsoft Hyper-V guest support > Microsoft Hyper-V client drivers
CONFIG_HYPERV_STORAGE: Device Drivers > SCSI device support > SCSI low-level drivers > Microsoft Hyper-V virtual storage driver

De façon à pouvoir utiliser le réseau, il est également nécessaire d’activer le support des drivers d’interface Ethernet Tulip (DEC – Tulip devices).

Une fois la compilation terminée, il suffit de copier le fichier /usr/src/linux/arch/x86/boot/bzimage en tant que gentoo64 sur le VPS et d’ajouter une nouvelle entrée au fichier de configuration de Grub.

menuentry 'Gentoo' --class debian --class gnu-linux --class gnu --class os {
        load_video
        insmod gzio
        insmod part_gpt
        insmod ext2
        set root='(/dev/sda,gpt2)'
        search --no-floppy --fs-uuid --set=root 9068308c-3790-44e7-82cb-f04fa8dcf9fe
        linux   /gentoo64
        initrd  /initram.igz
}

Après un redémarrage du serveur, on selectionne Gentoo dans le menu Grub.

Squashfs non supporté

Le noyau Gentoo démarre et reconnait bien l’initramfs de SysRescueCD, le disque HyperV est correctement détecté et le fichier sysrcd.dat est trouvé. Par contre il semble que le support de squashfs n’a pas été activé dans le noyau. Le message d’erreur lié à l’absence du fichier modules.dep peut être ignoré : le répertoire /lib/modules/4.1.12-gentoo n’a pas été créé dans l’initramfs, mais il n’est pas nécessaire de charger de modules : tout est pris en charge par le noyau.

Donc retour à la case départ : il faut recompiler le noyau après avoir sélectionné le système de fichiers squashfs 4.0 dans File systems / Miscellaneous filesystems et activer le support des différents algorithmes de compression.

Activation du support de squashfs

Après compilation, il faut copier une nouvelle fois le fichier /usr/src/linux/arch/x86/boot/bzimage en tant que gentoo64 sur le VPS.

Au redémarrage suivant, le processus d’initialisation va un peu plus loin : l’image squashfs est montée, mais cette fois c’est le support de Aufs qui fait défaut.

Aufs non supporté

Cette fois ci c’est plus gênant : Aufs n’est pas intégré dans le code du noyau Linux et ne le sera visiblement pas de sitôt. Il est nécessaire de patcher le noyau pour y ajouter le support de Aufs. Plusieurs solutions sont possibles sous Gentoo (https://wiki.gentoo.org/wiki/Aufs). Après avoir téléchargé le code source d’un noyau 4.3.0 pré-patché, il est compilé en réutilisant les options du noyau 4.1.12.

Encore une fois (la dernière j’espère), le fichier /usr/src/linux-4.3.0/arch/x86/boot/bzimage est copié en tant que gentoo64 sur le VPS.

SysRescueCD démarre

Cette fois c’est la bonne : le système démarre correctement.

A noter qu’il est possible comme avec le noyau rescue64 d’ajouter l’option docache à la ligne de commande pour accéder à la partition de boot démontée.

Chez BeHost

Petite particularité sur les serveurs virtuels de BeHost : il n’existe pas de partition de boot séparée, le /boot est présent directement sur le système de fichier racine. Par contre une partition de swap de 1 Go est présente. Donc si on veut travailler avec un /boot séparé, il suffit de désactiver la partition de swap par un swapoff et d’y créer à la place un système de fichiers ext3 pour pouvoir y stocker le noyau, l’initramfs et le sysrcd.dat. Si on a vraiment besoin d’espace de swap, il suffit d’utiliser comme zone d’échange un fichier dans le système de fichiers racine.

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s