Le but de ce post est principalement de me faire un pense-bête car avant d'effectuer la migration sur la machine finale, je vais d'abord tenter de reproduire cette configuration dans une virtualbox kvm, étant donné que virtualbox supporte très mal freebsd sur un hôte linux.

Recommandations

Attention, même si le but de ce post est d'éviter de devoir acheter plus de stockage afin de faire des backups, il est à suivre à vos risques et périls. De plus, je recommande vivement la lecture préalable des liens suivants :

La configuration initiale

Configuration système :

  • Gentoo 32bit
  • Athlon XP
  • 1 Go de Ram

Stockage

  • 1 disque dur de 120Go : Racine + Home
  • 1 disque dur de 400Go: lvm
  • 1 disque dur de 750Go : lvm

Les logical volumes du lvm sont tous formatés en reiserfs.

La configuration finale

Configuration système :

  • FreeBSD 7.0 (i386)
  • 3 Go de Ram (pour subvenir aux besoins de ZFS)

Stockage

  • 2 disques durs de 160Go (ad0 et ad1)
    • Pour remplacer le vieux de 120
    • Contiendra le /boot et le premier zpool : system
  • 2 disques durs de 400Go (ad2 et ad4): zpool tank
  • 2 disques durs de 750Go (ad3 et ad5) : zpool tank

Zpools

Il y aura 2 zpools. Le premier system sera en mirroring, contiendra l'ensemble des partitions systèmes (/, /var, /tmp...) et le /home.
Le second tank Contiendra les données déjà présentes dans le lvm. Il sera en z-raid, sachant qu'à terme, deux autres disques durs de 400Go et 750 Go seront rajoutés (en attendant, ce sera la même chose qu'un mirror).

Ce qu'il y a à faire

La difficulté réside dans l'installation de la racine freebsd dans un zpool mirror, mais aussi le paramétrage du boot manager : gestion intelligente de la présence de /boot sur les disques en mirroring) et enfin, la sauvegarde des données : données présentes sur du lvm/reiserfs, espace disque limité, création des zpool avec un seul disque.

Première installation

Du fait que les librairies pour zfs ne semblent pas être présentes sur le livecd, je n'ai pas trouvé d'autre solution que d'installer FreeBSD de façon normale pour ensuite créer le zpool system et y copier les fichiers.

Donc on va installer freebsd sur ad0 (le plus grand!), il n' a pas de consigne particulière si ce n'est que les fichiers correspondront à l'installation finale.
Pour le partitionnement, j'ai tout mis en automatique, cela me permettra de faire la même séparation dans le zpool system (/,/var,/tmp,/usr).
J'ai choisi l'ensemble de paquet "User", car on aura besoin des sources du kernel pour le recompiler. Penser à installer :

  • editor/vim-lite (sans les gui) si besoin
  • net/rsync
  • screen (non présent sur le cd)

Tuning du système

Une fois le système installé, on va tout d'abord le tuner pour faire marcher zfs (cf. TuningZFS). Cela comprend une recompilation du kernel. Vous devez donc d'abord récupérer les sources du kernel. Dans le cas où vous voudriez ensuite faire marcher un lvm, veuillez prendre les sources du kernel avec cvsup pour avoir celles de la 7.0-STABLE, il vous faut src-base, src-sys et src-crypto.

On ajoute dans le /boot/loader.conf ceci :
zfs_load="YES"
vm.kmem_size="512M"
vm.kmem_size_max="512M"
vfs.zfs.arc_max="100M"

On recompile le kernel en rajoutant la ligne options KVA_PAGES="512" et options GEOM_LINUX_LVM (si besoin) dans le fichier de config et on ajoute zfs_enable="YES" dans le /etc/rc.conf.

Ensuite, on reboot.

Création du zpool system

On créé zpool system sur ad1 (160-2), pour cela suit les instructions de ZFSOnRoot, il peut-être intéressant d'avoir le swap hors du ZFS tout comme le /boot (cf. ZFS Best Practices Guide).

Partitionnement de ad1 (160-2)

On initialise le disque avec un seul slice bootable :

fdisk -BI /dev/ad1

Puis on créé les partitions dans le slice ad1s1 :

bsdlabel -wB /dev/ad1s1
bsdlabel -e /dev/ad1s1

