Florent Peterschmitt

ZFS - FreeBSD 9.0-RELEASE - MAJ : 9.1

Il se peut que l'article ne soit pas très clair. J'étais jeune et si vous me le demandez (on sait jamais), je pourrai le clarifier plus tôt que prévu :)

UFS, c'est bien beau, mais c'est vieux et ça ne permet plus de faire ce qu'on veut. Ce système de fichier antique, hérité de 4.2BSD ne correspond plus à ce qu'on peut attendre d'un système de fichier aujourd'hui, à savoir la prise en charge native des volumes logiques, des quotas, de la compression à la volée et j'en passe. En plus, UFS est poussif. ZFS est maintenant supporté sous FreeBSD, depuis sa version 6, et je souhaite vous faire partager mon installation de FreeBSD sur un disque ZFS. La prouesse n'a rien d'original car on trouve facilement de la documentation partout sur internet, mais pour ceux qui ne veulent pas formater tout leur disque pour avoir une unique partition gpart (geom), cela pose problème. Dans un premier temps, je vous expliquerai le script original trouvé sur internet, puis la modification que j'y ai apporté pour pouvoir utiliser ZFS, en tout cas partiellement, afin de palier (plus ou moins salement) à l'impossibilité pour gpart de faire une partition GPT sur ada0s1 quand ada0 est en MBR.

Commencer une installation à partir de zéro

Attention, cette méthode n'est adaptée que si vous êtes prêt à effacer votre disque dur tout entier. Lisez quand même à titre informatif, car une bonne partie des informations présentes ici ne seront pas répétées dans l'autre méthode. Lancez votre installateur de FreeBSD, faites comme si vous vouliez faire une installation classique, mais sortez de là quand il vous propose de partitionner vos disque, puisque nous allons le faire nous-même. Entrez dans le shell. et chargez le module zfs.

$ kldload zfs

Script original

Voici la marche à suivre qu'on peut trouver sur une vidéo Youtube (lien plus bas), ou même sur la documentation en ligne. Pour simplifier, tout ce qui existe sur notre disque (ada0) est détruit, puis on créer une partition GPT avec gpart, dans laquelle on va y mettre une partition freebsd-boot de quelques Kio, un SWAP (de la taille que vous voulez) et enfin tout le reste sera alloué à ZFS. En effet, comme ZFS supporte la gestion des volumes logiques de façon native (et que c'est même la meilleure façon de faire ses disques), nul besoin de séparer les points de montage. Sauf s'il y a une raison particulière, comme changer quelques points de montage sur un autre disque physique. La séparation de partitions sur un même disque dur ne présente, à mon avis, plus d'intérêt face aux volumes logiques qui sont bien plus souples. Sauf dans le cas où on va se servir d'un espace d'échange entre deux OS et qu'on ne voudrait pas que notre partition soit corrompue. La partition ZFS aura un label nommé FBSD-ZROOT, ce qui est optionnel, mais je vous le conseil pour la suite. La mini partition de démarrage, freebsd-boot, est remplie de zéros, parce que nous allons y écrire un code qui fait moins que la taille de cette partition, et par mesure de précaution, il est préférable de tout effacer. A proprement parler, on sort dd est on y écrit nos zeros, ensuite avec gpart on inscrit notre « bootcode ». Maintenant que l'espace est alloué, que la partition de démarrage est écrite, tout le reste doit être écrit, mais sur du ZFS. C'est là que zpool entre en jeu, puis zfs :

$ zpool create -> créer un « disque » ZFS
$ -f  -> préciser sur quel périphérique
$ -m none -> pas de "mountpoint" pour l'instant
$ -o altroot=/mnt -> on met notre pool sur /mnt, là où l'installation sera faite
$ -o cachefile=/tmp/zpool.cache -> Le fichier de cache des pool ne s'installera pas où il voudra, au moins on est sûr de trouver le bon
$ tank -> donnez le nom que vous voulez, mais à chaque fois que vous verrez "tank", remplacez par celui que vous avez donné. Il s'agit du nom de notre pool
$ gpt/FBSD-ZROOT -> vous vous souvenez, le label ? Cette donnée sert à -f Une fois ceci fait, créons alors nos volumes logiques à l'intérieur de notre pool

Une pool (ne pond pas d’œuf ici) s'apparente à un disque physique, et nos volumes logiques à des partitions physiques. Sauf qu'ici, et c'est là tout l'intérêt, c'est que c'est virtuel. Bienvenu dans la matrize. Je pense que vous allez comprendre ce qu'il se passe, et je ne vous expliquerai pas que zfs create -o mountpoint=/truc tank/trucmuch créer un volume logique dans notre pool tank avec le nom trucmuch, à sa racine, et que le tout sera monté sur /truc de notre partition racine. Vala vala. Z'êtes contents ? Bon bah, c'est pas tout, mais il faut dire où on va démarrer ! zpool set bootfs=tank/root tank, c'est pas sorcier ! Voilà toutes les commandes :

