Автоматическая установка FreeBSD 8.2-RELEASE на ZFS
Все мы знаем что время от времени очень редко, практически никогда, но возникает ситуация, при которой внеплановый reset или сбой питания сервера FreeBSD приводит к остановке загрузки с настойчивым требованием запустить fsck от руки. Бывает, сервер соскучился, админ давно его не навещал, а может полнолуние какое, но данное явление в природе встречается. Пришла пора, думаю, переезжать на ZFS — народ рекомендует, стадию бета теста давно прошла, дисковое пространство зря не пропадает, и… в ZFS отсутствует потребность в утилите fsck для проверки целостности файловой системы(!). Проштудировав маны, wiki, лиссяру, пришел к выводу что надо кое-где рашпилем проточить, причесать, лакирнуть и пойдет в массы. Действительно, процесс, по сравнению со стандартным sysinstall, несколько затруднен, но зато быстр как никогда — 2 минуты и сервер с корневым разделом на ZFS готов.
Да, разумеется мы не будем запускать руками всю ту пачку команд, которую рекомендуют запускать, и не будем возиться с sysinstall, а сделаем скрипт автоматической установки, который запустим из режимаFixit. Для этого понадобится DVD или USBstick вариант инсталяции, сервер где хранится скрипт (доступный по ssh).
Процесс инсталяции выглядит так: загружаемся, выбираем режим Fixit — CD/DVD, вешаем IP на сетевуху и запускаем скрипт:
Fixit# ifconfig em0 192.168.1.100/24
Fixit# ssh user@192.168.1.1 ‘cat /opt/script/zfs-init’ | sh
Теперь обратимся к содержимому скрипта, он должен сделать следующее:
1. Разметить диск (GPT — boot, swap0, disk0)
2. Создать ZFS pool (/root, /tmp, /usr, /var, /opt) — раздел /root сделал отдельно, его можно тоже ограничивать в размере
3. Закинуть на ZFS фряху с минимальными конфигами для старта
Скрипт на шелле, просто перечень команд в определенной последовательности. В начале скрипта измените переменные dev (диск), iface (сетевуха), tank (название пула ZFS), hostname (имя хоста), tz (timezone). Вот и он:
- #!/bin/sh
- # Vars
- dev=da0
- tank=tank
- iface=em0
- hostname=core.domain.com
- tz=“Europe/Kiev”
- # gpart
- gpart create -s GPT $dev
- gpart add -s 64K -t freebsd-boot $dev
- gpart add -s 2G -t freebsd-swap -l swap0 $dev
- gpart add -t freebsd-zfs -l disk0 $dev
- gpart bootcode -b /mnt2/boot/pmbr -p /mnt2/boot/gptzfsboot -i 1 $dev
- sysctl kern.geom.debugflags=0x10
- # install ZFS
- kldload /mnt2/boot/kernel/opensolaris.ko
- kldload /mnt2/boot/kernel/zfs.ko
- mkdir /boot/zfs
- # сreate ZFS pool
- zpool create -f $tank /dev/gpt/disk0
- zfs set mountpoint=none $tank
- zfs set atime=off $tank
- zfs set checksum=fletcher4 $tank
- zfs create -o compression=off -o exec=on $tank/root
- zfs set mountpoint=/$tank $tank/root
- zpool set bootfs=$tank/root $tank
- zfs create -o compression=on -o exec=on -o setuid=off $tank/tmp
- zfs set mountpoint=/$tank/tmp $tank/tmp
- zfs create $tank/usr
- zfs set mountpoint=/$tank/usr $tank/usr
- zfs create $tank/var
- zfs set mountpoint=/$tank/var $tank/var
- zfs create -o compression=off -o setuid=off $tank/opt
- zfs set mountpoint=/$tank/opt $tank/opt
- cd /$tank ; ln -s /usr/home home && cd –
- mkdir /$tank/var/tmp
- chmod 1777 /$tank/var/tmp /$tank/tmp
- # install base system
- cd /dist/8.2–*
- export DESTDIR=/$tank
- for dir in base catpages dict doc info lib32 manpages; do (cd $dir ; echo “y” | ./install.sh) ; done
- cd src; ./install.sh all
- cd ../kernels ; ./install.sh generic
- cd /$tank/boot ; cp -Rlp GENERIC/* /$tank/boot/kernel/
- # install base configs
- cat << EOF > /$tank/etc/rc.conf
- zfs_enable=“YES”
- hostname=“$hostname“
- ifconfig_$iface=“DHCP”
- sshd_enable=“YES”
- ntpd_enable=“YES”
- ntpd_program=“/usr/sbin/ntpd”
- ntpd_flags=“-p /var/run/ntpd.pid -f /var/db/ntpd.drift”
- EOF
- cat << EOF > /$tank/etc/ntp.conf
- server 82.207.71.6 iburst maxpoll 9
- server 91.198.10.4 iburst maxpoll 9
- server 79.142.192.4 iburst maxpoll 9
- server 193.193.193.107 iburst maxpoll 9
- EOF
- echo ‘zfs_load=”YES”‘ > /$tank/boot/loader.conf
- echo “vfs.root.mountfrom=\”zfs:$tank/root\”“ >> /$tank/boot/loader.conf
- cp /mnt2/usr/share/zoneinfo/$tz /$tank/etc/localtime
- cp /boot/zfs/zpool.cache /$tank/boot/zfs/zpool.cache
- cat << EOF > /$tank/etc/fstab
- # Device Mountpoint FStype Options Dump Pass#
- /dev/gpt/swap0 none swap sw 0 0
- procfs /proc procfs rw 0 0
- EOF
- export LD_LIBRARY_PATH=/mnt2/lib
- cd /
- # correct ZFS mount points and quotas
- zfs unmount -a
- zfs set mountpoint=/opt $tank/opt
- zfs set quota=1G $tank/tmp && zfs set mountpoint=/tmp $tank/tmp
- zfs set quota=5G $tank/usr && zfs set mountpoint=/usr $tank/usr
- zfs set quota=10G $tank/var && zfs set mountpoint=/var $tank/var
- zfs set quota=512m $tank/root && zfs set mountpoint=legacy $tank/root
Во время работы скрипта клавиатуру трогать не надо, после окончания просто перегрузите сервер, и войдите в систему юзером root без пароля.
Материалы по теме: RootOnZFS/GPTZFSBoot,
Удачи