Ceci permet d'avoir un /boot a de 512Mo, un swap b de 2Go et le reste d pour le zpool system :

# /dev/ad1s1:
8 partitions:
# size offset fstype [fsize bsize bps/cpg]
a: 1048576 0 unused 2048 16384
b: 4142688 1048576 swap
c: * 0 unused 0 0 # "raw" part, don't edit
d: * * unused 2048 16384

Ensuite on créé le zpool system :

zpool create system ad1s1d

On indique au bootloader où se trouve la racine et on active zfs en ajoutant :

vfs.root.mountfrom="zfs:system"
dans le /boot/loader.conf

On créé le répertoire qui contiendra le /boot :

mkdir /system/bootdir1
cd /system
ln -s bootdir1/boot /system/boot

On formate /dev/ad1s1a :

newfs /dev/ad1s1a
mount /dev/ad1s1a /system/bootdir1

J'ai ensuite suivi les instructions de cette page ZFSQuickStartGuide. J'ai ainsi créé les dossiers tmp,var,home et usr dans le zpool system.

zfs create system/usr
zfs create system/tmp
zfs create system/var
zfs create system/home

Puis j'ai copié les fichiers depuis ad0 avec vers le zpool :

rsync -Pia --exclude=system --exclude=boot /* /system/
cp -Rp /boot /system/bootdir1/

Puis on oublie pas de configurer les points de montages de toutes les partitions :

zfs set mountpoint=/tmp system/tmp
zfs set mountpoint=/usr system/usr
zfs set mountpoint=/home system/home
zfs set mountpoint=/var system/var

On modifie le fstab du nouveau système /system/etc/fstab afin qu'il ne contienne que ceci :
/dev/ad1s1b none swap sw 0 0
/dev/ad1s1a /bootdir1 ufs rw 1 1
/dev/acd0 /cdrom cd9660 ro,noauto 0 0

Puis on paramètre le point de montage en legacy pour que le ZFS ne tente de le monter tout seul :

umount /system/bootdir1/
zfs set mountpoint=legacy system

Et enfin, on reboot sur 160-2 (ad1), un paramétrage du bios est sûrement nécessaire pour qu'il ignore 160-1. Il n'y a plus qu'à croiser les doigts.

Finalisation du zpool system

Ensuite, on recopie le bsdlabel de ad1 sur ad0 en ce qui concerne le bsdlabel : bsdlabel -wB /dev/ad0s1
bsdlabel /dev/ad1s1 > savedlabel
bsdlabel -R /dev/ad0s1 savedlabel

Puis on attache le disque en mirror :
zpool attach system ad1s1d ad0s1d
(L'ordre des partitions est important).

Et on rajoute le swap se trouvant sur ad0 et le boot dans /etc/fstab :

mkdir /bootdir0
/dev/ad0s1b none swap sw 0 0
/dev/ad0s1a /bootdir0 ufs rw 1 1

On effectue une copie :
cp -Rp /bootdir1/boot /bootdir0/

Et on va privilégier le /boot se trouvant sur ad0 :

rm -f /boot
ln -s /bootdir0/boot /boot

Il faudra donc penser à mettre à jour bootdir1 si on modifie le /boot.

Malheureusement, si un disque crash, la Freebsd ne sera pas capable de booter sans intervention, car le fait de ne pas arriver à monter des partitions dans le fstab bloque le processus de démarrage. Celui-ci peut-être repris et la FreeBSD démarrée, mais pas sans une intervention humaine. Seule solution trouvée à ce jour : enlever les swap et /boot du fstab et ajouter un script rc.d qui se charge de faire les swapon et les mount au démarrage.

/etc/rc.d/my_mountfs :
#!/bin/sh

. /etc/rc.subr

name="my_mountfs"
start_cmd="${name}_start"
stop_cmd="${name}_stop"

my_mountfs_start()
{
swapon /dev/ad1s1b
swapon /dev/ad0s1b
mount /dev/ad0s1a /bootdir0
mount /dev/ad1s1a /bootdir1
}

my_mountfs_stop()
{
swapoff /dev/ad1s1b
swapoff /dev/ad0s1b
umount /dev/ad0s1a
umount /dev/ad1s1a
}

load_rc_config $name
run_rc_command "$1"