Présentation de aufsroot

Présentation et principe

Il arrive souvent qu'on ait envie de tester un paquet, voire une mise à jour ou encore un tentative pour réparer une machine. Le problème est la difficulté de revenir en arrière complètement si la modification ne marche pas. On peut aussi tout bêtement essayer une solution pour aider un tiers sur un forum par exemple.

Depuis peu, les noyaux Debian (plus ceux que je fais) incluent AUFS (Another Union Files System) qui permet de faire ce genre de choses très facilement. Les noyaux linux standards n'intègrent pas AUFS pour des raisons obscures soutenues par Linux Torvald. Cela n'enlève rien au fait que parmi les systèmes équivalents, AUFS est de loin le plus fiable et peut être utilisé en production.

Son principe consiste à superposer des systèmes de fichiers les uns sur les autres: A1 mis sur A2 mis sur A3 ... sur AP. Quand on cherche un fichier, on le cherche sur A1, puis si il n'y est pas (effectivement ou par un drapeau disant sa destruction), on le cherche sur A2, etc. Dans la pratique A1 est en RAM, A2,..., Ap sont en lecture seule. Voir clefagreg ou encore des clefs USB live Fedora comme exemple d'utilisation.

Il est donc tout à fait possible de faire un système avec une racine figée en A2 et un système initialement vierge en A1 qui enregistrera les modifications. On ne touchera pas au système initial sur A2 lors du travail.

Dans la suite, outre AUFS, 3 versions sont exposées:

  1. Une méthode manuelle fabriquant un chroot réplique du système

  2. Une méthode manuelle pour bouter sur une racine en AUFS

  3. Une présentation d'un paquet contenant les scripts effectuant cela automatiquement

Préquis et Détails sur AUFS

La présence d'AUFS se voit à l'existence d'un module aufs.ko. Ce module existe sur les noyaux debian >= 3.0. Il peut se trouver aussi sur les noyaux utilisés par clefagreg ou sa version ISN et sur les clefs Fedora.

L'utilisation d'AUGS se fait simplement: Taper

mount -t aufs aufs /mnt -o dirs=/home/test=rw:/=ro

