Migrer sur du Full ZFS
Depuis peu : les derniers commit en -STABLE ont eu lieu ce WE, il est possible d'avoir un FreeBSD 100% en ZFS, avant il y avait une solution qui consistait à passer ses disques du format MBR au format GPT, mais nous pouvons maintenant le faire directement sur du MBR.
De plus il est possible de booter sur des RAID-Z ou des MIRROR zfs.
Attention : la manipulation suivante doit se faire avec un système 7-STABLE ou 8-CURRENT très récent, de plus il faut rajouter l'option LOADER_ZFS_SUPPORT=YES dans le /etc/src.conf ou /etc/make.conf suivant les goûts afin que le loader sache travailler sur du ZFS.
Dans le cas présent nous allons donc migrer un système FreeBSD-Current tout frais mono-disque d'une installation UFS vers ZFS. Dans mon cas je voulais changer le disque dur au passage donc tout est parfait.
Création du POOL
Après avoir ajouter le disque (ici ad6) dans la machine, et de l'avoir vidé de toutes ses éventuelles partitions, nous allons créer notre zpool, il est donc possible ici de faire du mirror ou des raidz :
$ zpool create tank ad6
$ zpool export tank
Ajout de ZFSBOOT dans le mbr
$ dd if=/boot/zfsboot of=/dev/ad6 bs=512 count=1
$ dd if=/boot/zfsboot of=/dev/ad6 bs=512 skip=1 seek=1024
Si vous voulez booter sur un mirror zfs n'oubliez pas de faire la même chose sur l'autre disque.
Réactivation du pool
$ zpool import tank
Vous pouvez maintenant créer tous les FS que vous voulez dedans. attention si vous décidez de créer des FS spécifique pour /usr ou /var, vous devrez changer le mountpoint après un reboot en mode single sur le nouveau disque ZFS.
dans mon cas j'ai créé un swap de 1G :
$ zfs create -V 1g tank/swap
$ zfs set org.freebsd:swap=on tank/swap
La dernière option permet d'activer le swap automatiquement au boot lors de l'activation du zpool tank.
Et comme les checksum ça sert à rien sur du swap :
$ zfs set checksum=off tank/swap
migration des données
Pour migrer les données vous avez tout le choix des outils habituels, dans mon cas j'ai pris rsync ce coup ci et j'y suis allé gaiement à coup de rsync, par exemple :
$ rsync -av /boot /tank
$ ...
$ rsync -av /var /tank
En ne migrant pas bien entendu /dev ou autre FS "particulier".
Finalisation
pour finir il faut vous assurez que
- /tank/boot/loader.conf contient bien zfs_load="YES"
- /tank/boot/loader.conf contient bien vfs.root.mountfrom="zfs:tank"
- /tank/boot/etc/rc.conf contient bien zfs_enable="YES"
- /tank/boot/etc/fstab est vide ou ne contient que des FS non gérés par ZFS genre le /tmp pour moi en tmpfs, et les FS pour l'émulation linux par exemple.
- Vérifier la présence de /tank/boot/zfs/zpool.cache
si ce dernier n'y est pas ou que vous voulez le recréer par précaution :
$ zpool export tank && zpool import tank
$ zfs mount -a
$ cp /boot/zfs/zpool.cache /tank/boot/zfs/zpool.cache
Si tout ça est bon, il ne nous reste plus qu'à préciser à votre zfs quel est votre FS de boot
$ zpool set bootfs=tank tank
et Enfin de ne pas spécifier de point de montage pour tank :
$ zfs set mountpoint=legacy tank
c'est bon vous pouvez redémarrer sur le nouveau disque en 100% ZFS et supprimer votre disque UFS.
Changer le disque système sur FreeBSD
La manipulation suivante a été faite sur un FreeBSD 8-CURRENT récent "kern.osreldate: 800074" Je ne sais pas si elle fonctionne sur les versions 7.x out of box. Qui plus est gjournal pour la partition / pose des soucis sur les freebsd plus vieux que FreeBSD 7.2.
La disque système de ma machine commençait à faire des siennes dessus il y avait mon / et mon /home le reste était réparti sur les autres disques durs.
Je voulais donc changer de disque dur sans me prendre la tête (ie sans livecd, sans réinstaller) Comme c'est une machine perso je ne me suis pas pris la tête sur le partitionnement, le disque faisant 80Gio j'ai mis :
- 10Gio pour le / (usr et tout dedans comme un gros gruiik),
- 2Gio pour la swap,
- le reste pour le /home.
J'ai donc rajouté un disque de la même taille sur la machine (il m'en restait un qui traînait dans un coin), enfin n'importe quel disque aurait pu faire l'affaire.
Une fois la machine bootée je me retrouve avec mon nouveau disque (ad2) et mon ancien disque (ad3)
Préparation du disque ad2
Pour le fun je me suis dis que j'allais partitionner mon disque au format GPT, puisque c'est à la mode (ça sert à rien dans mon cas, mais je voulais jouer avec)
j'ai donc détruit le partionnement existant :
$ gpart destroy ad2
Puis recréer en précisant le système de partitionnement GPT
$ gpart create -s GPT ad2
Une vérification que tout c'est bien passé :
$ gpart show
=> 34 156301421 ad2 GPT (75G)
34 156301421 - free - (75G)
Les BIOS classiques ne sont pas capable de booter sur du GPT, mais sous FreeBSD il y a une astuce qui marche impeccable
$ gpart add -b 34 -s 16 -t freebsd-boot ad2
$ gpart bootcode -b /boot/pmbr ad2
$ cp /boot/gptboot /tmp
$ dd if=/dev/zero bs=641 count=1 >> /tmp/gptboot
$ dd if=/tmp/gptboot of=/dev/ad2p1 bs=512
ainsi le système est bootable;
j'ai plus qu'à recréer mes partitions
$ gpart add -b 50 -s 20971520 -t freebsd-ufs ad2
$ gpart add -b 20971570 -s 4194304 -t freebsd-swap ad2
$ gpart add -b 25165874 -s 131135581 -t freebssd-ufs ad2
Vérification :
$ gpart show
=> 34 156301421 ad2 GPT (75G)
34 16 1 freebsd-boot (8.0K)
50 20971520 2 freebsd-ufs (10G)
20971570 4194304 3 freebsd-swap (2.0G)
25165874 131135581 4 freebsd-ufs (63G)
maintenant j'active le gjournal pour les partitions ufs
$ gjournal label /dev/ad2p2
$ gjournal label /dev/ad2p4
On format le tout (pour rappel sous freebsd pas besoin de formatter les partitions swap
$ newfs -J -L root /dev/ad2p2.journal
$ newfs -J -L home /dev/ad2p4.journal
Le -L signifie que l'on écrit un label ainsi les partitions sont facilement montable grâce à GLABEL qui les représente sous la forme : /dev/ufs/LABEL
Migration des données
maintenant il s'agit de migrer le contenu des partitions / et /home sur les nouvelles le tout à chaud :
$ mkdir /newroot
$ mount -o async /dev/ufs/root /newroot
$ cd /newroot
$ dump -0uanL -f - / | restore -rf -
$ mkdir /home2
$ mount -o async /dev/ufs/home /home2
$ cd /home2
$ dump -0uanL -f - /home | restore -rf -
il faut pour finir modifier la fstab du nouveau root pour rajouter :
- /dev/ufs/root comme partition / (et rajouter l'option async)
- /dev/ufs/home comme partition /home (et mettre l'option async)
- /dev/ad2p3 comme swap
Le fichier /etc/fstab obtenu est donc :
# Device Mountpoint FStype Options Dump Pass#
/dev/ad2p3 none swap sw 0 0
/dev/ufs/root / ufs rw,async 1 1
/dev/ufs/bapt /home ufs rw,async 1 1
Il ne reste plus qu'à rebooter dessus.


