FreeBSD : clean install ZFS avec support des BE

Les environnements d’initialisation - Boot Environment (BE) - est une fonctionnalité backportée de Solaris et liée au portage de ZFS sur FreeBSD. Son intérêt est de créer différentes versions du filesystem racine afin de garantir un démarrage sûr du système suite à une opération de maintenance comme l’installation, la mise à jour ou tout simplement une reconfiguration. Elle s’appuie intégralement sur des snapshots ZFS.
Techniquement, le pool racine ZFS doit respecter une organisation du type :
Cet article vise à présenter l’installation et l’utilisation d’un système supportant les BE.
Installation du système
Toute la procédure s’effectue depuis le CD de FreeBSD en mode live.
# gpart create -s gpt ada0
# gpart add -b 34 -s 94 -t freebsd-boot ada0
# gpart add -s 4G -t freebsd-swap -l swap0 ada0
# gpart add -t freebsd-zfs -l disk0 ada0
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0
# gpart create -s gpt ada1
# gpart add -b 34 -s 94 -t freebsd-boot ada1
# gpart add -s 4G -t freebsd-swap -l swap1 ada1
# gpart add -t freebsd-zfs -l disk1 ada1
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada1
# kldload geom_mirror.ko
# gmirror label -F -h -b round-robin swap /dev/gpt/swap0 /dev/gpt/swap1
# kldload opensolaris.ko
# kldload zfs.ko
# gnop create -S 4096 /dev/gpt/disk0
# gnop create -S 4096 /dev/gpt/disk1
# zpool create -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache rpool mirror /dev/gpt/disk0.nop /dev/gpt/disk1.nop
# zpool export rpool
# gnop destroy /dev/gpt/disk0.nop
# gnop destroy /dev/gpt/disk1.nop
# zpool import -o altroot=/mnt -o cachefile=/var/tmp/zpool.cache rpool
# zfs set checksum=fletcher4 rpool
# zfs set atime=off rpool
# zfs create rpool/ROOT
# zfs create -o mountpoint=/ rpool/ROOT/default
# zfs set freebsd:boot-environment=1 rpool/ROOT/default
# zpool set bootfs=rpool/ROOT/default rpool
# zfs create -o mountpoint=/usr/local rpool/local
# zfs create -o mountpoint=/var rpool/var
# zfs create -o compression=lzjb -o exec=off -o setuid=off rpool/var/crash
# zfs create -o exec=off -o setuid=off rpool/var/db
# zfs create -o compression=lzjb -o exec=on -o setuid=off rpool/var/db/pkg
# zfs create -o exec=off -o setuid=off rpool/var/empty
# zfs create -o compression=lzjb -o exec=off -o setuid=off rpool/var/log
# zfs create -o compression=gzip -o exec=off -o setuid=off rpool/var/mail
# zfs create -o exec=off -o setuid=off rpool/var/run
# zfs create -o compression=lzjb -o exec=on -o setuid=off rpool/var/tmp
# zfs create -o mountpoint=/tmp -o compression=on -o exec=on -o setuid=off rpool/tmp
# zfs create -o mountpoint=/home rpool/home
# chmod 1777 /mnt/tmp
# chmod 1777 /mnt/var/tmp
# sh
# cd /usr/freebsd-dist
# export DESTDIR=/mnt
# for file in base.txz lib32.txz kernel.txz doc.txz;
> do (cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}); done
# zfs set readonly=on zroot/var/empty
# cp /var/tmp/zpool.cache /mnt/ROOT/default/boot/zfs/zpool.cache
# ee /mnt/etc/fstab
/dev/mirror/swap none swap sw 0 0
# ee /mnt/boot/loader.conf
geom_mirror_load="YES"
zfs_load="YES"
vfs.root.mountfrom="zfs:rpool/ROOT/default"
# ee /mnt/etc/rc.conf
hostname="freebsd9"
keymap="fr.iso.acc"
zfs_enable="YES"
network_interfaces="lo0 em0"
defaultrouter="192.168.0.1"
ipv6_defaultrouter="fdcb:9921:3552:afd7::1"
ifconfig_em0="inet 192.168.0.2 netmask 255.255.255.0 polling"
ifconfig_em0_ipv6="inet fdcb:9921:3552:afd7::2 prefixlen 64"
clear_tmp_enable="YES"
tcp_drop_synfin="YES"
moused_enable="NO"
sendmail_enable="NONE"
sshd_enable="YES"
syslogd_flags="-ss"
# ee /mnt/etc/resolv.conf
nameserver 192.168.0.254
search my.domain
# echo 'daily_status_gmirror_enable="YES"' >> /mnt/etc/periodic.conf
# echo 'daily_status_zfs_enable="YES"'' >> /mnt/etc/periodic.conf
# echo 'daily_status_smart_devices="/dev/ada0 /dev/ada1"' >> /mnt/etc/periodic.conf
# echo 'daily_status_mail_rejects_enable="NO"' >> /mnt/etc/periodic.conf
# echo 'daily_status_include_submit_mailq="NO"' >> /mnt/etc/periodic.conf
# echo 'daily_submit_queuerun="NO"' >> /mnt/etc/periodic.conf
# echo 'WRKDIRPREFIX=/usr/obj' >> /mnt/etc/make.conf
# chroot /mnt
# passwd
# tzsetup
# cd /etc/mail
# vim aliases
# make aliases
# exit
# zfs umount -a
# zfs set mountpoint=/rpool rpool
# zfs set mountpoint=/rpool/ROOT rpool/ROOT
# zfs set mountpoint=legacy rpool/ROOT/default
# shutdown -r now
Démarrage du système
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 687M 14.7G 152K /rpool
rpool/ROOT 683M 14.7G 144K /rpool/ROOT
rpool/ROOT/default 683M 14.7G 683M legacy
rpool/home 144K 14.7G 144K /home
rpool/local 144K 14.7G 144K /usr/local
rpool/tmp 176K 14.7G 176K /tmp
rpool/var 1.89M 14.7G 564K /var
rpool/var/crash 148K 14.7G 148K /var/crash
rpool/var/db 388K 14.7G 244K /var/db
rpool/var/db/pkg 144K 14.7G 144K /var/db/pkg
rpool/var/empty 144K 14.7G 144K /var/empty
rpool/var/log 188K 14.7G 188K /var/log
rpool/var/mail 144K 14.7G 144K /var/mail
rpool/var/run 204K 14.7G 204K /var/run
rpool/var/tmp 152K 14.7G 152K /var/tmp
# zfs snapshot rpool/ROOT/default@clean
Création d’un nouvel environnement
On commence par installer la commande beadm :
# cd /usr/ports/sysutils/beadm
# make install
On peut dès lors vérifier que le BE default est bien détecté :
# beadm list
BE Active Mountpoint Space Created
default NR / 1.8G 2012-10-08 04:33
La création d’un BE nécessite uniquement de spécifier son nom :
# beadm create upgrade
Created successfully
# beadm list
BE Active Mountpoint Space Created
default NR / 1.8G 2012-04-19 15:05
upgrade - - 136.0K 2012-10-08 06:25
Il est également possible de cloner un BE existant en spécifiant son nom.
Au niveau du pool ZFS, le BE se matérialise par un nouveau clone :
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
rpool 1.83G 13.6G 152K /rpool
rpool/ROOT 1.68G 13.6G 144K /rpool/ROOT
rpool/ROOT/default 1.68G 13.6G 1.68G legacy
rpool/ROOT/upgrade 144K 13.6G 1.68G legacy
rpool/home 144K 13.6G 144K /home
rpool/local 4.14M 13.6G 4.14M /usr/local
rpool/tmp 184K 13.6G 184K /tmp
rpool/var 146M 13.6G 564K /var
rpool/var/crash 148K 13.6G 148K /var/crash
rpool/var/db 145M 13.6G 144M /var/db
rpool/var/db/pkg 196K 13.6G 196K /var/db/pkg
rpool/var/empty 144K 13.6G 144K /var/empty
rpool/var/log 192K 13.6G 192K /var/log
rpool/var/mail 144K 13.6G 144K /var/mail
rpool/var/run 204K 13.6G 204K /var/run
rpool/var/tmp 152K 13.6G 152K /var/tmp
Reste enfin à activer ce BE et redémarrer le système :
# beadm activate upgrade
Activated successfully
# shutdown -r now
A présent, l’ensemble des opérations affecte le BE upgrade. En cas d’erreur, une réactivation du BE default permettra un redémarrage du système.