monte sur /mnt le répertoire /home/test en lecture écriture par dessus la racine en lecture seule. Bien évidemment il ne peut y avoir de collision sur les systèmes de fichiers (monter / sur /sousrepertoire ne marchera pas.

Méthode manuelle

Le principe pour faire une réplique de la racineu système consiste à prendre chaque partition composant ce système et à les monter sur des répertoires donnés, puis pour chaque partition rajouter un répertoire qui sera plaqué dessus en lecture/écriture. Sur un exemple:

Un système de fichier suivant:

udev on /dev type devtmpfs (rw,relatime,size=1973056k,nr_inodes=493264,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=395944k,mode=755)
/dev/disk/by-uuid/b781c58b-e69c-4726-9e48-9a533a8a69a2 on / type ext4
tmpfs on /run/lock type tmpfs
tmpfs on /tmp type tmpfs
proc on /proc type proc
sysfs on /sys type sysfs
tmpfs on /run/shm type tmpfs
/dev/sda7 on /home type ext4

Les systèmes de fichiers concernés sont /dev/sda7 sur /home et /dev/disk/by-uuid/b781c58b-e69c-4726-9e48-9a533a8a69a2 syur la racine, /tmp est un système de fichiers en RAM donc constitue un endroit idéal où créer les répertoires utilisés.

Donc un répertoire de travail puis un par partition

mkdir -p /tmp/temporoot
mkdir -p /tmp/temporoot/M_ROOT
mkdir -p /tmp/temporoot/RW_ROOT
mkdir -p /tmp/temporoot/RW_home
mkdir -p /tmp/temporoot/M_home

on monte les partitions correspondantes sur les répertoires M_

mount /dev/disk/by-uuid/b781c58b-e69c-4726-9e48-9a533a8a69a2 /tmp/temporoot/M_ROOT
mount /dev/sda7 /tmp/temporoot/M_home

On crée le point de montage de la racine

mkdir -p /tmp/temporoot/mnt

On monte la racine en mettant M_ROOT+RW_ROOT

mount -t aufs aufs /tmp/temporoot/mnt -o dirs=/tmp/temporoot/RW_ROOT=rw:/tmp/temporoot/M_ROOT=ro

On y rajoute le répertoire /home (sur /tmp/temporoot/mnt/home donc)

mount -t aufs aufs /tmp/temporoot/mnt/home -o dirs=/tmp/temporoot/RW_home=rw:/tmp/temporoot/M_home=ro

et voilà. Un chroot sur /tmp/temporoot/mnt permettra de travailler sur une réplique parfaite de la racine, d'installer des paquets sans craindre de modifier le système réel. Quand c'est fini, il suffit de faire

umount /tmp/temporoot/mnt/home
umount /tmp/temporoot/M_home
umount /tmp/temporoot/mnt
umount /tmp/temporoot/M_ROOT

pour démonter le système. À noter que les modifications peuvent se retrouver dans les répertoires /tmp/temporoot/RW_home et /tmp/temporoot/RW_ROOT.

Le paquet debian aufsroot contient un script faisant tout cela automatiquement.

Racine en AUFS

Le principe est le même mais il faut le faire au moment du boute. Il faut donc créer un nouveau scenario de montage de la racine en modifiant le script de l'initramfs. Ce script doit chercher monter la racine telle que ci dessus avant de démarrer le processus init. Dans la pratique, il faudrait modifier le script /usr/share/initramfs-tools/scripts/local ce qui n'est pas une bonne idée. Le mieux est de créer un script dédié, version modifiée de /usr/share/initramfs-tools/scripts/local et de le mettre dans /etc/initramfs-tools/scripts/tempo. Il suffit de mettre boot=tempo dans la ligne de boute de grub pour appeler ce script plutôt que le script par défaut. Ne pas oublier de rajouter aufs au fichier /etc/initramfs-tools/modules pour que le module aufs.ko soit rajouter à l'initrd. Il suffit après de refaire l'initrd puis de bouter en rajoutant (par l'édition sous grub de boot=tempo ddans les options par exemple) pour être sur une racine comme ci dessus.

Cette partie est relativement complexe à décrire, seule la méthode est exposée ici. Dans la pratique je suggère hautement d'installer le paquet aufsroot disponible sur

deb http://boisson.homeip.net/depot wheezy divers

(dépot signé) ou bien

deb http://boisson.homeip.net/debian wheezy divers

(dépot non signé). Ce paquet ne modifie pas les fichiers systèmes et donc est inoffensif à l'installation.

Le paquet aufsroot

Ce paquet contient à la fois un script permettant de faire automatiquement un chroot comme expliqué en première partie et tout ce qui est nécessaire pour bouter sur une racine AUFS.

Il faut évidemment installer le paquet

temporoot

Le paquet contient un script /usr/bin/temporoot d'utilisation simple:

Sous root, tapez

temporoot m

Vous aurez quelque chose ressemblant à

root@portos:/tmp# temporoot m
/dev/sda7 /home home
Faites chroot /tmp/temporoot/mnt
root@portos:/tmp# 

La ligne /dev/sda7 /home home signifie simplement que /dev/sda7 est montée sur /home.

Il suffit de faire

 chroot /tmp/temporoot/mnt

pour être dans le chroot.

root@portos:/tmp# chroot /tmp/temporoot/mnt
root@TEMPORAIRE:/ # 

Vous pouvez noter que le prompt a changé. En effet suite à une histoire malheureuse, j'ai rajouté une modification (temporaire donc) du .bashrc de root permettant de différencier le prompt du chroot du prompt du système normal. Ça permet d'éviter des manipulations osées en croyant être dans le chroot alors qu'on est dans le systèmé réel.

On sort du chroot par un ^D et un simple

temporoot u

démonte tout le système:

root@portos:/tmp# temporoot u
Démontage de /tmp/temporoot/mnt//home
root@portos:/tmp# 

On peut prendre autre chose que le répertoire de travail /tmp/temporoot proposé, il suffit de faire

temporoot m /home/temporaire

pour que celui soit /home/temporaire. À noter que ici on aura comme message

root@portos:/tmp# temporoot m /home/temporaire
/dev/sda7 /home home
/dev/sda7 non utilisable
Faites chroot /home/temporaire/mnt
root@portos:/tmp#

La ligne /dev/sda7 non utilisable signifie que cette partition supportant le répertoire de travail ne peut être incorporée dans le montage. Elle est bêtement ignorée.

Le système se démonte par

temporoot u /home/temporaire

Boute sur racine AUFS

Le paquet contient un fichier /etc/initramfs-tools/scripts/tempo fabriquant la racine et un README d'explications.

Pour bouter sur une racine en AUFS avec ce paquet, procédez comme suit

  1. Rajouter «aufs» dans le fichier /etc/initramfs-tools/modules

  2. Refaites les initrd, pour cela faites la commande

update-initramfs -k all -u
  1. Créer un fichier /TEMPO contenant soit «RAM» (le répertoire de travail temporoot sera en RAM, l'inconvénient est que les manipulations seront perdues), soit une ligne «UUID=e3783217-84f0-4fa7-99ad-7ab13e18ce51» (sans les guillemets bien sûr), l'UUID est celui de la partition sur laquelle seront créés les répertoires temporaires (une arborescence sous temporoot). L'interêt dans ce dernier cas est que les modifications déjà effectuées se retrouveront au boute AUFS suivant. Si la partition est présente dans /etc/fstab, elle ne sera pas montée.

La machine est prête. Pour bouter avec une racine AUFS, lors du menu grub, après avoir sélectionner le noyau voulu, tapez sur e et rajoutez dans les options du boute boot=tempo, par exemple remplacez le quiet final (fréquent) par boot=tempo quiet. Tapez sur F10 pour démarrer et laissez faire. Des messages précisant le montage et indiquant une éventuelle partition non montée sont affichés. C'est la seule différence avec un boute normal.

Si vous regardez les répertoires montés, vous obtenez cela (par exemple avec un système temporaire en RAM):

udev on /dev type devtmpfs (rw,relatime,size=1973056k,nr_inodes=493264,mode=755)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime,size=395944k,mode=755)
none on /terre type tmpfs (rw,relatime)
none on /terre/tempo type tmpfs (rw,relatime)
/dev/disk/by-uuid/b781c58b-e69c-4726-9e48-9a533a8a69a2 on /terre/tempo/ROOT type ext4 (ro,relatime,data=writeback)
aufs on / type aufs (rw,relatime,si=cf2cfe18bc22b654)
/dev/disk/by-uuid/acd75cb7-d44b-4a14-b9ed-f34508b7b3f8 on /terre/tempo/M_home type ext4 (ro,relatime,data=ordered)
aufs on /home type aufs (rw,relatime,si=cf2cfe18bfb1ba54)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,relatime,size=791884k)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run/shm type tmpfs (rw,nosuid,nodev,relatime,size=791884k)
rpc_pipefs on /var/lib/nfs/rpc_pipefs type rpc_pipefs (rw,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,relatime)

On distingue les systèmes de fichiers RAM sur /terre et /terre/tempo, la racine / qui est bien de type aufs et les partitions /dev/disk/by-uuid/b781c58b-e69c-4726-9e48-9a533a8a69a2 et /dev/disk/by-uuid/acd75cb7-d44b-4a14-b9ed-f34508b7b3f8 montées en lecture seule.

On peut désormais basculer en sid, installez des paquets expérimentaux, etc. Lors du reboute suivant, on retrouvera le système d'origine.

Rq: Le seul bug (bizarre) à ce jour est le refus de dropbox de fonctionner. Cela vient sans doute d'une utilisation de dropbox de signaux indiquant qu'un système de fichiers a été modifié pour lancer la synchronisation. Il y a sans doute un souci avec aufs. Cela signifie qu'on tourne avec un dropbox non connecté le temps de la session sur une racine AUFS.