$ gpart destroy ada0
$ gpart create -s gpt ada0
$ gpart add -t freebsd-boot -s 128 ada0
$ gpart add -t freebsd-swap -s 4G ada0
$ gpart add -t freebsd-zfs -l FBSD-ZROOT ada0
$ dd if=/dev/zero of=/dev/ada0p1 count=560 bs=512
$ gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
$ zpool create -f -m none -o altroot=/mnt -o cachefile=/tmp/zpool.cache tank gpt/FBSD-ZROOT #si vous ne mettez pas de label à la commande précédente, utilisez /dev/ada0p3 pour indiquer la partition ZFS.
$ zfs set atime=off tank # qui s'inquiète de l'accès temporel aux fichiers ? Pas moi en tout cas. Attention, ceci fera que tous les volumes dépendants de tank héritent de cette propriété
$ zfs create -o mountpoint=/ tank/root #obligatoire, le reste peut se faire selon votre convenance.
$ zfs create -o mountpoint=/usr tank/root/usr
$ zfs create -o mountpoint=/var tank/root/var
$ zfs create -o mountpoint=/tmp tank/root/tmp
$ zfs create -o mountpoint=/usr/local tank/root/usr/local
$ zfs create -o mountpoint=/usr/ports tank/root/ports #très facultatif. Vous pouvez aussi mettre /usr/src.
$ zfs create -o mountpoint=/usr/home -o atime=off tank/root/usr/home
$ zpool set bootfs=tank/root tank

Quittez le shell, vous reviendrez au processus d'installation qui va extraire les paquets. Faites ce qu'il vous demande de faire par la suite (mot de passe root, etc.), ne discutez pas et admirez. Mais SURTOUT, ne redémarrez PAS. Ca n'est pas finit, et il vous faut encore paramétrer votre installation toute fraîche pour qu'il comprenne que, oui, vous êtes un bon et donc vous utilisez ZFS. Comme on va tout mettre sur notre partition ZFS, il ne reste que notre SWAP à monter, car ça ne se met pas sur du ZFS. Sortez de l'installateur, et quand il vous demande si vous voulez configurer manuellement votre système, répondez Oui.

$ echo '/dev/ada0p2 none swap sw 0 0' >> /etc/fstab
$ echo 'zfs_enable="YES"' >> /etc/rc.conf
$ echo 'opensolaris_load="YES"' > /boot/loader.conf
$ echo 'zfs_load="YES"' >> /boot/loader.conf
$ echo 'vfs.root.mountfrom="zfs:tank/root"' >> /boot/loader.conf

