FreeBSD:Install
The following is how to install FreeBSD using GEOM+UFS. This will offer a base system of which is redundant, scalable, efficient usage of disk space. This guide is mainly suited for use with workstations, it is setup for use with FreeBSD 9.0 or newer.
GEOM permits access and control to classes (Master Boot Records, BSD labels, etc.) through the use of providers, or the special files in /dev. Supporting various software RAID configurations, GEOM will transparently provide access to the operating system and operating system utilities.[1]
Booting the Installation Media
Boot from your chosen installation media, for use in creation of this article the following test environment was used:
VirtualBox 4.0.14_OSE r74382 FreeBSD-10.0-HEAD-20120120-JPSNAP-amd64-amd64-release.iso |
Upon first boot you will see the standard FreeBSD boot loader menu, feel free to wait out the allotted time or press enter to continue more rapidly. After the system has completed its boot up, you will be presented with the 'Welcome' window inside the new bsdinstall(8). Select < Shell > from the options and press enter.
Remote Installation Setup (Optional)
This section takes two things for granted; (a) that you have a personal set of SSH keys, and (b) that they are located on another server on the network, one that is already running an SCP capable SSH server. If you do not have one of these requirements feel free to skip this section or pause to set this up on your own. I feel it is easier to install via SSH due to the large amount of actual typing you are required to do, whereas with SSH you can merely copy/paste into the SSH window.
Change /tmp from read-only to writable (used to store the SSH keys) and then remount it. Ignore any errors you may or may not see from executing this command, the /tmp directory will still be unmounted.
umount /dev/md1
mdmfs -s 512M md1 /tmp
Connect to the network via DHCP with dhclient(8), for network interface name use ifconfig(8) (common interface names are em0, nfe0, etc; look for the one that mentions the media being Ethernet). Then create our SSH host keys via ssh-keygen(1).
dhclient <network interface>
cd /tmp
ssh-keygen -f /tmp/hostkey -t rsa1 -b 4096 -N ''
ssh-keygen -f /tmp/hostkey_dsa -t dsa -N ''
Next we will need to download your personal SSH keys from the network. Replace the username, IP address, and folder/file with the required information. After that is done go ahead and start up the SSH daemon with sshd(8).
scp <user>@<0.0.0.0>:~/.ssh/authorized_keys .
/usr/sbin/sshd -o PermitRootLogin=yes -o HostKey=/tmp/hostkey -o HostDSAKey=/tmp/hostkey_dsa -o AuthorizedKeysFile=/tmp/authorized_keys
Connect to the IP address that was assigned to the installation computer using ssh(1) with your personal SSH keys.[2]
ssh -l root <0.0.0.0>
Disk Partition Setup
First thing we need to do is switch into an sh(1) shell, then load the required kernel modules via kldload(8).
sh
kldload geom_journal
kldload geom_mirror
kldload geom_stripe
Moving on to the disk setup, first locate all of your disks, we can use dmesg(8) and egrep(1) for this. The system I am using for this guide has three disks, two disks will be utilized for the system and one will be dedicated for use by the /home partition. (There are many reasons for this, one being that you can then seamlessly switch between operating systems and still retain your /home folder.)
dmesg | egrep "^ad|^da|^hd"
ada0 at ahcich1 bus 0 scbus1 target 0 lun 0 ada0: <VBOX HARDDISK 1.0> ATA-6 SATA 2.x device ada0: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada0: Command Queueing enabled ada0: 512000MB (1048576000 512 byte sectors: 16H 63S/T 16383C) ada0: Previously was known as ad6 ada1 at ahcich2 bus 0 scbus2 target 0 lun 0 ada1: <VBOX HARDDISK 1.0> ATA-6 SATA 2.x device ada1: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada1: Command Queueing enabled ada1: 512000MB (1048576000 512 byte sectors: 16H 63S/T 16383C) ada1: Previously was known as ad8 ada2 at ahcich3 bus 0 scbus3 target 0 lun 0 ada2: <VBOX HARDDISK 1.0> ATA-6 SATA 2.x device ada2: 300.000MB/s transfers (SATA 2.x, UDMA6, PIO 8192bytes) ada2: Command Queueing enabled ada2: 256000MB (524288000 512 byte sectors: 16H 63S/T 16383C) ada2: Previously was known as ad10 |
For partition table setup we will be using GUID Partition Table (GPT) via gpart(8). Let's first pull up a list of the current partitions.
gpart show
If there are existing partitions on any disk remove them with the delete option, then destroy the disk partitioning scheme. You will need to fill in appropriate values according to your setup, the disk is the device node you pulled from dmesg(8), and the partition number is the one listed in the column underneath the device node name when using 'gpart show'. Replicate this for all disks as necessary.
gpart delete -i <partition#> <disk>
gpart destroy <disk>
GUID Partition Table
Filesystem | Mountpoint | disk#0 | disk#1 | disk#2 | Description |
---|---|---|---|---|---|
freebsd-boot | 64K | 64K | bootstrap / GTP bootcode | ||
freebsd-ufs | / | 5G | 5G | mirrored between disks, mounted read-only | |
freebsd-swap | SWAP | 8G | 8G | mirrored between disks, using geli(8) | |
freebsd-ufs | /var | 10G | 10G | striped between disks | |
freebsd-ufs | /var/log | 5G | 5G | striped between disks | |
freebsd-ufs | /usr | * | * | striped between disks | |
freebsd-ufs | /home | * | separate disk dedicated to /home | ||
/tmp | 1gb mounted on encrypted SWAP with tmpmfs |
Create a new partition scheme on each disk to prep each disk for its partition table. The disk setup I happened to be using mapped my drives out to be ada0, ada1, and ada2; your drives maybe be different, if so replace them in the following three commands.
disk0=ada0
disk1=ada1
disk2=ada2
gpart create -s gpt $disk<0-2>
Now we need to create all of the disk partitions, the following table indicates how we will be laying out the partition table of all the disks. Each disk will contain a boot, root and swap partitions (mirrored across $disk0 and $disk1), /var, /var/log, and /usr partitions (striped across $disk0 and $disk1), and finally a /home partition filling the entirety of $disk2. Adjust the size of your filesystem partitions to fit your disk size needs (starting trimming down with the /usr partition).
Create the boot partition on each disk and embed GPT bootstrap into protective MBR, then install GPT bootstrap onto the boot partition.
gpart add -s 64K -t freebsd-boot $disk<0-2>
gpart bootcode -b /boot/pmbr -i1 -p /boot/gptboot $disk<0-2>
Then create swap and filesystem partitions; finally create the partition for /home.
gpart add -s 5G -t freebsd-ufs -l root<0/1> $disk<0/1>
gpart add -s 8G -t freebsd-swap -l swap<0/1> $disk<0/1>
gpart add -s 10G -t freebsd-ufs -l var<0/1> $disk<0/1>
gpart add -s 5G -t freebsd-ufs -l log<0/1> $disk<0/1>
gpart add -t freebsd-ufs -l usr<0/1> $disk<0/1>
gpart add -t freebsd-ufs -l home $disk2
Verify the partition table to make sure all of the disks are setup correctly.
gpart show -lp
=> 34 1048575933 ada0 GPT (500G) 34 128 ada0p1 (null) (64k) 162 10485760 ada0p2 root0 (5.0G) 10485922 16777216 ada0p3 swap0 (8.0G) 27263138 20971520 ada0p4 var0 (10G) 48234658 10485760 ada0p5 log0 (5.0G) 58720418 989855549 ada0p6 usr0 (472G) => 34 1048575933 ada1 GPT (500G) 34 128 ada1p1 (null) (64k) 162 10485760 ada1p2 root1 (5.0G) 10485922 16777216 ada1p3 swap1 (8.0G) 27263138 20971520 ada1p4 var1 (10G) 48234658 10485760 ada1p5 log1 (5.0G) 58720418 989855549 ada1p6 usr1 (472G) => 34 524287933 ada2 GPT (250G) 34 128 ada2p1 (null) (64k) 162 524287805 ada2p2 home (250G) |
RAID0 & RAID1
Now that the partition table is laid out we can move on to setting up the RAID configuration and filesystem labels. We will be using gmirror(8) to put the root and swap partitions into RAID1 systems. Then using gstripe(8) put the /var, /var/log, and /usr partitions into RAID0 systems.
gmirror label -v -b load root gpt/root0 gpt/root1
gmirror label -v -b prefer swap gpt/swap0 gpt/swap1
gstripe label -v var gpt/var0 gpt/var1
gstripe label -v log gpt/log0 gpt/log1
gstripe label -v usr gpt/usr0 gpt/usr1
UFS Journaling
Journaling capability stores a log of file system transactions, i.e.: changes that make up a complete disk write operation, before meta-data and file writes are committed to the disk proper. This transaction log can later be replayed to redo file system transactions, preventing file system inconsistencies. This method is yet another mechanism to protect against data loss and inconsistencies of the file system.[3] Begin by creating all the journals for the filesystems with gjournal(8).
gjournal label mirror/root
gjournal label stripe/var
gjournal label stripe/log
gjournal label stripe/usr
glabel label home ${disk2}p2
gjournal label label/home
Clear/Mount Filesystems
The next natural step is to construct all of the UFSv2 file systems with newfs(8). We will be setting the minimum free space threshold to 5% in addition to enabling journaling and setting UFS to UFSv2.
newfs -m 5 -O 2 -J mirror/root.journal
newfs -m 5 -O 2 -J stripe/var.journal
newfs -m 5 -O 2 -J stripe/log.journal
newfs -m 5 -O 2 -J stripe/usr.journal
newfs -m 5 -O 2 -J label/home.journal
After this mount(8) the root partition and create all the base folders for the other mounts and then mount them as well.
mount -t ufs -o async /dev/mirror/root.journal /mnt
mkdir -p /mnt/home /mnt/usr /mnt/var
mount -t ufs -o async /dev/label/home.journal /mnt/home
mount -t ufs -o async /dev/stripe/usr.journal /mnt/usr
mount -t ufs -o async /dev/stripe/var.journal /mnt/var
mkdir -p /mnt/var/log
mount -t ufs -o async /dev/stripe/log.journal /mnt/var/log
At this point you mounts should look like the following.
df -HTt ufs | egrep "Filesystem|journal"
Filesystem Type Size Used Avail Capacity Mounted on /dev/mirror/root.journal ufs 4.2G 20k 3.9G 0% /mnt /dev/label/home.journal ufs 259G 8.2k 246G 0% /mnt/home /dev/stripe/usr.journal ufs 980G 8.2k 931G 0% /mnt/usr /dev/stripe/var.journal ufs 19G 12k 18G 0% /mnt/var /dev/stripe/log.journal ufs 9.4G 8.2k 8.9G 0% /mnt/var/log |
FreeBSD Installation
Now that the file system hierarchy is setup we can install the FreeBSD base system. In order to do so we will manually be entering the folder on the installation media where the installation files reside and then extracting them onto the new filesystem in its temporarily mounted location. (Only include the lib32.txz file if you are installing on an amd64 system with amd64 installation media.)
Manual Install
cd /usr/freebsd-dist
export DESTDIR=/mnt
for file in base.txz doc.txz lib32.txz kernel.txz;
do (cat $file | tar --unlink -xpJf - -C ${DESTDIR:-/}); done
Next chroot(8) (change root) into your newly installed system.
chroot /mnt
System Configuration
Setup the network and necessary startup files so the zpool will be mounted automatically on boot. Start by creating the /etc/rc.conf system configuration file.
cat >> /etc/rc.conf << _EOF_
hostname="VM.freebsd" ifconfig_em0="DHCP" geli_swap_flags="-e aes -l 256 -s 4096 -d" ntpd_enable="YES" ntpd_sync_on_start="YES" sshd_enable="YES" tmpmfs="YES" tmpsize="1024m" tmpmfs_flags="-m 0 -o async,noatime -S -p 1777" _EOF_ |
Next we need to create the /boot/loader.conf boot configuration file. Let us start by setting some defaults and then telling it which kernel modules you need loaded on boot. Then tell the loader what to boot from and how to mount said root partition.
cat >> /boot/loader.conf << _EOF_
autoboot_delay="5" loader_logo="beastie" ahci_load="YES" geom_eli_load="YES" geom_mirror_load="YES" geom_stripe_load="YES" vfs.root.mountfrom="ufs:/dev/mirror/root.journal" vfs.root.mountfrom.options="rw" _EOF_ |
Edit the /etc/fstab and add all the appropriate entries for the swap and filesystem partitions.
cat >> /etc/fstab << _EOF_
# Local Mounts /dev/mirror/swap.eli none swap sw 0 0 /dev/mirror/root.journal / ufs async,noatime,rw 1 1 /dev/label/home.journal /home ufs async,noatime,rw 2 2 /dev/stripe/usr.journal /usr ufs async,noatime,rw 2 2 /dev/stripe/var.journal /var ufs async,noatime,rw 2 2 /dev/stripe/log.journal /var/log ufs async,noatime,rw 2 2 _EOF_ |
Now that we have our default configuration lets set a root password, fix the local time zone, create a mail aliases database, and exit out of the chroot environment.
passwd
ln -s /dev/null /etc/localtime
tzsetup
cd /etc/mail ; make aliases
exit
At this point your FreeBSD system is fully installed with a very minimal base system. Go ahead and remove the installation media and reboot(8).
reboot now
Notes
- ^ "FreeBSD Handbook". Chapter 20 - GEOM: Modular Disk Transformation Framework. http://www.freebsd.org/doc/handbook/geom.html.
- ^ "PuTTY". If you are not using a Linux or BSD derived operating system you can alternatively use PuTTY. http://www.chiark.greenend.org.uk/~sgtatham/putty/.
- ^ "FreeBSD Handbook". Chapter 20.7 - UFS Journaling Through GEOM. http://www.freebsd.org/doc/handbook/geom-gjournal.html.