Le "vfs.root.mountfrom...blablabla", vous comprendrez qu'on indique clairement qu'on veut que notre partition racine soit tank/root, et que notre très aimé noyau FreeBSD trouvera son bonheur là dedans. Sortez du chroot et choisissez enfin le mode Live CD proposé. Ensuite, on « déconnecte » notre pool (comme quoi, les poules pondeuses automatiques, ça n'est pas pour dans longtemps) pour pouvoir y copier proprement notre cache de pool. Vous sentez venir la blague foireuse ? Quand les poules jouent à cache cache sur la route, gare aux tanks. Bon et enfin on copie notre cache de pool là où il va être utilisé dans notre système installé. A savoir, /boot/zfs, ce qui devient /mnt/boot/zfs dans le cas présent.

$ zpool export tank
$ zpool import -o altroot=/mnt -o cachefile=/tmp/zpool.cache tank
$ cp /tmp/zpool.cache /mnt/boot/zfs/

Redémarrez, c'est prêt !

Installation partielle UFS/ZFS, pour ceux qui en ont gros sur le disque dur

Voilà voilà, Windows 7, un Linux (inutile de dire lequel, tous les six mois ça change. Ok, OpenSUSE, Mandriva, ArchLinux, Debian, Ubuntu, Fedora, dans différentes versions. Je crois que c'est tout pour le moment), ben ça ne colle pas avec gpart, qui veut tout. Tout. Donc un disque entier. Et ça ne fonctionne pas si on lui demander de faire son nid sur un ada0sX par exemple, non. Bref, passons à l'action, il n'y en a plus pour longtemps. Allez, c'est tipar ! Lancez donc toujours l'installateur de FreeBSD, allez jusqu'à partitionnement (et partitionnez cette fois) pour arriver à cela :

-> ada0sX BSD
-> ada0sXa : freebsd-ufs, minimum 4Go si vous choisissez l'option sécurité, sinon 2G. mountpoint : /
-> ada0sXb : freebsd-swap
-> ada0sXc : freebsd-zfs, pas de point de montage. Prenez tout l'espace disque restant.

Concernant ce que j'appelle « l'option sécurité », il s'agit d'installer les sources sur cette partition UFS. Vous allez voir que, si vous vous bricolez un noyau personnalisé, le jour où vous oublierez ZFS ou un module dépendant, vous serez vraiment HEUREUX d'avoir les sources à disposition, ainsi que le compilateur et tout le tralala ! Finish him ! Quand il vous proposer de vous mettre en chroot (manual configuration) dans le système, allez-y, les modifications seront bien plus facile à faire et il n'y aura pas de transfert de cache et ainsi de suite. Chargez le module zfs, et nous voilà prêts. Bien, maintenant, créez une pool sur ada0sXc (<- adaptez les numéros et les lettres bien entendu) que vous nommerez par exemple... TheRoot. Comprendra qui pourra. C'est connu pourtant. Sans rire, nous allons la nommer tank, c'est plus simple à écrire.

$ zpool create tank /dev/ada0sXc

Avant de vous jeter sur zfs create -o mountpoint=/truc tank/truc, dites vous bien que si vous essayez de faire zfs create -o mountpoint=/ tank/root, vous allez droit dans le mur ! De même que si vous essayez de monter un quelconque dossier du système de base comme /bin, /usr/bin ou /sbin, /usr/sbin dans votre tank. Le montage étant immédiat, d'une vous ne pourrez plus rien faire de votre chroot, et au prochain redémarrage vous vous apercevrez bien vite que vous pourrez recommencer l'installation. Donc nous allons tricher en ne montant que le nécessaire et en jouant, un peu forcé, la carté sécurité (vous vous souvenez, laisser le système de base sur un disque USF prit en charge par le noyau sans oubli de module et tout et tout). Faites donc un peu cela, par exemple :

$ zfs set atime=off tank
$ zfs create -o mountpoint=/var tank/var # attention à cela tout de même, si ZFS n'est pas chargé à un moment donné, vous risquez de perdre des informations en remontant le volume ZFS.
$ zfs create -o mountpoint=/tmp tank/tmp
$ zfs create -o mountpoint=/usr/local tank/usr.local
$ zfs create -o mountpoint=/usr/home tank/usr.home

Vous pouvez aussi séparer vos ports :

$ zfs create -o mountpoint=/usr/ports tank/usr.ports

Et tout ce que vous voudrez, mais PAS le système de base. Point important : vous ne pouvez pas faire tank/usr/home car cela suppose d'avoir un volume tank/usr. Vous pouvez le faire, alors il ne vous faudra pas donner de point de montage. Dans le cas présent, je trouve plus judicieux de séparer /usr/local de /usr/home. Bien, maintenant n'oubliez pas d'éditer /boot/loader.conf, /etc/rc.conf et /etc/fstab comme suit :

/boot/loader.conf :

# krpc_load="YES" # je vous conseil d'ajouter "options KRPC" dans le fichier de configuration de votre noyau, car c'est une dépendance de ZFS.
# opensolaris_load="YES" # ligne non nécessaire, mais au moins on est fixé. # zfs_load="YES"

/etc/rc.conf :

# zfs_enable="YES" # cela autorise le montage automatique des volumes ZFS. Mieux vaut le mettre, non ?

/etc/fstab :

# /dev/ada0sXa /    ufs  rw,noatime 0 0 # ces deux lignes devraient être présentes. # /dev/ada0sXb none swap sw 0 0

Dans le cas où vous oubliez de modifier loader.conf et rc.conf, pas d'inquiétude, votre système de base étant sur de l'UFS, vous aurez tout le loisir d'effectuer la manipulation une fois le système démarré sans aucun problème, mais en mode mono-utilisateur pour garantir un accès minimum aux fichiers. Cependant, n'oubliez pas de le faire avant d'installer des ports, de créer des utilisateurs et ainsi de suite. Pensez aussi à faire un backup de /var (tar -cf /var.tar /var), pour le décompresser dans votre nouvelle partition logique ZFS tank/var correspondante (toujours dans l'hypothèse où vous avez oublié de modifier lesdits fichiers). Mise à jour du système de base, déplacement des sources. Maintenant vous vous posez la question de savoir comment mettre vous sources sur un volume ZFS tank/usr.src, sans pour autant délaisser votre bien aimé /usr/src sur UFS. Ben, en fait c'est simple :

$ zfs unmount tank/usr.src, et voilà, vous avez de nouveau accès à /usr/src.

Et comment accéder de nouveau à tank/usr.src ? Devinez.

$ zfs mount tank/usr.src

Pour la mise à jour de votre système de base, faites comme d'habitude, mais veillez à ce que les deux emplacements (tank/usr.src et /usr/src) soient en synchronisme. Si vous ne voulez pas télécharger toutes les sources sur la partition UFS, mettez au moins src-sys, src-contrib, src-crypto et src-base (pas dans l'ordre, mais ce n'est pas grave). Dans contrib se trouve ZFS. Il serait donc intelligent de ne pas l'oublier.